Last update: January 16th, 2023
This Jupyter Notebook is an exploration of SysML v2 from the user perspective. It shows some SysML v2 basics, but mainly focuses on the special features compared to SysML v1 and how they can be used. For a detailed introduction to the textual syntax of SysML v2, I recommend the following PDF: Introduction to the SysML v2 Language Textual Notation.
Please note: This is work in progress. You will see sketchy stuff. If you have any comments, contact me: tim@mbse4u.com.
This section provides
The target audience for this Jupyter notebook is SysML v1 modelers. The basic concepts like "What is a Use Case?" or "What is a Part Decomposition?" are not explained.
It is not (yet) a complete SysML v2 tutorial. It uses the SysML v2 pilot implementation which is not intended as full modeling tool for industrial application.
SysML v1 is primarily known for its diagrams. Although they are only the visualization of the model information and the real treasure of a real SysML model is the model data behind the diagrams.
SysML v2 also provides graphical visualizations and additionally a textual notation. Both are equivalent notations and tools can provide editors for both.
The SysML v2 pilot implementation has so far only a textual editor and generates the graphical notation. Therefore, some have been under the impression that SysML v2 is primarily textual. This is not the case. Those who wish can use SysML v2 as they would SysML v1 and edit the model using graphical editors only.
The simple example system is the following electrical vehicle:
Let's start with a logical architecture of the vehicle. A first major difference compared to SysML is that there is a textual syntax for SysML v2. The following cell shows the textual SysML v2 syntax of the logical architecture. The package statement defines the namespace of the architecture. The eVehicle architecture itself is a simple set of parts.
package eVehicle_LogicalArchitecture {
part eVehicle {
part body;
part battery;
part engine;
part frontAxis;
part rearAxis;
part frontWheel[2];
part rearWheel[2];
}
}
Package eVehicle_LogicalArchitecture (82277ca4-ea03-4932-9920-efbf66837aec)
Run the cell above to create the real model. The text above is only the textual syntax of SysML v2. The show command provides a deep insight into the model structure:
%show eVehicle_LogicalArchitecture
Package eVehicle_LogicalArchitecture (82277ca4-ea03-4932-9920-efbf66837aec) [OwningMembership] PartUsage eVehicle (784dc059-a193-493b-b9f5-cc76f285d52c) [Subsetting (implicit)] PartUsage parts (2ff9017b-e54e-4f55-8bf4-b32f6a6479e1) [FeatureMembership] PartUsage body (9d3e416f-2abd-4adc-a887-22780d88dbdf) [Subsetting (implicit)] PartUsage subparts (6727b1b0-c4ff-4ffd-9bb1-13acd6bca757) [OwningMembership] Multiplicity (5ae8da0e-cc9a-4d11-bd0e-3de6c50b20c8) [Subsetting (implicit)] MultiplicityRange exactlyOne (0619242c-c834-4036-a488-bf45c9552e6c) [FeatureMembership] PartUsage battery (444a8c02-b5bc-47bd-bda0-bfb811381389) [Subsetting (implicit)] PartUsage subparts (6727b1b0-c4ff-4ffd-9bb1-13acd6bca757) [OwningMembership] Multiplicity (7aacfffc-afc0-4032-8d55-7fd1223ef77a) [Subsetting (implicit)] MultiplicityRange exactlyOne (0619242c-c834-4036-a488-bf45c9552e6c) [FeatureMembership] PartUsage engine (ab8525db-a1c1-45d3-9342-15676e8d124b) [Subsetting (implicit)] PartUsage subparts (6727b1b0-c4ff-4ffd-9bb1-13acd6bca757) [OwningMembership] Multiplicity (064dbbec-2047-415d-858f-d7f0c6807522) [Subsetting (implicit)] MultiplicityRange exactlyOne (0619242c-c834-4036-a488-bf45c9552e6c) [FeatureMembership] PartUsage frontAxis (c6af6a4b-4968-4887-ae6d-3da8b88fbb99) [Subsetting (implicit)] PartUsage subparts (6727b1b0-c4ff-4ffd-9bb1-13acd6bca757) [OwningMembership] Multiplicity (4b0efe2a-8f83-4833-8318-3847c10bef6e) [Subsetting (implicit)] MultiplicityRange exactlyOne (0619242c-c834-4036-a488-bf45c9552e6c) [FeatureMembership] PartUsage rearAxis (234e5162-6e97-48c3-9eda-529547d0475e) [Subsetting (implicit)] PartUsage subparts (6727b1b0-c4ff-4ffd-9bb1-13acd6bca757) [OwningMembership] Multiplicity (8771680e-d9ef-4d21-9497-94ce5c3b6fb5) [Subsetting (implicit)] MultiplicityRange exactlyOne (0619242c-c834-4036-a488-bf45c9552e6c) [FeatureMembership] PartUsage frontWheel (3066cf83-52f1-4d82-9957-0ce262312a62) [Subsetting (implicit)] PartUsage subparts (6727b1b0-c4ff-4ffd-9bb1-13acd6bca757) [OwningMembership] MultiplicityRange (1f289ea1-a543-4530-a197-7848917b3c7a) [Subsetting (implicit)] Feature naturals (41e1cbaf-102a-403a-ae1e-36d7409b7bd0) [OwningMembership] LiteralInteger (f0a0c7f1-aaa4-4f25-8245-9eca902e6517) [ReturnParameterMembership] Feature result (83e26187-3d82-467c-a858-22977e15a373) [FeatureMembership] PartUsage rearWheel (97a96405-c614-4d88-aaf6-bd94701a7bc6) [Subsetting (implicit)] PartUsage subparts (6727b1b0-c4ff-4ffd-9bb1-13acd6bca757) [OwningMembership] MultiplicityRange (3fedb3bc-2c8c-44b3-878b-216d0b3a828f) [Subsetting (implicit)] Feature naturals (41e1cbaf-102a-403a-ae1e-36d7409b7bd0) [OwningMembership] LiteralInteger (5b9c4855-846d-4a8d-bed9-747bb9c21477) [ReturnParameterMembership] Feature result (e501ca4c-44f6-4f72-a577-9330a188f700)
More convenient for the common model user, of course, is the graphical notation presented after the execution of the following cell:
%viz --view=tree eVehicle_LogicalArchitecture
The diagram is only a view, and not an editor. A graphical editor is not provided in the pilot implementation. Future SysML v2 modeling tools will certainly offer graphical editors.
SysML v2 is a complete new language with a different foundation than SysML v1. Therefore, there are plenty of differences. Here, I highlight only the changes that are most relevant to the modeler.
If I had modeled the eVehicle in SysML v1, I would have had to first define blocks and then part properties whose types are the blocks.
Did you notice it in my simple SysML v2 example above? There are no blocks there, only parts. To put it simply, this would be like modeling part properties in SysML v1 without blocks. Basically, it works that in SysML v1 you define a part without a block. But what is not possible in SysML v1 is that the parts themselves define substructures.
However, the parts of the eVehicle also have a type. Above in the output of the %show command you can see "[Subsetting (implicit)] PartUsage subparts". "subparts" is a special part from the SysML v2 library. This implicit connection is set in the background. By subsetting "subparts", the parts of the eVehicle get a generic type "Part" from the SysML v2 library.
Modeling a decomposition is a typical capability that an MBSE modeling language must have. The simple example of the eVehicle uses the part decomposition.. For example, there is also the decomposition of functions.
In SysML v2, you can define parts without types, but with substructures, for example, attributes. The following model extends the example and adds a property to the wheel to specify the size. The type of the attribute is Integer. Units are skipped for now.
package eVehicle_LogicalArchitecture {
import ScalarValues::*;
part eVehicle {
part body;
part battery;
part engine;
part frontAxis;
part rearAxis;
part frontWheel[2] {
attribute size : Integer;
}
part rearWheel[2] {
attribute size : Integer;
}
}
}
Package eVehicle_LogicalArchitecture (0c9a6990-d41c-4a4f-bab7-95beb2561ab7)
Run the cell with the SysML v2 model, and visualize the model. If you also would like to see the model structure, execute the %show command as described above.
%viz --view=tree eVehicle_LogicalArchitecture
As in SysML v1, a part always needs a context in SysML v2. In our example, the part eVehicle is the context of the parts body, battery, and so forth. No context is explicitly defined for the part eVehicle. Then the context is implicitly the most general part definition named Part from the SysML v2 model library.
Although it is still very simple, the model already smells of reuse. The size attribute is currently defined twice. Now, we define a type respectively PartDefinition Wheel and specify that as the type of the parts. The PartDefinition can be compared to the SysML v1 Block.
package eVehicle_LogicalArchitecture {
import ScalarValues::*;
part def Wheel {
attribute size : Integer;
}
part eVehicle {
part body;
part battery;
part engine;
part frontAxis;
part rearAxis;
part frontWheel : Wheel[2];
part rearWheel : Wheel[2];
}
}
Package eVehicle_LogicalArchitecture (36c4a853-40d1-4f34-aa2b-244ae32da21c)
%viz --view=tree eVehicle_LogicalArchitecture
The attribute size itself can also be defined and reused for several attribute usages. It is a common concept in SysML v2 to separate the definition of elements and the usage of elements. SysML v1 also follows this concept, but not as consequent as SysML v2.
The attribute definition is not mandatory and only partly useful in this example, because the size is only used at one place. But I added it anyhow as an example for attribute definitions. The keyword attribute can be omitted as, for example, in the definition of the size value. The AttributeDefinition can be compared to the SysML v1 ValueType.
package eVehicle_LogicalArchitecture {
attribute def WheelSize {
import ScalarValues::*;
size : Integer;
deviation : Integer;
}
part def Wheel {
attribute sizeOfWheel : WheelSize;
}
part eVehicle {
part body;
part battery;
part engine;
part frontAxis;
part rearAxis;
part frontWheel : Wheel[2];
part rearWheel : Wheel[2];
}
}
Package eVehicle_LogicalArchitecture (6233a504-65da-4e54-b11e-0cc11d20d8a6)
%viz --view=tree eVehicle_LogicalArchitecture
SysML v2 provides an extensive model library that also includes geometric figures. We can specialize the PartDefinition "Wheel" from a cylinder. As an example, in the following model, a radius is set. The imported SI library contains the unit "mm". The ":=" symbol is an assignment for the initial value of the attribute.
package eVehicle_LogicalArchitecture {
import SI::*;
attribute def WheelSize {
size : LengthValue;
deviation : LengthValue;
}
part def Wheel :> ShapeItems::CircularCylinder {
:>> radius = sizeOfWheel.size;
attribute sizeOfWheel : WheelSize {
:>> size := 325 [mm];
:>> deviation := 1 [mm];
}
}
part eVehicle {
part body;
part battery;
part engine;
part frontAxis;
part rearAxis;
part frontWheel : Wheel[2];
part rearWheel : Wheel[2];
}
}
Package eVehicle_LogicalArchitecture (b55c4410-a91e-47f2-b65b-167558c46c6a)
%viz eVehicle_LogicalArchitecture
A simple rule of thumb could be: if you use a thing only once, model it as a part. If it is used multiple times or specializations of it, then model it as a part definition.
Part definition is a classification of things, and parts are usages of part definitions. If you have only one engine in the model, then you can model it directly as a part. As described above, the part still has a part definition, which in this case is implicitly the general part definition Part from the system library.
Specialization between definition elements is a subclassification relationship. For example, the FrontWheel part definition is a special kind of a Wheel part definition. Specialization between usage elements is a subsetting relationship. For example, the part frontLeftWheel is a subset of the part frontWheel.
package eVehicle_LogicalArchitecture {
import SI::*;
attribute def WheelSize {
size : LengthValue;
deviation : LengthValue;
}
part def Wheel :> ShapeItems::CircularCylinder {
:>> radius = sizeOfWheel.size;
attribute sizeOfWheel : WheelSize {
:>> size := 325 [mm];
:>> deviation := 1 [mm];
}
constraint pressureConstraint : WheelPressureConstraint {
in currentPressure = pressure;
in limitPressure = maxPressure;
}
attribute pressure : PressureValue;
attribute maxPressure : PressureValue;
}
part def FrontWheel :> Wheel {
attribute redefines maxPressure = 200000 [Pa];
}
part def RearWheel :> Wheel {
attribute redefines maxPressure = 200000 [Pa];
}
constraint def WheelPressureConstraint {
in currentPressure : PressureValue;
in limitPressure : PressureValue;
currentPressure <= limitPressure
}
part eVehicle {
part body;
part battery;
part engine;
part frontAxis;
part rearAxis;
part frontWheel : FrontWheel[2];
part frontLeftWheel :> frontWheel {
redefines pressure = 100000 [Pa];
}
part frontRightWheel :> frontWheel {
redefines pressure = 100000 [Pa];
}
part rearWheel : RearWheel[2];
part rearLeftWheel :> rearWheel {
redefines pressure = 200000 [Pa];
}
part rearRightWheel :> rearWheel {
redefines pressure = 200000 [Pa];
}
}
}
Package eVehicle_LogicalArchitecture (6b3577b0-b0ba-40b7-9fa2-1943f61c94bb)
%viz --view=tree eVehicle_LogicalArchitecture
By now the model only defines the breakdown structure of the vehicle. There is no definition yet of how the parts are connected. The next example model eVehicle_LogicalArchitecture connects the parts in a meaningful way.
package eVehicle_LogicalArchitecture {
import SI::*;
attribute def WheelSize {
size : LengthValue;
deviation : LengthValue;
}
part def Wheel :> ShapeItems::CircularCylinder {
:>> radius = sizeOfWheel.size;
attribute sizeOfWheel : WheelSize {
:>> size := 325 [mm];
:>> deviation := 1 [mm];
}
constraint pressureConstraint : WheelPressureConstraint {
in currentPressure = pressure;
in limitPressure = maxPressure;
}
attribute pressure : PressureValue;
attribute maxPressure : PressureValue;
}
part def FrontWheel :> Wheel {
attribute redefines maxPressure = 200000 [Pa];
}
part def RearWheel :> Wheel {
attribute redefines maxPressure = 200000 [Pa];
}
constraint def WheelPressureConstraint {
in currentPressure : PressureValue;
in limitPressure : PressureValue;
currentPressure <= limitPressure
}
part eVehicle {
part body;
part battery;
part engine;
part frontAxis;
part rearAxis;
part frontWheel : FrontWheel[2];
part frontLeftWheel :> frontWheel {
redefines pressure = 100000 [Pa];
}
part frontRightWheel :> frontWheel {
redefines pressure = 100000 [Pa];
}
part rearWheel : RearWheel[2];
part rearLeftWheel :> rearWheel {
redefines pressure = 200000 [Pa];
}
part rearRightWheel :> rearWheel {
redefines pressure = 200000 [Pa];
}
connect battery to engine;
connect engine to frontAxis;
connect frontAxis to frontWheel;
connect rearAxis to rearWheel;
connect body to battery;
connect body to engine;
connect body to frontAxis;
connect body to rearAxis;
}
}
Package eVehicle_LogicalArchitecture (55fb3c7e-c9dc-4a47-bf54-db82d97d023f)
%viz --view=interconnection eVehicle_LogicalArchitecture::eVehicle
The interaction points are defined by ports in SysML v2, similar to SysML v1. The following extended example defines the interaction points between the engine and the battery. The connection is changed to connect the ports instead of the parts.
package eVehicle_LogicalArchitecture {
import SI::*;
attribute def WheelSize {
size : LengthValue;
deviation : LengthValue;
}
part def Wheel :> ShapeItems::CircularCylinder {
:>> radius = sizeOfWheel.size;
attribute sizeOfWheel : WheelSize {
:>> size := 325 [mm];
:>> deviation := 1 [mm];
}
constraint pressureConstraint : WheelPressureConstraint {
in currentPressure = pressure;
in limitPressure = maxPressure;
}
attribute pressure : PressureValue;
attribute maxPressure : PressureValue;
}
part def FrontWheel :> Wheel {
attribute redefines maxPressure = 200000 [Pa];
}
part def RearWheel :> Wheel {
attribute redefines maxPressure = 200000 [Pa];
}
constraint def WheelPressureConstraint {
in currentPressure : PressureValue;
in limitPressure : PressureValue;
currentPressure <= limitPressure
}
part eVehicle {
part body;
part battery {
port powerOut;
}
part engine {
port powerIn;
}
part frontAxis;
part rearAxis;
part frontWheel : FrontWheel[2];
part frontLeftWheel :> frontWheel {
redefines pressure = 100000 [Pa];
}
part frontRightWheel :> frontWheel {
redefines pressure = 100000 [Pa];
}
part rearWheel : RearWheel[2];
part rearLeftWheel :> rearWheel {
redefines pressure = 200000 [Pa];
}
part rearRightWheel :> rearWheel {
redefines pressure = 200000 [Pa];
}
connect battery.powerOut to engine.powerIn;
connect engine to frontAxis;
connect frontAxis to frontWheel;
connect rearAxis to rearWheel;
connect body to battery;
connect body to engine;
connect body to frontAxis;
connect body to rearAxis;
}
}
Package eVehicle_LogicalArchitecture (0d22c33e-d798-4490-84d8-acab23c4935d)
%viz --view=interconnection eVehicle_LogicalArchitecture::eVehicle
The ports powerIn and powerOut have no types respectively the SysML v2 library element Port as default type. The consistent usage/definition pattern applies here as well. The port is a usage. With a PortDef the interaction point can be defined. In this example it is a good candidate for a model library.
The port only specifies the interaction point. The interface defines the connection between interaction points. The PowerOutPort is conjugated for the consumerPort port.
package eVehicleLibrary {
import ScalarValues::Integer;
item def ElectricEnergy;
attribute def BatteryCapacity :> ScalarValues::Integer;
attribute def Speed :> ScalarValues::Integer;
port def PowerOutPort {
out energy : ElectricEnergy;
}
interface def PowerInterface {
end supplierPort : PowerOutPort;
end consumerPort : ~PowerOutPort;
}
}
Package eVehicleLibrary (44ae31fb-d288-483f-bb18-2a3dd86449a5)
%viz --view=tree eVehicleLibrary
Next, the definitions of the port and the interface are applied to the model. Do not forget to run the eVehicleLibrary cell above.
package eVehicle_LogicalArchitecture {
import SI::*;
import eVehicleLibrary::*;
attribute def WheelSize {
size : LengthValue;
deviation : LengthValue;
}
part def Wheel :> ShapeItems::CircularCylinder {
:>> radius = sizeOfWheel.size;
attribute sizeOfWheel : WheelSize {
:>> size := 325 [mm];
:>> deviation := 1 [mm];
}
constraint pressureConstraint : WheelPressureConstraint {
in currentPressure = pressure;
in limitPressure = maxPressure;
}
attribute pressure : PressureValue;
attribute maxPressure : PressureValue;
}
part def FrontWheel :> Wheel {
attribute redefines maxPressure = 200000 [Pa];
}
part def RearWheel :> Wheel {
attribute redefines maxPressure = 200000 [Pa];
}
constraint def WheelPressureConstraint {
in currentPressure : PressureValue;
in limitPressure : PressureValue;
currentPressure <= limitPressure
}
part def Battery {
attribute capacity : BatteryCapacity;
port powerOut : PowerOutPort;
}
part def Engine {
port powerIn : ~PowerOutPort;
}
part eVehicle {
part body;
part battery : Battery;
part engine : Engine;
part frontAxis;
part rearAxis;
part frontWheel : FrontWheel[2];
part frontLeftWheel :> frontWheel {
redefines pressure = 100000 [Pa];
}
part frontRightWheel :> frontWheel {
redefines pressure = 100000 [Pa];
}
part rearWheel : RearWheel[2];
part rearLeftWheel :> rearWheel {
redefines pressure = 200000 [Pa];
}
part rearRightWheel :> rearWheel {
redefines pressure = 200000 [Pa];
}
interface : PowerInterface connect
supplierPort ::> battery.powerOut to
consumerPort ::> engine.powerIn;
connect engine to frontAxis;
connect frontAxis to frontWheel;
connect rearAxis to rearWheel;
connect body to battery;
connect body to engine;
connect body to frontAxis;
connect body to rearAxis;
}
}
Package eVehicle_LogicalArchitecture (3c9f29b0-01ff-4094-bbed-f31576d33e9c)
%viz --view=interconnection eVehicle_LogicalArchitecture::eVehicle
package eVehicle_Behavior {
action chargeBattery {
in item power : ElectricalEnergy;
succession flow chargeBattery.power to charge.power;
first start;
then action 'insert charging plug';
then action 'secure charging plug';
then action charge {
in item power : ElectricalEnergy;
}
then action 'unsecure charging plug';
then action removePlug : 'Remove charging plug';
then done;
}
action def 'Remove charging plug';
item def ElectricalEnergy;
}
Package eVehicle_Behavior (170d7c5e-e4ee-4427-8a8e-8bcbb96f9bc4)
%viz eVehicle_Behavior
Connecting an structural item flow to an input parameter of an action. For simplicity, only the relevant elements are modeled below:
package eVehicleSystem {
part eVehicle {
port powerPort : PowerInPort;
flow of ElectricalEnergy from eVehicle.powerPort to chargeBattery.power;
action chargeBattery {
in item power : ElectricalEnergy;
}
}
port def PowerInPort {
in energy : ElectricalEnergy;
}
item def ElectricalEnergy;
}
Package eVehicleSystem (0d21321e-efae-4bd4-8fb1-cc159d8f1e9b)
%viz --view=interconnection eVehicleSystem.eVehicle
SysML v2 provides model elements for variants. This is a new feature compared to SysML v2. Following the typical approach of SysML, these are only generic concepts, but they form the foundation for tools to provide functions for them and for language extensions to be defined.
Run the cells eVehicleLibrary and eVehicle_LogicalArchitecture above before continuing with the variability model.
%viz eVehicle_LogicalArchitecture
Now, the model is prepared to add variability. We define two battery kinds with different capacities, and two engine kinds.
package eVehicle_VariantModel {
import eVehicle_LogicalArchitecture::*;
package eVehicle_Configurations {
import eVehicle_Variations::*;
part eVehicleStandard :> eVehicleVariations {
part redefines engine = standardEngine;
part redefines battery = batteryLow;
}
part eVehiclePremium :> eVehicleVariations {
part redefines engine = powerEngine;
part redefines battery = batteryHigh;
}
part INVALIDeVehicle :> eVehicleVariations {
part redefines engine = powerEngine;
part redefines battery = batteryLow;
}
}
package eVehicle_Variations {
import eVehicle_Variants::*;
abstract part eVehicleVariations :> eVehicle {
variation part redefines battery : Battery {
variant part batterLow;
variant part batteryHigh;
}
variation part redefines engine : Engine {
variant part standardEngine;
variant part powerEngine;
}
abstract constraint { (battery == batteryLow & engine == standardEngine) ^ (battery == batteryHigh) }
}
}
package eVehicle_Variants {
part batteryLow : Battery {
attribute redefines capacity = 40;
}
part batteryHigh : Battery {
attribute redefines capacity = 40;
}
part powerEngine : Engine;
part standardEngine : Engine;
}
}
Package eVehicle_VariantModel (5b608aaf-c082-43a7-a5ad-bac67be6605d)
%viz --view=tree eVehicle_VariantModel::eVehicle_Variations::eVehicleVariations
%viz --view=tree eVehicle_VariantModel::eVehicle_Configurations
When modeling variability with SysML v1, the model can easily explode, i.e., a small variability can lead to the need to model many model elements. I change a bit the structure of the vehicle, for example, I define the wheels as parts of the axis. I also remove the part definition Wheel and define a some lug bolts of the wheels. Finally, we have a deep nested structure: eVehicle owns axis owns wheel owns lug bolt.
package eVehicle_LogicalArchitecture_ExplosionExample {
part eVehicle {
part engine;
part frontAxis {
part frontWheel[2] {
part lugBolt[6];
part boltCircle;
connect boltCircle to lugBolt;
}
part housing;
connect housing to frontWheel;
}
part rearAxis {
part rearWheel[2] {
part lugBolt[6];
part boltCircle;
connect boltCircle to lugBolt;
}
part housing;
connect housing to rearWheel;
}
connect engine to frontAxis;
}
}
Package eVehicle_LogicalArchitecture_ExplosionExample (d3369a46-d2c5-45bb-8c3c-1deacb1829ca)
%viz --view=interconnection eVehicle_LogicalArchitecture_ExplosionExample
The structure eVehicle/axis/wheel/lugBolt can easily be modeled with SysML v1. It is slightly different in that in SysML v1 we have to use types, i.e. blocks, and cannot model parts directly.
Now, if we introduce variants of lug bolts, this variance ripples up through the entire structure:
In SysML v2 it looks like this:
package eVehicleVariants_ExplosionExample {
part lugBolt42;
part lugBolt23;
}
package eVehicle_LogicalArchitecture_ExplosionExample {
import eVehicleVariants_ExplosionExample::*;
part eVehicle {
part engine;
part frontAxis {
part frontWheel[2] {
/*-----------------------------
* Definition of the variation
* ----------------------------*/
variation part lugBolt[6] {
variant part lugBolt23;
variant part lugBolt42;
}
part boltCircle;
connect boltCircle to lugBolt;
}
part housing;
connect housing to frontWheel;
}
part rearAxis {
part rearWheel[2] {
part lugBolt[6];
part boltCircle;
connect boltCircle to lugBolt;
}
part housing;
connect housing to rearWheel;
}
connect engine to frontAxis;
}
}
Package eVehicleVariants_ExplosionExample (8e20ff47-3f5a-4d26-81dc-fdcb97fbc015) Package eVehicle_LogicalArchitecture_ExplosionExample (978bafa2-516e-4828-9a8a-4cc93af34fd7)
%viz --view=tree eVehicle_LogicalArchitecture_ExplosionExample
A concrete variant configuration of the eVehicle with lug bolts 42 can be simply created by specialization:
package eVehicle_Edition42 {
import eVehicle_LogicalArchitecture_ExplosionExample::*;
part eVehicle42 :> eVehicle {
part redefines lugBolt42 = frontAxis.frontWheel.lugBolt;
}
}
Package eVehicle_Edition42 (f81a8e27-81a9-4caf-9e4e-3aefdf6fb396)
A requirement definition is a special kind of a constraint definition including parameters and required constraints. Do not forget to run the eVehicleLibrary cell above.
package eVehicleRequirementDefinitions {
import eVehicleLibrary::*;
requirement def BatteryCapacityReqDef {
doc /* The actual battery capacity shall be greater than or equal
* to the required capacity. */
attribute capacityActual : BatteryCapacity;
attribute capacityRequired : BatteryCapacity;
require constraint{ capacityActual <= capacityRequired }
}
requirement def MaxSpeedReqDef {
doc /* The maximum speed of the vehicle shall be
* not greater than the required maximum speed. */
attribute maxSpeedVehicle : Speed;
attribute maxSpeedRequired : Speed;
require constraint{ maxSpeedVehicle <= maxSpeedRequired }
}
}
Package eVehicleRequirementDefinitions (1a38f855-fb95-486e-bf25-affc959e7b51)
%viz eVehicleRequirementDefinitions
The definition of a requirement provides a reusable structure. Next, the requirement definition BatteryCapacityRequirementDef is used to specify a concrete requirement for the eVehicle. The requirement REQ.B.1 redefines the requirement attribute capacityRequired with a concrete value.
It is possible to define requirement groups to manage a large set of requirements by defining that a requirement requires other requirements. Do not forget to run the eVehicleRequirementDefinitions and eVehicle_LogicalArchitecture cells above.
package eVehicleRequirements {
import eVehicleRequirementDefinitions::*;
import eVehicle_LogicalArchitecture::*;
requirement eVehicleSpecification {
doc /* Requirement Specification of the eVehicle */
require eVehicleBatteryCapacity;
require eVehicleMaxSpeed;
}
requirement <'REQ.B.1'> eVehicleBatteryCapacity : BatteryCapacityReqDef {
attribute :>> capacityRequired = 50;
attribute :>> capacityActual = eVehicle.battery.capacity;
}
requirement <'REQ.V.1'> eVehicleMaxSpeed : MaxSpeedReqDef {
attribute :>> maxSpeedRequired = 140;
attribute :>> maxSpeedVehicle = eVehicle.maxSpeed;
}
}
Package eVehicleRequirements (11c0991f-9cf7-4001-b0aa-510962adcd30)
%viz eVehicleRequirements
Finally, we model that the eVehicle satisfies the requirement.
package eVehicle_LogicalArchitecture {
import eVehicleLibrary::*;
import eVehicleRequirements::*;
import eVehicle_LogicalArchitecture::*;
satisfy eVehicleSpecification by eVehicle;
}
Package eVehicle_LogicalArchitecture (e28fcc81-b766-45bc-a808-3e37b5e1eb2b)