Create and Analyze Random Schedules for a Model Using the Schedule Editor API
This example uses the Schedule Editor API to perform operations on the schedule. Then it uses a function to generate random schedules and analyze them in Simulation Data Inspector
Open the Model and Get the Schedule Object
Open a model of a Throttle Position Control system and use get_param
to obtain the simulink.schedule.OrderedSchedule
object. This object contains the current schedule.
model = 'ScheduleEditorAPIWithSubsystemPartitions'; open_system(model); schedule = get_param(model,'Schedule')
schedule = OrderedSchedule with properties: Order: [7x3 table] RateSections: [3x1 simulink.schedule.RateSection] Events: [0x1 simulink.schedule.Event] Description: ''
Examine the Schedule Object
The schedule object has an Order
property that contains the execution order of the partitions in the model. The Order
property displays a table that contains partition names, their index, type, and their trigger.
schedule.Order
ans = 7x3 table Index Type Trigger _____ ________ _______ Cont 1 Periodic "0" TPSSecondaryRun5ms 2 Periodic "0.005" MonitorRun5ms 3 Periodic "0.005" ControllerRun5ms 4 Periodic "0.005" ActuatorRun5ms 5 Periodic "0.005" APPSnsrRun 6 Periodic "0.01" TPSPrimaryRun10ms 7 Periodic "0.01"
Use the index variable in the Order
table to change the execution order of the model
schedule.Order.Index('ActuatorRun5ms') = 2;
schedule.Order
ans = 7x3 table Index Type Trigger _____ ________ _______ Cont 1 Periodic "0" ActuatorRun5ms 2 Periodic "0.005" TPSSecondaryRun5ms 3 Periodic "0.005" MonitorRun5ms 4 Periodic "0.005" ControllerRun5ms 5 Periodic "0.005" APPSnsrRun 6 Periodic "0.01" TPSPrimaryRun10ms 7 Periodic "0.01"
Any moves within the Order
property that are made to modify the schedule should result in valid schedule. To perform the schedule modifications and valid moves easier, each partition is grouped with partitions of the same rate in the RateSections
property. Each element of the RateSection
property contains an order table with partitions of the same rate.
schedule.RateSections(2) schedule.RateSections(2).Order
ans = RateSection with properties: Rate: "0.005" Order: [4x3 table] ans = 4x3 table Index Type Trigger _____ ________ _______ ActuatorRun5ms 2 Periodic "0.005" TPSSecondaryRun5ms 3 Periodic "0.005" MonitorRun5ms 4 Periodic "0.005" ControllerRun5ms 5 Periodic "0.005"
Use the index variable to move the partitions within RateSections
.
schedule.RateSections(2).Order.Index('ActuatorRun5ms') = 5;
schedule.Order
ans = 7x3 table Index Type Trigger _____ ________ _______ Cont 1 Periodic "0" TPSSecondaryRun5ms 2 Periodic "0.005" MonitorRun5ms 3 Periodic "0.005" ControllerRun5ms 4 Periodic "0.005" ActuatorRun5ms 5 Periodic "0.005" APPSnsrRun 6 Periodic "0.01" TPSPrimaryRun10ms 7 Periodic "0.01"
Create a Function to Generate Random Schedules
In this section, we create three different functions: randomSchedule
, generateSimulationInputs
and simulateRandomSchedules
randomSchedule
function is used to create random schedules by using random permutations of index modifications in the schedule
object. Using the Order
and the RateSections
properties of the schedule
object, partitions in the schedules are moved around in different, random combinations. With these randomly created schedules, models are simulated and compared to study the effect of different schedules on simulation. In the function randomSchedule
, the input is the model name. Then use get_param
to obtain the simulink.schedule.OrderedSchedule
object of the model. The schedule
object and its properties are used to modify and randomize the schedules. Create a variable firstExecutionOrder
for the first rate section of the model. The rateSections(1).ExecutionOrder = [firstExecutionOrder(1,:); reSchedule(firstExecutionOrder(2:end,:))]
line of code calls the function reSchedule
which creates random permutations of the indexes.
type randomSchedule
function schedule = randomSchedule(model) % schedule = randomSchedule(model) Produces a % simulink.schedule.OrderedSchedule that has a randomized permutation % of the model's original execution order schedule arguments model char = bdroot end schedule = get_param(model, 'Schedule'); rateSections = schedule.RateSections; firstOrder = rateSections(1).Order; % This assumes that the slowest discrete rate is at index 1. This may % not be the case for all models (ex. JMAAB-B). rateSections(1).Order = [firstOrder(1,:); reSchedule(firstOrder(2:end,:))]; for i=2:length(rateSections) rateSections(i).Order = reSchedule(rateSections(i).Order); end schedule.RateSections = rateSections; end function out = reSchedule(in) numPartitions = height(in); in.Index = in.Index(randperm(numPartitions)); out = in; end
To analyze the effects of different schedules on the model, simulate the model with the different schedules. In this function, create an array of Simulink.SimulationInput
objects. Through this array of Simulink.SimulationInput
objects, you can apply the schedules to the model with the setModelParameters
method of the Simulink.SimulationInput
object.
type generateSimulationInputs
function in = generateSimulationInputs(model, numSimulations) % in = generateSimulationInputs(model, numSimulations) Generates % numSimulations Simulink.SimulationInput objects each containing a % different, randomized execution order schedule arguments model char = bdroot numSimulations double = 10 end in(numSimulations) = Simulink.SimulationInput(); in = in.setModelName(model); for idx = 1:numSimulations in(idx) = in(idx).setModelParameter('Schedule', randomSchedule(model)); end end
In the last function, use the array of Simulink.SimulationInput
objects to run multiple simulations. Once the simulations are complete, you can plot the output of all the simulations in Simulation Data Inspector.
type simulateRandomSchedules
function out = simulateRandomSchedules(model, numSimulations) % out = simulateRandomSchedules(model, numSimulations) Simulates a % model numSimulations number of times. Each simulation has a % randomized execution order schedule. arguments model char = bdroot numSimulations double = 10 end in = generateSimulationInputs(model, numSimulations); out = sim(in); plot(out); end
Execute the Functions
Now run the above functions for the ScheduleEditorAPIWithSubsystemPartitions
model. First, use the randomSchedule
function to create randomly generated schedules, then, use the generateSimulationInputs
function to generate an array of Simulink.SimulationInput
objects, and use the simulateRandomSchedule
function to simulate the model with different schedules and plot their results for comparison. Let's run simulations with 15 randomly generated schedules.
simulateRandomSchedules(model,15)
[05-Sep-2024 18:56:39] Running simulations... [05-Sep-2024 18:56:49] Completed 1 of 15 simulation runs [05-Sep-2024 18:56:51] Completed 2 of 15 simulation runs [05-Sep-2024 18:56:53] Completed 3 of 15 simulation runs [05-Sep-2024 18:56:55] Completed 4 of 15 simulation runs [05-Sep-2024 18:56:56] Completed 5 of 15 simulation runs [05-Sep-2024 18:56:58] Completed 6 of 15 simulation runs [05-Sep-2024 18:56:59] Completed 7 of 15 simulation runs [05-Sep-2024 18:57:00] Completed 8 of 15 simulation runs [05-Sep-2024 18:57:02] Completed 9 of 15 simulation runs [05-Sep-2024 18:57:03] Completed 10 of 15 simulation runs [05-Sep-2024 18:57:05] Completed 11 of 15 simulation runs [05-Sep-2024 18:57:06] Completed 12 of 15 simulation runs [05-Sep-2024 18:57:07] Completed 13 of 15 simulation runs [05-Sep-2024 18:57:08] Completed 14 of 15 simulation runs [05-Sep-2024 18:57:10] Completed 15 of 15 simulation runs ans = 1x15 Simulink.SimulationOutput array