Lizard is a domain-specific language to define hardware behavior. It is intended to run on embedded systems which are connected to motor controllers, sensors etc. Most of the time it is used in combination with a higher level engine like ROS or RoSys. You can think of the microcontroller as the machine's lizard brain which ensures basic safety and performs all time-critical actions.
The idea is to not compile and deploy specific C++ code for every new hardware requirement. Instead you simply write your commands in a text-based language which can be changed on the fly.
- Shell-like input and output over serial communication to ease the development
- Quick and resource-efficient execution on embedded hardware
- Built-in checksums to detect transmission errors
- Safety conditions that are checked continuously
- Ability to work across multiple microcontrollers
- Human-readable and easy-to-type (like Python)
- Persistent "startup" commands to apply configuration after boot
Lizard consists of individual hardware modules that are either defined in a persistent startup script or interactively via console input. Each module has a name, a number of required or optional constructor arguments and possibly a step function as well as a number of properties.
Furthermore, Lizard allows to define rules, possibly asynchronous routines and variables. A routine is simply a collection of Lizard statements. If a rule's condition evaluates to true, the corresponding routine is started. Conditions can involve variables, module properties and constant expressions.
core module is automatically defined first.
It provides interaction with the microcontroller itself, e.g. reading the system's time or causing a restart.
During a main loop Lizard repeatedly performs the following tasks:
- Read and evaluate input from the serial interface.
- Run the step functions of each module. (The
coremodule is evaluated last.)
- Check all rules and execute associated routines.
- Advance routines that are already running and waiting for certain conditions.