API
Running Simulations
SimpleSim.simulate
— Methodsimulate(model; kwargs...)
Runs the simulation for the given model
.
Returns a NamedTuple
with all time-series information about the simulation.
Mandatory Keyword Arguments
T
: Total time of the simulation. Mand
Optional Keyword Arguments
uc
: Expects a function(t) -> u
defining the input to a continuous-time model at timet
. Defaults to(t) -> nothing
.ud
: Expects a function(t) -> u
defining the input to a discrete-time model at timet
. Defaults to(t) -> nothing
.Δt_max
: Maximum step size used for continuous-time model integration. Defaults toΔT_DEFAULT
set inSimpleSim.jl
.t0
: Initial time. Defaults to0 // 1
.xc0
: Initial state for continuous-time model. Overwrites any initial state defined in the model itself. Defaults tonothing
.xd0
: Initial state for discrete-time model. Overwrites any initial state defined in the model itself. Defaults tonothing
.integrator
: Integration method to be used for continuous-time models. See below for supported integrators. Defaults toRK4.
options
: See below for additional options that can be set.
Supported Numerical Integration Methods
These options can be passed to the simulate
function as the integrator
keyword argument:
@enum SimpleSimIntegrator RK4 = 1 Euler = 2 Heun = 3 RKF45 = 4
Options
SimpleSim.jl
has a few default parameters for running simulations that generally do not need to be changed. However, if necessary the following options can be passed in a NamedTuple
to the options
keyword argument.
Δt_default
: replaces the default (maximum) step size used for continuous-time integration. Should be rational. Defaults to global parameterΔT_DEFAULT
.Δt_min
: replaces the minimum step size used for continuous-time integration. Especially relevant for adaptive step size integrators. Defaults to1 // 1_000_000
.zero_crossing_tol
: absolute tolerance used when computing the time of a zero-crossing. Defaults to1e-5
.RKF45_rel_tol
: relative tolerance between the truncation error and the 5th order Runge-Kutta estimate leading to termination of theRKF45
integrator. Defaults to1e-6
.RKF45_abs_tol
: absolute tolerance for the truncation error leading to termination of theRKF45
integrator. Defaults to1e-7
.silent
: if set totrue
all output, including warnings and erros is disabled. To only print erros and warnings and disable all other output setdisplay_progress
anddebug
tofalse
. Defaults tofalse
.debug
: set totrue
to get additional information printed in the terminal that might help you debug your models. Defaults tofalse
.display_progress
: set tofalse
if you don't want to be updated about simulation progress in the terminal. Defaults totrue
.progress_spacing
: time between progress updates in the terminal. Defaults to1 // 1
.base_rng
: random number generator used for random draw functions. Defaults toMersenneTwister
.out_stream
: IO stream used for console output. Defaults tostdout
.
Example with Options
out = simulate(my_model,
T = 20 // 1,
options = (
silent = true,
base_rng = Xoshiro,
)
)
Updating Submodels
SimpleSim.@call!
— Macro@call! model u
The @call!
macro is crucial for running simulations with submodels. In the parent model's gc
or gd
function every one of its submodels must be called using @call!
. Otherwise the submodels will not be updated.
Returns the output of model
after the update. Use @state
after calling @call!
to access the new state.
Example
function gc_parent_model(x, u, p, t; models)
# ...
y_child = @call! models[1] u_child
# ...
end
Note: The @call!
must not be used inside a dynamics (fc
/ fd
) function. This will throw an error. If you need access to a submodels output/state inside your parent model's dynamics function use @out
/ @state
.
SimpleSim.@call_ct!
— Macro@call_ct! model u
This macro should be used instead of @call!
for calling the continuous-time dynamics of a hybrid model. This prevents ambiguity. See @call!
.
SimpleSim.@call_dt!
— Macro@call_dt! model u
This macro should be used instead of @call!
for calling the discrete-time dynamics of a hybrid model. This prevents ambiguity. See @call!
.
Access to Submodel Output
SimpleSim.@out
— Macro@out model
Returns the current output of model
. This macro is useful in fc
or fd
functions when access to a submodel's output is needed. The macro works similar to @state
.
Example
function fc_parent_model(x, u, p, t; models)
y_child = @out models[1]
# ...
end
Note: @out
does not update the model
. It only returns its current output. Use @call!
to update submodels.
SimpleSim.@out_ct
— Macro@out_ct model
Returns the output of a given continuous-time model. Especially useful when retrieving the output of a hybrid model in which case @out
would be ambiguous. See @out
.
SimpleSim.@out_dt
— Macro@out_dt model
Returns the output of a given discrete-time model. Especially useful when retrieving the output of a hybrid model in which case @out
would be ambiguous. See @out
.
Access to Submodel State
SimpleSim.@state
— Macro@state model
Returns the current state of model
. This macro is useful in fc
or fd
functions when access to a submodel's state is needed. The macro works similar to @out
.
Note: @state
does not update the model
. It only returns its current state. Use @call!
to update submodels.
Example
function fc_parent_model(x, u, p, t; models)
x_child = @state models[1]
# ...
end
SimpleSim.@state_ct
— Macro@state_ct model
Returns the state of a given contiuous-time model. Especially useful when retrieving the state of a hybrid model in which case @state
would be ambiguous. See @state
.
SimpleSim.@state_dt
— Macro@state_dt model
Returns the state of a given discrete-time model. Especially useful when retrieving the state of a hybrid model in which case @state
would be ambiguous. See @state
.
Convenience Functions
SimpleSim.print_model_tree
— Functionprint_model_tree(model; io = stdout)
Prints a tree of the given model similar to a folder tree printed by the Linux tree
command.
An example for a feedback-controlled inverted pendulum could look like this
julia> print_model_tree(my_model)
└─1 (TypeCT): top-level model / FeedbackSystem
├─2 (TypeCT): .inverted_pendulum / NamedTuple
└─3 (TypeCT): .controller / NamedTuple
First, the model_id
is indicated, following the type (TypeCT
, TypeDT
or TypeHybrid
). Then follows the name of each model in the super model. This is either its field name in the NamedTuple
passed as models
or the index in the case of vectors or tuples. Finally, after the slash, the type of each model is indicated. This should either be the name of a struct
type, or NamedTuple
.
You can also pass your own IO stream to print_model_tree
as follows
print_model_tree(my_buffer, model)