Control
Embedded Firmware Control Systems Toolbox (Pure C and GNU Octave)
Install / Use
/learn @swedishembedded/ControlREADME
Swedish Embedded Control Systems Toolbox

This is a control systems design library written in pure C that provides you with advanced algorithms for control, state estimation and model identification specifically designed for use on embedded systems. It has been adopted for use with embedded systems and Swedish Embedded Platform SDK
- Community: https://swedishembedded.com/community
- Consulting: https://swedishembedded.com/consulting
- Training: https://swedishembedded.com/tag/training
It library is fully compatible with Zephyr RTOS so you can simply add it as a module to your west.yml file and start using it.
It is focused on practical numerical methods that work best in realtime embedded environment without any complex dependencies.
It uses no dynamic memory allocation. All operations are done on C arrays. The functions provided by this library are generic implementations that can be used to implement controllers that use specific array sizes.
Original library is based on excellent work by Daniel Mårtensson who has developed the original algorithms in C and GNU Octave.
This library provides following functionality:
-
Artificial Intelligence
- Astar algorithm for quick path finding
- Point-in-polygon algorithm for checking if a point is inside the area
-
Control Engineering
- Kalman filter update
- Linear Quadratic Integral regulator
- Model predictive Control
- Model Reference Adaptive Control
- Transfer function to state space
- Stability check
- Continuous to discrete
-
Filtering
- Monte Carlo Simulation
- Comming soon: Particle filter
- Filtfilt
- Square Root Unscented Kalman Filter
-
Linear Algebra
- Balance matrix
- Cholesky decomposition
- Cholesky update
- QR decomposition
- LUP decomposition
- Determinant
- Discrete Lyapunov solver
- Eigenvalues symmetric + Eigenvectors
- Random real eigenvalues and random imaginary eigenvalues
- Hankel matrix
- Inverse
- Pseudo inverse
- Linear solver
- Nonlinear solver
- Multiplication
- Singular Value Decomposition Golup Reinsch
- Singular Value Decomposition Jacobi One Sided
- Transpose
- Matrix sum
- Norm
- Matrix exponential
-
Miscellaneous
- Concatenate
- Cut matrix
- Insert sub matrix into matrix
- Print matrix or vector
- Saturation
- Sign
- Randn
- Mean
- Standard deviation
- Value min
- Value max
-
Optimization
- Linear programming maximization
- Linear programming minimization
-
System Identification
- Observer Kalman Filter identification
- Eigensystem Realization Algorithm
- Recursive Least Square with forgetting factor and kalman filter identification
- Square Root Unscented Kalman Filter for parameter estimation
Building locally
The library core library should build just fine using the standard cmake approach:
mkdir build
cmake ..
make && make test
Building and running examples
The tests inside this repository are created to be buildable on top of Swedish Embedded Platform SDK. If you are using 'swedishembedded/build:latest' docker image then you should be able to simply run:
west init -l .
west update
./scripts/test
If you want to build locally, you should be able to do so by installing west, running west init and then installing the SDK dependencies locally:
pip3 install -g west
mkdir workspace && cd workspace
# it is important that you clone into a workspace!
git clone git@github.com:swedishembedded/control.git
west init -l .
west update
../sdk/scripts/install-sdk
This will install several different cross compilation toolchains and all the other tools you need in order to build firmware for a wide variety of architectures.
To build and run individual tests on specific boards you can do like this:
west boards # list boards
west build -p -b <board> tests/ai -t run # build and run
west build -t run # do a subsequent run after building for the first time
Building documentation
apt update &&
apt install -qy
libglib2.0-dev
libglib2.0-dev-bin
libgtest-dev
ruby2.7-dev
libcairo2-dev
libpango1.0-dev
libgdk-pixbuf2.0-dev
libxml2-dev
pip install asciidoxy
gem install asciidoctor-mathematical
mkdir build &&
cd build &&
cmake .. &&
make docs
How to help to build on this control toolbox
If you are interested in contributing to this library, feel free to raise a pull request.
GNU Octave Functions
Installing GNU Octave's Control-Toolbox or MATLAB's Control-Toolbox/System Identification Toolbox WILL cause problems with this toolbox because they are using the same function names. This toolbox implements better versions of the original functions so you should either use this toolbox inside you .m file or opt for using the default gnuoctave implementations - but not both.
System Identification Toolbox
- OKID for multivariable hydraulic systems or temperature systems
- ERA-DC for mechanical damped systems in the time plane
- SINDY for multivariable abritary nonlinear systems
- RLS for all kind of arbitary single input and single output systems (Use this first!)
- OCID for linear feedback systems (I haven't found any real world practice for this method yet)
- FILTFILT2 for low pass filtering without phase delay
- SPA for spectral analysis
- IDBODE for mechanical damped systems in the frequency plane
- RPCA for filtering data and images
- ICA for separating signals so they are independent from each other
- SR-UKF-Parameter-Estimation for finding parameters from an very complex system of equation if data is available
- SR-UKF-State-Estimation for filtering noise and estimate the state of a system
- SVM for classification of data
- N4SID for MIMO, SIMO, MISO or SISO state space systems
- MOESP for MIMO, SIMO, MISO or SISO state space systems
- PIMOESP for MIMO, SIMO, MISO, or SISO state space systems
State space model identification methods
|Function|Description|Status|Model |--------|-----------|------|----- |eradc|Eigensystem Realization Algorithm Data Correlation|Done|MIMO |okid|Observer Kalman Filter Identification|Done|MIMO |ocid|Observer Controller Identification|Done|MIMO |rls|Recursive Least Square|Done|SISO
Nonlinear system identification methods
|Function|Description|Status|Model |--------|-----------|------|----- |sindy|Sparse Identification of Nonlinear Dynamics|Done|MIMO |sr_ukf_parameter_estimation|Estimate parameters for a nonlinear system. Notice that this is parameter estimation. Not system identification.|Done|MIMO |sr_ukf_state_estimation|Estimate states for a nonlinear system. This is system identification|Done|MIMO
Subspace identification algorithms
|Function|Description|Status|Model |--------|-----------|------|----- |moesp|Multivariable Output-Error State Space|Done|MIMO |pimoesp|Past-Input Multivariable Output-Error State Space|Done|MIMO |n4sid|Numerical algorithms for Subspace State Space System IDentification|Done|MIMO
Analysis and filtering
|Function|Description|Status |--------|-----------|------ |spa|Plot bode spectral analysis plot using Fast Fourier Transform|Done |filtfilt2|Zero phase filtering with low pass filter|Done |idbode|Plot bode diagram from frequency data|Done |rpca|Filter data using Robust Principal Component Analysis|Done |ica|Separate signals from each other so they are independent|Done
Classification
|Function|Description|Status |--------|-----------|------ |Svm|Support Vector Machine with C code generation|Done |--------|-----------|------
Control systems design toolbox
These functions are used for control system design.
Model creation
|Function name|Description|Status|MIMO|TF/SS|Discrete |-------------|-----------|------|----|-----|-------- |tf|Crate transfer function model|Done|No|N/N|Y |zpk|Create zero-pole-gain model|Done|No|N/N|Y |ss|Create state space model|Done|Yes|N/N|Y
Model transformation
|Function name|Description|Status|MIMO|TF/SS|Discrete |-------------|-----------|------|----|-----|-------- |minreal|Minimal realization|Done|Yes|Y/Y|Y |balreal|Balanced realization|Done|Yes|N/Y|Y |modred|Model reduction|Done|Yes|N/Y|Y |append|Append systems|Done|Yes|Y/Y|Y |feedback|Feedback model|Done|Yes|Y/Y|Y |series|Serial model|Done|Yes|Y/Y|Y |parallel|Parallel model|Done|Yes|Y/Y|Y |pade|Internal time delay to model|Done|Yes|Y/N|Y |referencegain|Create gain for better tracking|Done|Yes|N/Y|Y
Model data access
|Function name|Description|Status|MIMO|TF/SS|Discrete |-------------|-----------|------|----|-----|-------- |dcgain|Get the low frequency gain|Done|Yes|Y/Y|Y |pzmap|Plot poles and zeros|Done|Yes|Y/Y|Y |damp|Get the damping|Done|Yes|Y/Y|Y |pole|Get poles|Done|Yes|Y/Y|Y |zero|zeros for SISO |Done|No|Y/Y|Y |tzero|zeros for MIMO |Done|Yes|N/Y|Y
Model conversions
|Function name|Description|Status|MIMO|TF/SS|Discrete |-------------|-----------|------|----|-----|-------- |c2d|Convert continuous to discrete|Done|Yes|Y/Y|N |c2dt|Convert continuous to discrete with delay|Done|Yes|Y/Y|N |d2c|Convert discrete to continuous|Done|Yes|Y/Y|Y |d2d|Rediscrete the model|Done|Yes|Y/Y|Y |tf2ss|Transfer function to state space|Done|No|Y/N|Y |ss2tf|State space to transfer function|Done|Yes|N/Y|Y
Frequency domain analysis
|Function name|Description|Status|MIMO|TF/SS|Discrete |-------------|-----------|------|----|-----|-------- |evalfr|Get one frequency|Done|Yes|Y/Y|Y |freqresp|Get multiple frequencies|Done|Yes|Y/Y|Y |bode|Bode diagram|Done|Yes|Y/Y|Y |bodemag|Bode diagram without phase|Done|Yes|Y/Y|Y |nyquist|Nyquist diagram|Done|Yes|Y/Y|Y |sigma|Singular value diagram|Done|Yes|Y/Y|Y |margin|Stability margins|Done|Yes|Y/Y|Y |allmargin|Show all margin|Done|Yes|Y/Y|Y |sensitivity|Show sensitivity margins|Done|Yes|Y/Y|Y |db2mag|Convert dB to magnintude|Done|Yes|Y/Y|Y |mag2db|Conver magnintude to dB|Done|Yes|Y/Y|Y |rlocus|Root locus plot|Done|Yes|Y/Y|Y |rlocfind|Find the
