Run Simulink Simulation from C++

MATLAB Command to Run Simulation

You can run Simulink® simulations using the MATLAB® Engine API for C++. Here are the basic steps to run a simulation programmatically:

  • Start a MATLAB session.

  • Load the Simulink model in MATLAB using the MATLAB load_system (Simulink) function.

  • Run the simulation with specific simulation parameters using the MATLAB sim (Simulink) function.

  • Access the results of the simulation using methods of the returned Simulink.SimulationOuput (Simulink) object.

For information on running simulations programmatically from MATLAB, see Run Individual Simulations (Simulink).

Simulink vdp Model from C++

The Simulink vdp block diagram simulates the van der Pol equation, which is a second order differential equation. Simulink solves the equations using the initial conditions and configuration parameters defined by the model.

MATLAB Code to Run Simulation

This MATLAB code shows the commands to run the simulation programmatically. The Simulink.SimulationOuput object get method returns the results and time vector.

load_system('vdp');
parameterStruct.SaveOutput = 'on';
parameterStruct.OutputSaveName = 'yOut';
parameterStruct.SaveTime = 'on';
parameterStruct.TimeSaveName = 'tOut';
simOut = sim('vdp',parameterStruct);
y = simOut.get('yOut');
t = simOut.get('tOut');

This MATLAB code creates a graph of the simulation output and exports the graph to a JPEG image file.

plot(t,y)
print('vdpSimulation','-djpeg')

C++ Code to Run Simulation

This sample code runs the Simulink simulation for the vdp model. The code performs these operations:

  • Connect to a named MATLAB session that has Simulink installed.

  • Create a matlab::data::ArrayFactory and build a StructArray that contains the simulation parameters.

  • Pass the simulation parameter structure to the MATLAB workspace.

  • Load the vdp Simulink model using an asynchronous call to MATLABEngine::evalAsync. Execution waits for MATLAB to load the model.

  • Run the simulation using another asynchronous call to MATLABEngine::evalAsync. Execution waits for the simulation to finish.

  • Extract the simulation data from the Simulink.SimulationOutput object in the MATLAB workspace.

  • Graph the data and export a JPEG image to the MATLAB current folder using MATLABEngine::eval to execute MATLAB commands.

#include "MatlabDataArray.hpp"
#include "MatlabEngine.hpp"
#include <chrono>
#include <iostream>

void runSimulation() {

    using namespace matlab::engine;
    
    // Connect to named shared MATLAB session started as:
    // matlab -r "matlab.engine.shareEngine('myMatlabEngine')"
    String session(u"myMatlabEngine");
    std::unique_ptr<MATLABEngine> matlabPtr = connectMATLAB(session);

    // Create MATLAB data array factory
    matlab::data::ArrayFactory factory;
    
    // Create struct for simulation parameters
    matlab::data::StructArray parameterStruct = factory.createStructArray({ 1,4 }, {
        "SaveOutput",
        "OutputSaveName",
        "SaveTime",
        "TimeSaveName" });
    parameterStruct[0]["SaveOutput"] = factory.createCharArray("on");
    parameterStruct[0]["OutputSaveName"] = factory.createCharArray("yOut");
    parameterStruct[0]["SaveTime"] = factory.createCharArray("on");
    parameterStruct[0]["TimeSaveName"] = factory.createCharArray("tOut");

    // Put simulation parameter struct in MATLAB
    matlabPtr->setVariable(u"parameterStruct", parameterStruct);

    // Load vdp Simulink model
    FutureResult<void> loadFuture = matlabPtr->evalAsync(u"load_system('vdp')");
    std::cout << "Loading Simulink model... " << std::endl;
    std::future_status loadStatus;
    do {
        loadStatus = loadFuture.wait_for(std::chrono::seconds(1));
    } while (loadStatus != std::future_status::ready);
    std::cout << "vdp model loaded\n";

    // Run simulation
    FutureResult<void> simFuture = matlabPtr->evalAsync(u"simOut = sim('vdp',parameterStruct);");
    std::cout << "Running simulation... " << std::endl;
    std::future_status simStatus;
    do {
        simStatus = loadFuture.wait_for(std::chrono::seconds(1));
    } while (simStatus != std::future_status::ready);
    std::cout << "vdp simulation complete\n";

    // Get simulation data and create a graph
    matlabPtr->eval(u"y = simOut.get('yOut');");
    matlabPtr->eval(u"t = simOut.get('tOut');");
    matlabPtr->eval(u"plot(t,y)");
    matlabPtr->eval(u"pause(10)");
    matlabPtr->eval(u"print('vdpSimulation','-djpeg')");
}

For information on how to setup and build C++ engine programs, see Build C++ Engine Programs.

See Also

| |

Related Topics