Hi,
I'm working on a concept for running a simulink model from C++. The model has a collection of input and output ports at the root. I need to drive the model input ports from a C++ application and retrieve the output port values after stepping through the model once. I have been able to use MatlabEngine to interact with Simulink session.
Here's what I have tried so far:
Using sim command:
I created a Simulink.SimulationInput object and used it to provide values for all root-level input ports. The model uses discrete fixed-step solver so I set both sample time and stop time to same fixed value e.g. 50ms. Then I ran the simulation using sim command and was able to retrieve the output port values using Simulink.SimulationOutput object. This seems to work fine for simple cases. However, the calling C++ application would be required to simulate the model in a loop with different input values. Since sim command would only simulate the model for one frame (due to the aforementioned configuration), if the model has internal states, these states would not persist between individual simulation attempts. This means that the simulation output will be incorrect if it depends on a value from previous frame. I did some digging into ModelOperatingPoint to try to use FinalState of simulation from previous frame as InitialState for current frame however that didn't work since the snapshot time of FinalState from previous frame would be same as stop time (e.g. 50ms) and I only want the model to run for a single step every time it gets called from C++.
Using Simulink debugger:
I tried using debug mode with step top to get the model to step only once. However, this approach does not allow driving the input ports.
Using set_param with SimulationCommand:
I created a Simulink.SimulationData.Dataset object (similar to first approach) to drive root-level input ports and used that as ExternalInput for the model. Now instead of sim command, I used set_param(<model>, 'SimulationCommand', 'start', 'SimulationCommand', 'pause') to start and set_param(<model>, 'SimulationCommand', 'continue', 'SimulationCommand', 'pause') for each iteration of C++ loop. This seems to run the simulation once and the internal states seem to persist as expected. However, if I change any input via Simulink.SimulationData.Dataset object the new value does not get used for simulation. If I stop and restart simulation using SimulationCommand, it does pick the new value but now it has lost the internal state info.
Is there anyway to implement what I'm trying to do?
Any help would be much appreciated.
Cheers,
sunny