Question

I was trying to execute 2 models one by one in a simulation via state chart. The pseudo-code follows. In model test, there are two blocks, stateA and stateB. At the beginning of the simulation, stateA is executed. 10 seconds later, stateA is stopped while stateB is executed. The value of v at the stop point needs to transfer from stateA to stateB. Could anybody give me some advises? Thanks a lot!


model test 
  inner Integer v(start = 1); 

  block StateA 
    outer output Integer v; 
  equation 
    v = previous(v) + 2; 
  end StateA; 
  StateA stateA; 

  block StateB 
    outer output Integer v; 
  equation 
    v = previous(v) - 1; 
  end StateB; 
  StateB stateB; 

equation 
  initialState(stateA); 
  transition(stateA, stateB, t >= t0, immediate=false); 
end test;

Another thing is why I cannot simulate the following simple example in openModelica?

model StateMachine1
  inner Integer i(start=0);

  block State1
    outer output Integer i;
  equation
    i = previous(i) + 2;
  end State1;
  State1 state1;

  block State2
    outer output Integer i;
  equation
    i = previous(i) - 1;
  end State2;
  State2 state2;

equation
  initialState(state1);
  transition(state1, state2, i > 10, immediate=false);
  transition(state2, state1, i < 1, immediate=false);
end StateMachine1;

Error: Class initialState not found in scope StateMachine1

Was it helpful?

Solution

about your model I think that the best way to realize it is to have the three models coded in three different classes, and then have a wrapper in which you have all the variables of our model, and then implement in the wrapper a when - elsewhen - elsewhen statement that will restart the state variables of the models that is been activated, and finally a if - elseif - else statement to link the wrapper variables to the corresponding one of the active block. This way you can also change causality of the variables in your models without causing errors. As an example I post the case of a broken pendulum model:

model BreakingPendulum2
extends BasePendulum(p(m=1, g=9.81, L=0.5));
input Boolean Broken;
protected
Pendulum pend (p=p, u=u, enable=not Broken);
BrokenPendulum bpend(p=p, u=u, enable=Broken);
equation
when Broken then
reinit(bpend.pos, pend.pos);
reinit(bpend.vel, pend.vel);
end when;
pos = if not Broken then pend.pos else bpend.pos;
vel = if not Broken then pend.vel else bpend.vel;
end BreakingPendulum2;

The class BasePendulum implements the variables that you need to compute about the system is been simulated. Extending from that cass you implement your three different versions of the models valid in different cases. Then you write a block like the one I posted and implement the logic based on the validity of the different models.

OTHER TIPS

what you are trying to do is described in details in the material regarding the new state machine functionalities introduced into the Modelica 3.3 specifications. Below you can find some references:

The mistake in your model is that in Modelica 3.3 sampling time inference for all variables has been introduced, i.e. discrete variables with different discretization in time cannot be used in the same equations, in other words you must use only variables with the same clock within an equation. In your case you have a continous variable (time), and a discrete one v. Therefore you cannot use time into a transition statement (that will become an equation during the translation of the modelica code) that affects the behaviour of the discrete variable v. In order to do what you need, one solution is todefine a clock for all the variables in your model and then build up the logic (if you need more than one sampling time you must use special operators such as superSample).

    model StateMachine3
  Real i(start = 0,fixed=true);
  inner Real id(start = 2);
  Real td(start = 0,fixed=true);

  State1 state1;

  model State1
    outer output Real id;
  equation 
    id = 2;
  end State1;

  model State2
    outer output Real id;
  equation 
    id = - 1;
  end State2;
  State2 state2;
equation 
  td = sample(time, Clock(1, 10));
  when Clock(1, 10) then
    i =  previous(i) + id;
  end when;
  initialState(state1) ;
  transition(
    state1,
    state2,td > 10,
    immediate=false,
    reset=false,
    priority=1,synchronize=false);
end StateMachine3;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top