Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clocking of synchronous state machines #3580

Open
sturmk opened this issue Oct 1, 2024 · 6 comments
Open

Clocking of synchronous state machines #3580

sturmk opened this issue Oct 1, 2024 · 6 comments

Comments

@sturmk
Copy link

sturmk commented Oct 1, 2024

I currently try to model a simple controller with the State Machine language constructs as described in the Modelica Specification (Chapter 17).
The specification mentions quite a few time the words "clock tick". Yet, the specification fails to describe how to establish a formal relation between a clock and a state machine (either semantically or syntactically). I'd request a clarification on this matter in the next version of the language spec.
For reference: I currently use OpenModelica, and tried to guess a solution by defining a clock in the state machine module, and also by exporting it to the sub-blocks with inner/outer definitions. Unfortunately, I was not able to change the state machine clock tick rate by this, and it stayed unchanged at one tick / second.

@HansOlsson
Copy link
Collaborator

I would say that it corresponds to the condition of transitions being on that clock.

There are several ways of handling that.

We have the following Example:
transition(A0, A1, sample(time, Clock(1, 1000)) > 0.0095);
Here the clock of the condition is Clock(1, 1000).

The second option is where everything is clocked, but without specifying a clock as in https://specification.modelica.org/maint/3.6/state-machines.html#example
That can be handled by using the same style as AssignClock (or using that component directly) - by adding:

public
  Clock c=Clock(1,100);
  Integer dummy;
equation
   when c then
    dummy=v;
  end when;

@sturmk
Copy link
Author

sturmk commented Oct 1, 2024

I would say that it corresponds to the condition of transitions being on that clock.

There are several ways of handling that.

We have the following Example: transition(A0, A1, sample(time, Clock(1, 1000)) > 0.0095); Here the clock of the condition is Clock(1, 1000).

I don't fully understand how this would produce a "synchronous" state machine. This means that for different transitions, differing clock tick rates can be set. Also I want to implement transitions based on specific signal events, and not a timed transition.
I expected, given the name "synchronous", one clock which evaluates all transitions at a clock tick, much like finite state automata in digital electronics.

The second option is where everything is clocked, but without specifying a clock as in https://specification.modelica.org/maint/3.6/state-machines.html#example That can be handled by using the same style as AssignClock (or using that component directly) - by adding:

public
  Clock c=Clock(1,100);
  Integer dummy;
equation
   when c then
    dummy=v;
  end when;

I cannot follow your example. None of the State Machine language constructs are used here.

@HansOlsson
Copy link
Collaborator

I would say that it corresponds to the condition of transitions being on that clock.
There are several ways of handling that.
We have the following Example: transition(A0, A1, sample(time, Clock(1, 1000)) > 0.0095); Here the clock of the condition is Clock(1, 1000).

I don't fully understand how this would produce a "synchronous" state machine. This means that for different transitions, differing clock tick rates can be set.

No, the transitions should all be on the clock of the state-machine. That is only possible if they all tick synchronously.

I expected, given the name "synchronous", one clock which evaluates all transitions at a clock tick, much like finite state automata in digital electronics.

Having sample(cond, clock) with different conditions but the same clock, for all of the conditions of all transitions would ensure that they are all handled according to the given clock. Having an event-based finite-state-machine instead would be a future extension (currently you can implement them using event clocks, but it becomes messy).

The second option is where everything is clocked, but without specifying a clock as in https://specification.modelica.org/maint/3.6/state-machines.html#example That can be handled by using the same style as AssignClock (or using that component directly) - by adding:

public
  Clock c=Clock(1,100);
  Integer dummy;
equation
   when c then
    dummy=v;
  end when;

I cannot follow your example. None of the State Machine language constructs are used here.

It's in addition to the code in HierarchicalAndParallelStateMachine from the link (that contains those constructs) so:

model SpecifiedClock
   extends HierarchicalAndParallelStateMachine;
public
  Clock c=Clock(1,100);
  Integer dummy;
equation
   when c then
    dummy=v;
  end when;
end SpecifiedClock;

@casella
Copy link
Collaborator

casella commented Oct 1, 2024

Having sample(cond, clock) with different conditions but the same clock, for all of the conditions of all transitions would ensure that they are all handled according to the given clock. Having an event-based finite-state-machine instead would be a future extension (currently you can implement them using event clocks, but it becomes messy).

This is also discussed quite extensively in #2287, unfortunately the discussion did not reach ignition temperature back then. I think this could be very interesting for the modelling of control automata in power system models, @adriguir, @marcochiaramello, @joyelfeghali, and @rosiereflo could comment on that.

@sturmk
Copy link
Author

sturmk commented Oct 4, 2024

@HansOlsson thank you for your explanations! Still, I think we need to dissect the topic a bit more:

Consider me reading the Modelica language spec, in which the terms "clock of the state machine" and "clock tick of the state machine" are used, but never clearly defined. Now let's consider the following example:

model statemachine_example
inner Integer i(start = 0);

block StateA
  outer output Integer i;
equation
  i = previous(i) + 1;
end StateA;
StateA sA;

block StateB
  outer output Integer i;
equation
  i = previous(i) - 1;
end StateB;
StateB sB;

equation

transition(sA, sB, sample(i, Clock(1,  100)) >= 10, immediate=false);
transition(sB, sA, sample(i, Clock(1,1000)) <=  0, immediate=false);

initialState(sA);

end statemachine_example;

What is here "the clock of the state machine"? I assume Clock(1,1000)? And will therefore the Clock(1,100) be disregarded?

Then let's look at a different case; a formulation with the when(...)-operator:

model SpecifiedClock
   extends HierarchicalAndParallelStateMachine;
public
  Clock c=Clock(1,100);
  Integer dummy;
equation
   when c then
    dummy=v;
  end when;
end SpecifiedClock;

I would consider this to be an anti-pattern, or negative example, since
A) it brings into questions the usefulness of the introduction of superfluous language constructs such as transition() and initialState()-operators, and
B) possible lack of tool support, with difficulties for Modelica environments/IDEs to extract an FSM diagram.

So I guess an ideal, "expressive" solution for my problem would likely be (if correct, doesn't seem to work currently with OpenModelica):

model statemachine_example
inner Integer i(start = 0);

block StateA
  outer output Integer i;
equation
  i = previous(i) + 1;
end StateA;
StateA sA;

block StateB
  outer output Integer i;
equation
  i = previous(i) - 1;
end StateB;
StateB sB;

Clock clk = Clock(1,100);

equation

transition(sA, sB, sample(i, clk) >= 10, immediate=false);
transition(sB, sA, sample(i, clk) <=  0, immediate=false);

initialState(sA);

end statemachine_example;

Since it clearly introduces "the one and only" state machine clock, and uses the state machine Modelica language constructs as intended.

@HansOlsson
Copy link
Collaborator

@HansOlsson thank you for your explanations! Still, I think we need to dissect the topic a bit more:

Consider me reading the Modelica language spec, in which the terms "clock of the state machine" and "clock tick of the state machine" are used, but never clearly defined. Now let's consider the following example:

...

transition(sA, sB, sample(i, Clock(1, 100)) >= 10, immediate=false);
transition(sB, sA, sample(i, Clock(1,1000)) <= 0, immediate=false);

initialState(sA);

end statemachine_example;


What is here "the clock of the state machine"? I assume Clock(1,1000)? And will therefore the Clock(1,100) be disregarded?

No, the model is invalid.

The synchronous sample goes from non-clocked to clocked, but i is already clocked which makes it illegal. If it had been sample(time, ...) (or sample(hold(i), ...)- there would be two clocks for the same clocked partition and that would be illegal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants