For iterator (loop) - matlab

I am trying to simulate throw of the ball under angles using simulink. I'm able to simulate it for one angle but I would like to simulate it using loop. This is what I want to do in simulink using FOR :
for i=-5:10:85
Here is picture of my simulink:

If I understand your question correctly, you essentially want to rerun your simulation multiple times for different values of the constant Degrees. Instead of using a For Iterator, you may be able to achieve effectively the same result by using vector operations. That is to say, change the value of the constant Degrees from being a scalar value to instead being a vector (in this particular case just set its value to be [5:10:85]). The outputs of your Simulink model (ie the x and y results) should now be vectors corresponding to the various Degree values.

Put all the blocks into the for-iterator subsystem. The For Iterator block will output the current iteration, you can use that index (which starts at 0/1) to cycle the angle from -5 to 85 (try to hook the For Iterator block up to a Gain and Sum block). At each iteration, all the blocks in the for-iterator subsystem will run, and the output of the For Iterator block will increment by one.
The previous solution to make the angles a vector will also work.

Using MATLAB's for reference page, I'd rewrite your line as:
for i=5:10:85
...
end

Related

How to trace out a curve

I am working on a project dealing with closed curves. I want to trace out a curve swept out by a coordinate vector moves. Just to get the code down I'm trying to accomplish the goal using a circle. I am able to animate the motion of the vector with the following command
animate(arrow, [[cos(2*Pi*n/1000),sin(2*Pi*n/1000)], shape = arrow,
scaling = constrained], n=0..1000, frames = 100);
Is there a way to trace the circle that is swept out by this curve. Again my goal is to be able to do this for an arbitrary parameterized curve. Any help is greatly appreciated.
Here is a basic but verbose way to do it,
restart;
plots:-animate(plots:-display,
[ 'plots:-arrow([cos(2*Pi*n/1000),
sin(2*Pi*n/1000)],
shape = arrow)',
'plot([cos(2*Pi*nn/1000),
sin(2*Pi*nn/1000),nn=0..n])',
scaling = constrained ],
n=0..1000, frames = 30);
If that seems complicated then perhaps it's good to review Maple's evaluation rules for procedure calls. Maple normally evaluates the arguments before passing them to the procedure.
But sometimes you don't want that evaluation to occur until, say, the procedure can provide a numeric value for a parameter in some argument. That is to say, sometimes you want to avoid premature evaluation of the arguments.
The seq command deals with this by having so-called special-evaluation rules, where the evaluation of the argument is delayed unto the seq index variable takes on it individual values.
The plots:-animate command allows you to deal with it by separating the main command from its arguments (which get passed separately, in a list). That is often adequate, but not when those arguments in the list also contain full calls to plotting commands which would not evaluate ok (ie. without error, up front) until the animating parameter gets its actual values.
That is why I also used single right-quotes to delay the evaluation of the calls to plots:-arrow and plot in the example above. Those evaluations need to wait until the animating parameter n takes on its actual numeric values.
And another, related approach is to create a procedure which accepts the animating parameter value and constructs a whole frame.
F := proc(n)
plots:-display(
plots:-arrow([cos(2*Pi*n/1000),
sin(2*Pi*n/1000)],
shape = arrow),
plot([cos(2*Pi*nn/1000),
sin(2*Pi*nn/1000),
nn=0..n]),
scaling = constrained);
end proc:
This can be handy as it lets you test beforehand.
F(307.2);
(I didn't bother to optimize F, but you could notice that the sin and cos calls happen twice, and instead do them just once inside the procedure and assign to local variables. That might make things easier when you go on to more involved parametric curves.)
Now the calls to plots:-animate can be terse,
plots:-animate(F, [ n ],
n=0..1000, frames = 30);
The above produces the same animation as before.
Here's another way, by constructing a list containing a sequence of all the frames.
Note that, as written, evaluating F at unknown, unassigned name n produces an error.
F(n);
Error, (in plots/arrow) invalid input: plottools:-arrow
expects its 3rd argument, pv, to be of type {Vector, list,
vector, complexcons, realcons}, but received 0.5000000000e-1*
(cos(0.6283185308e-2*n)^2+sin(0.6283185308e-2*n)^2)^(1/2)
The error occurs because n does not have a numeric value.
But the special-evaluation rules of the seq command allow us to proceed anyway, since it delays the evaluation of F(n) until n gets its values.
# note termination with full colon, to suppress output
S := [seq(F(n), n=0..1000, (1000-0)/(30-1))]:
nops(S); # check that we really got 30 frames
30
plots:-display(S, insequence=true);
That last command also displays the same 30-frame animation.

Updating value in Simulink

I am currently working on a spacecraft body with actuator, and given the equation below:
J·w_dot = -w^x·J·w + u (1)
where w^x is actually a notation of 3x3 matrix
[ 0 -w3 w2
w3 0 -w1
-w2 w1 0]
By rearranging (1), I got w_dot = (-w^x·J·w + u)/J. And here I face the problem, I need to update value constantly for w_dot but I have no idea how. I have tried the Memory block but it only update every 0.2 seconds which is not appropriate for the system.
This is my current setting:
I was thinking the integrator block could be the one to be updated every single cycle as initial condition could be set.
Yes, your solution seems about right; the integrator block will cause the system to be continuous-time, rather than discrete-time. This will output results as accurately as Simulink can accomplish.
You can set initial values for the integrator by double-clicking on the integrator block, setting the "Initial condition source" to "external", then connecting another input or constant block, output, or whatever else you want providing the initial value.
By the way, is J is the inertia tensor? In that case, you can't simply "divide" by it; you should multiply by its inverse (setting "Matrix" as the "Multiplication" option in the Divide block's options)

