Updating value in Simulink - matlab

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)

Related

How does Dymola choose the iteration variables during nonlinear system initialization process?

Assuming I have a very complicated thermal-fluid model built with Dymola. During the initialization process, how would dymola choose the iteration variables for the nonlinear solver? Is there a standard for this issue in dymola? I wanna make this clear, cause sometimes if the start values of the iteration variables are too far away from the right solution, there would be a divergence issue during the initialization process. I think if I could know the choice of iteration variables, I could make sure their values are appropriate instead of checking all the start values.
I think this information is not available to the public. At least I could not find anything in the user manuals. Therefore, you have only limited options.
What you can do is:
List your current iteration variables
Try to influence the selection
Get information on performed iterations
List iteration variables
You can list your current iteration variables by activating the flag
Advanced.LogNonLinearIterationVariables = true;
The iteration variables will be listed in the Translation tab as info message Variables appearing in the nonlinear systems of equations:
Influence selected variables
You can influence (but not control) the variables selected for iteration by setting start values. Take this code for example:
model MyNonLinear
Real x;
Real y;
Real z(start=-1);
equation
0 = y - z;
x = (y + z)^2;
x = (y + z) + time;
end MyNonLinear;
If you translate it with the above flag active, Dymola will give this information in the translation tab of the message window:
Iteration variables:
y
When you additionally set a start value for x, (e.g. start=1) x becomes the iteration variable in this case.
Information on performed iterations
To get more information on the performed iterations, activate the Nonlinear solver diagnostics flags in the Debug tab of the Simulation Setup:
Dymola will then display additional information in the simulation log. Note that some of these flags can generate a log of output.
This is possible via a very lightly documented feature. See the 2019 FD01 release highlights for some limited info: https://www.3ds.com/fileadmin/PRODUCTS/CATIA/DYMOLA/PDF/Dymola-2019FD01-highlights.pdf
Specifically:

if statement block in Simulink accumulates last true value

If statement in Simulink is not like in a programming language, it accumulates last true value untill it occurs again.
As it can be seen here, when random value is lower than 0.5 (if condition) output dosn't give zero as one normally expects from if statement.
What is the proper way to use an if? (Where preferably I don't want to put saturation and matlab function)
The Out block within the If Action subsystem has a property to either hold or reset its output when disabled. The default is to hold; you want it to reset. You'll also need to specify 0 as the initial condition, which is what it'll reset to.
So far what I could do this to use an elementary matlab function;
function y = fcn(u)
if u>0
y = u;
else
y = 0;
end
end
but I wondered it would be a proper way of using if block.
Change out blocks property in If action subsystem to 'reset', it looks like it is 'held' in your current implementation

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!

Simulink return not-valid input

I have a model which takes the root of the input in an matlab function block. The input should always positive; however, sometimes simulink gives a negative number. The reason is that i use an implicit solver (ode15s due to other part of the system being stiff) and simulink have a invalid estimate. My question is: how can I tell simulink that the input is invalid which makes the solver take a smaller step (without stopping)? Can I return a special value (e.g., NaN) or throw an error (without stopping the simulation)?
You can return 0 in your MATLAB Function block if the input is negative:
if u<=0
y = 0;
else
y = sqrt(u);
end
where u is the input and y the output of the function.
Use the Hit Crossing Block to force the solver to take small time steps as your signal approaches zero. This will work assuming your model is correctly set up to force the signal to go no lower than zero (i.e. it works something like an Abs block, which will hit zero and then continue with a positive value).
My solution was to add another output, isInputValid. This is 0 if the input is invalid and 1 if the input is valid. This output is then integrated by a new integration block. It seems like the discontinuity produced by the boolean variable makes sure that the integrator takes smaller steps.
Example:
if ( u<0)
y = -realmax;
isInputValid = 0;
else
y = sqrt(u);
isInputValid = 1;
end
Then attach an integrator to the output of isInputValid.

For iterator (loop)

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