open-simulation-platform / libcosimc

OSP C co-simulation API
Mozilla Public License 2.0
12 stars 2 forks source link

User story: disable / enable a simulator while an execution is running #44

Open xmirabel opened 1 year ago

xmirabel commented 1 year ago

NEED

On a vehicule (boat, aircraft, rolling vehicle), an external device can be part of the simulation. It should be able to be enabled or disabled by the operator during an experiment without disturbing the global execution of a simulation.

DESCRIPTION

As a OSP user
I want to be able to disable / enable a simulator while an execution is running
So that the execution continue running with its last output data but without (when disabled) / with (when enabled) executing the simulator "set inputs" and then "do step" and then "get outputs".

ACCEPTANCE TESTS

Given that a simulator is enabled
When the user disable it
Then the simulator is frozen in its current state, i.e. no more interaction are done with the FMU, but its last output values are available to the rest of the platform. The execution is not disturbed at all by this event.
Given that a simulator is disabled
When the user enable it
Then the simulator is restarted in its new current state, i.e. interactions restart with the FMU, with its last input values. The execution is not disturbed at all by this event.
Given that a simulator is enabled
When the user enable it
Then nothing happens.
Given that a simulator is disabled
When the user disable it
Then nothing happens.

EXAMPLE OF SIGNATURES

/**
 *  Enable a slave execution.
 *
 *  \param [in] execution
 *      The concerned execution.
 *  \param [in] cosim_slave_index
 *      The slave to be enabled.
 *
 *  \returns
 *      0 on success and -1 on error.
 */
int cosim_execution_enable_slave(cosim_execution* execution, cosim_slave_index slave);

/**
 *  Disable a slave execution.
 *
 *  \param [in] execution
 *      The concerned execution.
 *  \param [in] cosim_slave_index
 *      The slave to be disabled.
 *
 *  \returns
 *      0 on success and -1 on error.
 */
int cosim_execution_disable_slave(cosim_execution* execution, cosim_slave_index slave);

// Slave execution status.
typedef enum
{
    COSIM_SLAVE_EXECUTION_DISABLED,
    COSIM_SLAVE_EXECUTION_ENABLED
} cosim_slave_execution_status;

/**
 *  Get a slave execution status.
 *
 *  \param [in] execution
 *      The concerned execution.
 *  \param [in] cosim_slave_index
 *      The slave to be queried.
 *  \param [out] status
 *      The slave status.
 *
 *  \returns
 *      0 on success and -1 on error (if slave index is invalid for instance).
 */
int cosim_execution_get_slave_execution_status(cosim_execution* execution, cosim_slave_index slave, cosim_slave_execution_status* status);
kyllingstad commented 1 year ago

Thanks for your feedback! My first thought is that this wouldn't be too hard to implement (though there are surely some complicating details I haven't thought of yet).

We have much of the machinery in place in libcosim already, in the form of cosim::algorithm::add_simulator() and cosim::algorithm::remove_simulator(). The latter removes a subsimulator entirely from the co-simulation, but that should have the effect you are asking for: other connected subsimulators will just see its latest output values.

Then, a hypothetical execution::disable_slave() function would simply call algorithm::remove_simulator(). A complementary execution::enable_slave() function would have to do some more work; in addition to calling algorithm::add_simulator(), it must also restore all connections to other subsimulators. But I think we have the info to do that inside execution already.