SysML v2
The MBSE working group has a subgroup "Application example" that deals with the pilot implementation of SysML V2, which is provided by the OMG. The main goal is to develop a first feeling for the possibilities but also the pitfalls of the new version SysML v2. Therefore the focus is on getting to know the syntax and semantics of the new version, the differences to v1, and just playing around with the language.
On the basis of an application example, the following aspects will be put through their paces:
- Modeling of requirements, behavior, and structure
- Collaboration and modularization of SysML v2 models
- Collecting feedback for the SST SysML v2 working group
- Evaluation of the existing implementation in Eclipse and Jupyter Notebook
Since there is currently not much literature available on the topic of SysML v2, we try to get a picture ourselves and make our findings and our example model available on this page.
Useful Links:
An extensive SysML Example
Under construction ...
This image depicts the high-level architecture of our robotic vacuum cleaner model. As shown, the modules within the architecture import pertinent information from other modules, facilitating the robot's operation.
package 'Robotic Vacuum Cleaner'{
import Controller::*;
import Navigation::*;
import EnergySupplySystem::*;
import VacuumingSystem::*;
import Ports::*;
part def RoboticVacuumCleaner{
part ControllerSystem : controller;
part NavigationSystem : navigation;
part EnergySystem : energySupplySystem;
part VaccumingSystem : vacuumingSystem;
port driverUnitControlSignal : DriverUnitControlSignal;
port powerSignal : PowerSignal;
port dirtyAirFlow : DirtyAirFlow;
port cleanAirFlow : CleanAirFlow;
interface : DriverUnitControlInterface connect
supliertPort ::> ControllerSystem.driverSignalOutputPort to
consumerPort ::> NavigationSystem.driverUnitControlSignalInputPort;
// Interfaces to/from Vaccuming System
connect ControllerSystem to VacuumingSystem;
// Control signal for level of suction intesity
interface def suctionLevelPorts {
end supplierPort : SuctionLevel;
end consumerPort : SuctionLevel;
}
interface: suctionLevelPorts connect
supplierPort ::> ControllerSystem.suctionLevel;
consumerPort ::> VacuumingSystem.suctionLevel;
// Control signal for brush rotation level
interface def brushRotationLevelPorts {
end supplierPort : BrushRotationLevel;
end consumerPort : BrushRotationLevel;
}
interface: brushRotationLevelPorts connect
supplierPort ::> ControllerSystem.brushRotationLevel;
consumerPort ::> VacuumingSystem.brushRotationLevel;
// Current fill state of debris container
interface def fillStatePorts {
end supplierPort : FillState;
end consumerPort : FillState;
}
interface: fillStatePorts connect
supplierPort ::> VacuumingSystem.fillState;
consumerPort ::> ControllerSystem.fillState;
// Dirty air flow
interface def dirtyAirPorts {
end supplierPort : DirtyAirFlow;
end consumerPort : DirtyAirFlow;
}
interface: dirtyAirPorts connect
supplierPort ::> dirtyAirFlow;
consumerPort ::> VacuumingSystem.dirtyAirFlow;
// Clean air flow
interface def cleanAirPorts {
end supplierPort : CleanAirFlow;
end consumerPort : CleanAirFlow;
}
interface: cleanAirPorts connect
supplierPort ::> VacuumingSystem.cleanAirFlow;
consumerPort ::> cleanAirFlow;
}
}
The depicted image shows the controller, which assumes responsibility for interfacing with external systems and relaying information to the various sub-systems.
package Controller{
import Ports::*;
port def DriverUnitControlSignal {
out attribute forward : Boolean;
out attribute left : Boolean;
out attribute right : Boolean;
}
interface def DriverUnitControlInterface{
end supplierPort : DriverUnitControlSignal;
end consumerPort : ~DriverUnitControlSignal;
flow supplierPort.forward to consumerPort.forward;
flow supplierPort.left to consumerPort.left;
flow supplierPort.right to consumerPort.right;
}
interface def DriverUnitControlPassThroughInterface{
end supplierPort : ~DriverUnitControlSignal;
end consumerPort : ~DriverUnitControlSignal;
flow supplierPort.forward to consumerPort.forward;
flow supplierPort.left to consumerPort.left;
flow supplierPort.right to consumerPort.right;
}
part def controller{
port driverSignalOutputPort : DriverUnitControlSignal;
port powerSignal : ~PowerSignal;
// To Vacuuming System
port suctionLevel : SuctionLevel;
port brushRotationLevel : BrushRotationLevel;
// From Vacuuming System
port fillState : ~FillState;
}
}
ToDo: add description.
package EnergySupplySystem{
import Ports::*;
part def energySupplySystem{
port powerSignal : PowerSignal;
}
}
This image portrays the high-level architecture of our navigation system. Similarly to the previous module, the architecture imports data from other modules to enable proper functionality
package Navigation{
/*This module implements the Navigation-System
* The Navigation-System is used for navigating the system
*/
import Ports::*;
private import Controller::*;
private import Bumber::*;
private import Engine::*;
private import LaserTower::*;
private import DriveController::*;
private import InfraredController::*;
part def navigation{
part DriveController : driveController;
part Engine[2] : engine;
part LaserTower : laserTower;
part Bumber : bumber;
part InfraredController : infraredController;
port driverUnitControlSignalInputPort : ~DriverUnitControlSignal;
port powerSignal : PowerSignal;
interface : bumberInterface connect
suppliertPort ::> Bumber.CollisionOutputPort to
consumerPort ::> DriveController.CollisionInputPort;
interface : laserTowerInterface connect
supplierPort ::> LaserTower.LaserTowerPositionOutputPort to
consumerPort ::> DriveController.LaserTowerInputPort;
interface : infraredControllerInterface connect
supplierPort ::> InfraredController.ContactChargerOutputPort to
consumerPort ::> DriveController.ContactChargerInputPort;
interface : pwmControllInterface connect
suppliertPort ::> Engine.PwmInputPort to
consumerPort ::> DriveController.PwmOutputPort;
interface : DriverUnitControlPassThroughInterface connect
suppliertPort ::> driverUnitControlSignalInputPort to
consumerPort ::> DriveController.driverUnitControlSignalInputPort;
}
}
This image showcases the Bumber implementation.
package Bumber{
/* This package implements the Bumber-System
* The Bumber detects collision*/
item def collisionDetection;
port def collision{
out item CollisionDetection : collisionDetection;
}
interface def bumberInterface{
end supplierPort : collision;
end consumerPort : ~collision;
flow supplierPort.CollisionDetection to consumerPort.CollisionDetection;
}
interface def bumberPassThroughInterface{
end supplierPort : ~collision;
end consumerPort : ~collision;
flow supplierPort.CollisionDetection to consumerPort.CollisionDetection;
}
part def bumber {
port CollisionOutputPort : collision;
}
}
This image showcases the DriveController implementation.
package DriveController{
/* This package implements the DriveContoller-System
* The DriveController drives the system*/
private import Controller::*;
private import Bumber::*;
private import Engine::*;
private import LaserTower::*;
private import InfraredController::*;
private import InfraredController::infraredController;
part def stearingController{
port PwmOutputPort : ~pwmPort;
port driverUnitControlSignalInputPort : ~DriverUnitControlSignal;
}
part def orienttationController{
port CollisionInputPort : ~collision;
port LaserTowerInputPort : ~laserTowerPosition;
port ContactChargerInputPort : ~contactCharger;
}
part def driveController {
port CollisionInputPort : ~collision;
port LaserTowerInputPort : ~laserTowerPosition;
port PwmOutputPort : ~pwmPort;
port ContactChargerInputPort : ~contactCharger;
port driverUnitControlSignalInputPort : ~DriverUnitControlSignal;
part StearingController : stearingController;
part OrientationController : orienttationController;
interface : bumberPassThroughInterface connect
supplierPort ::> CollisionInputPort to
consumerPort ::> OrientationController.CollisionInputPort;
interface : pwmPassThroughInterface connect
supplierPort ::> PwmOutputPort to
consumeport ::> StearingController.PwmOutputPort;
interface : infraredControllerPassThroughInterface connect
supplierPort ::> ContactChargerInputPort to
consumerPort ::> OrientationController.ContactChargerInputPort;
interface : laserTowerPassThroughInterface connect
supplierPort ::> LaserTowerInputPort to
consumerPort ::> OrientationController.LaserTowerInputPort;
interface : DriverUnitControlPassThroughInterface connect
suppliertPort ::> driverUnitControlSignalInputPort to
consumerPort ::> StearingController.PwmOutputPort;
}
}
This image showcases the Engine implementation.
package Engine{
/* This package implements the Engine-System
* The engine drives the system*/
part def Tire;
item def pwm;
port def pwmPort{
in item PWM : pwm;
}
interface def pwmControllInterface{
end supplierPort : pwmPort;
end consumerPort : ~pwmPort;
flow supplierPort.PWM to consumerPort.PWM;
}
interface def pwmPassThroughInterface{
end supplierPort : ~pwmPort;
end consumerPort : ~pwmPort;
flow supplierPort.PWM to consumerPort.PWM;
}
part def engine {
part motorTire : Tire [2];
port PwmInputPort : pwmPort;
state def motorDirection {
entry; then idle;
state idle;
transition idle_to_left
first idle
then left;
transition idle_to_right
first idle
then right;
state left;
transition left_to_idle
first left
then idle;
state right;
transition right_to_idle
first right
then idle;
}
}
}
This image showcases the LaserTower implementation.
package LaserTower{
/* This package implements the LaserTower-System
* The LaserTower finds the relative position to other objects*/
item def angle;
item def distance;
port def laserTowerPosition{
out item Angle : angle;
out item Distance : distance;
}
interface def laserTowerInterface {
end supplierPort : laserTowerPosition;
end consumerPort : ~laserTowerPosition;
flow supplierPort.Angle to consumerPort.Angle;
flow supplierPort.Distance to consumerPort.Distance;
}
interface def laserTowerPassThroughInterface {
end supplierPort : ~laserTowerPosition;
end consumerPort : ~laserTowerPosition;
flow supplierPort.Angle to consumerPort.Angle;
flow supplierPort.Distance to consumerPort.Distance;
}
part def laserTower {
port LaserTowerPositionOutputPort : laserTowerPosition;
}
}
This image showcases the InfraredController implementation.
package InfraredController{
/*This module implements the InfrarotControler subsystem
* The InfrarotControler is to ensure the position to charging point */
item def contact;
port def contactCharger{
out item Contact : contact;
}
interface def infraredControllerInterface{
end supplierPort : contactCharger;
end consumerPort : ~contactCharger;
flow supplierPort.Contact to consumerPort.Contact;
}
interface def infraredControllerPassThroughInterface{
end supplierPort : ~contactCharger;
end consumerPort : ~contactCharger;
flow supplierPort.Contact to consumerPort.Contact;
}
part def infraredController{
port ContactChargerOutputPort : contactCharger;
}
}
This image showcases the public ports utilized in the system's operation.
package Ports {
import ScalarValues::*;
import ISQ::*;
import SI::*;
import ISQSpaceTime::*;
import ISQMechanics::*;
// Ports for Navigation System
port def PowerSignal{
out constantCurrent :> totalCurrent;
out constantVoltage :> voltage;
}
// Ports for Vacuuming System
port def DirtyAirFlow{
in dirtyAirFlow :> ISQSpaceTime::volume;
}
port def CleanAirFlow{
out cleanAirFlow :> ISQSpaceTime::volume;
}
port def Debris {
out debrisVolume :> SI::'m³';
out debrisMass :> SI::kg;
}
port def FillState {
out fillState :> Real;
}
port SuctionLevel {
out suctionLevel :> Real;
}
port SuctionPower {
out suctionPower :> ISQ::power;
}
port BrushRotationLevel {
out brushRotationLevel :> Real;
}
port def BrushRotationSpeed {
out brushRotationSpeed :> ISQSpaceTime::rotationalFrequency;
}
}
ToDo: add description.
package VacuumingSystem{
import BrushSystem::*;
import SuctionDevice::*;
import FilterSystem::*;
import Ports::*;
part def vacuumingSystem{
part bs : brushSystem;
part sd : suctionDevice;
part fs : filterSystem;
port dirtyAirFlow : DirtyAirFlow;
port cleanAirFlow : CleanAirFlow;
port debris : Debris;
port fillState : FillState;
port suctionLevel : ~SuctionLevel;
port brushRotationLevel : ~BrushRotationLevel;
interface def rotationLevelPorts {
end supplierPort : BrushRotationLevel;
end consumerPort : BrushRotationLevel;
}
interface: rotationLevelPorts connect
supplierPort ::> brushRotationLevel;
consumerPort ::> bs.brushRotationLevel;
interface def externalDirtyAirPorts {
end supplierPort : DirtyAirFlow;
end consumerPort : DirtyAirFlow;
}
interface: externalDirtyAirPorts connect
supplierPort ::> dirtyAirFlow;
consumerPort ::> sd.dirtyAirFlowIn;
connect sd to fs;
interface def internalDirtyAirPorts {
end supplierPort : DirtyAirFlow;
end consumerPort : DirtyAirFlow;
}
interface: internalDirtyAirPorts connect
supplierPort ::> sd.dirtyAirFlowOut;
consumerPort ::> fs.dirtyAirFlow;
interface def cleanAirPorts {
end supplierPort : CleanAirFlow;
end consumerPort : CleanAirFlow;
}
interface: cleanAirPorts connect
supplierPort ::> fs.cleanAirFlow;
consumerPort ::> cleanAirFlow;
interface def suctionLevelPorts {
end supplierPort : SuctionLevel;
end consumerPort : SuctionLevel;
}
interface: suctionLevelPorts connect
supplierPort ::> suctionLevel;
consumerPort ::> sd.suctionlevel;
interface def fillStatePorts {
end supplierPort : FillState;
end consumerPort : FillState;
}
interface: fillStatePorts connect
supplierPort ::> fs.fillState;
consumerPort ::> fillState;
}
}
ToDo: add description.
package BrushSystem {
import Ports::*;
import ISQSpaceTime::*;
calc def calcSetpointRPM (rotationLevel : Real, maxRPM :> ISQSpaceTime::rotationalFrequency) :> ISQSpaceTime::rotationalFrequency {
rotationLevel * maxRPM
}
part def MainBrush {
port rotationSpeed : ~BrushRotationSpeed;
}
part def SmallBrush {
port rotationSpeed : ~BrushRotationSpeed;
}
part def BrushController {
port rotationSpeed : BrushRotationSpeed;
port brushRotationLevel : ~BrushRotationLevel;
attribute parMaxRPM :> ISQSpaceTime::rotationalFrequency;
calc setpointRPM : calcSetpointRPM (
rotationLevel = brushRotationLevel::brushRotationLevel,
maxRPM = parMaxRPM
) return pOut = rotationSpeed::rotationSpeed;
}
part def brushSystem{
part mb : MainBrush;
part sb : SmallBrush[2];
part bc : BrushController{
attribute redefines parMaxRPM = 167; // 10000 rpm is a common rotational speed of the brushes, recalculation because rotationalFrequency is [1/s]
};
port brushRotationLevel : ~BrushRotationLevel;
connect bc to mb;
interface def rotationSetPointMainPorts {
end supplierPort : BrushRotationSpeed;
end consumerPort : BrushRotationSpeed;
}
interface: rotationSetPointMainPorts connect
supplierPort ::> bc.brushRotationSpeed;
consumerPort ::> mb.brushRotationSpeed;
connect bc to sb;
interface def rotationSetPointSmallPorts {
end supplierPort : BrushRotationSpeed;
end consumerPort : BrushRotationSpeed;
}
interface: rotationSetPointSmallPorts connect
supplierPort ::> bc.brushRotationSpeed;
consumerPort ::> sb.brushRotationSpeed;
}
}
ToDo: add description.
package FilterSystem {
import Ports::*;
part def Tank {
port debris : ~Debris;
port fillState : FillState;
// Missing State Machine
}
part def Filter {
port dirtyAirFlow : DirtyAirFlow;
port cleanAirFlow : CleanAirFlow;
port debris : Debris;
}
part def filterSystem {
port dirtyAirFlow : DirtyAirFlow;
port cleanAirFlow : CleanAirFlow;
port fillState : FillState;
part filter : Filter;
part tank : Tank;
interface def dirtyAirFlowPorts {
end supplierPort : DirtyAirFlow;
end consumerPort : DirtyAirFlow;
}
interface: dirtyAirFlowPorts connect
supplierPort ::> dirtyAirFlow;
consumerPort ::> filter.dirtyAirFlow;
interface def cleanAirFlowPorts {
end supplierPort : CleanAirFlow;
end consumerPort : CleanAirFlow;
}
interface: cleanAirFlowPorts connect
supplierPort ::> filter.cleanAirFlow;
consumerPort ::> cleanAirFlow;
connect filter to tank;
interface def debrisPorts {
end supplierPort : Debris;
end consumerPort : Debris;
}
interface: dirtyAirFlowPorts connect
supplierPort ::> filter.debris;
consumerPort ::> tank.debris;
interface def fillStatePorts {
end supplierPort : fillState;
end consumerPort : fillState;
}
interface: fillStatePorts connect
supplierPort ::> tank.fillState;
consumerPort ::> fillState;
}
}
ToDo: add description.
package SuctionDevice {
import Ports::*;
import ISQ::*;
import ISQMechanics::*;
import ISQSpaceTime::*;
import ScalarValues::*;
calc def calcActualPower (powerLevel :> Real, maxPower :> ISQ::power) :> ISQ::power {
powerLevel * maxPower
}
calc def calcVolFlow (setpointPower :> ISQ::power, diffPressure :> ISQ::pressure) :> ISQMechanics::volumeFlowRate {
actPower / diffPressure
}
calc def calcFlowRate (inFlow :> ISQSpaceTime::volume, volFlow :> ISQMechanics::volumeFlowRate) :> ISQSpaceTime::volume {
// not sure how to model without time steps
}
}
part def SuctionMotor {
port suctionLevel = ~SuctionLevel;
port suctionPower = SuctionPower;
attribute parMaxPower :> ISQ::power;
calc powerOut : calcActualPower (
powerLevel = suctionLevel::suctionLevel,
maxPower = parMaxPower
) return pOut = suctionPower::suctionPower;
}
part def SuctionChamber {
port dirtyAirFlowIn = DirtyAirFlow;
port dirtyAirFlowOut = ~DirtyAirFlow;
port suctionPower : ~SuctionPower;
attribute parDiffPressure :> ISQ::pressure;
calc volFlow : calcVolFlow (
actPower = suctionPower::suctionPower,
diffPressure = parDiffPressure
) return currentFlow
calc flowRate : calcFlowRate (
inFlow = dirtyAirFlowIn::dirtyAirFlow;
volFlow = currentFlow
) return currentFlowRate = dirtyAirFlowOut::dirtyAirFlow;
}
part def suctionDevice {
part sm : SuctionMotor;
part sc : SuctionChamber {
attribute redefines parDiffPressure = 25000; // 25kPa is a common pressure difference for suction devices
}
port dirtyAirFlowIn : DirtyAirFlow;
port dirtyAirFlowOut : ~DirtyAirFlow;
port suctionLevel : ~SuctionLevel;
interface def dirtyAirFlowInPorts {
end supplierPort : DirtyAirFlow;
end consumerPort : DirtyAirFlow;
}
interface: dirtyAirFlowInPorts connect
supplierPort ::> dirtyAirFlowIn;
consumerPort ::> sc.dirtyAirFlowIn;
interface def dirtyAirFlowOutPorts {
end supplierPort : DirtyAirFlow;
end consumerPort : DirtyAirFlow;
}
interface: dirtyAirFlowOutPorts connect
supplierPort ::> sc.dirtyAirFlowOut;
consumerPort ::> dirtyAirFlowOut;
interface def suctionLevelPorts {
end supplierPort : SuctionLevel;
end consumerPort : SuctionLevel;
}
interface: suctionLevelPorts connect
supplierPort ::> suctionLevel;
consumerPort ::> sm.suctionlevel;
connect sm to sc;
interface def suctionPowerPorts {
end supplierPort : SuctionPower;
end consumerPort : SuctionPower;
}
interface: suctionPowerPorts connect
supplierPort ::> sm.suctionPower;
consumerPort ::> sc.suctionPower;
}
}