Handling Multiplicity in State Machines
Overview
Multiplicity defines the number of instances that can exist for a given part or reference property.
For example, assume the UAV in this tutorial is a quadcopter with exactly four distinct motors: one to power each propeller.
This translates to a multiplicity of 4..4
(minimum of 4 and maximum of 4) in SysML.
In this section, you will use a repeating substate to have the flight controller arm each motor one by one.
This section covers the following concepts:
- Multiplicity
- State entry and exit behaviors
Figure A1: Iterating through a property with multiplicity greater than one
Prerequisites
Prerequisite | Description |
---|---|
Moxie Installation | You must have installed Moxie. |
Tutorial Project | You must start this section with the Moxie simulation project from the previous section. If you did not complete the previous section, you can use the following project from the Moxie installation: \documentation\tutorialFiles\02\ChangeEvents.mdzip |
Recommended Reading |
Before completing this section, you may want to read the following help topic:
|
Instructions
Create a block for the motors
- Open the project from the previous section.
-
In the System Definition (the BDD),
select the
Thing
block, click the downward-pointing Generalization button () on the context toolbar, and then click anywhere on the canvas to add a new block. -
Select the new block on the diagram
and enter
Motor
as its name. - Click the Create Element button () on the upper-right corner of the block and select Part Property.
-
Enter
armDuration : FixedDuration
as the property's name and type. - Double-click the new property, set the Visibility to public, set the Aggregation to shared, and click .
-
Select the
Motor
block again, click the Create Element button () on the upper-right corner of the block, and select Operation (or press ). -
Enter
arm
as the operation's name. - Double-click the new operation, set the Visibility to public, and click .
Assign the block to properties
The Motor
block should be a part property of the UAV and reference property of the flight controller,
with a multiplicity of four in both cases, indicating that there are exactly four motors for a single UAV and flight controller.
-
Select the
UAV
block, click the Directed Composition button () on the context toolbar, and then click theMotor
block. -
Double-click the new association
and in the Role of Motor category,
set the Name to
motors
and the Multiplicity to4
. -
In the Role of UAV category,
set the Multiplicity to
1
and click . -
In the toolbar to the left of the BDD canvas,
select Directed Association,
click the
FlightController
block, and then click theMotor
block. -
Double-click the new association
and in the Role of Motor category,
set the Name to
motors
and the Multiplicity to4
. -
In the Role of FlightController category,
set the Multiplicity to
1
and click . -
Select the
FlightController
block, click the Create Element button () on the upper-right corner of the block, and select Value Property. -
Enter
motorsArmed : Integer
as the property's name and type. - Double-click the new property, set the Visibility to private, and click .
Figure B1: The system definition (BDD)
Create instance specifications for the motors
The four motors each need their own instance specification.
However, assuming they are identical, they will all take the same amount of time to arm,
so they can share a single armDuration
instance specification.
-
Right-click the
Motor
block and select Tools > Create Instance.... -
In the 1. Select parts page,
select the
armDuration
property, click the cell to the right of Value, and then click the button in the right corner of the cell. -
Select the Simulation >
armingWaitDuration
instance specification, click , and then click . - Set the Name to the string armDuration and click , , and then .
- In the 2. Select a package page, select the Simulation package and click .
- In the 3. Create a diagram page, clear the Create a new diagram checkbox and click .
-
In the Containment Tree,
set the
seconds
value of the newarmDuration
instance specification to3
. -
Copy (
motor
instance specification, select the Simulation package, and paste ( ) the instance specification three times.
) the -
Rename the four motor instance specifications to
uav.frontLeftMotor
,uav.frontRightMotor
,uav.rearLeftMotor
, anduav.rearRightMotor
.
Assign the instance specifications to properties
- Open the Instance Specification Diagram.
-
Drag the the four motor instance specifications
from the Containment Tree
into the
uav
instance specification on the diagram and click for each of them. -
For each motor instance specification:
Select it, click the Link button () on the context toolbar, click on theuav
instance specification to add the link, and then click on both pages of the dialog window. -
Double-click the
uav.flightController
instance specification and select Slots from the left pane of the specification window. -
In the center pane,
select the
motors
slot and click . - Click , then the Add Recursively button () to add all four motor instance specifications, and then and .
-
Drag the Simulation >
armDuration
instance specification from the Containment Tree into theuav
instance specification on the diagram. -
(Optional)
For each motor instance specification:
Select it, click the Link button () on the context toolbar, and then click on thearmDuration
instance specification to add the link.
Figure B2: The instance specification diagram
Create a state with entry and exit behaviors
States can activate behaviors upon entry and exit just like transitions activate behaviors in their effects. These entry and exit behaviors activate regardless of which transitions are taken into and out of the state. Also like with transition effects, Moxie requires these behaviors to be opaque behaviors with bodies written as opaque expressions.
-
In the FlightController State Machine diagram,
select State from the toolbar to the left of the canvas,
click the transition from the
Idle
state to the choice pseudostate, and then click . -
Enter
ArmingMotors
as the new state's name. -
Double-click the transition from
Idle
toArmingMotors
. - In the Effect category, set the Behavior Type to <UNSPECIFIED> and click .
-
Double-click the
ArmingMotors
state. - In the Entry category, set the Behavior Type to OpaqueBehavior.
-
Set the Body and Language to the string
motorsArmed = 0;
. - In the Exit category, set the Behavior Type to OpaqueBehavior.
-
Set the Body and Language to the string
isArmed = true;
and click .
Model the internal behavior with a repeating substate
Similarly to how you modeled simultaneous behavior by nesting states inside a composite superstate, you can model the internal behavior of a state by nesting substates inside of it.
-
In the toolbar to the left of the state machine canvas,
select Initial
and click in the
ArmingMotors
state to add an initial pseudostate. -
Click the Transition button () on the context toolbar,
right-click in the state and select State,
and then enter
ArmingMotor
as its name. - Click the Transition button () on the context toolbar again. Then right-click in the state and select Final State to add a final pseudostate.
-
Select the
ArmingMotor
state again, click the Transition button () on the context toolbar, and click theArmingMotor
state (or click the Transition to Self button ()). -
Double-click the transition-to-self on the
ArmingMotor
state. -
In the Trigger category,
set the Event Type to TimeEvent,
set When to the string
motors.getValueAt(motorsArmed).armDuration
, and set Is Relative totrue
. -
Set the Guard to the string
motorsArmed < motors.size()
and (optionally) add a line break beforemotorsArmed < motors.size()
. -
In the Effect category,
set the Behavior Type to OpaqueBehavior,
set the Body and Language to the string
motors.getValueAt(motorsArmed).arm(); motorsArmed += 1;
, and (optionally) add line breaks beforemotors.getValueAt(motorsArmed).arm();
andmotorsArmed += 1;
. Then click . -
Double-click the transition from the
ArmingMotor
state to the final pseudostate, set the Guard to the stringmotorsArmed == motors.size()
, and click . -
Run () the simulation
and observe that the flight controller arms the motors one by one before setting itself as ready for takeoff.
Figure B3: The flight controller state machine
- Save your work before continuing.
Next Tutorial!