Skip to content
LIBRARY

CCodeExport ​

Export a purely discrete model as standalone C code.

The model is compiled by SynchToolkit into a synchronous node whose step function is exported by SynchJulia (top.c, top.h, synchjulia.h, top.pc): the model's top-level input connectors become the inputs of the node, followed by the clock tick and a struct of the model's parameters, and its top-level output connectors become the fields of the result struct. The clock of the node is either carried by the model, through a PeriodicClock connected to one of its inputs, or specified by the analysis through dt, which places every input of the model on a periodic clock with that sample interval. A model without a clock of its own must therefore have at least one top-level input to be exported with dt.

The MPC controllers in the model must solve in C (backend must not be Julia), and what their steps call is shipped next to the node: for LinearMPCController/LinearMPCOptimizer the C code LinearMPC.jl generated for the QP, in lmpc_<id>/, together with DAQP's solver sources (daqp/, see daqp_sources); for ACADOSMPC (built with backend = C) the compiled acados solver library libacados_<id> and the acados runtime libraries (libacados, libhpipm, libblasfeo). A Makefile builds one shared library per LinearMPC controller and then the node against all of them.

With compile = true the exported tree is compiled here as a check that it builds (this needs a C compiler; the same one the controllers were built with).

This defines an entirely new type of analysis (not derived from an existing analysis)

Usage ​

CCodeExport(...)

Source ​

dyad
"""
Export a purely discrete model as standalone C code.

The model is compiled by SynchToolkit into a synchronous node whose step function is exported by
SynchJulia (`top.c`, `top.h`, `synchjulia.h`, `top.pc`): the model's top-level input connectors
become the inputs of the node, followed by the clock tick and a struct of the model's parameters,
and its top-level output connectors become the fields of the result struct. The clock of the node
is either carried by the model, through a `PeriodicClock` connected to one of its inputs, or
specified by the analysis through `dt`, which places every input of the model on a periodic clock
with that sample interval. A model without a clock of its own must therefore have at least one
top-level input to be exported with `dt`.

The MPC controllers in the model must solve in C (`backend` must not be `Julia`), and what their
steps call is shipped next to the node: for `LinearMPCController`/`LinearMPCOptimizer` the C code
LinearMPC.jl generated for the QP, in `lmpc_<id>/`, together with DAQP's solver sources (`daqp/`,
see `daqp_sources`); for `ACADOSMPC` (built with `backend = C`) the compiled acados solver library
`libacados_<id>` and the acados runtime libraries (`libacados`, `libhpipm`, `libblasfeo`). A
`Makefile` builds one shared library per LinearMPC controller and then the node against all of them.

With `compile = true` the exported tree is compiled here as a check that it builds (this needs a C
compiler; the same one the controllers were built with).
"""
partial analysis CCodeExport
  extends Analysis
  model::Dyad.EmptyComponent = Dyad.EmptyComponent()
  "Directory the C sources are written to"
  parameter output_dir::String = "ccode"
  "Compile the exported sources into a shared library as a build check (needs a C compiler)"
  parameter compile::Boolean = true
  "DAQP solver sources for the MPC libraries"
  parameter daqp_sources::DAQPSources = DAQPSources.Download()
  "Sample interval of the node's clock; 0 takes the clock from a PeriodicClock in the model"
  parameter dt::Real = 0
relations
end
  • Examples