OMG Systems Modeling Language (SysML) v2¶
fsmc provides native parsing and emission for the OMG SysML v2 textual state definition grammar, including hardware I/O ports with range contracts, internal attribute memory registers, and action behaviors.
1. SysML v2 Statechart Grammar Reference¶
fsmc supports the standard declarative SysML v2 statechart constructs:
A. State Machine Definition & Domains¶
package SpacecraftSubsystems {
state def FlightController {
// 0. Data Definitions (Enums and Structs)
enum def FlightPhase {
Preflight;
Ascent;
Cruise;
Descent;
Terminal;
}
struct def NavigationVector {
attribute latitude : Real;
attribute longitude : Real;
attribute altitude : Real;
}
// 1. Read-only Input Ports with formal range constraints
in port sensor_altitude : Real { assert constraint { self >= 0.0 and self <= 100000.0; } }
in port gps_lock : Boolean;
in port target_waypoint : NavigationVector;
// 2. Write-only Output Ports
out port thruster_level : Real { assert constraint { self >= 0.0 and self <= 100.0; } }
out port active_phase : FlightPhase;
// 3. Persistent Internal Memory (Registers / z^-1 state)
attribute orbit_count : Integer = 0;
attribute fault_counter : Integer = 0;
attribute current_pos : NavigationVector;
// 4. Initial transition entry point
entry; then Preflight;
// State definitions follow...
}
}
B. State Lifecycles & Nested Hierarchies (HFSM)¶
state Preflight {
entry action initializeSensors();
do action runSelfTest();
exit action logPreflightComplete();
transition on EvArmed if in.gps_lock then ActiveFlight;
}
// Composite / Hierarchical State
state ActiveFlight {
entry; then Ascending;
state Ascending {
transition on AltitudeReached if in.sensor_altitude > 10000.0 then Cruising;
}
state Cruising {
transition on OrbitComplete do action { reg.orbit_count = reg.orbit_count + 1; } then Cruising;
}
// High-level interrupt transition out of composite state
transition on EvEStop then EmergencyHold;
}
state EmergencyHold;
[!WARNING] MBSE Exchange vs C++ Backend (
ECPP006): State-leveldo action <Activity>();(do_activity) is fully parsed and preserved inFsmIrfor lossless MBSE model exchange (e.g., SysML v2 \(\leftrightarrow\) SCXML \(\leftrightarrow\) Cameo \(\leftrightarrow\) Stateflow). However, the zero-heap synchronous C++ reference backend rejects unlowereddo_activitywith diagnosticECPP006, because synchronous finite state automata require discrete zero-time run-to-completion semantics. For background work in C++, use transition actions or the multi-threadedthread_safe_fsmexecutor.
C. Transition Syntax Varieties & Fork/Join Synchronization¶
fsmc parses both full explicit transition statements and shorthand forms:
| Transition Style | Syntax | Description |
|---|---|---|
| Full Explicit | transition tr1 first Idle accept EvStart if in.gps_lock do action { out.thrust = 50.0; } then Running; |
Complete specification with explicit source, trigger, guard, action, and target. |
| Shorthand Trigger | transition on EvStart to Running; |
Inline trigger inside a state block targeting Running. |
| Temporal Trigger (after) | transition on after(500 ms) then TimeoutFault; |
Discrete-time dwell delay transition. |
| Temporal Trigger (at) | transition on at(12:00:00) then ScheduledSync; |
Absolute clock trigger transition. |
| Guarded Shorthand | transition if in.sensor_altitude <= 0.0 then Landed; |
Immediate guard-evaluated transition. |
| Fork Transition | transition fork (Region1, Region2); |
Direct multi-target fork transition activating concurrent orthogonal regions. |
| Join Transition | transition join (Region1, Region2) then Converged; |
Direct multi-source join transition synchronizing completion of orthogonal regions. |
| Fork Pseudostate | fork Fork1; transition first St1 then Fork1; transition first Fork1 then ParallelA; |
Spawns concurrent execution across orthogonal regions. |
| Join Pseudostate | join Join1; transition first ParallelA then Join1; transition first Join1 then St2; |
Synchronizes completion of orthogonal regions. |
| Connection Point | entry point En1; exit point Ex1; |
Structured entry and exit connection points across state boundaries. |
D. Nested Qualified Packages & Binding Connectors¶
SysML v2 namespaces can be nested or qualified, with explicit port bindings and structural connectors:
package Avionics::PowerSystem {
state def BatterySupervision {
in port raw_bus_voltage : Real;
out port filtered_voltage : Real;
// Port bindings and structural connectors
bind filtered_voltage = raw_bus_voltage;
connect telemetry_out to GroundStation::rx_bus;
// Nested package hierarchy
package ThermalSubsystem {
state def Cooler {
entry; then Passive;
state Passive;
}
}
}
}
E. Choice Pseudostates & Branching¶
choice ClearanceCheck;
transition first Preflight accept EvRequestLaunch then ClearanceCheck;
transition check_ok first ClearanceCheck if in.gps_lock then ActiveFlight;
transition check_fail first ClearanceCheck if not in.gps_lock then Preflight;
2. Formal Directives in SysML v2¶
You can embed formal verification specifications and requirement traceability annotations directly into SysML v2 comments and declarations:
package MissionSafety {
state def UAVControl {
// Formal Safety Invariant: Never allow HighThrust while Landed
@fsm:property InvariantNoThrustOnGround = "G !(Landed && HighThrust)";
// Formal Liveness Property: When LowBattery occurs, the system must eventually Land
@fsm:property ResponseLanding = "G (EvLowBattery -> F Landed)";
state Landed {
// Requirement Traceability Tag
@fsm:req "REQ-UAV-001";
// Defer sensor payload commands until flight is active
@fsm:defer [EvStreamTelemetry, EvStartMission];
}
state HighThrust;
}
}
3. End-to-End Example: SysML v2 to C++20 Header¶
package Aerospace {
state def SpacecraftControl {
in port battery_soc : Real { assert constraint { self >= 0.0 and self <= 100.0; } }
out port heater_cmd : Real { assert constraint { self >= 0.0 and self <= 100.0; } }
attribute cycles : Integer = 0;
@fsm:property SafeBat = "G (EvCritBat -> F SafeMode)";
entry; then Standby;
state Standby {
transition on EvLaunch if in.battery_soc > 20.0 then OrbitOps;
}
state OrbitOps {
transition on EvCritBat if in.battery_soc <= 20.0 then SafeMode;
}
state SafeMode;
}
}
stateDiagram-v2
%% @fsm:name SpacecraftControl
%% @fsm:port name=battery_soc type=Real dir=in min=0.0 max=100.0
%% @fsm:port name=heater_cmd type=Real dir=out min=0.0 max=100.0
%% @fsm:property name=SafeBat kind=Liveness formula="G (EvCritBat -> F SafeMode)"
[*] --> Standby
Standby --> OrbitOps: EvLaunch [in.battery_soc > 20.0]
OrbitOps --> SafeMode: EvCritBat [in.battery_soc <= 20.0]
#pragma once
#include <fsm/backend/cpp/runtime/fsm.hpp>
namespace Aerospace {
struct InPorts {
double battery_soc{0.0};
};
struct OutPorts {
double heater_cmd{0.0};
};
struct Registers {
int64_t cycles{0};
};
struct Standby {};
struct OrbitOps {};
struct SafeMode {};
struct EvLaunch {};
struct EvCritBat {};
} // namespace Aerospace
4. CLI Invocations¶
# Formally verify SysML v2 specification (Interval Analysis + Model Checking)
fsmc -i spacecraft.sysml --verify
# Generate standalone C++20 header
fsmc -i spacecraft.sysml -o spacecraft_fsm.hpp --std 20
# Export canonical SMV logic for external nuXmv proof
fsmc -i spacecraft.sysml --export smv -o formal_model.smv
# Transpile SysML v2 into PlantUML or Mermaid diagram
fsmc -i spacecraft.sysml --export plantuml -o diagram.puml