Vehicle System: Full SysML v2 Demo

A complete worked example showing every major SysML v2 element type and every diagram path provided by sphinx-need-sysml — both the PlantUML directives (needsysml-bdd, needsysml-ibd, needsysml-req) and the inline-SVG variants powered by sphinx-need-svg (needsysml-bdd-svg and raw needsvg templates).

Setup

Enable the extensions in docs/conf.py:

extensions = [
    "sphinx_needs",
    "sphinxcontrib.plantuml",
    "sphinx_need_sysml",
    "sphinx_need_svg",  # optional, enables SVG diagrams
]

plantuml_output_format = "svg"  # required for clickable PlantUML links

Structural Model

The vehicle decomposes into a powertrain (engine + transmission) and a chassis with four wheels.

PartDefs (definitions)

PartDef: Vehicle PD-001
status: accepted

Top-level vehicle system.

PartDef: Powertrain PD-002
status: accepted
owned_by: PD-001

Powertrain subsystem: engine plus transmission.

PartDef: Engine PD-003
status: accepted
owned_by: PD-002

Internal combustion engine.

PartDef: Transmission PD-004
status: accepted
owned_by: PD-002

Multi-speed gearbox.

PartDef: Chassis PD-005
status: accepted
owned_by: PD-001

Vehicle chassis carrying the wheels.

PartDef: Wheel PD-006
status: accepted
owned_by: PD-005

Wheel and tyre assembly.

Parts (usages)

Part: powertrain P-001
owned_by: PD-001
multiplicity: 1
definition: PD-002

The vehicle’s powertrain instance.

Part: engine P-002
owned_by: PD-002
multiplicity: 1
definition: PD-003

The engine instance.

Part: transmission P-003
owned_by: PD-002
multiplicity: 1
definition: PD-004

The transmission instance.

Part: chassis P-004
owned_by: PD-001
multiplicity: 1
definition: PD-005

The chassis instance.

Part: front_left_wheel P-005
owned_by: PD-005
multiplicity: 1
definition: PD-006
Part: front_right_wheel P-006
owned_by: PD-005
multiplicity: 1
definition: PD-006
Part: rear_left_wheel P-007
owned_by: PD-005
multiplicity: 1
definition: PD-006
Part: rear_right_wheel P-008
owned_by: PD-005
multiplicity: 1
definition: PD-006

Ports and Connections

Ports specify how parts interface; connections wire compatible ports together.

PortDef: FuelPort POD-001
direction: in

Fuel inlet port type.

PortDef: PowerOutPort POD-002
direction: out

Rotational power output port type.

PortDef: PowerInPort POD-003
direction: in

Rotational power input port type (conjugate of POD-002).

Port: fuel_in PO-001
owned_by: P-002
direction: in
definition: POD-001
Port: power_out PO-002
owned_by: P-002
direction: out
definition: POD-002
Port: power_in PO-003
owned_by: P-003
direction: in
definition: POD-003
Port: drive_out PO-004
owned_by: P-003
direction: out
definition: POD-002
Port: drive_in PO-005
owned_by: P-004
direction: in
definition: POD-003
ConnectionDef: EngineToTransLink CD-001
source_port: POD-002
target_port: POD-003

Connector type carrying rotational power.

Connection: engine_to_trans C-001
definition: CD-001
source_port: PO-002
target_port: PO-003

Wires engine power_out into transmission power_in.

Connection: trans_to_chassis C-002
definition: CD-001
source_port: PO-004
target_port: PO-005

Wires transmission drive_out into chassis drive_in.

Package Organization

Packages organize the model into nested groupings, with cross-package dependencies labelled by kind.

Package Definitions

Package: VehicleSystem PKG-001

Top-level package for the whole vehicle system.

Package: PowertrainPkg PKG-002
parent_package: PKG-001
Package: ChassisPkg PKG-003
parent_package: PKG-001
Package: ControlsPkg PKG-004
parent_package: PKG-001

Dependencies

Dependency: pt_uses_controls DEP-001
kind: use
source_ref: PKG-002
target_ref: PKG-004
Dependency: chassis_imports_controls DEP-002
kind: import
source_ref: PKG-003
target_ref: PKG-004

Package Diagram (PlantUML)

.. needsysml-pkg:: PKG-001
   :align: center

@startuml

' Config

skinparam package {
BackgroundColor #EEEEFF
BorderColor #336699
}
skinparam ArrowColor #336699







