A framework for Linux-based Real-time control sytems


OpenRTDynamics (ORTD) is a framework to implement block/signal based control- or signal processing systems and aims to be an open-source alternative to Simulink Coder / LabView / Xcos code generation. This framework is suitable for implementing discrete-time signal processing algorithms, using the same principles like in Scicos/Xcos or Simulink. However, schematics are described by combining special Scilab functions provided by the framework (a typical Scilab-file describing an ORTD-schematic is e.g. []). A comparision to Xcos and Simulink is given in Comparison.pdf. The obtained programs are real-time capable.

Launch a demo application - sorry, Safari does not work - (Source Code)

How it works

// Superblock: A simple oscillator without damping
function [sim, x,v] = oscillator(sim, u)
    // create a feedback signal
    [sim,x_feedback] = libdyn_new_feedback(sim);

        // implement a double-integrator chain
        [sim,a] = ld_add(sim, 0, list(u, x_feedback), [1, -1]);
        [sim,v] = ld_ztf(sim, 0, a, 1/(z-1) * T_a ); // Integrator approximation
        [sim,x] = ld_ztf(sim, 0, v, 1/(z-1) * T_a ); // Integrator approximation  
        // feedback gain
        [sim,x_gain] = ld_gain(sim, 0, x, 0.6);
    // close loop x_gain = x_feedback
    [sim] = libdyn_close_loop(sim, x_gain, x_feedback);
  • Each function call ld_* describes the relation between input- and output signals in dependence of potential inner states.
  • libdyn_new_feedback and libdyn_close_loop are used to realize feedback-loops.
  • By defining the function oscillator, a new function for describing I/O relationships is introduced

What you get

ORTD features the ability to implement state machines represented by multiple, switching subsystems (each subsystem corresponds to one state) [] . Subsystems (sub-simulations) can also run in the context of separated threads (with or without synchronisation to another one), e.g. to divide high- and low frequency portions [] or to run computationally intensive tasks in the background. Because of a remote control interface [] and the ability to include Scilab-Code (similar to Matlab S-functions) that could execute e.g. calibration routines [], ORTD is also ideally suited for laboratory automation.  Hereby, the ability to online-replace sub-schematics (sub-simulations) with replacements [] [] removes the effort of restarting the main real-time program when new algorithms are designed. An example for automating experiments using these concepts: []. The reliability of ORTD has been proven in a number of large experimental set-ups in medical engineering.

Because the real-time interpreter is implemented in a shared library, ORTD can also be easily integrated into other simulation frameworks e.g. Scicos or used within other software. The LGPL-license also allows commercial usage.

Slides that give a short introduction are available: ortd_slides.pdf (updated 02.6.2014). For technical details please consider the README. It also includes intructions on how to install ORTD on embedded ARM-systems, like the beaglebone. A tutorial and plenty of examples for each feature of ORTD are included in the package and finally, documentation for each individual block is available through the Scilab-Help.

Please Note: OpenRTDynamics does not depend on any part of Scicos/Xcos. ORTD does not use code-generation, but instead, algorithms for time-deterministic interpretation of simulations instead. The Scilab programming language is used for describing the schematics. When you run the Scilab-file a compilation procedure is performed resulting in a binary-like representation of your algorithm. This code can be transferred and executed by the ORTD-interpreter on the target device.

Tags: Realtime control implementation, Laboratory automation, Linux RT-Preempt, Signal-based simulation, Scilab, Embeddable C-Code libray, No code generation required


Installation of the interpreter

On any target device (e.g. any Linux-based ARM-single board computer, Ubuntu, MacOS): Clone the repository at GitHub into your favorite directory:

git clone

If you are compiling for Mac, you should configure the proper target:

echo MACOSX > target.conf

To compile and install issue

make config
make install

Now, you can try to run the interpreter


Please note: This is only the basic installation. Depending on the presence of certain libraries, the functionality of the interpreter might be limited.

Feature Overview

Several modules are available to extend the basic functions:

Basic concepts

ORTD supports basic features like (realtime) threads, for-loops, state-machines ...


// The main real-time thread
function [sim, outlist, userdata] = Thread_MainRT(sim, inlist, userdata)
  // This will run in a thread
  [sim, Tpause] = ld_const(sim, 0, 1/27);  // The sampling time that is constant at 27 Hz in this example
  [sim, out] = ld_ClockSync(sim, 0, in=Tpause); // synchronise this simulation

  // print the time interval
  [sim] = ld_printf(sim, 0, Tpause, "Time interval [s]", 1);

  // save the absolute time into a file
  [sim, time] = ld_clock(sim, 0);
  [sim] = ld_savefile(sim, 0, fname="AbsoluteTime.dat", source=time, vlen=1);

  // Add you own control system here

  outlist = list();

