{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# SysML v2 JupyterBook\n",
"\n",
"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](https://github.com/Systems-Modeling/SysML-v2-Release/blob/master/doc/Intro%20to%20the%20SysML%20v2%20Language.pdf).\n",
"\n",
"**Please note: This is work in progress. You will see sketchy stuff. If you have any comments, contact me: [tim@mbse4u.com](mailto:tim@mbse4u.com).**\n",
"\n",
"## Table of Contents\n",
"* [Modeling with SysML v2](#sysmlv2mod)\n",
" * [Introduction](#sysmlv2modintroduction)\n",
" * [Example and first steps](#sysmlv2modexample)\n",
" * [Parts and PartDefinitions](#sysmlv2modparts)\n",
" * [Putting the parts together](#sysmlv2modconnect)\n",
" * [Modeling Interfaces](#sysmlv2modinterfaces)\n",
" * [Modeling variants](#sysmlv2modvariants)\n",
" * [Modeling requirements](#sysmlv2modrequirements)\n",
" * [Mapping from SysML v1 to SysML v2](#sysmlv2modv1mapping)\n",
" * [Libraries for the eVehicle example](#sysmlv2modlibrary)\n",
"* [SysML v2 MBSE Methodologies JupyterBook](#sysmlv2modmethodologies)\n",
" * [SYSMOD with SysML v2](#sysmlv2sysmod)\n",
" * [System Idea and System Objectives](#sysmlv2sysmodidea)\n",
" * [System Context](#sysmlv2sysmodcontext)\n",
" * [FAS with SysML v2](#sysmlv2fas)\n",
" * [VAMOS (Variant Modeling with SysML](#sysmlv2vamos)\n",
"\n",
"# Modeling with SysML v2\n",
"\n",
"## Introduction\n",
"\n",
"This section provides \n",
"\n",
"* a brief introduction of the modeling with SysML v2,\n",
"* with a special focus on what is different compared to SysML v1.\n",
"\n",
"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. \n",
"\n",
"## Example and first steps\n",
"\n",
"The simple example system is the following electrical vehicle:\n",
"\n",
"\n",
"\n",
"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.\n",
"The following cell shows the textual SysML v2 syntax of the logical architecture. The package statement defines the namespace of our architecture. The architecture itself is a simple hierarchical set of parts."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture (5c3623ba-2bbf-43e1-b0e5-fbb7126d7d9b)\n"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_LogicalArchitecture {\n",
" part eVehicle { \n",
" part body;\n",
" part battery;\n",
" part engine;\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel[2];\n",
" part rearWheel[2];\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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:"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture (76692bb7-ae0c-4f26-9ff0-45cb083e7474)\n",
" [Import] Package eVehicle_Definitions (13ab3067-79ba-4b36-b0ec-9a2455c43fb1)\n",
" [Membership] PartUsage eVehicle (4b1f0203-ed9b-46e1-93a7-5c1d18f634b4)\n",
" [Subsetting] PartUsage parts (210455cc-0a23-429e-9e49-95acce6c7873)\n",
" [FeatureMembership] PartUsage body (024078d4-0770-4463-aae2-8e719418e84b)\n",
" [Subsetting] PartUsage parts (210455cc-0a23-429e-9e49-95acce6c7873)\n",
" [FeatureMembership] PartUsage battery (424c8834-3081-41bc-9c7b-50d742c262a1)\n",
" [Subsetting] PartUsage parts (210455cc-0a23-429e-9e49-95acce6c7873)\n",
" [FeatureMembership] PartUsage engine (d532d210-ecd4-42da-ae40-68efe9b00196)\n",
" [Subsetting] PartUsage parts (210455cc-0a23-429e-9e49-95acce6c7873)\n",
" [FeatureMembership] PartUsage frontAxis (88292f1b-8e8f-4257-91be-c5cc1bcc7f26)\n",
" [Subsetting] PartUsage parts (210455cc-0a23-429e-9e49-95acce6c7873)\n",
" [FeatureMembership] PartUsage rearAxis (0f8be90b-1c95-45e1-9c7d-fd696f36dc55)\n",
" [Subsetting] PartUsage parts (210455cc-0a23-429e-9e49-95acce6c7873)\n",
" [FeatureMembership] PartUsage frontWheel (544633d7-17af-4945-a964-e689e999e4e0)\n",
" [FeatureTyping] PartDefinition Wheel (38f9638f-d02a-4839-a2e3-d75d1482c48d)\n",
" [Subsetting] PartUsage parts (210455cc-0a23-429e-9e49-95acce6c7873)\n",
" [FeatureMembership] MultiplicityRange (c2685a7f-07d6-42a4-b25b-f718a5b9bead)\n",
" [Redefinition] MultiplicityRange (9492ec5c-54a6-476e-89ee-d6797ce5f96c)\n",
" [FeatureMembership] LiteralInteger (daf6910f-4c14-4e74-b13b-6b99a89a6da1)\n",
" [ReturnParameterMembership] Feature $result (5081c478-3632-4bdf-b1d7-1b16248e6ef6)\n",
" [FeatureMembership] PartUsage rearWheel (28b858ea-f602-4d63-8614-696634c85db4)\n",
" [FeatureTyping] PartDefinition Wheel (38f9638f-d02a-4839-a2e3-d75d1482c48d)\n",
" [Subsetting] PartUsage parts (210455cc-0a23-429e-9e49-95acce6c7873)\n",
" [FeatureMembership] MultiplicityRange (5a450f99-45cd-42f3-8592-8eb15558df96)\n",
" [Redefinition] MultiplicityRange (9492ec5c-54a6-476e-89ee-d6797ce5f96c)\n",
" [FeatureMembership] LiteralInteger (2180d5b9-d6dd-4a48-a2db-b7963c83e8d9)\n",
" [ReturnParameterMembership] Feature $result (6edf8788-b982-4e0c-b827-d128bec28c3b)\n"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%show eVehicle_LogicalArchitecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"More convenient for the common model user, of course, is the graphical notation presented after the execution of the following cell:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_LogicalArchitecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Changes to SysML v1\n",
"\n",
"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.\n",
"\n",
"If I had modeled the eHSUV in SysML v1, I would have had to first define blocks and then part properties whose types are the blocks.\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following SysML v2 model describes the mapping of SysML v1 concepts to SysML v2 concepts. The formal transformation specification from SysML v1 to v2 is, of course, much more detailed. The following mapping is human-readable, but somewhat less precise. The current implementation of SysML v2 does not provide the allocate relationship yet, which I would like to use for the mapping. Instead, I use the dependency relationship. The mapping only describes the model elements I used so far. A complete mapping of all elements covered in this book are described in chapter [Mapping from SysML v1 to SysML v2](#sysmlv2modv1mapping)."
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package SysMLv1ToSysMLv2MappingLibrary (4a1e975c-3fad-4ec6-888e-4f41f75f09a9)\n",
"Package SysMLv1ToSysMLv2Mapping (c82d16f0-73a9-48cc-94ff-89533503a62c)\n"
]
},
"execution_count": 98,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package SysMLv1ToSysMLv2MappingLibrary {\n",
" part def SysMLModelElement;\n",
"}\n",
"\n",
"package SysMLv1ToSysMLv2Mapping {\n",
" \n",
" import SysMLv1ToSysMLv2MappingLibrary::*;\n",
" \n",
" part SysMLv1 {\n",
" part Block:SysMLModelElement;\n",
" part Dependency:SysMLModelElement;\n",
" part Package:SysMLModelElement;\n",
" part PartProperty:SysMLModelElement;\n",
" }\n",
" \n",
" part SysMLv2 {\n",
" part Dependency:SysMLModelElement;\n",
" part Package:SysMLModelElement;\n",
" part Part:SysMLModelElement;\n",
" part PartDefinition:SysMLModelElement;\n",
" }\n",
" \n",
" // Mapping SysML v1 to SysML v2\n",
" dependency from SysMLv1::Block to SysMLv2::PartDefinition;\n",
" dependency from SysMLv1::Dependency to SysMLv2::Dependency;\n",
" dependency from SysMLv1::Package to SysMLv2::Package;\n",
" dependency from SysMLv1::PartProperty to SysMLv2::Part;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz SysMLv1ToSysMLv2Mapping"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Parts and PartDefinitions\n",
"\n",
"In SysML v2, you can define parts without types. However, you could define types if you like. A type can be used to reuse definitions. I extend our example and add a property to the wheel to specify the size. The type of the attribute is Integer. I skip units for now. The textual syntax allows the keyword *attribute* or *value*. I prefer *value*."
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture (0a92252a-e270-4d19-aab7-b017bdfaf8a9)\n"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_LogicalArchitecture {\n",
" \n",
" import ScalarValues::Integer;\n",
" \n",
" part eVehicle { \n",
" part body;\n",
" part battery;\n",
" part engine;\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel[2] {\n",
" value size : Integer;\n",
" }\n",
" part rearWheel[2] {\n",
" value size : Integer;\n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_LogicalArchitecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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 Parts. "
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicleDefinitions (bf5b8d43-4f6c-47d1-8c41-b80b7978518a)\n",
"Package eVehicle_LogicalArchitecture (85567e94-df2b-4967-b589-11e10e914c50)\n"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicleDefinitions {\n",
"\n",
" import ScalarValues::Integer; \n",
" \n",
" part def Wheel {\n",
" value size : Integer;\n",
" }\n",
"}\n",
"\n",
"package eVehicle_LogicalArchitecture {\n",
"\n",
" import eVehicleDefinitions::*;\n",
" \n",
" part eVehicle { \n",
" part body;\n",
" part battery;\n",
" part engine;\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel : Wheel[2];\n",
" part rearWheel : Wheel[2];\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_Definitions"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_LogicalArchitecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The attribute size itself can also be defined and reused for several attribute usages. It is a common concept in SysML v2 to separate definition of elements and usage of elements. SysML v1 also follows this concept, but not as consequent as SysML v2. For example, SysML v1 does not provide a separate attribute definition.\n",
"\n",
"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* attribute. Alternatively, the keyword *value* can be used instead of *attribute*."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"jupyter": {
"source_hidden": true
}
},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_Definitions (d70a8a62-b9ee-48e4-ad83-0ddfbf74cd92)\n",
"Package eVehicle_LogicalArchitecture (dd4b3fad-565a-4770-9998-0c0a66335376)\n"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_Definitions {\n",
" \n",
" attribute def WheelSize {\n",
" import ScalarValues::Integer;\n",
" size : Integer;\n",
" }\n",
" \n",
" part def Wheel {\n",
" attribute sizeOfWheel : WheelSize;\n",
" }\n",
"}\n",
"\n",
"package eVehicle_LogicalArchitecture { \n",
" \n",
" import eVehicle_Definitions::*;\n",
" \n",
" part eVehicle { \n",
" part body;\n",
" part battery;\n",
" part engine;\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel : Wheel[2];\n",
" part rearWheel : Wheel[2];\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_Definitions"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_LogicalArchitecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Putting the parts together\n",
"\n",
"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.\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture (d9e0e944-5b16-4067-9987-b819e369c4a7)\n"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_LogicalArchitecture {\n",
" \n",
" import eVehicleDefinitions::*;\n",
" \n",
" part eVehicle { \n",
" part body;\n",
" part battery;\n",
" part engine;\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel : Wheel[2];\n",
" part rearWheel : Wheel[2];\n",
" \n",
" connect battery to engine;\n",
" connect engine to frontAxis;\n",
" connect frontAxis to frontWheel;\n",
" connect rearAxis to rearWheel;\n",
" connect body to battery;\n",
" connect body to engine;\n",
" connect body to frontAxis;\n",
" connect body to rearAxis;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=interconnection eVehicle_LogicalArchitecture::eVehicle"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Modeling interfaces\n",
"\n",
"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."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture (ff608f69-3f82-4b20-bf6f-e92cbc7dea68)\n"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_LogicalArchitecture {\n",
" \n",
" import eVehicleDefinitions::*;\n",
" \n",
" part eVehicle { \n",
" part body;\n",
" part battery {\n",
" port powerOut;\n",
" }\n",
" part engine {\n",
" port powerIn;\n",
" }\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel : Wheel[2];\n",
" part rearWheel : Wheel[2];\n",
" \n",
" connect battery::powerOut to engine::powerIn;\n",
" connect engine to frontAxis;\n",
" connect frontAxis to frontWheel;\n",
" connect rearAxis to rearWheel;\n",
" connect body to battery;\n",
" connect body to engine;\n",
" connect body to frontAxis;\n",
" connect body to rearAxis;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=interconnection eVehicle_LogicalArchitecture::eVehicle"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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.\n",
"\n",
"The port only specifies the interaction point. The interface defines the connection between interaction points. The *PowerOutPort* is conjugated for the *consumerPort* port."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicleLibrary (51306574-6576-4a15-b56c-b00db80676de)\n"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicleLibrary {\n",
" \n",
" import ScalarValues::Integer;\n",
" \n",
" attribute def ElectricEnergy;\n",
" \n",
" port def PowerOutPort {\n",
" out energy : ElectricEnergy;\n",
" }\n",
" \n",
" interface def PowerInterface {\n",
" end supplierPort : PowerOutPort;\n",
" end consumerPort : ~PowerOutPort;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicleLibrary"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, the definitions of the port and the interface are applied to the model. **Do not forget to run the eVehicle_Definitions and eVehicleLibrary in section [Libraries for the eVehicle example](#sysmlv2modlibrary).**"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture (9c26478f-36cf-409c-ba7d-05d3c264c6e5)\n"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_LogicalArchitecture {\n",
" \n",
" import eVehicleDefinitions::*;\n",
" import eVehicleLibrary::*;\n",
" \n",
" part eVehicle { \n",
" part body;\n",
" part battery {\n",
" attribute capacity : BatteryCapacity;\n",
" port powerOut : PowerOutPort;\n",
" }\n",
" part engine {\n",
" port powerIn : ~PowerOutPort;\n",
" }\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel : Wheel[2];\n",
" part rearWheel : Wheel[2];\n",
" \n",
" interface : PowerInterface connect \n",
" supplierPort => battery::powerOut to \n",
" consumerPort => engine::powerIn;\n",
" connect engine to frontAxis;\n",
" connect frontAxis to frontWheel;\n",
" connect rearAxis to rearWheel;\n",
" connect body to battery;\n",
" connect body to engine;\n",
" connect body to frontAxis;\n",
" connect body to rearAxis;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 94,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=interconnection eVehicle_LogicalArchitecture::eVehicle"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Modeling variants\n",
"\n",
"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.\n",
"\n",
"The electrical vehicle model is extended with different types of batteries and engines. First, we extend the *eVehicleDefinitions* and *eVehicleLibrary*, and define a part definition for the battery. The complete library can be found in section [Libraries for the eVehicle example](#sysmlv2modlibrary)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicleLibrary (8756a65a-a48f-4b80-91a6-43a04906f4fb)\n",
"Package eVehicleDefinitions (1dcfeb37-79d5-4fc7-8992-8c27890cd5a2)\n"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicleLibrary {\n",
" \n",
" import ScalarValues::Integer;\n",
" \n",
" attribute def ElectricEnergy;\n",
" attribute def BatteryCapacity :> ScalarValues::Integer;\n",
" \n",
" port def PowerOutPort {\n",
" out energy : ElectricEnergy;\n",
" }\n",
" \n",
" interface def PowerInterface {\n",
" end supplierPort : PowerOutPort;\n",
" end consumerPort : ~PowerOutPort;\n",
" }\n",
"}\n",
"\n",
"package eVehicleDefinitions {\n",
"\n",
" import eVehicleLibrary::*; \n",
" \n",
" part def Wheel {\n",
" value size : Integer;\n",
" }\n",
" \n",
" part def Battery {\n",
" value capacity : BatteryCapacity;\n",
" }\n",
" \n",
" part def Engine;\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The new part definition of the *Battery* is now used in the eVehicle architecture."
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture (018276f1-ac3b-4f10-8e86-ee4ca277ed3e)\n"
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_LogicalArchitecture {\n",
" \n",
" import eVehicleDefinitions::*;\n",
" import eVehicleLibrary::*;\n",
" \n",
" part eVehicle { \n",
" value maxSpeed :Speed = 142;\n",
" part body;\n",
" part battery : Battery {\n",
" value redefines capacity = 42;\n",
" port powerOut : PowerOutPort;\n",
" }\n",
" part engine : Engine {\n",
" port powerIn : ~PowerOutPort;\n",
" }\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel : Wheel[2];\n",
" part rearWheel : Wheel[2];\n",
" \n",
" interface : PowerInterface connect \n",
" supplierPort => battery::powerOut to \n",
" consumerPort => engine::powerIn;\n",
" connect engine to frontAxis;\n",
" connect frontAxis to frontWheel;\n",
" connect rearAxis to rearWheel;\n",
" connect body to battery;\n",
" connect body to engine;\n",
" connect body to frontAxis;\n",
" connect body to rearAxis;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz eVehicle_LogicalArchitecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, the model is prepared to add variability. We define two battery kinds with different capacities, and two engine kinds."
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_VariantModel (676ce442-82a2-4473-ac7f-d50fe825fd71)\n"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_VariantModel {\n",
" \n",
" import eVehicle_LogicalArchitecture::*;\n",
" \n",
" \n",
" package eVehicle_Configurations {\n",
"\n",
" import eVehicle_Variations::*;\n",
" \n",
" part eVehicleStandard :> eVehicleVariations {\n",
" part redefines engine :> standardEngine;\n",
" part redefines battery :> batteryLow;\n",
" }\n",
" part eVehiclePremium :> eVehicleVariations {\n",
" part redefines engine :> powerEngine;\n",
" part redefines battery :> batteryHigh;\n",
" }\n",
" part INVALIDeVehicle :> eVehicleVariations {\n",
" part redefines engine :> powerEngine;\n",
" part redefines battery :> batteryLow;\n",
" }\n",
" }\n",
" \n",
" package eVehicle_Variations {\n",
" \n",
" import eVehicle_Variants::*;\n",
" \n",
" abstract part eVehicleVariations :> eVehicle {\n",
" \n",
" variation part redefines battery : Battery {\n",
" variant part batterLow;\n",
" variant part batteryHigh; \n",
" }\n",
" variation part redefines engine : Engine {\n",
" variant part standardEngine;\n",
" variant part powerEngine;\n",
" }\n",
" \n",
" abstract constraint { (battery == batteryLow & engine == standardEngine) ^ (battery == batteryHigh) }\n",
" }\n",
" } \n",
" \n",
" package eVehicle_Variants {\n",
" \n",
" part batteryLow : Battery {\n",
" value redefines capacity = 40;\n",
" }\n",
" part batteryHigh : Battery {\n",
" value redefines capacity = 40;\n",
" }\n",
" \n",
" part powerEngine : Engine;\n",
" part standardEngine : Engine;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 91,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_VariantModel::eVehicle_Variations::eVehicleVariations"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_VariantModel::eVehicle_Configurations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Avoiding the \"variability model explosion\"\n",
"\n",
"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."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture_ExplosionExample (6e11aba2-e881-4e07-a6c9-e206039f7ace)\n"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
" package eVehicle_LogicalArchitecture_ExplosionExample {\n",
" \n",
" import eVehicleDefinitions::*;\n",
" import eVehicleLibrary::*;\n",
" \n",
" part eVehicle { \n",
" part engine : Engine;\n",
"\n",
" part frontAxis {\n",
" part frontWheel[2] {\n",
" part lugBolt[6];\n",
" part boltCircle;\n",
" connect boltCircle to lugBolt;\n",
" }\n",
" part housing; \n",
" connect housing to frontWheel;\n",
" }\n",
" \n",
" part rearAxis {\n",
" part rearWheel[2] {\n",
" part lugBolt[6];\n",
" part boltCircle;\n",
" connect boltCircle to lugBolt;\n",
" }\n",
" part housing; \n",
" connect housing to rearWheel;\n",
" } \n",
" connect engine to frontAxis;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=interconnection eVehicle_LogicalArchitecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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.\n",
"\n",
"\n",
"\n",
"Now, if we introduce variants of lug bolts, this variance ripples up through the entire structure:\n",
"\n",
"\n",
"\n",
"In SysML v2 it looks like this:"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicleVariants_ExplosionExample (17bc5747-f80e-4aa2-ae99-0b3ed8af6e25)\n",
"Package eVehicle_LogicalArchitecture_ExplosionExample (f334f542-ef0d-4c12-bf94-6775c86799d5)\n"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicleVariants_ExplosionExample {\n",
" part lugBolt42;\n",
" part lugBolt23;\n",
"}\n",
"\n",
"package eVehicle_LogicalArchitecture_ExplosionExample {\n",
" \n",
" import eVehicleDefinitions::*;\n",
" import eVehicleLibrary::*;\n",
" import eVehicleVariants_ExplosionExample::*;\n",
" \n",
" part eVehicle { \n",
" part engine : Engine;\n",
"\n",
" part frontAxis {\n",
" part frontWheel[2] {\n",
" /*-----------------------------\n",
" * Definition of the variation\n",
" * ----------------------------*/\n",
" variation part lugBolt[6] {\n",
" variant part lugBolt23;\n",
" variant part lugBolt42; \n",
" }\n",
" part boltCircle;\n",
" connect boltCircle to lugBolt;\n",
" }\n",
" part housing; \n",
" connect housing to frontWheel;\n",
" }\n",
" \n",
" part rearAxis {\n",
" part rearWheel[2] {\n",
" part lugBolt[6];\n",
" part boltCircle;\n",
" connect boltCircle to lugBolt;\n",
" }\n",
" part housing; \n",
" connect housing to rearWheel;\n",
" } \n",
" connect engine to frontAxis;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree eVehicle_LogicalArchitecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A concrete variant configuration of the eVehicle with lug bolts *42* can be simply created by specialization:"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_Edition42 (32530ac1-177d-4b73-a122-921ed3bf232c)\n"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_Edition42 {\n",
" \n",
" import eVehicle_LogicalArchitecture_ExplosionExample::*;\n",
" \n",
" part eVehicle42 :> eVehicle {\n",
" part redefines lugBolt42 :> frontAxis::frontWheel::lugBolt;\n",
" }\n",
"}\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Modeling requirements\n",
"\n",
"A requirement definition is a special kind of a constraint definition including parameters and required constraints. \n",
"\n",
"**Do not forget to run the eVehicle_Definitions and eVehicleLibrary in section [Libraries for the eVehicle example](#sysmlv2modlibrary).**"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicleRequirementDefinitions (8be10a06-3d86-4205-9079-d9ddd7d04e4e)\n"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicleRequirementDefinitions {\n",
" \n",
" import eVehicleDefinitions::*;\n",
" \n",
" requirement def BatteryCapacityReqDef {\n",
" doc /* The actual battery capacity shall be greater than or equal\n",
" * to the required capacity. */\n",
"\n",
" attribute capacityActual : BatteryCapacity;\n",
" attribute capacityRequired : BatteryCapacity;\n",
" \n",
" require constraint{ capacityActual <= capacityRequired }\n",
" }\n",
" \n",
" requirement def MaxSpeedReqDef {\n",
" doc /* The maximum speed of the vehicle shall be \n",
" * not greater than the required maximum speed. */\n",
" \n",
" attribute maxSpeedVehicle : Speed;\n",
" attribute maxSpeedRequired : Speed;\n",
" \n",
" require constraint{ maxSpeedVehicle <= maxSpeedRequired }\n",
" }\n",
" \n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz eVehicleRequirementDefinitions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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.\n",
"\n",
"It is possible to define requirement groups to manage a large set of requirements by defining that a requirement requires other requirements.\n",
"\n",
"**Do not forget to run the eVehicle_VariantModel above before you run this model.**"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz eVehicle_LogicalArchitecture::eVehicle"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicleRequirements (b8416c8b-39cc-4136-a156-ff81f4d31e3c)\n"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicleRequirements {\n",
" \n",
" import eVehicleRequirementDefinitions::*;\n",
" import eVehicle_LogicalArchitecture::*;\n",
" \n",
" requirement eVehicleSpecification {\n",
" doc /* Requirement Specification of the eVehicle */\n",
" subject eVehicle :>> eVehicle;\n",
" require eVehicleBatteryCapacity;\n",
" require eVehicleMaxSpeed;\n",
" }\n",
" \n",
" requirement id 'REQ.B.1' eVehicleBatteryCapacity : BatteryCapacityReqDef {\n",
" subject eVehicle :>> eVehicle;\n",
" attribute :>> capacityRequired = 50;\n",
" attribute :>> capacityActual = eVehicle::battery::capacity;\n",
" }\n",
" \n",
" requirement id 'REQ.V.1' eVehicleMaxSpeed : MaxSpeedReqDef {\n",
" subject eVehicle :>> eVehicle;\n",
" attribute :>> maxSpeedRequired = 140;\n",
" attribute :>> maxSpeedVehicle = eVehicle::maxSpeed;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz eVehicleRequirements"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we model that the eVehicle satisfies the requirement."
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicle_LogicalArchitecture (dff6e5c3-b1ce-4dec-b6d1-7dfe983a7684)\n"
]
},
"execution_count": 83,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicle_LogicalArchitecture {\n",
" \n",
" import eVehicleDefinitions::*;\n",
" import eVehicleLibrary::*;\n",
" import eVehicleRequirements::*;\n",
" \n",
" part eVehicleContext {\n",
" \n",
" part eVehicle { \n",
" value maxSpeed :Speed = 142;\n",
" part body;\n",
" part battery : Battery {\n",
" value redefines capacity = 42;\n",
" port powerOut : PowerOutPort;\n",
" }\n",
" part engine : Engine {\n",
" port powerIn : ~PowerOutPort;\n",
" }\n",
" part frontAxis;\n",
" part rearAxis;\n",
" part frontWheel : Wheel[2];\n",
" part rearWheel : Wheel[2];\n",
" \n",
" interface : PowerInterface connect \n",
" supplierPort => battery::powerOut to \n",
" consumerPort => engine::powerIn;\n",
" connect engine to frontAxis;\n",
" connect frontAxis to frontWheel;\n",
" connect rearAxis to rearWheel;\n",
" connect body to battery;\n",
" connect body to engine;\n",
" connect body to frontAxis;\n",
" connect body to rearAxis;\n",
" }\n",
" satisfy eVehicleSpecification by eVehicle;\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Mapping from SysML v1 to SysML v2\n",
"\n",
"The following SysML v2 model describes the mapping of SysML v1 concepts to SysML v2 concepts. The formal transformation specification from SysML v1 to SysML v2 is, of course, much more detailed. The following mapping is human-readable, but somewhat less precise. The current implementation of SysML v2 does not provide the allocate relationship yet, which I would like to use for the mapping. Instead, I use the dependency relationship. The mapping only describes the model elements used in this book."
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package SysMLv1ToSysMLv2MappingLibrary (ddf8e43f-fb4f-4710-ba94-a488341f4700)\n",
"Package SysMLv1ToSysMLv2Mapping (f42acfd8-8b54-44e2-96ff-901d083374c3)\n"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package SysMLv1ToSysMLv2MappingLibrary {\n",
" part def SysMLModelElement;\n",
"}\n",
"\n",
"package SysMLv1ToSysMLv2Mapping {\n",
" doc /* Mapping of SysML v1 model elements to SysML v2 */\n",
" \n",
" import SysMLv1ToSysMLv2MappingLibrary::*;\n",
" \n",
" part SysMLv1 {\n",
" part AssociationBlock:SysMLModelElement;\n",
" part Block:SysMLModelElement;\n",
" part Connector:SysMLModelElement;\n",
" part Dependency:SysMLModelElement;\n",
" part 'Import':SysMLModelElement;\n",
" part Package:SysMLModelElement;\n",
" part PartProperty:SysMLModelElement;\n",
" part Port:SysMLModelElement;\n",
" part Requirement:SysMLModelElement;\n",
" part ValueProperty:SysMLModelElement;\n",
" }\n",
" \n",
" part SysMLv2 {\n",
" part Attribute:SysMLModelElement;\n",
" part Connection:SysMLModelElement;\n",
" part Dependency:SysMLModelElement;\n",
" part 'Import':SysMLModelElement;\n",
" part InterfaceDefinition:SysMLModelElement;\n",
" part Package:SysMLModelElement;\n",
" part Part:SysMLModelElement;\n",
" part PartDefinition:SysMLModelElement;\n",
" part Port:SysMLModelElement;\n",
" part RequirementDefinition:SysMLModelElement;\n",
" part 'Variant':SysMLModelElement;\n",
" part 'Variation':SysMLModelElement;\n",
" }\n",
" \n",
" // Mapping SysML v1 to SysML v2\n",
" dependency from SysMLv1::AssociationBlock to SysMLv2::InterfaceDefinition;\n",
" dependency from SysMLv1::Block to SysMLv2::PartDefinition;\n",
" dependency from SysMLv1::Connector to SysMLv2::Connection;\n",
" dependency from SysMLv1::Dependency to SysMLv2::Dependency;\n",
" dependency from SysMLv1::'Import' to SysMLv2::'Import';\n",
" dependency from SysMLv1::Package to SysMLv2::Package;\n",
" dependency from SysMLv1::PartProperty to SysMLv2::Part;\n",
" dependency from SysMLv1::Port to SysMLv2::Port;\n",
" dependency from SysMLv1::Requirement to SysMLv2::RequirementDefinition;\n",
" dependency from SysMLv1::ValueProperty to SysMLv2::Attribute;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=interconnection SysMLv1ToSysMLv2Mapping"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Libraries for the eVehicle example\n",
"\n",
"This section contains the complete libraries used in the examples of this chapter. You must run them to execute the examples."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package eVehicleLibrary (d19e9f8e-6380-44ea-be6d-8a4e489f7449)\n",
"Package eVehicleDefinitions (611d2dfe-6a2b-4e7f-9fad-8e6d89f859dc)\n"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package eVehicleLibrary {\n",
" \n",
" attribute def ElectricEnergy;\n",
" attribute def BatteryCapacity :> ScalarValues::Integer;\n",
" attribute def Speed :> ScalarValues::Integer;\n",
" \n",
" port def PowerOutPort {\n",
" out energy : ElectricEnergy;\n",
" }\n",
" \n",
" interface def PowerInterface {\n",
" end supplierPort : PowerOutPort;\n",
" end consumerPort : ~PowerOutPort;\n",
" }\n",
"}\n",
"\n",
"package eVehicleDefinitions {\n",
"\n",
" import eVehicleLibrary::*; \n",
" \n",
" part def Wheel {\n",
" value size : ScalarValues::Integer;\n",
" }\n",
" \n",
" part def Battery {\n",
" value capacity : BatteryCapacity;\n",
" }\n",
" \n",
" part def Engine;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz eVehicleLibrary"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz eVehicleDefinitions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# SysML v2 MBSE Methodologies JupyterBook\n",
"\n",
"This chapter covers the impact of SysML v2 on MBSE methodologies.\n",
"\n",
"Which methods continue to work well and which would need to be adapted? Theoretically, the methodologies have been developed independently of the SysML language, but definitely with a focus on SysML v1.\n",
"\n",
"New features of SysML v2 can also lead to new methods in the methodologies.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## SYSMOD with SysML v2\n",
"\n",
"The example is taken from the book [SYSMOD - The Systems Modeling Toolbox](https://leanpub.com/sysmod). It is a Forest Fire Detection System (FFDS)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### System Idea and System Objectives\n",
"\n",
"The language extension of SysML v2 is still under development. Until it is available, I use a simplified approach to introduce SYSMOD concepts into the language. \n",
"\n",
"The following SysML v2 code defines the SYSMOD concepts of a *system* and an *objective*. They are applied to define the forest fire detection system element including the problem statement and the system idea, and the three system objectives. The complete definition of SYSMOD is described in chapter [SYSMOD Language Library](#sysmodlibrary).\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package SYSMOD (05ab296a-3725-4287-99a8-99cde1755d83)\n"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package SYSMOD {\n",
"\n",
" doc /* SYSMOD - The Systems Modeling Toolbox, Version 5.0beta */\n",
" \n",
" requirement def Objective {\n",
" doc /* A objective is an objective of the system. It is a special kind of a requirement that is typically not satisfied but amplified by the system. */\n",
" }\n",
" \n",
" part def System {\n",
" doc /* Marks the system under development. Typically there is only one block in the model with that stereotype. However in a System of Systems (SoS) model there could be more. */\n",
" import ScalarValues::String;\n",
" value problemStatement : String;\n",
" value systemIdea : String;\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz SYSMOD"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package ForestFireDetectionSystemModel (0f6b62b1-0ccc-46be-96be-9e2db42c5e00)\n"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package ForestFireDetectionSystemModel {\n",
" \n",
" import SYSMOD::*;\n",
" \n",
" package FFDS_Core {\n",
" \n",
" part FFDS : System {\n",
" value redefines problemStatement = \"How can we provide a forest fire detection system for forest authorities that can be scaled to any forest size, is affordable, highly reliable and accurate in detecting forest fires.\";\n",
" value redefines systemIdea = \"The FFDS is a satellite-based system to detect forest fires in very large areas. The system is also equipped with stationary sensors and animal sensors. Using different sources for the fire detection increases the reliability of the system and enables different system configurations for different environmental contexts and price segments. Main features of the FFDS are Detecting and reporting forest fires on time Monitoring forest and fires Uses the behavior of forest animals to detect fires\";\n",
" }\n",
" \n",
" package FFDS_Requirements {\n",
" package FFDS_Objectives {\n",
" requirement id 'OBJ-B1' 'Market Leader' : Objective {\n",
" doc /* The system will make the vendor the market leader for forest fire detection systems. */\n",
" }\n",
" requirement id 'OBJ-S1' 'Reliable Detection' : Objective {\n",
" doc /* Any forest fire is detected by the system on time to start effective counteractions. */\n",
" }\n",
" requirement id 'OBJ-S2' 'Affordability' : Objective {\n",
" doc /* The system is affordable for any forest authority. */\n",
" } \n",
" }\n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz ForestFireDetectionSystemModel"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### System Context"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The concepts of use cases and actors are not yet defined in SysML v2. Therefore, the external entities of the system are defined as parts of the context. You must execute the SYSMOD library in chapter [SYSMOD Language Library](#sysmodlibrary) before executing the following cell."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package ForestFireDetectionSystemModel (bf2420d2-8028-4da6-bd97-00469c680382)\n"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package ForestFireDetectionSystemModel {\n",
" \n",
" import SYSMOD::*;\n",
" \n",
" package FFDS_Core {\n",
" \n",
" part 'FFDS System Context' : SystemContext {\n",
" part FFDS : System :> systemOfInterest { \n",
" value redefines problemStatement = \"How can we provide a forest fire detection system for forest authorities that can be scaled to any forest size, is affordable, highly reliable and accurate in detecting forest fires.\";\n",
" value redefines systemIdea = \"The FFDS is a satellite-based system to detect forest fires in very large areas. The system is also equipped with stationary sensors and animal sensors. Using different sources for the fire detection increases the reliability of the system and enables different system configurations for different environmental contexts and price segments. Main features of the FFDS are Detecting and reporting forest fires on time Monitoring forest and fires Uses the behavior of forest animals to detect fires\";\n",
" }\n",
" part Operator : User subsets actors;\n",
" part Administrator : User subsets actors;\n",
" part 'Forest Ranger' : User subsets actors;\n",
" part Maintenance : User subsets actors;\n",
" part 'Fire Department' : ExternalSystem subsets actors;\n",
" part 'Meteorology data system' : ExternalSystem subsets actors;\n",
" part 'Research analysis system' : ExternalSystem subsets actors;\n",
" part 'Weather' : EnvironmentalEffect subsets actors;\n",
" part 'Fire' : EnvironmentalEffect subsets actors;\n",
" part 'Planet Environment' : EnvironmentalImpact subsets actors; \n",
" } \n",
" \n",
" package FFDS_Requirements {\n",
" package FFDS_Objectives {\n",
" requirement id 'OBJ-B1' 'Market Leader' : Objective {\n",
" doc /* The system will make the vendor the market leader for forest fire detection systems. */\n",
" }\n",
" requirement id 'OBJ-S1' 'Reliable Detection' : Objective {\n",
" doc /* Any forest fire is detected by the system on time to start effective counteractions. */\n",
" }\n",
" requirement id 'OBJ-S2' 'Affordability' : Objective {\n",
" doc /* The system is affordable for any forest authority. */\n",
" } \n",
" }\n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz ForestFireDetectionSystemModel"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### System Use Cases"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Use Case Activities"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Domain Model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Quality Requirements"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Logical Architecture "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Product Architecture"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### System States"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Verify Architecture with Scenarios"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Test Cases"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### SYSMOD Language Library"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package SYSMOD (66d2be83-519e-496c-b6f8-cabb4d6228ca)\n"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package SYSMOD {\n",
"\n",
" doc /* SYSMOD - The Systems Modeling Toolbox, Version 5.0beta */\n",
" \n",
" requirement def Objective {\n",
" doc /* A objective is an objective of the system. It is a special kind of a requirement that is typically not satisfied but amplified by the system. */\n",
" }\n",
" \n",
" part def System {\n",
" doc /* Marks the system under development. Typically there is only one block in the model with that stereotype. However in a System of Systems (SoS) model there could be more. */\n",
" import ScalarValues::String;\n",
" value problemStatement : String;\n",
" value systemIdea : String;\n",
" }\n",
" \n",
" part def SystemContext {\n",
" doc /* A system context is a wrapper around the system and it's actors to allow a detailed system context modeling. The system context references the appropriate system. This is important in a SoS model. */\n",
" \n",
" part systemOfInterest : System;\n",
" part actors[0..*]; \n",
" }\n",
" \n",
" part def User;\n",
" part def ExternalSystem;\n",
" part def EnvironmentalEffect;\n",
" part def EnvironmentalImpact;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz SYSMOD"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## FAS with SysML v2\n",
"\n",
"The example is taken from the tutorial of the FAS plugin for MagicDraw: http://sourceforge.net/projects/fas4md/files/FAS_plugin_tutorial.pdf/download."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Package TheFASJukeBox (c7fafbbd-172c-407c-9fb0-82b40b0b5342)\n"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"package TheFASJukeBox {\n",
" \n",
" package FASLanguage {\n",
" part def FunctionalBlock;\n",
" }\n",
" \n",
" package UseCases {\n",
" activity '(Un)install and Move Jukebox';\n",
" activity 'Ask for Track to Play';\n",
" activity 'Assemble Music Collection';\n",
" activity 'Connect Jukebox with Electrical Supply';\n",
" activity 'Disconnect from Electrical Supply';\n",
" activity 'Distribute Energy';\n",
" activity 'Get Energy';\n",
" activity 'Get Mechanical Energy';\n",
" activity 'Get Money';\n",
" activity 'Insert Cash';\n",
" activity 'Install Jukebox';\n",
" activity 'Listen to Music';\n",
" activity 'Make Music Available';\n",
" activity 'Monitor Payment';\n",
" activity 'Play Music Track';\n",
" activity 'Produce Sound';\n",
" activity 'Provide Music Track';\n",
" activity 'Retrieve Identification of Music Track';\n",
" activity 'Retrieve Money';\n",
" activity 'Supply Jukebox with Energy';\n",
" activity 'Transform Mechanical Engery into Something Harmless';\n",
" activity 'Uninstall Jukebox';\n",
" activity 'Use Means of Music Transfer to Retrieve Music';\n",
" }\n",
" \n",
" package DomainKnowledge {\n",
" item def AudioSignal;\n",
" item def ClearanceToPlayMusic;\n",
" item def ElectricalEnergy;\n",
" item def IdentificationOfMusicTrack;\n",
" item def MechanicalEnergy;\n",
" item def Money;\n",
" item def MusicTrack;\n",
" }\n",
"\n",
" package FunctionalArchitecture {\n",
" \n",
" import UseCases::*;\n",
" import DomainKnowledge::*;\n",
" import FASLanguage::*;\n",
" import SYSMOD::*;\n",
" \n",
" package FunctionalInterfaces {\n",
"\n",
" port def AudioSignalPort {\n",
" out item a : AudioSignal;\n",
" }\n",
" port def ClearanceToPlayMusicPort {\n",
" out item m : ClearanceToPlayMusic;\n",
" }\n",
" port def ElectricalEnergyPort {\n",
" out item e : ElectricalEnergy;\n",
" }\n",
" port def IdentificationOfMusicTrackPort {\n",
" out item m : IdentificationOfMusicTrack;\n",
" }\n",
" port def MechanicalEnergyPort {\n",
" out item m : MechanicalEnergy;\n",
" }\n",
" port def MoneyPort {\n",
" out item m : Money;\n",
" }\n",
" port def MusicTrackPort {\n",
" out item m : MusicTrack;\n",
" }\n",
" }\n",
"\n",
" part TheFASJukeBoxFunctionalContext {\n",
" \n",
" import FunctionalInterfaces::*;\n",
" \n",
" part TheFASJukeBoxFunctionalArchitecture {\n",
"\n",
" dependency from TheFASJukeBoxFunctionalArchitecture to '(Un)install and Move Jukebox';\n",
" dependency from TheFASJukeBoxFunctionalArchitecture to 'Assemble Music Collection';\n",
" dependency from TheFASJukeBoxFunctionalArchitecture to 'Listen to Music';\n",
" dependency from TheFASJukeBoxFunctionalArchitecture to 'Supply Jukebox with Energy';\n",
"\n",
" part 'I/O Customer' : FunctionalBlock {\n",
" dependency from 'I/O Customer' to 'Ask for Track to Play';\n",
" dependency from 'I/O Customer' to 'Get Money';\n",
" dependency from 'I/O Customer' to 'Produce Sound';\n",
" \n",
" port p1 : MoneyPort;\n",
" port p2 : ~AudioSignalPort;\n",
" port p3 : IdentificationOfMusicTrackPort;\n",
" }\n",
" part 'I/O Electrical Supply' : FunctionalBlock {\n",
" dependency from 'I/O Electrical Supply' to 'Get Energy';\n",
" \n",
" port p1 : ElectricalEnergyPort;\n",
" }\n",
" part 'I/O Music Supplier' : FunctionalBlock {\n",
" dependency from 'I/O Music Supplier' to 'Use Means of Music Transfer to Retrieve Music';\n",
" \n",
" port p1 : MusicTrackPort;\n",
" }\n",
" part 'I/O Pub Interior' : FunctionalBlock {\n",
" dependency from 'I/O Pub Interior' to 'Get Mechanical Energy';\n",
" \n",
" port p1 : MechanicalEnergyPort;\n",
" }\n",
" part 'I/O Pub Manager' : FunctionalBlock {\n",
" dependency from 'I/O Pub Manager' to 'Connect Jukebox with Electrical Supply';\n",
" dependency from 'I/O Pub Manager' to 'Disconnect from Electrical Supply';\n",
" dependency from 'I/O Pub Manager' to 'Insert Cash';\n",
" dependency from 'I/O Pub Manager' to 'Retrieve Identification of Music Track';\n",
"\n",
" port p1 : IdentificationOfMusicTrackPort;\n",
" }\n",
" part Accounting : FunctionalBlock {\n",
" dependency from Accounting to 'Monitor Payment';\n",
" \n",
" port p1 : ClearanceToPlayMusicPort;\n",
" port p2 : ~MoneyPort;\n",
" }\n",
" part 'Energy Distribution' : FunctionalBlock {\n",
" dependency from 'Energy Distribution' to 'Distribute Energy';\n",
" \n",
" port p1 : ~ElectricalEnergyPort;\n",
" }\n",
" part 'Music Player' : FunctionalBlock {\n",
" dependency from 'Music Player' to 'Play Music Track';\n",
" \n",
" port p1 : AudioSignalPort;\n",
" }\n",
" part 'Music Storage' : FunctionalBlock {\n",
" dependency from 'Music Storage' to 'Make Music Available';\n",
" dependency from 'Music Storage' to 'Provide Music Track';\n",
"\n",
" port p1 : ~IdentificationOfMusicTrackPort;\n",
" port p2 : ~MusicTrackPort;\n",
" port p3 : ClearanceToPlayMusicPort;\n",
" }\n",
" part Suspension : FunctionalBlock {\n",
" dependency from Suspension to 'Uninstall Jukebox';\n",
" \n",
" port p1 : ~MechanicalEnergyPort;\n",
" }\n",
"\n",
" connect 'I/O Pub Manager'::p1 to 'Music Storage'::p1;\n",
" connect 'I/O Pub Manager' to 'Accounting';\n",
" connect 'I/O Music Supplier'::p1 to 'Music Storage'::p2;\n",
" connect 'Accounting'::p1 to 'Music Storage'::p3;\n",
" connect 'I/O Customer'::p1 to Accounting::p2;\n",
" connect 'Music Player'::p1 to 'I/O Customer'::p2;\n",
" connect 'I/O Customer'::p3 to 'Music Storage'::p1;\n",
" connect 'I/O Electrical Supply'::p1 to 'Energy Distribution'::p1;\n",
" connect 'I/O Pub Interior'::p1 to Suspension::p1;\n",
" }\n",
"\n",
" part Customer : User;\n",
" part 'Pub Manager' : User;\n",
" part 'Music Supplier' : ExternalSystem;\n",
" part 'Electrical Supply' : ExternalSystem;\n",
" part 'Pub Interior' : ExternalSystem;\n",
" \n",
" connect 'Pub Manager' to TheFASJukeBoxFunctionalArchitecture::'I/O Pub Manager';\n",
" connect 'Music Supplier' to TheFASJukeBoxFunctionalArchitecture::'I/O Music Supplier';\n",
" connect Customer to TheFASJukeBoxFunctionalArchitecture::'I/O Customer';\n",
" connect 'Electrical Supply' to TheFASJukeBoxFunctionalArchitecture::'I/O Electrical Supply';\n",
" connect 'Pub Interior' to TheFASJukeBoxFunctionalArchitecture::'I/O Pub Interior';\n",
" }\n",
" } \n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=tree TheFASJukeBox"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%viz --view=interconnection TheFASJukeBox::FunctionalArchitecture::TheFASJukeBoxFunctionalContext"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# VAMOS (Variant Modeling with SysML)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "SysML",
"language": "sysml",
"name": "sysml"
},
"language_info": {
"codemirror_mode": "sysml",
"file_extension": ".sysml",
"mimetype": "text/x-sysml",
"name": "SysML",
"pygments_lexer": "java",
"version": "1.0.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}