Sample models for multiple model simulation
Let’s take a complete example of multiple-model simulation. We will use 2 models: one simulation model (a model with simulation rules) to drive our test scenario, and one real-time model. For the sake of brevity, we will only define simple rules for each model that illustrate the concepts.
All the files used in this sample are available for download on GitHub.
Simulation model
We will define 2 properties for this model. A counter (to validate that the instances’ rules are getting executed) and a timestep value, which we will use to control how often each simulation instance is woken up to execute rules during the simulation.
Our simulation rules will be simple:
The first rule (INCREASE COUNTER) increments our counter each time the instance’s rules are executed. We will use that to track that our instance is executing rules at the right pace.
The second rule (DELAY) sends the instruction to the simulation manager not to wake this instance up for the duration of the specified Timestep value. For instance, if an instance is set to delay for 3 seconds and the simulation time increment is 1 second, this particular instance will not execute any rules for 3 simulation time increments. We will use this rule to validate that the instances are delaying as expected when different values are passed to the DELAY function.
The third rule demonstrates the EMIT_TELEMETRY function, which sends data to the simulation instance’s corresponding real-time instance. In this case, you can observe that a real-time instance is automatically created by the EMIT_TELEMETRY call if it doesn’t already exist. This also shows how to send data using data collections. We defined a data collection named Telemetry, which includes the Counter instance property. At the time EMIT_TELEMETRY is invoked, the message sent to the real-time instance will include the current values of the instance property.
The fourth rule shows the use of DELETE_INSTANCE to remove an existing real-time instance.
The last simulation rule demonstrates how to remove a simulation instance.
Our simulation model also has a basic message rule (to log) to demonstrate the ability of a real-time model to send data back to its data source (the simulation instance, in this case).
The full model JSON definition file TestModelSim.json is available for download on GitHub.
Real-time model
The real-time model we use in this sample does not use complex rules. A more realistic model would do more with the data it receives from sensors. This one only logs messages or sends data from a data collection back to its data source (in this case the simulation instance) using the SEND_TO_DATASOURCE.
The full model JSON definition file TestModelRT.json is available for download on GitHub.
Importing instances from CSV
In this sample, we import 3 instances for the simulation model from a CSV file (see below). Each instance has a different Timestep value, so they are delayed in a staggered way (1 second, 2 seconds, or 3 seconds). The simulation rules above are defined to call EMIT_TELEMETRY, which will send a message to the respective real-time instance. We do not need to import the real-time instances–they will be created automatically when the telemetry is sent by a simulation rule.
Id,Timestep,Counter
InstanceA,1000,0
InstanceB,2000,0
InstanceC,3000,0
The CSV file TestModelSim.csv is available for download on GitHub.
Running the simulation
Once the models are open and the simulation instances have been imported, the simulation run can be started.
In this example, the start date/time does not matter for our simulation, so we can leave the default value. We will pick a delay of 1 second for the real delay between simulation steps, and a simulation time increment of 1000 ms, which means that the simulation will effectively be in real time.
Finally, create a metric for the average value of Counter in our simulation instance.
The simulation is ready to be started. When we press Play, the simulation starts in continuous mode. We will be able to see the Simulation status go from Not started to Running and the current simulation time step increase with every iteration.
Based on the simulation rules described above, Instance A will increase its counter and delay execution for 1 second (so effectively not delay since our time step increment is 1 second). Instance B will increase its counter and delay for 2 seconds (missing every other iteration), and Instance C will delay for 3 seconds (only running one in 3 iterations). As a result, you will be able to observe as the simulation progresses that Instance A’s Counter property gets incremented at a rate twice as fast as Instance B. You will also notice that the real-time instances get created when their simulation counterparts’ Counter property reaches the value 2 because of the EMIT_TELEMETRY call.
Throughout the simulation, you can observe the metric getting updated with each iteration. In this sample, the metric is there to showcase the capability, but in a real test scenario, you could track other values (such as the max value of an instance property), and monitor it to see that it never goes beyond a certain value. You can also click on any instance in the tree to see the values of all instance properties.
Note
You can pause the simulation at any point and switch to step-by-step execution if you want to manually observe the effect of any iteration. You can resume execution by pressing Play again.
Once a Counter property reaches 20 on one simulation instance, the corresponding real-time instance will get deleted. Instance A will get deleted first after 20 seconds of simulation time, while Instance B will get deleted after 40 seconds, etc.
Once a Counter property reaches 22, the simulation instance will get deleted.
Once no simulation instances are left (they all self-delete after reaching 22), there is no more work to do in the simulation, so it will automatically stop.
You can reset the simulation (you will need to re-import the simulation instances) and change simulation parameters as many times as you need.