Load simulation state in Simulink Coder generated C code

We're trying to solve the loading of initial state into a Simscape model which is used by our system via code generation, so our integration tests use the Linux shared object of the Simscape model generated by Simulink Coder tool.
We've already tried 2 ways to save and then load the state:
Approach 1: C API
1. Enable C API access for block signals, block parameters, block states, inport/outport signals, then generate code and a shared object.
2. Run the simulation, save states what I can access via the C API into the memory as a test, terminate simulation.
3. Initialize the simulation again, load back the state from the memory and start the simulation.
Approach 2: Saving all continuous and discrete states, based on this suggestion: https://www.mathworks.com/matlabcentral/answers/2088581-save-load-simulink-code-generated-state.
We would prefer Approach 1. Hovwever after implementing it, we didn’t get the expected results, the simulation is not resumed to the expected state.
Approach 2 is more complicated to implement than approach 1, because structures representing continuous and discrete states are quite complex and hard to serialize, since they contain several pointers to other internal structures (void pointers and hard to find the underlining types) and we aren't sure what is necessary to save and what not.
Which approach should work? Are we on the right track, just something is missing or should we move on to a different approach?

4 Commenti

Check out Simscape Operating Point maybe?
I believe it supports code-generation. But the operating point (initial conditions) becomes part of the generated code and you won't be able to swap to a different set.
Hello Yifeng Tang,
Thank you for the suggestion, as you wrote Simscape operating points support code generation and that way I managed to create shared object from the model which contains the operating point as a starting point for the simlation.
I also tried to implement a more dynamic solution to avoid handling of separate .so for every intial state, based on Approach 2, could you take a look at it? Is this a misuse of the generated code?
This is may save function:
void saveModelState(const char *filename) {
FILE *file = fopen(filename, "wb");
if (file != NULL) {
// Save block signals
fwrite(&labo2vpu_model_B, sizeof(B_labo2vpu_model_T), 1, file);
// Save discrete states
fwrite(&labo2vpu_model_DW, sizeof(DW_labo2vpu_model_T), 1, file);
// Save continuous states
fwrite(&labo2vpu_model_X, sizeof(X_labo2vpu_model_T), 1, file);
// save disabled state vector
fwrite(&labo2vpu_model_XDis, sizeof(XDis_labo2vpu_model_T), 1, file);
// Save mass matrices
fwrite(&labo2vpu_model_MassMatrix, sizeof(MassMatrix_labo2vpu_model_T), 1, file);
fclose(file);
} else {
printf("Error opening file for saving state.\n");
}
}
I also created a load function analogously. If I use it the way below, it works as expected, the state is loaded back and simulation is resumed at the desired previous step:
void executeModel()
{
labo2vpu_model_initialize();
int currentTime = 0;
while (rtmGetErrorStatus(labo2vpu_model_M) == NULL &&
!rtmGetStopRequested(labo2vpu_model_M)) {
labo2vpu_model_step();
if (currentTime == 500) {
saveModelState("model_state.dat");
}
if (currentTime == 990) {
loadModelState("model_state.dat");
}
currentTime++;
}
if (rtmGetErrorStatus(labo2vpu_model_M) != NULL) {
printf("Termination cause: %s\n", rtmGetErrorStatus(labo2vpu_model_M));
}
labo2vpu_model_terminate();
}
What is my main goal, to load the state of the model from a previous execution, unfortunately doesn't work. If I run the executeModel() function first to save the state into the file and then run it again without the saveModelState() step, just trying to load back the simulation state from the previously created file. In this case it seems that state is not loaded back correctly. (I use the Simulink Coder C-API to check the internal state of the model.)
Yifeng Tang
Yifeng Tang il 10 Mar 2025
Modificato: Yifeng Tang il 10 Mar 2025
It sounds like you are not trying load one particular set of initial states in the generated code, but you want to be able to load "any" initial states, generated from prior simulations, to start the Simscape mode in the generated code. Could you please confirm this?
If this is the case, I don't think Simscape operating point would work, because the states in the operating point object will be hardwired in the generated code. It cannot be changed externally.
I think there is a way to do what you want though. If you could confirm my understanding above, I can get into more details on this.
Yes, I can confirm, the best would be to save/serialize the (internal) state of a long running simulation during the execution, let's say at the 90% of the total simulation time and load this state later in another execution of the exactly same simulation, to save time during integration testing.

Accedi per commentare.

Risposte (1)

I think it's possible to do what you are envisioning using "Simulink Parameters" in the initial conditions. I attached an example based on a double-mass-spring-damper example in the documentation. Screenshot below.
The initial conditions of the spring deformation are x1_init and x2_init, which are Simulink parameters in the model workspace.
You may do a similar thing with non-initial-condition parameters like mass and spring constants, but you'll need to make the parameter "run-time" instead of "compile-time".
With such settings, the above variables in the initial conditions and the run-time parameters will show up in the generated code. See snapshot below. I believe the actual definition of the values is in [*modelname*]_data.c. You should be able to parse and modify this file to change the initial conditions and model parameters.
Please give it a try, probably with a simpler model, and see if this workflow works for you.

Prodotti

Release

R2024a

Richiesto:

il 5 Mar 2025

Risposto:

il 10 Mar 2025

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by