III: Python and C Codegen

  • Keep advantages of statically-allocated C code generation
    • Lustre
    • Heptagon
    • Scade
  • Use dedicated tools (e.g., wcet)
  • Use modern Python libraries for simulation, debug, prototyping
    • GUIs (Tkinter, PyQt, IPython)
    • numpy, matplotlib
    • python-control
    • scikit-learn

Under the hood

  • Compile to C (classic)
  • Generate Python wrapper (using swig)
  • Link the dynamic library
In [1]:
node pendulum(d2x: bool) returns (theta: float)
var thetap, d2theta: float;
let
  thetap = 0.0 fby theta;
  d2theta = (g *. sin(thetap) -. d2x0 *. cos(thetap)) /. l;
  theta = integ(0.0, integ(0.0, d2theta));
tel

node cart(x_user: float; mode_change: bool) returns (p: pendulum)
var d2x, theta: float; last x: float = 0.0;
let
  theta = pendulum(d2x);
  x = integ(0.0, integ(0.0, d2x));
  automaton
    state User
      do mode_name = "user";
        d2x = 10.0 *. (x_user -. last x);
      unless mode_change then PID

    state PID
      do mode_name = "PID control";
         d2x = 10.0 *. pid<<kP, kI, kD>>(error);
      unless mode_change then BangBang

    state BangBang
      do mode_name = "BangBang control";
         d2x = bangbang(error, 50.0);
      unless mode_change then User
  end
tel

Swig generates a Python wrapper for the C code
We can then import the pendulum module and call the nodes.

In [2]:
import pendulum

window = Canvas(Tk(), width=pendulum.max_w, height=pendulum.max_h)
cart = pendulum.Cart()
cart.reset()
x_user = get_mouse_pos_x()

def repaint():
    window.delete("all")
    out = cart.step(x_user)
    display(out)
    window.after(int(1000 * pendulum.dt), repaint)