ModelingToolkit for (continuous) Model ID with (discrete) input and output data

I want to model a quadrocpter with MTK. In the first step I want to identify the parameters of a simple model from real flight data. In the second step I want to learn not yet modeled effects from the data by different experiments with (Neural Networks, Universal Differential Equations, …). Finally, I want to use the model to optimize controller parameters. To do this, I want to differentiate from a trajectory error through the entire model to the controller parameters.

  1. Should discrete inputs be available as variables or as parameters? (Under the aspect that I later need a gradient from the continuous model into the discrete controller.)

  2. I currently use a varaible because I can have the data more conveniently in the output for logging. Is there also a solution with changing parameters?
    Update parameters in ModelingToolkit using callbacks

  3. Is there a better solution to connect continuous with discrete than callbacks? (I have not yet tried to differentiate the structure automatically. To optimize controller parameters later.)
    ModelingToolkit - DiscreteUpdate
    Mixing time-discrete and time-continuous systems in a simulation
    Coupling MTK with time discrete control · Issue #1180 · SciML/ModelingToolkit.jl · GitHub

The code is shortened to show the relevant parts.

@variables (action)(t) = 0.0;

function condition(u, t, integrator)
    # Points in time at which input data is available
    t in data.timestamp
end

function affect!(integrator)
    # searches for the next input
    i = findfirst(t -> t == integrator.t, data.timestamp)
    integrator.u[1] = data.action[i]
end

cb = DiscreteCallback(condition, affect!, save_positions = (true, true))

# for logging
eqs = vcat(
    Dt(action) ~ 0, 
);

 # Stops at the points in time at which new inputs are present.
sol = solve(prob, Tsit5(), callback = cb, tstops = data.timestamp);

Optimization
4. I have several flight trajectories. To identify the parameters, I want to apply the real actions (discrete) to the model (continuous) and calculate the trajectory deviation at the recorded discrete time points (as loss). I don’t want to do this for just one trajectory, but for all of them at the same time. My input in the affect!(integrator) function is taken from a global data source. Do I have to create a new ODEProblem(sys, u0, tspan, p) every time or is there a better solution?

cost_function = build_loss_objective(prob, Tsit5(), callback = cb, tstops = data.timestamp, loss(data.timestamp,  data.trajectory),
                                        Optimization.AutoForwardDiff(),
                                        maxiters = 10000, verbose = false);

Hello and welcome to the community :wave:

There is a plan for a better way, but this is not yet ready. See prior discussions

And the relevant issue label discrete-time

1 Like

I have had good results for some systems using DataInterpolations.jl to create an interpolated function for the data and using that function at the appropriate place in the model. PiecewiseConstant interpolation is very similar to using callbacks, although Linear is easier to build a stable model around.

1 Like

Interpolations only work if the signal is known in advance. You cannot use them in place of callbacks if the signal is, e.g., computed as a function of the simulation state. If the discrete-time input comes from a controller that acts based on the simulation state, an interpolation will not be a viable solution.

1 Like