I created this state machine chart in Simulink using the StateFlow :
There are two states (S1,S2), one of which (S1) has 3 nested parallel FSM , each one has 4 states (SS1, SS2, SS2, SS4) , I put a default state in all of the 3 FSMs (SS1), and in the main two states (default S2).
To test the main FSM (S1,S2) , I used signal builder for all my inputs/events. One of the inputs is a square wave which is a clock event for my main FSM (1 Hz) and the duration of the simulation is 50 sec.
The problem i have is that i can see in the signal builder that i have a square wave, however when i put scope to that clock i see one square wave (extending from 0 to 49.5 second then drops to 0) .
Where is my clock ? what isn't it feeding my FSM properly ?
Here is the FSM:
The orthogonal sub-states are :
in details:
in in between S1 and S2
One of the signal builder , which has the Clock signal is:
The other has the following signals:
The problem is that you are using the default step size with ode3. When using a fixed-step solver the auto step size is calculated as (StopTime-StartTime)/50. In your case this gives a step size of 1.
Since at t = 0,1,2,3,...49 the Clock has a value of 2, that's what you see in the scope.
At t =50 the Clock has a value of 0, and that's what you're seeing in the scope.
You need to go to the Solver Panel of the Simulaton->Model Configuration Parameters pull-down menu.
Then open up the Additional Options option and change the step size to something smaller, such as 0.01.
Alternatively (depending on your other requirements) you could use a variable step solver.
Related
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)
Question
Is there a way to enforce the simulation step to be smaller than a compile-time constant in a simulink model?
Context
I'm trying to build a PWM block on simulink. As it is now, I have to make sure that the user chooses a step size responsibly (smaller than half the period chosen by him), otherwise the block behaves abnormally. The only way I came up was to stop the simulation if the step size is not small enough, but I find that very annoying (as a user). If possible, I'd like for the user to not worry about this at all.
Here's what I would do: add the following pseudo-code to the block callback StartFcn:
T_PWM = get_param(gcb,...); % get the block parameter (period) of the current PWM block (string)
T_PWM = str2double(T_PWM);
T_solver = get_param(bdroot,'FixedStep'); % get fixed used by the solver (string)
T_solver = str2double(T_solver); % convert from string to double
if T_solver > 0.5*T_PWM
error('Solver step size must be smaller than half the PWM period')
end
I have a MATLAB function block in simulink and for each step simlulink does I want to input a counter with increment 1.
Ex:
1st Step -> Acc=1
2nd Step -> Acc=2
I tried using a Count up block + Pulse generator but the time step of simulink is not constant.
Any ideas?
A common way to do this is to use a sum and a memory block with an initial condition of 0. It should count steps in both fixed and variable step simulations. In fact I believe this would be build and perform very much like an s-function solution during simulation.
Why not just use an integrator block? You can choose with a discreet or continuous integrator block depending on your model type. You can specify the start conditions/value and reset conditions if needed. The image below shows an example of discreet and continuous blocks. Both are just using their default values. To do what you want (adding 1 to the output every step) just define the model sample time as an environment variable (eg sT=0.01) and set the integrator gain to be 1/sT.
i'm trying to simulate a distributed scheduler for ev (electric vehicle) charging. the desired behavior would shave peaks and fill valley, in other words minimize the peak-to-average ratio of the electric load on a test grid. ( such as in this paper: web.eecs.umich.edu/~hiskens/publications/1940.pdf )
Picture of wanted result:
So, basically, what I'm doing is this:
send to each user the aggregate load of the rest of the grid
initialize the charge scheduling vector randomly, this will be the starting point x0 of the IPM optimization
optimize: i want to minimize the peak-to-average ratio, or equivalently, the cost (quadratic fcn) of the supplied energy
The constraints are the following:
The sum of the charges scheduled between now and the departure moment of the vehicle is equal to the energy requirement (first line of Aeq)
Past scheduling cannot be changed (so it's equal to past load, ecs.ev_load ), scheduling post-departure must be zero ( I , the rest of Aeq matrix)
lower bound of energy consumption is zero
upper bound is a given parameter, ecs.max_load
x0=ecs.schedule;
I=eye(ecs.timeslots);
I(ecs.currenttime:ecs.ev.departure,:)=[];
Aeq=[zeros(1,ecs.currenttime-1) -1*ones(1,ecs.ev.departure-ecs.currenttime+1) zeros(1,ecs.timeslots-ecs.ev.departure);I];
beq=[-1*ecs.ev.requested_chg*ecs.nslotsperhour;ecs.ev_load;zeros(ecs.timeslots-ecs.ev.departure,1)];
A=[];
b=[];
nonlcon=[];
lb=zeros(ecs.timeslots,1);
ub=ecs.max_load*ones(ecs.timeslots,1);
options = optimoptions('fmincon','Algorithm','interior-point','MaxFunEvals',30000);
The objective function par at each ev sums
x: the scheduled load of the vehicle (the optimization variable)
other_loads: the future behavior of every non-ev load (unrealistic), the loads of the rest of ev schedules
other_loads=ecs.game_l; %l_n (all schedules in the grid, mine included)
other_loads(:,ecs.id)=[]; %l_-n (removed my own schedule)
schedule = fmincon(#par,x0,A,b,Aeq,beq,lb,ub,nonlcon,options);
function f=par(x)
tot=sum([x other_loads],2);
f=max(tot)/mean(tot);
end
Picture of what I'm getting:
Here's my problem: the optimization doesn't work. I keep tinkering with the code, but I always get (almost) the same result, where the valleys aren't filled at all, and the behaviour is almost constant. I verified by debugging that the content of the variables is correct, maybe I'm doing something wrong with the optimizer?
Thanks in advance
I am trying to implement a counter logic in SIMULINK where
in1, in2 are inputs
out1 is the output
if in2 = 0, out1 = 0;
if in2 = 1, out1 = 1 after x high edges of in1
I have tried using "Detect Rise Positive" block but failed miserably because I don't have sufficient experience of implementing a timing diagram correctly in SIMULINK. Could anyone kindly point me to the right direction?
Update
An approach I have taken since I posted this question is the "Triggered and enabled subsystem". I am trying to set it up so that:
in2 becomes the enable signal
in1 becomes the trigger
in2 becomes the intput to the subsystem
Out1 becomes the output of the subsystem
But I think that the above was rubbish. Unfortunately it is not VHDL where I could have implemented it using 4-5 lines of description of the hardware logic.
Using a Triggered and Enabled subsystem is the right approach, but your inputs (and no doubt what's inside the subsystem) needs to be modified.
Don't have any input to the subsystem (other than the trigger and enable signals).
Inside the subsystem,
set the enable block property to reset the state when disabled.
set the outport property to reset when disabled and give the initial condition as 0.
create a counter out of a constant (value=1), a summation and a unit delay block.
feed the counter into a Compare to Constant block set to the 'x' value in your question.
feed that block to the outport.
When enabled, the counter should count the required number of steps (when triggered) before the output goes high.
A counter logic can be implemented very easily in simulink. Take a switch,give the control input as int1. If int1 is 1 ur output shuld be 0 else take another switch give its control input as int2. if int2 is 1 ur output shuld be 1+ previous value given in feedback funit delay block