Zélus Continued - Real-Time and Embedded Systems

Zélus Continued:
a (starting) programming of the Simulink blocks
from the standard library 1
Timothy Bourke
Marc Pouzet
DI, ENS
SYNCHRON, Kiel, Germany
December 2015
1
Joint work with JL. Colaco, B. Pagano, C. Pasteur (Core Team, Esterel-Tech.)
Zélus, a synchronous language with ODEs
2
Recycle synchronous language principles and compilation techniques.
Milestones
I
A discrete-time semantics [JCSS’12]
I
A Lustre kernel with ODEs [LCTES’11]
I
Hierarchical automata, both discrete and hybrid [EMSOFT’11]
I
Causality analysis [HSCC’14]
I
Sequential code generation [CC’15]
SCADE Hybrid at Esterel-Tech. (2014 - 2015)
I
Prototype based on KCG 6.4 (now KCG 6.6)
I
SCADE Hybrid = full SCADE + ODEs
I
Generates FMI 1.0 model-exchange FMUs with Simplorer
2
zelus.di.ens.fr
Separation between Discrete and Continuous Time
The type language [LCTES’11]
D
C
bt ::= float | int | bool | zero | · · ·
σ
k
k
::= bt × ... × bt −→ bt × ... × bt
::= D | C | A
Function Definition: fun f(x1,...)
I
= (y1,...)
Combinatorial functions (A); usable anywhere.
Node Definition: node f(x1,...)
I
= (y1,...)
Discrete-time constructs (D) of SCADE/Lustre: pre, ->, fby.
Hybrid Definition: hybrid f(x1,...)
I
A
= (y1,...)
Continuous-time constructs (C): der x = ..., up, down, etc.
An excerpt of the Pervasives module from Zélus
AD for discrete stateless functions.
val
val
val
val
val
val
val
val
( on ) : zero * bool -> zero
orz : zero * zero -> zero
( = ) : ’a * ’a -AD-> bool
( <> ) : ’a * ’a -AD-> bool
( < ) : ’a * ’a -AD-> bool
( > ) : ’a * ’a -AD-> bool
( <= ) : ’a * ’a -AD-> bool
( >= ) : ’a * ’a -AD-> bool
val
val
val
val
...
min : ’a * ’a -A-> ’a
not : bool -A-> bool
( & ) : bool * bool -A-> bool
( or ) : bool * bool -A-> bool
The Zélus typing discipline
I
I
I
All discontinuities are aligned with a zero-crossing.
Checked during static typing.
In particular, values with a discrete type (e.g., bool, int) do not
change during integration.
Discrete events
A zero-crossing up(e) returns a value of type zero.
It can be used to trigger a regular Lustre node.
let hybrid down(x) = up(-.x)
let hybrid cross(x) = orz(up(x), down(x)
let hybrid above(x) = present (cross(x)) -> true else false
value down: float -C-> zero
val either: float -C-> zero
val above: float -C-> bool
Calling a synchronous stream function
let node counter(x) = o where
rec o = (if x then 1 else 0) + (0 fby x)
(* Compute when [z] is present. Otherwise, previous value *)
let hybrid trigger(z) =
present z -> counter(x) init 0
val counter: int -D-> int
val trigger: zero -C-> int
counter(x) computes a discrete-time signal (a stream); trigger(x)
computes a piece-wise constant continuous-time signal.
A program that is rejected
let hybrid wrong(x, y) = x >= y
File "wrong.zls", line 1, characters 25-31:
>let hybrid wrong(x, y) = x >= y
>
^^^^^^
Type error: this is a stateless discrete expression
and is expected to be continuous.
let hybrid above(x) = present
| up(x) -> true
| up(-. x) -> false
init
(x >= 0)
val above : float -C-> bool
Zélus prevents from writting a boolean signal that may change during
integration, even if it is not used.
Zélus vs SCADE Hybrid
SCADE Hybrid is less constraining: Only state changes must be aligned
on a zero-crossing. But, the argument of an up(.) must be continuous.
The separation between continous-time and discrete-time is done during
the clock calculus.
It is possible to write comparisons and signals that are discontinuous
during integration, whereas Zélus forbids, e.g.:
if x >= high then high else if x <= low then low else x
...
der x = if x >= 0.0 then -1.0 else 1.0 init 0.0
An extra type system indicates whether a signal is piece-wise constant,
continuous or (possibly) discontinuous between two zero-crossings.
How Zélus behave for programming classical blocks of the
Simulink standard library?
The Simulink Standard Library
Common Used Blocks
The Integrator Block
Various form of integration blocks: with reset, with saturation, both, etc.
Integrator blocks, saturation block
Either/Above block
The either block detect that an input x is “not far” from a value v.
At the moment, leaving 0 is not an event in Zélus. This explain the
necessary use of . Can we do better?
Either (2)
ok = true when abs(x − v ) ≤ SCADE Hybrid allows for writting (in Zélus syntax):
let hybrid either_disc(eps, x, v) = ok where
rec ok = abs_float(x -. v) <= eps
ok is tagged to be discontinuous between two zero-crossings.
Example: modeling a second order system with saturation
See: http://blogs.mathworks.com/seth/2014/01/22/
how-to-model-a-hard-stop-in-simulink/
Second order with limit
Simulink propose to use a special block so x does not depend
instantaneously on u.
At the moment, the causality analysis of Zélus considers x to depend
instantaneously of u. With no reason!
Yet, SCADE Hybrid does the analysis and generates code correctly!
Current work
Continue to program blocks from the standard Simulink library; write
complete examples to exercice both compilers.
I
Both Zélus and SCADE Hybrid.
I
E.g., Backhoe, Bang bang controller, clutch model, etc.
I
These experiments exercice all features of the languages.
I
There is a change in style.
I
Systems have to be programmed differently: Boolean for logic
operations instead of floats.
Compare efficiency, accuracy, style, in detail.
Preliminary results and problems to solve
I
Causality analysis: fix it so that output do not depend on a
condition when it weak. SCADE Hybrid does this correctly.
I
Improve the implementation such that zero-crossings are shared: if
two zero-crossing appears in exclusive modes, only one must be
computed.
I
The typing constraint may be overly constraining. SCADE Hybrid is
less constraining. More experiments must be done.
I
Translate ODEs into difference equations (synchronous code) for
real-time simulation.
I
Arrays. SCADE Hybrid have them; Implementation in Zélus is
under way with a form of iterator inspired by SISAL.