An integrated real-time safety-critical control framework in C++.
Lodestar is a lightweight C++11 framework for rapidly prototyping and deploying real-time control systems. Traditionally, issues such as data dependencies, execution order, hardware interfacing, and networking have had to be manually solved by developers; Lodestar provides abstractions and automatic routines for resolving these common problems, without obscuring functional relations. Using Lodestar, one is only responsible for specifying function blocks and their interconnections; Lodestar takes care of the rest.
Lodestar aims to be a framework that provides directly executable code, unlike most modeling and simulation-centric toolboxes, which have not been tailored for use in real-time applications. At the same time, Lodestar also allows for code generation when performance is particularly important. It comes built-in with many compile-time checks that cover most common typos and bugs (i.e., matrix-vector dimensions mismatch, connecting inputs to inputs, etc.).
To this end, Lodestar adopts a function block description of systems, where
each Block
provides a pure function (i.e., one that only alters its internal state). Each of these block may have
any number of inputs, parameters, and outputs. The resulting functional block diagrams can easily be extended with new
user-defined block types, without incurring overhead.
Parameters
+-----------------------------------------+
Inputs --->| Block : f(Input, Parameters) -> Outputs |---> Outputs
+-----------------------------------------+
- Automatic resolution of circular data-dependencies (algebraic loops).
- Transparent compile-time error checking, as well as run-time checks prior to executing code.
- Easy extensibility with a simple yet powerful
Block
API based on template metaprogramming. - Clean C++ code generation with predetermined function execution order, as well as resolved data-dependencies.
- Zero-overhead abstraction using templated classes; it does not matter if you have a thousand inputs, or just one.
- Out-of-the-box networking support, with efficient serialization.
- Automatic direct encryption and decryption of messages for enhanced security using state-of-the-art elliptic curve algorithms.
- CMake
- A C++11-compliant compiler
- GiNaC (optional, for resolving algebraic loops)
- nng (optional, for networking)
Simply clone the repository and build using CMake.
If you just want to grab a static library, run cmake ..
instead of a debug build.
Installing/disabling dependencies
You can install the dependencies as follows:
- On Ubuntu (Debian):
sudo apt-get install libginac-dev libcln-dev libnng-dev
- On macOS:
brew install ginac nng
You can disable GiNaC and NNG using the -DWITH_GINAC=OFF -DWITH_NNG=OFF
flags when running the cmake
command:
cmake .. -DCMAKE_BUILD_TYPE=Debug -DWITH_GINAC=OFF -DWITH_NNG=OFF
git clone https://github.com/helkebir/Lodestar
cd Lodestar
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug
make
sudo make install
You can find some demos in the examples/
folder, as well as unit tests of different components in the tests/
folder.
Here's an example to get you started. We will be using ConstantBlock
, SumBlock
, and GainBlock
objects to construct
a simple program.
#include <Lodestar/blocks/std/ConstantBlock.hpp>
#include <Lodestar/blocks/std/SumBlock.hpp>
#include <Lodestar/blocks/std/GainBlock.hpp>
#include <Lodestar/blocks/BlockUtilities.hpp>
#include <Lodestar/blocks/aux/Executor.hpp>
using namespace ls::blocks;
using namespace ls::blocks::std;
/*
* (+)
* +---+ +---+ +---+
* | c |--->| g |--->| s |--->
* +---+ +---+ +---+
* ^ (-)
* +----+ |
* | c2 |--------------+
* +----+
*/
int main()
{
ConstantBlock<double> c{5}, c2{2};
SumBlock<double, 2> s;
GainBlock<double> g{0.5};
s.setOperators(decltype(s)::Plus, decltype(s)::Minus);
// We now establish the interconnections:
connect(c.o<0>(), g.i<0>());
connect(g.o<0>(), s.i<0>());
connect(c2.o<0>(), s.i<1>());
// We group all our blocks in a BlockPack object,
// which contains all components of our system.
BlockPack bp{c, c2, s, g};
// We pass the BlockPack onto the Executor,
// which will allow us to resolve the execution order,
// providing a single trigger function for the entire system.
aux::Executor ex{bp};
ex.resolveExecutionOrder();
// Triggering the entire system is as simple as
// calling the trigger function of the executor.
ex.trigger();
// We obtain +5*0.5 -2 = 0.5
auto res = (s.o<0>().object == 0.5);
return 0;
}
More information can be found on the Lodestar website. If you need any more help, feel free to open an issue!
Hamza El-Kebir
@helkebir
Pre-alpha
This project is licensed under the BSD3 License - see the LICENSE.md file for details.
Inspiration was drawn from the following projects, old and new alike:
- Modelica, for its approach to block definitions, syntax, as well as a number of canonical blocks.
- Esterel and Lustre, for their approach to signal passing and handling, as well as functional block definitions.
The name Lodestar is used to refer to a guiding or navigation star (such as Polaris), underscoring the goal of Lodestar to be a framework that reliably guides users to a stable solution to their control problems.