Exporting a model
A model runs in more places than magnet simulate:
- inside a co-simulation master;
- under a scheduler;
- on a board under your own firmware.
Each of those is a runtime, meaning whatever calls the model’s step. One
command exports a model for it:
magnet build --runtime fmi3 # an FMU a co-simulation master stepsmagnet build --runtime fmi3 --interface scheduled-execution # an FMU whose clock a scheduler ticksmagnet build --runtime embassy # the glue an embassy firmware steps the model throughThe editor has the same two FMU exports under File › Export › FMU.
Which model
Section titled “Which model”The first of these that is set picks the model:
--model, as ausepath (controller::Controller);- the manifest’s
[deploy] model; - the model
magnet simulateruns, which is the package’s only one, or the one at the top that steps the others.
A generic model is a template and cannot be exported, so name an instantiation of it.
--runtime exports the release crate as files and takes neither --profile
nor --format. [deploy] runtime is magnet flash’s
key, and build does not read it.
Deliverables land in target/export/.
What every export shares
Section titled “What every export shares”The model crate does not change. An export writes the same #![no_std]
crate magnet build writes to target/codegen/release/<package>/. Beside it
goes a glue crate, target/codegen/<runtime>/<package>/, which depends on:
- the model crate;
- one crate from crates.io:
fmitefor an FMU,embassy-timefor a firmware; - the crates behind any
externblocks the model uses.
The glue is what a runtime needs and the model does not, written out in plain Rust you can read. For an FMU it is a struct whose fields are the variables and whose private field is the model. For a firmware it is a driver around the model.
Settings are the constructor’s arguments. What an FMU calls parameters and
a host sets is what params takes and magnet simulate --param writes. They
are not the fields of the parameters struct, which the constructor derives from
them. A change to one takes effect from the next tick.
An argument whose type is a model is a child’s whole parameters. It is fixed at its default, and a model that gives it none cannot be exported.
Only the interface crosses. Settings, inputs and outputs are what a runtime
sees. Probes are the simulation’s: the export is the release crate, which
strips them with the rest of the sim profile.
The model only ever steps at the sample time it declares. A step with
@every(10ms) runs at 10 ms. A model whose children are rated runs at the
largest step all their rates are a whole number of. A host’s interval is cut
into whole ticks of that step, and an interval that does not divide into them
is refused, because a model is only verified at the sample times it declares.
A model with no rate anywhere takes a Co-Simulation master’s interval as its
dt, exactly as magnet simulate --dt does. A Scheduled Execution FMU and an
embassy loop need a period of the model’s own and refuse one without.
Next: an FMU, with the GNC controller exported and stepped, or a firmware, from the glue to a board on your desk.