ThreadPrioStruct.prio2=0; // for ORTD.ORTD_RT_REALTIMETASK: 1-99 as described in   man sched_setscheduler
                          // for ORTD.ORTD_RT_NORMALTASK this is the nice-value (higher value means less priority)
ThreadPrioStruct.cpu = -1; // The CPU on which the thread will run; -1 dynamically assigns to a CPU, 
                           // counting of the CPUs starts at 0

[sim, StartThread] = ld_initimpuls(sim, 0); // triggers your computation only once
[sim, outlist, computation_finished] = ld_async_simulation(sim, 0, ...
                      inlist=list(), ...
                      insizes=[], outsizes=[], ...
                      intypes=[], outtypes=[], ...
                      nested_fn = Thread_MainRT, ...
                      TriggerSignal=StartThread, name="MainRealtimeThread", ...
                      ThreadPrioStruct, userdata=list() );

  • Unlimited number of threads
  • Each thread has its own loop-timing as enforced by ld_ClockSync
  • Irregular timing possible


function [sim, outlist, userdata] = ForLoopFn(sim, inlist, LoopCounter, userdata)
  // input data
  in1 = inlist(1);
  in2 = inlist(2);

  // sample data for the output
  [sim, outdata1] = ld_constvec(sim, 0, vec=[1200]);

  [sim, LoopCounter] = ld_Int32ToFloat(sim, 0, LoopCounter);
  [sim] = ld_printf(sim, 0, LoopCounter, "Loop count active: ", 1);

  // the user defined output signals of this nested simulation
  outlist = list(outdata1);
[sim, outlist, userdata] = ld_ForLoopNest(sim, 0, ...
inlist=list(data1, data2), ..
insizes=[1,2], outsizes=[1], ... 
ForLoop_fn=ForLoopFn, SimnestName="ForLoopTest", NitSignal=CountTo, list("UserdataTest")  );
  • Nested simultion is executed for each turn of the for-loop.

Documentation / Getting started

To start with a bare-bones template for a real-time application (fixed, regular timing) you might choose the following example. Run the file RTmain.sce using Scilab (with the ORTD-toolbox loaded) which will generate the compiled real-time program files RTmain.ipar and RTmain.rpar. Then, from the command line and within the same folder of the RTmain.*-files, run ortdrun (or ortdrun -s RTmain) to start the real-time program.

To start with a template that also includes an HTML-based GUI please follow: node.js/ORTD/HTML-Template

For reference on the available commands/blocks please consider the HTML-Documentation pages .


A plenty amount of examples demonstrating the use of various functions is given in the example-folder. Furthermore, examples specific to the individual modules (e.g. how to interface I2C-hardware) are generally found in the demo-subfolder of each module. The folder of all modules. A template for the development of modules/plugins in C++ might be further useful to integrate custom-hardware.

Data Visualisation / User Control

A new open-source, plugin-based software PaPi for live-visualisation and user interaction in conjunction with real-time control systems is currently being developed at Technische Universit├Ąt Berlin. It is the successor of the software qrtailab that could only be used in combination with RTAI. There is full support for ORTD and ongoing support for Simulink. It allows you to easily create Graphical User Interfaces to your real-time programs. All GUI-logic along with possible calibration routines can be implemented in the real-time target using into ORTD embedded Scilab. PaPI is used to connect to such RT-programs via a network connection. [GUI Example]. [static GUI].

As an alternative, it is made easy to implement web-based user interfaces.

In this example, an ORTD simulation (real-time part) is communicating to a node.js script by UDP-packets. The node.js part provides a web-interface and streams the information from the real-time part to the web-interface. Additionally, parameter changes are forwarded from the web-interface to the real-time part. The source-code is available from [].

Future Directions

In addition to the existing state machines, logic constructs like Select/Case (done; in svn) [] , for-loops [] (also done; in svn) , do-until-loops will be added. These apply to nested simulations that are e.g. conditionally executed or for multiple times in a loop. For visualisation and user control purposes, a strong collaboration with PaPi is ongoing to allow automatically generated user interfaces (with minimal effort for the user) that allow e.g. interaction with automated experiments.


Responsible person: Christian Klauer

Acknowledgement / References

Huge portions have been funded by the European Commision (2010-2013) in the 7th framework Program within the project MUNDUS. During this project, ORTD has been used to develop a prototype for a next generation neuro-prosthetic system.

Development was, further, funded by the German Federal Ministry of Education and Research (BMBF) within the project BeMobil (FKZ 16SV7069K) and by European project RETRAINER (Horizon 2020, Research and Innovation Programme, grant agreement No 644721).