package "VehicleSystem" [[../examples/vehicle_system.html#PKG-001]] {



package "PowertrainPkg" [[../examples/vehicle_system.html#PKG-002]]




package "ChassisPkg" [[../examples/vehicle_system.html#PKG-003]]




package "ControlsPkg" [[../examples/vehicle_system.html#PKG-004]]


}



"PowertrainPkg" ..> "ControlsPkg" : <<use>>



"ChassisPkg" ..> "ControlsPkg" : <<import>>



@enduml

Package Diagram (SVG)

.. needsysml-pkg-svg:: PKG-001
   :align: center

Use Cases

Use cases capture stakeholder-system interactions inside a system boundary. Actor.interacts_with wires actors to use cases; UseCase.extends / .includes / .generalizes wire use cases to each other.

Actors

Actor: Driver ACTOR-001
interacts_with: USECASE-001
Actor: Mechanic ACTOR-002
interacts_with: USECASE-002, USECASE-003

Use Cases

UseCase: Start engine USECASE-001
subject: Vehicle
UseCase: Diagnose fault USECASE-002
subject: Vehicle
extends: USECASE-001
UseCase: Authenticate key USECASE-003
subject: Vehicle
UseCase: Perform service USECASE-004
subject: Vehicle
includes: USECASE-003

Use Case Diagram (PlantUML)

.. needsysml-uc::
   :align: center

@startuml

' Config

skinparam usecase {
BackgroundColor #FFEEDD
BorderColor #CC8800
}
skinparam actor {
BackgroundColor #EEEECC
BorderColor #886600
}
skinparam rectangle {
BorderColor #336699
}
left to right direction













actor "Driver" [[../examples/vehicle_system.html#ACTOR-001]]

actor "Mechanic" [[../examples/vehicle_system.html#ACTOR-002]]



rectangle "Vehicle" {

    usecase "Start engine" [[../examples/vehicle_system.html#USECASE-001]]

    usecase "Diagnose fault" [[../examples/vehicle_system.html#USECASE-002]]

    usecase "Authenticate key" [[../examples/vehicle_system.html#USECASE-003]]

    usecase "Perform service" [[../examples/vehicle_system.html#USECASE-004]]

}









"Driver" --> "Start engine"











"Mechanic" --> "Diagnose fault"







"Mechanic" --> "Authenticate key"
















"Diagnose fault" ..> "Start engine" : <<extend>>


















"Perform service" ..> "Authenticate key" : <<include>>






@enduml

Use Case Diagram (SVG)

.. needsysml-uc-svg::
   :align: center

Sequence

A sequence diagram captures the cross-component interaction during key-on ignition: DriverECUStarter. The two combined fragments illustrate an alt (sync vs. accessory mode) and a loop (warm-up).

Action Definition

ActionDef: IgnitionSequence AD-010

Key-on ignition interaction across Driver, ECU, and Starter.

Lifelines

Lifeline: driver_ll LIFELINE-001
definition: AD-010
Lifeline: ecu_ll LIFELINE-002
definition: AD-010
Lifeline: starter_ll LIFELINE-003
definition: AD-010

Messages

Message: turn_key_msg MSG-001
from_lifeline: LIFELINE-001
to_lifeline: LIFELINE-002
message_kind: sync
Message: crank_msg MSG-002
from_lifeline: LIFELINE-002
to_lifeline: LIFELINE-003
message_kind: async
fragment_group: F1
fragment_kind: alt
fragment_guard: key_position == 'start'
Message: ok_msg MSG-003
from_lifeline: LIFELINE-003
to_lifeline: LIFELINE-002
message_kind: return
fragment_group: F1
Message: heartbeat_msg MSG-004
from_lifeline: LIFELINE-002
to_lifeline: LIFELINE-002
message_kind: async
fragment_group: F2
fragment_kind: loop
fragment_guard: engine_warming

Sequence Diagram (PlantUML)

.. needsysml-sd:: AD-010
   :align: center

@startuml

' Config

skinparam sequence {
ParticipantBackgroundColor #E0E8F0
ParticipantBorderColor #336699
ArrowColor #336699
LifeLineBorderColor #888888
GroupBackgroundColor #F4F4FF
GroupBorderColor #336699
}









participant "driver_ll" [[../examples/vehicle_system.html#LIFELINE-001]]

participant "ecu_ll" [[../examples/vehicle_system.html#LIFELINE-002]]

participant "starter_ll" [[../examples/vehicle_system.html#LIFELINE-003]]








"driver_ll" -> "ecu_ll" : [[../examples/vehicle_system.html#MSG-001 turn_key_msg]]









alt key_position == 'start'




"ecu_ll" ->> "starter_ll" : [[../examples/vehicle_system.html#MSG-002 crank_msg]]









"starter_ll" --> "ecu_ll" : [[../examples/vehicle_system.html#MSG-003 ok_msg]]








end

loop engine_warming




"ecu_ll" ->> "ecu_ll" : [[../examples/vehicle_system.html#MSG-004 heartbeat_msg]]



end
@enduml

Sequence Diagram (SVG)

.. needsysml-sd-svg:: AD-010
   :align: center

Activity Diagram

needsysml-act walks the ActionDef’s owned actions, groups them into swimlanes by :partition:, and connects them via the controlflow (and optional objectflow) edges.

Action Definitions

ActionDef: StartEngine AD-001

Cold-start sequence for the engine.

Action: insert_key A-001
definition: AD-001
partition: Driver
Action: turn_key A-002
definition: AD-001
partition: Driver
Action: power_rails A-003
definition: AD-001
partition: ECU
Action: fork_node A-004
definition: AD-001
partition: ECU
activity_kind: fork
Action: crank_starter A-005
definition: AD-001
partition: ECU
Action: fuel_pump_prime A-006
definition: AD-001
partition: ECU
Action: join_node A-007
definition: AD-001
partition: ECU
activity_kind: join

Control Flows

ControlFlow: insert→turn CTRLFLOW-001
from_action: A-001
to_action: A-002
ControlFlow: turn→power CTRLFLOW-002
from_action: A-002
to_action: A-003
ControlFlow: power→fork CTRLFLOW-003
from_action: A-003
to_action: A-004
ControlFlow: fork→crank CTRLFLOW-004
from_action: A-004
to_action: A-005
ControlFlow: fork→fuel CTRLFLOW-005
from_action: A-004
to_action: A-006
ControlFlow: crank→join CTRLFLOW-006
from_action: A-005
to_action: A-007
ControlFlow: fuel→join CTRLFLOW-007
from_action: A-006
to_action: A-007

Activity Diagram (PlantUML)

.. needsysml-act:: AD-001
   :show-partitions: true
   :align: center

@startuml

' Config

skinparam activity {
BackgroundColor #FFEEDD
BorderColor #CC9966
DiamondBackgroundColor #FFE0AA
DiamondBorderColor #CC8800
}
skinparam partition {
BackgroundColor #FAF6EE
BorderColor #CC9966
}















package "Driver" <<swimlane>> {

class "A-001\ninsert_key" <<action>> [[../examples/vehicle_system.html#A-001]]

class "A-002\nturn_key" <<action>> [[../examples/vehicle_system.html#A-002]]

}



package "ECU" <<swimlane>> {

class "A-003\npower_rails" <<action>> [[../examples/vehicle_system.html#A-003]]

class "A-004\nfork_node" <<fork>> [[../examples/vehicle_system.html#A-004]]

class "A-005\ncrank_starter" <<action>> [[../examples/vehicle_system.html#A-005]]

class "A-006\nfuel_pump_prime" <<action>> [[../examples/vehicle_system.html#A-006]]

class "A-007\njoin_node" <<join>> [[../examples/vehicle_system.html#A-007]]

}





"A-001\ninsert_key" --> "A-002\nturn_key"



"A-002\nturn_key" --> "A-003\npower_rails"



"A-003\npower_rails" --> "A-004\nfork_node"



"A-004\nfork_node" --> "A-005\ncrank_starter"



"A-004\nfork_node" --> "A-006\nfuel_pump_prime"



"A-005\ncrank_starter" --> "A-007\njoin_node"



"A-006\nfuel_pump_prime" --> "A-007\njoin_node"



@enduml

Activity Diagram (SVG)

.. needsysml-act-svg:: AD-001
   :align: center

State Machine Diagram

needsysml-stm walks the StateDef’s usages and renders them with their transitions. Pseudostates (initial / final / history / choice / junction) appear with their UML notation.

State Definitions

StateDef: EngineState SD-001

Lifecycle states of the engine.

StateUsage: off SU-001
owned_by: P-002
definition: SD-001
pseudo_kind: initial
StateUsage: starting SU-002
owned_by: P-002
definition: SD-001
StateUsage: running SU-003
owned_by: P-002
definition: SD-001
StateUsage: stopping SU-004
owned_by: P-002
definition: SD-001

Transitions

Transition: key_on_transition TRANS-001
from_state: SU-001
to_state: SU-002
trigger: key_on
effect: start_seq
Transition: engine_ok_transition TRANS-002
from_state: SU-002
to_state: SU-003
trigger: engine_ok
Transition: key_off_transition TRANS-003
from_state: SU-003
to_state: SU-004
trigger: key_off
Transition: spindown_transition TRANS-004
from_state: SU-004
to_state: SU-001
trigger: spindown_complete
Transition: critical_fault_transition TRANS-005
from_state: SU-003
to_state: SU-001
trigger: fault
guard: severity == 'critical'

State Machine Diagram (PlantUML)

.. needsysml-stm:: SD-001
   :align: center

@startuml

' Config

skinparam state {
BackgroundColor #EEEEDD
BorderColor #888866
}
skinparam state<<choice>> {
BackgroundColor #FFEEBB
BorderColor #CC9900
}
skinparam state<<junction>> {
BackgroundColor #DDDDDD
BorderColor #888888
}













state "starting" as SU_002 [[../examples/vehicle_system.html#SU-002]]




state "running" as SU_003 [[../examples/vehicle_system.html#SU-003]]




state "stopping" as SU_004 [[../examples/vehicle_system.html#SU-004]]


[*] --> SU_001










[*] --> SU_002 : key_on / start_seq











SU_002 --> SU_003 : engine_ok











SU_003 --> SU_004 : key_off











SU_004 --> [*] : spindown_complete











SU_003 --> [*] : fault [severity == 'critical']




@enduml

State Machine Diagram (SVG)

.. needsysml-stm-svg:: SD-001
   :align: center
SU-001 SU-002 starting SU-003 running SU-004 stopping key_on / start_seq engine_ok key_off spindown_complete fault [severity == 'critical']

Block Definition Diagram

needsysml-bdd renders a class-diagram BDD with composition arrows via PlantUML.

Block Definition Diagram (PlantUML)

.. needsysml-bdd:: PD-001
   :depth: 2
   :scale: 80%
   :align: center

@startuml

' Config

skinparam class<<PartDef>> {
BackgroundColor #DDEEFF
BorderColor #336699
}
skinparam class<<Part>> {
BackgroundColor #BBDDFF
BorderColor #336699
}
hide empty members
left to right direction






node "<size:12>PartDef</size>\n**Vehicle**\n<size:10>PD-001</size>" as PD_001 [[../examples/vehicle_system.html#PD-001]] #DDEEFF

node "<size:12>PartDef</size>\n**Powertrain**\n<size:10>PD-002</size>" as PD_002 [[../examples/vehicle_system.html#PD-002]] #DDEEFF
PD_001 *-- PD_002

node "<size:12>PartDef</size>\n**Engine**\n<size:10>PD-003</size>" as PD_003 [[../examples/vehicle_system.html#PD-003]] #DDEEFF
PD_002 *-- PD_003


node "<size:12>PartDef</size>\n**Transmission**\n<size:10>PD-004</size>" as PD_004 [[../examples/vehicle_system.html#PD-004]] #DDEEFF
PD_002 *-- PD_004



node "<size:12>PartDef</size>\n**Chassis**\n<size:10>PD-005</size>" as PD_005 [[../examples/vehicle_system.html#PD-005]] #DDEEFF
PD_001 *-- PD_005

node "<size:12>PartDef</size>\n**Wheel**\n<size:10>PD-006</size>" as PD_006 [[../examples/vehicle_system.html#PD-006]] #DDEEFF
PD_005 *-- PD_006




@enduml

Block Definition Diagram (SVG)

.. needsysml-bdd-svg:: PD-001
   :align: center

Custom SVG with needsvg

For full control, drop into a raw needsvg directive and use the Jinja helpers (needs, filter, flow, ref) directly.

.. needsvg::
   :align: center

   {% set root_id = "PD-002" %}
   {% set root = needs.get(root_id) %}
   {% set children = filter("type == 'partdef' and owned_by == '" + root_id + "'") %}
   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 240">
     <g transform="translate(240, 20)">{{ flow(root_id) }}</g>
     {% for child in children %}
     {% set cx = 150 * loop.index %}
     <line x1="300" y1="60" x2="{{ cx }}" y2="180"
           stroke="#336699" stroke-width="1.5"/>
     <g transform="translate({{ cx - 60 }}, 180)">{{ flow(child.id) }}</g>
     {% endfor %}
   </svg>

Internal Block Diagram

needsysml-ibd renders an IBD showing parts and their ports inside a boundary rectangle.

Internal Block Diagram (PlantUML)

.. needsysml-ibd:: PD-002
   :show-ports: true
   :align: center

@startuml

' Config

skinparam component<<Part>> {
BackgroundColor #BBDDFF
BorderColor #336699
}
skinparam rectangle<<ibd>> {
BackgroundColor transparent
BorderColor #336699
}








rectangle "Powertrain" <<ibd>> {

    component "P-002\nengine" <<Part>> as "P-002" {


        portin "PO-001"



        portout "PO-002"


    }

    component "P-003\ntransmission" <<Part>> as "P-003" {


        portin "PO-003"



        portout "PO-004"


    }

}




"PO-002" --> "PO-003" : engine_to_trans







@enduml

Internal Block Diagram (SVG)

.. needsysml-ibd-svg:: PD-002
   :align: center

Requirements

Requirements link to the structural elements they govern via satisfies, refines, and allocates.

Requirement Definitions

RequirementDef: SafetyRequirement RD-001
abstract: True

Abstract base for vehicle safety requirements.

Requirement: Braking Distance R-001
satisfies: PD-001
refines: RD-001

The vehicle shall stop within 50 m from 100 km/h.

Requirement: Engine Power R-002
satisfies: PD-003

The engine shall produce at least 150 kW at 5000 rpm.

Requirement: Fuel Efficiency R-003
satisfies: PD-001
allocates: P-002

The vehicle shall achieve 6 L / 100 km combined cycle.

Requirement: Acceleration R-004
satisfies: PD-001
refines: RD-001

The vehicle shall accelerate 0 to 100 km/h in under 8 s.

Requirements Diagram (PlantUML)

.. needsysml-req:: type == 'requirement'
   :show-satisfy: true
   :show-refine: true
   :show-allocate: true
   :align: center

@startuml

' Config

skinparam class<<requirement>> {
BackgroundColor #FFF0CC
BorderColor #CC9900
}
hide empty members




node "<size:12>PartDef</size>\n**Vehicle**\n<size:10>PD-001</size>" as PD_001 [[../examples/vehicle_system.html#PD-001]] #DDEEFF




node "<size:12>PartDef</size>\n**Powertrain**\n<size:10>PD-002</size>" as PD_002 [[../examples/vehicle_system.html#PD-002]] #DDEEFF




node "<size:12>PartDef</size>\n**Engine**\n<size:10>PD-003</size>" as PD_003 [[../examples/vehicle_system.html#PD-003]] #DDEEFF




node "<size:12>PartDef</size>\n**Transmission**\n<size:10>PD-004</size>" as PD_004 [[../examples/vehicle_system.html#PD-004]] #DDEEFF




node "<size:12>PartDef</size>\n**Chassis**\n<size:10>PD-005</size>" as PD_005 [[../examples/vehicle_system.html#PD-005]] #DDEEFF




node "<size:12>PartDef</size>\n**Wheel**\n<size:10>PD-006</size>" as PD_006 [[../examples/vehicle_system.html#PD-006]] #DDEEFF




node "<size:12>Part</size>\n**powertrain**\n<size:10>P-001</size>" as P_001 [[../examples/vehicle_system.html#P-001]] #BBDDFF




node "<size:12>Part</size>\n**engine**\n<size:10>P-002</size>" as P_002 [[../examples/vehicle_system.html#P-002]] #BBDDFF




node "<size:12>Part</size>\n**transmission**\n<size:10>P-003</size>" as P_003 [[../examples/vehicle_system.html#P-003]] #BBDDFF




node "<size:12>Part</size>\n**chassis**\n<size:10>P-004</size>" as P_004 [[../examples/vehicle_system.html#P-004]] #BBDDFF




node "<size:12>Part</size>\n**front_left_whee**\n**l**\n<size:10>P-005</size>" as P_005 [[../examples/vehicle_system.html#P-005]] #BBDDFF




node "<size:12>Part</size>\n**front_right_whe**\n**el**\n<size:10>P-006</size>" as P_006 [[../examples/vehicle_system.html#P-006]] #BBDDFF




node "<size:12>Part</size>\n**rear_left_wheel**\n<size:10>P-007</size>" as P_007 [[../examples/vehicle_system.html#P-007]] #BBDDFF




node "<size:12>Part</size>\n**rear_right_whee**\n**l**\n<size:10>P-008</size>" as P_008 [[../examples/vehicle_system.html#P-008]] #BBDDFF




node "<size:12>PortDef</size>\n**FuelPort**\n<size:10>POD-001</size>" as POD_001 [[../examples/vehicle_system.html#POD-001]] #FFEECC




node "<size:12>PortDef</size>\n**PowerOutPort**\n<size:10>POD-002</size>" as POD_002 [[../examples/vehicle_system.html#POD-002]] #FFEECC




node "<size:12>PortDef</size>\n**PowerInPort**\n<size:10>POD-003</size>" as POD_003 [[../examples/vehicle_system.html#POD-003]] #FFEECC




node "<size:12>Port</size>\n**fuel_in**\n<size:10>PO-001</size>" as PO_001 [[../examples/vehicle_system.html#PO-001]] #FFE0AA




node "<size:12>Port</size>\n**power_out**\n<size:10>PO-002</size>" as PO_002 [[../examples/vehicle_system.html#PO-002]] #FFE0AA




node "<size:12>Port</size>\n**power_in**\n<size:10>PO-003</size>" as PO_003 [[../examples/vehicle_system.html#PO-003]] #FFE0AA




node "<size:12>Port</size>\n**drive_out**\n<size:10>PO-004</size>" as PO_004 [[../examples/vehicle_system.html#PO-004]] #FFE0AA




node "<size:12>Port</size>\n**drive_in**\n<size:10>PO-005</size>" as PO_005 [[../examples/vehicle_system.html#PO-005]] #FFE0AA




node "<size:12>ConnectionDef</size>\n**EngineToTransLi**\n**nk**\n<size:10>CD-001</size>" as CD_001 [[../examples/vehicle_system.html#CD-001]] #EEDDFF




node "<size:12>Connection</size>\n**engine_to_trans**\n<size:10>C-001</size>" as C_001 [[../examples/vehicle_system.html#C-001]] #DDCCFF




node "<size:12>Connection</size>\n**trans_to_chassi**\n**s**\n<size:10>C-002</size>" as C_002 [[../examples/vehicle_system.html#C-002]] #DDCCFF




folder "<size:12>Package</size>\n**VehicleSystem**\n<size:10>PKG-001</size>" as PKG_001 [[../examples/vehicle_system.html#PKG-001]] #EEEEFF




folder "<size:12>Package</size>\n**PowertrainPkg**\n<size:10>PKG-002</size>" as PKG_002 [[../examples/vehicle_system.html#PKG-002]] #EEEEFF




folder "<size:12>Package</size>\n**ChassisPkg**\n<size:10>PKG-003</size>" as PKG_003 [[../examples/vehicle_system.html#PKG-003]] #EEEEFF




folder "<size:12>Package</size>\n**ControlsPkg**\n<size:10>PKG-004</size>" as PKG_004 [[../examples/vehicle_system.html#PKG-004]] #EEEEFF




node "<size:12>Dependency</size>\n**pt_uses_control**\n**s**\n<size:10>DEP-001</size>" as DEP_001 [[../examples/vehicle_system.html#DEP-001]] #DDDDDD




node "<size:12>Dependency</size>\n**chassis_imports**\n**_controls**\n<size:10>DEP-002</size>" as DEP_002 [[../examples/vehicle_system.html#DEP-002]] #DDDDDD




actor "<size:12>Actor</size>\n**Driver**\n<size:10>ACTOR-001</size>" as ACTOR_001 [[../examples/vehicle_system.html#ACTOR-001]] #EEEECC




actor "<size:12>Actor</size>\n**Mechanic**\n<size:10>ACTOR-002</size>" as ACTOR_002 [[../examples/vehicle_system.html#ACTOR-002]] #EEEECC




node "<size:12>UseCase</size>\n**Start engine**\n<size:10>USECASE-001</size>" as USECASE_001 [[../examples/vehicle_system.html#USECASE-001]] #FFEEDD




node "<size:12>UseCase</size>\n**Diagnose fault**\n<size:10>USECASE-002</size>" as USECASE_002 [[../examples/vehicle_system.html#USECASE-002]] #FFEEDD




node "<size:12>UseCase</size>\n**Authenticate**\n**key**\n<size:10>USECASE-003</size>" as USECASE_003 [[../examples/vehicle_system.html#USECASE-003]] #FFEEDD




node "<size:12>UseCase</size>\n**Perform service**\n<size:10>USECASE-004</size>" as USECASE_004 [[../examples/vehicle_system.html#USECASE-004]] #FFEEDD




node "<size:12>ActionDef</size>\n**IgnitionSequenc**\n**e**\n<size:10>AD-010</size>" as AD_010 [[../examples/vehicle_system.html#AD-010]] #FFEEDD




node "<size:12>Lifeline</size>\n**driver_ll**\n<size:10>LIFELINE-001</size>" as LIFELINE_001 [[../examples/vehicle_system.html#LIFELINE-001]] #E0E8F0




node "<size:12>Lifeline</size>\n**ecu_ll**\n<size:10>LIFELINE-002</size>" as LIFELINE_002 [[../examples/vehicle_system.html#LIFELINE-002]] #E0E8F0




node "<size:12>Lifeline</size>\n**starter_ll**\n<size:10>LIFELINE-003</size>" as LIFELINE_003 [[../examples/vehicle_system.html#LIFELINE-003]] #E0E8F0




node "<size:12>Message</size>\n**turn_key_msg**\n<size:10>MSG-001</size>" as MSG_001 [[../examples/vehicle_system.html#MSG-001]] #D0E0F0




node "<size:12>Message</size>\n**crank_msg**\n<size:10>MSG-002</size>" as MSG_002 [[../examples/vehicle_system.html#MSG-002]] #D0E0F0




node "<size:12>Message</size>\n**ok_msg**\n<size:10>MSG-003</size>" as MSG_003 [[../examples/vehicle_system.html#MSG-003]] #D0E0F0




node "<size:12>Message</size>\n**heartbeat_msg**\n<size:10>MSG-004</size>" as MSG_004 [[../examples/vehicle_system.html#MSG-004]] #D0E0F0




node "<size:12>ActionDef</size>\n**StartEngine**\n<size:10>AD-001</size>" as AD_001 [[../examples/vehicle_system.html#AD-001]] #FFEEDD




node "<size:12>Action</size>\n**insert_key**\n<size:10>A-001</size>" as A_001 [[../examples/vehicle_system.html#A-001]] #FFE0CC




node "<size:12>Action</size>\n**turn_key**\n<size:10>A-002</size>" as A_002 [[../examples/vehicle_system.html#A-002]] #FFE0CC




node "<size:12>Action</size>\n**power_rails**\n<size:10>A-003</size>" as A_003 [[../examples/vehicle_system.html#A-003]] #FFE0CC




node "<size:12>Action</size>\n**fork_node**\n<size:10>A-004</size>" as A_004 [[../examples/vehicle_system.html#A-004]] #FFE0CC




node "<size:12>Action</size>\n**crank_starter**\n<size:10>A-005</size>" as A_005 [[../examples/vehicle_system.html#A-005]] #FFE0CC




node "<size:12>Action</size>\n**fuel_pump_prime**\n<size:10>A-006</size>" as A_006 [[../examples/vehicle_system.html#A-006]] #FFE0CC




node "<size:12>Action</size>\n**join_node**\n<size:10>A-007</size>" as A_007 [[../examples/vehicle_system.html#A-007]] #FFE0CC




node "<size:12>ControlFlow</size>\n**insert→turn**\n<size:10>CTRLFLOW-001</size>" as CTRLFLOW_001 [[../examples/vehicle_system.html#CTRLFLOW-001]] #DDEEEE




node "<size:12>ControlFlow</size>\n**turn→power**\n<size:10>CTRLFLOW-002</size>" as CTRLFLOW_002 [[../examples/vehicle_system.html#CTRLFLOW-002]] #DDEEEE




node "<size:12>ControlFlow</size>\n**power→fork**\n<size:10>CTRLFLOW-003</size>" as CTRLFLOW_003 [[../examples/vehicle_system.html#CTRLFLOW-003]] #DDEEEE




node "<size:12>ControlFlow</size>\n**fork→crank**\n<size:10>CTRLFLOW-004</size>" as CTRLFLOW_004 [[../examples/vehicle_system.html#CTRLFLOW-004]] #DDEEEE




node "<size:12>ControlFlow</size>\n**fork→fuel**\n<size:10>CTRLFLOW-005</size>" as CTRLFLOW_005 [[../examples/vehicle_system.html#CTRLFLOW-005]] #DDEEEE




node "<size:12>ControlFlow</size>\n**crank→join**\n<size:10>CTRLFLOW-006</size>" as CTRLFLOW_006 [[../examples/vehicle_system.html#CTRLFLOW-006]] #DDEEEE




node "<size:12>ControlFlow</size>\n**fuel→join**\n<size:10>CTRLFLOW-007</size>" as CTRLFLOW_007 [[../examples/vehicle_system.html#CTRLFLOW-007]] #DDEEEE




node "<size:12>StateDef</size>\n**EngineState**\n<size:10>SD-001</size>" as SD_001 [[../examples/vehicle_system.html#SD-001]] #EEEEDD




node "<size:12>StateUsage</size>\n**off**\n<size:10>SU-001</size>" as SU_001 [[../examples/vehicle_system.html#SU-001]] #DDDDCC




node "<size:12>StateUsage</size>\n**starting**\n<size:10>SU-002</size>" as SU_002 [[../examples/vehicle_system.html#SU-002]] #DDDDCC




node "<size:12>StateUsage</size>\n**running**\n<size:10>SU-003</size>" as SU_003 [[../examples/vehicle_system.html#SU-003]] #DDDDCC




node "<size:12>StateUsage</size>\n**stopping**\n<size:10>SU-004</size>" as SU_004 [[../examples/vehicle_system.html#SU-004]] #DDDDCC




node "<size:12>Transition</size>\n**key_on_transiti**\n**on**\n<size:10>TRANS-001</size>" as TRANS_001 [[../examples/vehicle_system.html#TRANS-001]] #EEDDDD




node "<size:12>Transition</size>\n**engine_ok_trans**\n**ition**\n<size:10>TRANS-002</size>" as TRANS_002 [[../examples/vehicle_system.html#TRANS-002]] #EEDDDD




node "<size:12>Transition</size>\n**key_off_transit**\n**ion**\n<size:10>TRANS-003</size>" as TRANS_003 [[../examples/vehicle_system.html#TRANS-003]] #EEDDDD




node "<size:12>Transition</size>\n**spindown_transi**\n**tion**\n<size:10>TRANS-004</size>" as TRANS_004 [[../examples/vehicle_system.html#TRANS-004]] #EEDDDD




node "<size:12>Transition</size>\n**critical_fault_**\n**transition**\n<size:10>TRANS-005</size>" as TRANS_005 [[../examples/vehicle_system.html#TRANS-005]] #EEDDDD




node "<size:12>RequirementDef</size>\n**SafetyRequireme**\n**nt**\n<size:10>RD-001</size>" as RD_001 [[../examples/vehicle_system.html#RD-001]] #FFF0CC




node "<size:12>Requirement</size>\n**Braking**\n**Distance**\n<size:10>R-001</size>" as R_001 [[../examples/vehicle_system.html#R-001]] #FFEEAA




node "<size:12>Requirement</size>\n**Engine Power**\n<size:10>R-002</size>" as R_002 [[../examples/vehicle_system.html#R-002]] #FFEEAA




node "<size:12>Requirement</size>\n**Fuel Efficiency**\n<size:10>R-003</size>" as R_003 [[../examples/vehicle_system.html#R-003]] #FFEEAA




node "<size:12>Requirement</size>\n**Acceleration**\n<size:10>R-004</size>" as R_004 [[../examples/vehicle_system.html#R-004]] #FFEEAA




node "<size:12>ConstraintParameter</size>\n**fuel_output_par**\n**am**\n<size:10>PARAM-010</size>" as PARAM_010 [[../examples/vehicle_system.html#PARAM-010]] #FFE8C8




node "<size:12>ConstraintParameter</size>\n**fuel_duration_p**\n**aram**\n<size:10>PARAM-011</size>" as PARAM_011 [[../examples/vehicle_system.html#PARAM-011]] #FFE8C8




node "<size:12>ConstraintParameter</size>\n**fuel_efficiency**\n**_param**\n<size:10>PARAM-012</size>" as PARAM_012 [[../examples/vehicle_system.html#PARAM-012]] #FFE8C8




node "<size:12>ConstraintBlock</size>\n**FuelConsumption**\n**Equation**\n<size:10>CONSTRAINT-010</size>" as CONSTRAINT_010 [[../examples/vehicle_system.html#CONSTRAINT-010]] #FFF0DC




node "<size:12>ValueProperty</size>\n**engine_power**\n<size:10>VALUE-010</size>" as VALUE_010 [[../examples/vehicle_system.html#VALUE-010]] #E8F4FF




node "<size:12>ValueProperty</size>\n**trip_time**\n<size:10>VALUE-011</size>" as VALUE_011 [[../examples/vehicle_system.html#VALUE-011]] #E8F4FF




node "<size:12>ValueProperty</size>\n**engine_efficien**\n**cy**\n<size:10>VALUE-012</size>" as VALUE_012 [[../examples/vehicle_system.html#VALUE-012]] #E8F4FF




node "<size:12>BindingConnector</size>\n**bind_output**\n<size:10>BIND-010</size>" as BIND_010 [[../examples/vehicle_system.html#BIND-010]] #D8E8FF




node "<size:12>BindingConnector</size>\n**bind_duration**\n<size:10>BIND-011</size>" as BIND_011 [[../examples/vehicle_system.html#BIND-011]] #D8E8FF




node "<size:12>BindingConnector</size>\n**bind_efficiency**\n<size:10>BIND-012</size>" as BIND_012 [[../examples/vehicle_system.html#BIND-012]] #D8E8FF




@enduml

Requirements Diagram (SVG)

A simple SVG list of requirements with their satisfy links, built using needsvg:

.. needsvg::
   :align: center

   {% set reqs = filter("type == 'requirement'") | list %}
   <svg xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 640 {{ 40 + (reqs | length) * 60 }}">
     {% for r in reqs %}
     <g transform="translate(20, {{ 20 + loop.index0 * 60 }})">
       <a href="{{ ref(r.id) }}">
         <rect width="120" height="40" rx="4" fill="#ddeeff" stroke="#336699"/>
         <text x="60" y="16" text-anchor="middle" font-size="10" fill="#666">{{ r.id }}</text>
         <text x="60" y="30" text-anchor="middle" font-size="11">{{ r.title }}</text>
       </a>
     </g>
     {% if r.satisfies %}
     <text x="160" y="{{ 45 + loop.index0 * 60 }}"
           font-family="sans-serif" font-size="11" fill="#444">
       satisfies → {{ r.satisfies }}
     </text>
     {% endif %}
     {% endfor %}
   </svg>
R-001 Braking Distance satisfies → PD-001 R-002 Engine Power satisfies → PD-003 R-003 Fuel Efficiency satisfies → PD-001 R-004 Acceleration satisfies → PD-001

Query Tables

Once the model is in place, sphinx-needs queries work across every SysML element:

.. needtable::
   :filter: type == 'requirement' and satisfies != ""
   :columns: id, title, satisfies, refines, status

ID

Title

Satisfies

Refines

Status

R-001

Braking Distance

PD-001

RD-001

R-002

Engine Power

PD-003

R-003

Fuel Efficiency

PD-001

R-004

Acceleration

PD-001

RD-001

.. needtable::
   :filter: type == 'part'
   :columns: id, title, definition, owned_by

ID

Title

Definition

Owned By

P-001

powertrain

PD-002

PD-001

P-002

engine

PD-003

PD-002

P-003

transmission

PD-004

PD-002

P-004

chassis

PD-005

PD-001

P-005

front_left_wheel

PD-006

PD-005

P-006

front_right_wheel

PD-006

PD-005

P-007

rear_left_wheel

PD-006

PD-005

P-008

rear_right_wheel

PD-006

PD-005

Allocation Matrix

The needsysml-alloc directive renders a traceability table showing which requirements allocate to which parts. Rows are needs with non-empty allocates; columns are the unique part IDs referenced.

P-002

A-001

A-002

A-003

A-004

A-005

A-006

A-007

ACTOR-001

ACTOR-002

AD-001

AD-010

C-001

C-002

CD-001

CTRLFLOW-001

CTRLFLOW-002

CTRLFLOW-003

CTRLFLOW-004

CTRLFLOW-005

CTRLFLOW-006

CTRLFLOW-007

DEP-001

DEP-002

LIFELINE-001

LIFELINE-002

LIFELINE-003

MSG-001

MSG-002

MSG-003

MSG-004

P-001

P-002

P-003

P-004

P-005

P-006

P-007

P-008

PD-001

PD-002

PD-003

PD-004

PD-005

PD-006

PKG-001

PKG-002

PKG-003

PKG-004

PO-001

PO-002

PO-003

PO-004

PO-005

POD-001

POD-002

POD-003

R-001

R-002

R-003

R-004

RD-001

SD-001

SU-001

SU-002

SU-003

SU-004

TRANS-001

TRANS-002

TRANS-003

TRANS-004

TRANS-005

USECASE-001

USECASE-002

USECASE-003

USECASE-004

You can also filter explicitly:

.. needsysml-alloc::
   :rows: type == 'requirement'
   :columns: type == 'part'

Parametric Diagram

Parametric diagrams show constraint blocks with their parameters and binding connectors to value properties. PlantUML uses a class-diagram approximation.

Constraint Parameters

ConstraintParameter: fuel_output_param PARAM-010
ConstraintParameter: fuel_duration_param PARAM-011
ConstraintParameter: fuel_efficiency_param PARAM-012
ConstraintBlock: FuelConsumptionEquation CONSTRAINT-010
expression: fuel_used = output * duration / efficiency
parameters: PARAM-010, PARAM-011, PARAM-012

Value Properties

ValueProperty: engine_power VALUE-010
owned_by: P-002
value_type: kW
default_value: "150"
ValueProperty: trip_time VALUE-011
owned_by: P-001
value_type: h
ValueProperty: engine_efficiency VALUE-012
owned_by: P-002
value_type: ""

Binding Connectors

BindingConnector: bind_output BIND-010
unit: kW
source_parameter: PARAM-010
target_value: VALUE-010
BindingConnector: bind_duration BIND-011
unit: h
source_parameter: PARAM-011
target_value: VALUE-011
BindingConnector: bind_efficiency BIND-012
source_parameter: PARAM-012
target_value: VALUE-012

Parametric Diagram (PlantUML)

@startuml

' Config

skinparam class<<constraint>> {
BackgroundColor #FFF0DC
BorderColor #CC9966
RoundCorner 12
}
skinparam class<<valueproperty>> {
BackgroundColor #E8F4FF
BorderColor #336699
}
hide empty members






class "FuelConsumptionEquation" as CONSTRAINT-010 {
<<constraint>>
fuel_used = output * duration / efficiency
}




note right of CONSTRAINT-010 : fuel_output_param




note right of CONSTRAINT-010 : fuel_duration_param




note right of CONSTRAINT-010 : fuel_efficiency_param







note bottom of CONSTRAINT-010 : → engine_power (kW)




note bottom of CONSTRAINT-010 : → trip_time (h)




note bottom of CONSTRAINT-010 : → engine_efficiency



@enduml