Simulink S-Functions - Retrieve Initial Values from another S-Function

I'm trying to model the respective processes of an internal combustion engine. My current modelling approach is to have different sub functions which model the different processes.
Within each sub function is a Level 2 S-Function which solves the ODEs to give the in cylinder state (pressure, temperature, etc).
The problem that I'm having is that each sub function is enabled depending on the current crank angle which is computed from the current timestep in Simulink. The first process works fine as I manually set the initial values, but then I can't pass the latest in-cylinder state (the output from the first sub function) to the second sub function to use as the initial conditions (it insists on using the initial values I set at the beginning of the simulation).
Is there any way round this? Currently I'm going along a path of global data stores, but haven't had any joy so far.
There are a lot of different ways to solve this problem.
I'll show some of them as examples.
You can create additive output with Unit dalay block like this:
So you can get value of your crank angle from previous timestep and USE IT in formula for solving you equations.
Also you can use some code like this:
if (t == 0)
% equations with your initial values
sred = 0;
else
% equations with other values
y = uOld + myCoeef;
end
Another idea: sometimes I use persistent variables in Matlab function to save values of some variable from previous step. But I think it makes calculation slower.
One more idea - if you have Stateflow you can create chart with two states: first for initial moment with your coefficient and second to solve new equations.
If I understood you in wrong way you can show your code and we'll offer some new ideas!
P.S. Example of my using of S-Function:
My S-Function needs 2 values: Q is calculated in simulink at every step, ro is initial I took from big matrix I loaded from workspace in table and took necessary value depending of time.
So there is no any initial values in S-Function - all needed values I transmit into it from simulink!

using from workspace block in simulink

how to use the "from workspace block in simulink" ?
I have tried using the from workspace block by given 10*2 matrix as input. it is appending some extra data along the data I have given .
and I have such 3 such blocks and want to know how I merge them.
Read the documentation. Simulink is time-based so the data in your From Workspace block must be as a function of time. Does your 10 x 2 matrix represent a signal as a function of time? If so, it needs to be as follows:
A two-dimensional matrix:
The first element of each matrix row is a
time stamp.
The rest of each row is a scalar or vector of signal
values.
The leftmost element of each row is the time stamp of the
value(s) in the rest of the row.
10 values isn't very much, it's likely that Simulink will need additional data points at intermediate times, if you have the Interpolate Data check box ticked. If not, "the current output equals the output at the most recent time for which data exists".
I think you may have a misunderstanding of the variables intended to be read by the FromWorkspace block.
The block expects a time series defining the value at various points in the simulation.
The From Workspace block help should point you in the right direction on this. Mathworks Help Documentation
I believe that something like the following would work for you:
>> WorkspaceVar.time=0;
>> WorkspaceVar.signals.values=zeros(10,2)
>> WorkspaceVar.signals.dimensions = [10,2]

how to create a changing variable for fsolve

i want fsolve to calculate the output for different uc each time (increasing uc by 0.001 each time). each output from fsolve should be sent to a simulink model seperatly. so i set a loop to do so, but i believe that at the currenty constellation (if it will work)will just calculate 1000 different values? is there a way to send out the values seperately?
if not, how can i create a parameter uc. that goes from 0 to say 1000? i tried uc=0:0.001:1000, but again, the demension doen't seem to fit.
how do i create a function that takes the next element of a vector/matrix each time the function is called?
best regards
The general approach to iterating over an array of values and feeding them one-by-one into a series of evaluations of a function follows this form:
for ix = 0:0.1:10
func(arg1, arg2, ix)
end
See how each call to func includes the current value of ix ? On the first iteration ix==0, on the next ix==0.1 and so forth. You should be able to adapt this to your needs; in your code the loop index (which you call i) is not used inside the loop.
Now some un-asked-for criticism of your code. The lines
x0=[1,1,1];
y=x0(1);
u=x0(2);
yc=x0(3);
options=optimset('Display','off');
do not change as the loop iterations advance; they always return the same values whatever the value of the loop iterator (i in your code) may be. It is pointless including them inside the loop.
Leaving them inside the loop may even be a waste of a lot of time if Matlab decides to calculate them at every iteration. I'm not sure what Matlab does in this case, it may be smart enough to figure out that these values don't change at each iteration, but even if it does it is bad programming practice to write your code this way; lift constant expressions such as these out of loops.
It's not clear from the fragment you've posted why you have defined y, u and yc at all, they're not used anywhere; perhaps they're used in other parts of your program.