Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Papyrus-RT/User/User Guide/Getting Started"

(Introduction: Updated where to get the installation procedure for Papyrus-RT)
m (Select the architecture context for the model: corrected typo)
 
(65 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[File:PapyrusForRealTime-Logo-Icon.png|left|bottom-align|]]<br/><br/><span style="font-family: Helvetica,Arial,sans-serif; font-size: 48px;"><b>Getting Started with Papyrus for RealTime</b></span><br/><br/><br/>
+
[[File:PapyrusForRealTime-Logo-Icon.png|left|bottom-align|]]<br/><br/><span style="font-family: Helvetica,Arial,sans-serif; font-size: 48px;"><b>Getting Started with Papyrus for Real Time v1.0</b></span><br/><br/><br/>
  
 
__TOC__
 
__TOC__
  
= Introduction =
+
== Introduction ==
  
This tutorial will show the creation of a simple model using '''Papyrus for RealTime version 0.7.0''' (based on Eclipse Mars).
+
This tutorial will show the creation of a simple model using '''Papyrus for Real Time version 1.0''' (based on Eclipse Oxygen).
  
'''As a precondition to going through this tutorial, you must have Papyrus for Real Time installed and the tool '''open'''. Please see [[Papyrus-RT/User#Installation | Installing Papyrus-RT]] for the various methods to install Papyrus for Real Time.
+
{{warning |Installation| As a precondition to going through this tutorial, you must have Papyrus for Real Time installed. Please see the [[Papyrus-RT/User#Installation | Papyrus-RT User installation page]] for information on installing Papyrus for Real Time. &mdash; We recommend using the RCP installation as it is the easiest way to get started.}}
  
'''Note''': <code>The instructions in this tutorial are illustrated using Linux. Steps and images may differ slightly if the installation is done on a different operating system (both Windows and Mac OS are supported for developing models). Some of these differences have been indicated when known, but some may also be missing.</code>
+
{{note|Linux| The instructions in this tutorial are illustrated using Linux. Steps and images may differ slightly if the installation is done on a different operating system (both Windows and Mac OS are supported for developing models). Some of these differences have been indicated when known and some may be missing.}}
  
At its base, a UML-RT model consists of capsules (UML active classes with composite structure) that communicate through ports defined by protocols (collaboration specifications) These protocols specify the messages (signals) that can be exchanged between capsules, as well as their payloads. Hierarchical state machines are used to represent the behavior of capsules, where transitions between states are triggered by messages received on the capsule's ports.
+
{{note|PDF Version| A [https://wiki.eclipse.org/images/a/ae/Getting_Started_with_Papyrus_for_RealTimev1.0.pdf PDF version] of this tutorial is also available.}}
  
If you are not familiar with UML-RT and want to know a bit more, you should take a look at the [https://www.eclipse.org/papyrus-rt/content/overview.php Papyrus Overview] page.
+
This exercise will show the creation of a project and model and how UML-RT concepts can be used to easily create the application's structure and behavior.
  
The model that will be created as part of this tutorial is a simple, &quot;PingPong&quot; game with two players. In this model, implemented using UML-RT, two players will be playing an eternal game of ping pong.
+
At its base, a UML-RT model consists of capsules (UML active classes with composite structure) that communicate through ports defined by protocols (collaboration specifications) These protocols specify the messages (signals) that can be exchanged between capsules, as well as their payloads. Hierarchical state machines are used to represent the behavior of capsules, where transitions between states are triggered by messages received on the capsule's ports.
  
It is a very simple model that will show how a UML-RT model is constructed. Each player will be portrayed using UML-RT capsules and a UML-RT protocol will be used to define how the ball is exchanged between players through ports on each player capsule.
+
If you are not familiar with UML-RT and want to know a bit more, you should take a look at the initial [https://www.eclipse.org/papyrus-rt/content/overview.php Papyrus-RT Overview] page. Note that this page reflects an early version of Papyrus-RT and visual elements shown on that page may not completely match those of this tutorial. The concepts, however, ar the same).
  
= Create a Papyrus for Real Time Project containing a UML-RT model. =
+
The model that will be created as part of this tutorial is a simple "PingPong" model. In this model, implemented using UML-RT, two players will be playing a limited game of ping pong.
  
Papyrus for Real Time is a Domain-Specific Modeling Language (DSML) tool based on Papyrus. We will use the Papyrus Project creation wizard to create a project configured for Papyrus for Real Time.
+
It is a very simple model that will show how a UML-RT model is constructed. Players will each be portrayed using a UML-RT capsule and a common UML-RT protocol will be used to define how the ball is exchanged between players through ports on each player capsule.
  
== Select File -> New -> Papyrus Project ==
+
{{note|Use of Papyrus-RT| For brevity, "Papyrus-RT," the short form of "Papyrus for Real time," will be used throughout this document.}}
  
[[Image:Papyrus-rt-Select_New_Papyrus_Project.png]]
+
==Starting Papyrus-RT==
  
== Selecting the language to be used for the model ==
+
Start Papyrus for Real Time. This is typically done by double-clicking on its executable (on some platforms, the executable may be found under the "*papyrusrt*" folder).
  
In the resulting dialog:
+
As it starts, the launcher will display the Papyrus for Real Time splash screen.
  
# Select '''UML-RT''' as the language for the model that will be created by clicking on the radio button next to the UML-RT icon
+
[[Image:PRT10Splash.png]]
# Click on '''[Next]'''.
+
  
[[Image:Papyrus-rt-Select-model-language.png]]
+
===Creating a workspace===
  
== Define the project ==
+
Workspaces are Eclipse's way of creating development environments for various tasks. You can use workspace for different projects, different aspects of a project, or different tasks.
  
You can now define the project's name and its location, as well as the name of the model file that will be created.
+
After the launch splash screen is dismissed, you will be asked to specify a workspace.  
  
# Enter the '''name''' for the project. This project can hold multiple artefacts and will contain a Papyrus model by default. For this tutorial, we will use the name &quot;'''PingPong'''&quot;.
+
# You can opt for the provided default location or substitute your own.
# By default, the project will be created in the current workspace. You can, however, select an alternative location if, for example, you wish to store your project under source control.
+
# Click on '''[Launch]''' to continue.
# Enter &quot;'''PingPong'''&quot; as the model file name.
+
# Click on '''[Next]'''
+
  
[[Image:Papyrus-rt-define-the-project.png]]
+
[[Image:PRT10CreateWorkspace.png]]
  
== Provide model initialization information ==
+
===The workspace===
  
There is more information that can be provided to create a useful model.
+
After starting Papyrus-RT and dismissing the welcome screen, you are presented with the actual Papyrus-RT workspace
  
# The &quot;Root model element&quot; is a representation of the model itself. For this tutorial, and for consistency, we will name it &quot;'''PingPong'''&quot;.
+
[[Image:GSwPRT10WorkspaceDesc.png]]
# There is no more information to add on this dialog as they are already set in the wizard. Click '''[Finish]''' to create the project and contained model.
+
  
As shown in the image below, you should now have a project named &quot;PingPong&quot; containing a &quot;PingPong&quot; model in the Project Explorer as well as that model opened in the Model Explorer.
+
== Create a Papyrus for Real Time Project containing a UML-RT model==
  
[[Image:Papyrus-rt-model-initialization-info.png]]
+
Papyrus for Real Time is a Domain-Specific Modeling Language (DSML) tool based on Papyrus. We will use the Papyrus Project creation wizard to create a  project configured for Papyrus for Real Time.
  
== Project and Model Created ==
+
=== Select File -> New -> Papyrus Project ===
  
After expanding the &quot;PingPong&quot; project in the Project Explorer and the &quot;PingPong&quot; model in the Model Explorer, you will see that they have both been created and are now available for modeling.
+
[[Image:RT10NewPapyrusProject.png]]
  
[[Image:Papyrus-rt-project-and-model-created.png]]
+
=== Select the architecture context for the model ===
  
= Add profiles the model =
+
The architecture context defines the type of model you will be using to build you application. Papyrus can support various architecture model and provides extension points to add more if needed.
  
A lot has been done already to create an empty model and you have seen, in the previous step, that the base UML-RT profile has been applied. There are a few more components that need to be added to enhance the experience and the capabilities of the tool.
+
In the displayed dialog:
  
The first step will be to add some profiles.
+
# Select the '''UML-RT''' architecture context
 +
# Notice that the by clicking on UML-RT, both the architecture context and the viewpoints change to the ones required for UML-RT modeling.
 +
# Click on '''[Next]'''.
  
== Select the PingPong model in the Model Explorer and, in the Properties View, select the "Profile" tab. ==
+
You will notice that there are two "UML-RT Modeling" viewpoints. The difference between the two is in the amount of information displayed to the user, e.g., in the model explorer. Users who intend to only use Papyrus-RT for UML-RT would typically only need to use the "Basic" variant. Users who would like to mix in other diagrams, such as class diagrams, as well as "toolsmiths" and some "super-users" could benefit from the added information and capabilities from the '''Advanced''' UML-RT viewpoint.
 +
In the context of this tutorial, we will stay with the '''Basic UML-RT Modeling Viewpoint.'''
  
We will start by adding two profiles to the model:
+
[[Image:PRT10RT10ArchitectureContext.png]]
  
* &quot;'''UML RT StateMachines'''&quot; defines stereotypes and rules for state machines to support UML-RT specific semantics;
+
=== Define the project ===
* &quot;'''UML-RT C++ Property Set Profile'''&quot; defines stereotypes that enable more precise code generation for many model elements.
+
  
Both these profiles are part of the Papyrus-RT distribution and have already been registered during installation.
+
You can now define the project's name and its location, as well as the name of the model file that will be created.
  
# With the &quot;PingPong&quot; model selected in the Model Explorer, click on the &quot;Profile&quot; tab of the Properties view.
+
# Enter the '''name''' for the project. 1. This project can hold multiple artefacts and will contain a Papyrus model by default. For this tutorial, we will use the name "'''PingPong'''."
# Click on the &quot;'''Apply registered profile'''&quot; button
+
# As you type the name of the project, you will note that the model file name is filled with the same information. It is common to to use the same name for both. If you do need to have a different name for the model file, you can change it from the "Model file name" entry field.
 +
# By default, the project will be created in the current workspace. You can, however, select an alternative location if, for example, you wish to store your project under source control.
 +
# Click on '''[Next]'''
  
[[Image:Papyrus-rt-select-pingpong-profile-model-properties.png]]
+
[[Image:PRT10DefineProject.png]]
  
== Select the profiles to be added to the model ==
+
=== Provide model initialization information ===
  
# In the resulting dialog, select the both the &quot;'''UML RT StateMachines'''&quot; and &quot;'''UML-RT C++ Property Set Profile'''&quot; entries.
+
There is more information that can be provided to create a useful model.
# Click '''[OK]'''
+
  
[[Image:Papyrus-rt-select-additional-profiles.png]]
+
# The "Root model element" is a representation of the model itself. For this tutorial, and for consistency, we will name it "'''PingPong'''."
 +
# Typically, for UML-RT modeling, we would not start from a diagram. In addition, the two basic diagrams for UML-RT will be created automatically as part of the modeling workflow. As such, we will '''not''' select any "'''Representation Kind'''."
 +
# The wizard let's you select a template of the model you are creating, select "'''UML-RT for C++'''."
 +
# We will also '''not''' select to apply any '''profile'''. The project/model creation wizard automatically applies those that are required to create a Papyrus-RT model. This part of the dialog could be used to add other profiles that deployed in your environment or that are provided by other add-ons.
 +
# Click on ['''Finish'''] to create the model.
  
== Add profiles to the model ==
+
[[Image:PRT10ModelInit.png]]
  
# In the resulting dialog, click &quot;Select All&quot;
+
Note that there are three templates that you can select in the v1.0 version of Papyrus-RT:
# Note that both profiles are checked
+
# Click '''[OK]'''
+
  
[[Image:Papyrus-rt-add-profiles.png]]
+
# '''UML-RT for structural modelling''': only provides support for capsule, ports, and protocol. Capsule state machines cannot be created when this template is used.
 +
# '''UML-RT basic''': provides all UML-RT capabilities, including the creation of capsule state machines to express the behaviour of capsules. However, no target language is set for code generation.
 +
# '''UML-RT for C++''': provides all the capabilities to create UML-RT models that can generate C++ code. This includes the the UML-RT RTS and C++ primitive types libraries.
  
== The new profiles are now applied. ==
+
Note that these templates build on top of each other, so even if you select one of the first two template, you can still add the profiles and libraries to get to the "UML-RT  for C++" configuration later, once you are in the tool.
  
[[Image:Papyrus-rt-new-profiles-applied.png]]
+
== Project and Model Created ==
  
= Add UML-RT Runtime Services Library =
+
You now have an empty model ready to be populated!
  
A model library containing elements and protocols from the UML-RT Runtime Services layer is also available. This library contains class definitions and protocols that are useful, and in some cases, essential, for the creation of UML-RT models.
+
[[Image:PRT10ProjectModelCreated.png]]
  
This library needs to be imported before it can be used.
+
== Our project: PingPong ==
  
== Open the package import dialog ==
+
For this tutorial, we will be creating a simple model of a ping pong game, with two players.
  
# Right-click on the model in the Model Explorer and select &quot;'''Import &gt; Import Registered Package'''&quot;
+
The system will consist of two capsules ("active classes) that will communicate to show whose turn it is to hit the ball. Because the system is run by computer, no errors will be made playing so the game could go on forever... To prevent this, we will add a check to ensure that the game only runs for a pre-determined number of exchanges.
  
[[Image:Papyrus-rt-import-registered-package.png]]
+
So let's get started!
  
== Import the "UML-RT Runtime Services" package ==
+
== Create a protocol ==
 
+
# In the resulting dialog, select the &quot;'''UML-RT Runtime Services'''&quot; package from the list
+
# Click '''[OK]'''
+
 
+
[[Image:Papyrus-rt-import-umlrt-runtime-services.png]]
+
 
+
== Import all parts for the UML-RT model library ==
+
 
+
# Click on '''[Load All]'''
+
# Note that only the top-level element is selected - that is the expected behavior as it contains everything.
+
# Click on '''[OK]'''
+
 
+
[[Image:Papyrus-rt-import-all-umlrt-model-library.png]]
+
 
+
== Repeat the previous steps and select "UMLPrimitiveTypes" as the library to import. ==
+
 
+
The &quot;'''UMLPrimitiveTypes'''&quot; library contains the standard UML types. These can be used to specify property types. To use more specific or specialized base types, you could also use the &quot;'''AnsiCLibrary'''&quot; or the properties defined as part of the &quot;'''RTCppProperties'''&quot; stereotype. In this tutorial, we will not have a need to use specific types.
+
 
+
== The model libraries are now available to the model developer ==
+
 
+
You can now see that both the &quot;'''RTS'''&quot; and &quot;'''UML Primitive Types'''&quot; libraries are imported into the model.
+
 
+
'''Note 1:''' Neither of these model libraries are stored within the &quot;'''PingPong'''&quot; model. They are actually part of Papyrus-RT plugins and are &quot;read-only&quot;. You can, however, still make use of their content as part of the modelling of &quot;'''PingPong'''&quot;.
+
 
+
'''Note 2''': The code generator handles the &quot;'''RTS'''&quot; library is a special way and will not generate code for it as it only reflects the actual runtime services, which are provided separately as part of the Papyrus-RT distribution.
+
 
+
We are now ready to start our modelling our PingPong system.
+
 
+
[[Image:Papyrus-rt-model-libraries-now-available.png]]
+
 
+
= Create a protocol to specify the messages that can be exchanged between players =
+
  
 
Let's start by determining how the PingPong ball will go from one player to the other. To do this, we can think of the ping pong ball as a message to the other player to which they need to reply (hit the ball back). In UML-RT, the structure that governs the messages that can be exchanged between entities (players in this case) is a protocol.
 
Let's start by determining how the PingPong ball will go from one player to the other. To do this, we can think of the ping pong ball as a message to the other player to which they need to reply (hit the ball back). In UML-RT, the structure that governs the messages that can be exchanged between entities (players in this case) is a protocol.
 
+
Protocols contain protocol messages that define how messages can be sent and received between model elements (called "Capsules" in UML-RT - more on that later). These protocol messages can be incoming, outgoing, or symmetrical (i.e., both ingoing and outgoing).
Protocols define protocol messages that define how messages can be sent and received between model elements (called &quot;Capsules&quot; in UML-RT - more on that later). These protocol messages can be incoming, outgoing, or symmetrical (i.e., both ingoing and outgoing).
+
 
+
 
In the case of protocols that are not purely symmetric, i.e., that have either or both incoming and outgoing messages, there is also a need for the concept of conjugation, i.e., of reversing the role of the protocol, a concept that will be addressed further when used later in this tutorial.
 
In the case of protocols that are not purely symmetric, i.e., that have either or both incoming and outgoing messages, there is also a need for the concept of conjugation, i.e., of reversing the role of the protocol, a concept that will be addressed further when used later in this tutorial.
 +
In the case of this ''Getting Started'' tutorial, we could create a symmetric protocol where there would be a single symmetrical protocol message called, for example, "ball". However, to better explore the concept of protocols, we will define our "PingPong" protocol to have one outgoing protocol message called "ping" and one incoming protocol message called "pong".
  
In the case of this ''Getting Started'' tutorial, we could create a symmetric protocol where there would be a single symmetrical protocol message called, for example, &quot;ball&quot;. However, to better explore the concept of protocols, we will define our &quot;PingPong&quot; protocol to have one outgoing protocol message called &quot;ping&quot; and one incoming protocol message called &quot;pong&quot;.
+
=== Protocol Creation ===
 
+
== Create the protocol ==
+
  
 
The first step is to create the protocol itself.
 
The first step is to create the protocol itself.
  
# Right-click on the &quot;PingPong&quot; model in the Model Explorer and select &quot;'''UMLRealTime &gt; Protocol'''&quot;
+
# Right-click on the "PingPong" model in the Model Explorer and select "'''New UML-RT Child &gt; Protocol'''"
 
+
# The name of the protocol is highlighted, name the protocol "'''PingPongProtocol'''" and hit return.
You now have a &quot;protocol&quot; in the Model Explorer.
+
# You can also see the protocol and its messages in the Properties view. As the protocol was just created, it does not yet contain any protocol messages.
 
+
[[Image:Papyrus-rt-create-protocol.png]]
+
 
+
== Rename the protocol ==
+
 
+
Give the protocol a better name.
+
  
# Right-click on the protocol in the Model Explorer
+
You now have a "protocol" in the Model Explorer.
# Select &quot;'''Rename'''&quot;
+
# In the dialog, provide &quot;'''PingPong'''&quot; as the new name
+
# Click '''[OK]'''
+
# The protocol has been renamed
+
  
[[Image:Papyrus-rt-rename-protocol.png]]
+
[[Image:PRT10CreateProtocol.png]]
  
== Add protocol messages to the protocol ==
+
=== Add protocol messages to the protocol ===
  
A protocol is actually a complex construct and, as part of the UML-RT DSML, we are hiding its complexity so you do not need to know what lies beneath to create models!
+
As mentioned previously, a protocol may contain many different "protocol messages" that specify "''operations''" and their associated data.
  
Our protocol will &quot;ping&quot; its opponent and, in return, will respond to a &quot;pong&quot;. This tells us that there will be a &quot;ping&quot; outgoing protocol message and a &quot;pong&quot; incoming protocol message.
+
Our protocol will "''ping''" its opponent and, in return, will respond to a "''pong''" sent to it. This tells us that there will be a "ping" outgoing protocol message and a "pong" incoming protocol message.
  
'''Tip''': Protocols should be defined from the client's perspective. In practice, this means that the provider of the service defined by the protocol will have their ports conjugated and the client's ports will by un-conjugated. This makes sense as there will typically be more clients than service providers, so adopting this best practice will reduce the number of ports that need to be conjugated.
+
{{Tip|Protocol perspective|Protocols should be defined from the client's perspective. In practice, this means that the provider of the service defined by the protocol will have their ports conjugated and the client's ports will by un-conjugated. This makes sense as there will typically be more clients than service providers, so adopting this best practice will reduce the number of ports that need to be conjugated.}}
  
In the case of this model, it does not matter as there is no distinct service provider or client. After all, in a game of ping pong, both sides &quot;serve&quot;! In this tutorial, we will define the protocol from the point fo the player that will &quot;ping&quot;.
+
In the case of this model, it does not matter as there is no distinct service provider or client. After all, in a game of ping pong, both sides "serve"! For this tutorial, we will consider that the player that starts the game will be sending the "ping" and will therefore be the "server" / "Service Provider."
  
 
# Right-click on the protocol
 
# Right-click on the protocol
# Select to create a &quot;'''UMLRealTime &gt; ProtocolMessage Out'''&quot;.
+
# Select to create a "'''New UML-RT Child &gt; InProtocolMessage'''".
# Expand the protocol (by clicking on the right-pointing triangle at its left) and notice that a new protocol message is available.
+
# The protocol message is created and its name is ready to be edited in the model explorer in the model explorer .
 +
# Rename the protocol message to "ping" (remember, as the server, the port will be conjugated, so it will have to be the opposite of the action we expect, so incoming).
  
[[Image:Papyrus-rt-add-protocol-messages.png]]
+
[[Image:PRT10ProtocolMsgs2Prot.png]]
  
== Rename the outgoing protocol message ==
+
=== Add the "pong" Protocol Message ===
  
Right-click on the new protocol message, select &quot;Rename&quot;, and change its name to &quot;ping&quot;.
+
To create the "pong" message, use the same process as for the creation of the "ping" protocol message, above, except that you will instead create a "ProtocolMessageOut" and name the protocol message "pong"
  
[[Image:Papyrus-rt-rename-outgoing-protocol-message.png]]
+
# Right-click on the PingPong protocol and select "'''New UML-RT Child &gt; OutProtocolMessage'''"
 +
# Rename the resulting protocol message to "'''pong'''"
 +
# You now have a "'''pong'''" protocol message in addition to "ping".
  
== Add a "pong" Incoming Protocol Message ==
+
[[Image:PRT10AddPongPMsg.png]]
  
To create the &quot;pong&quot; message, use the same process as for the creation of the &quot;ping&quot; protocol message, above, opting to create a &quot;ProtocolMessageIn&quot; instead and renaming the protocol message &quot;pong&quot;
+
=== The "PingPong" protocol is now available ===
  
# Right-click on the PingPong protocol and select &quot;'''UMLRealTime &gt; ProtocolMessageIn'''&quot;
+
The protocol and its protocol messages can now be seen in both the Model Explorer and the Properties view and is available for modeling.
# Rename the resulting protocol message to &quot;'''pong'''&quot;
+
# You now have a &quot;'''pong'''&quot; protocol message in addition to &quot;ping&quot;.
+
  
[[Image:Papyrus-rt-add-pong-incoming-protocol-message.png]]
+
[[Image:PRT10WholeProtocolAvailable.png]]
  
== The "PingPong" protocol is now complete ==
+
== Defining the Tutorial's "PingPong" System's Structure ==
  
The protocol and its protocol messages can now be seen in both the Model Explorer and the Properties view.
+
Now that we have a protocol, we can move on to creating the structure of the "PingPong System."
 
+
[[Image:Papyrus-rt-pingpong-protocol-complete.png]]
+
 
+
= Defining the Tutorial's "PingPong" System's Structure =
+
  
 
We will need to create three capsules for this tutorial model:
 
We will need to create three capsules for this tutorial model:
  
;'''Two capsules representing the two players (&quot;Pinger&quot; and &quot;Ponger&quot;)'''
+
* '''Two capsules that will be representing the two players: "Pinger"''' ("player 1") and "Ponger ("player 2")
: We will be creating two capsules to highlight some aspects of the communication mechanisms, especially related to how ports are used with asymmetric protocols. If we had a symmetric protocol, we could simply use two instances of the same capsule, and that would be a less interesting model for a tutorial.
+
: We will be creating two capsules to highlight some aspects of the communication mechanisms, especially related to how ports are used with asymmetric protocols. If we had a symmetric protocol, we could simply use two instances of the same capsule, but that would be a less interesting model for a tutorial. Also note that, in this example, the two capsules will be slightly different as one has the added responsibility to start the game
 
+
* '''A top capsule representing the complete system ("Top")'''
;'''A top capsule representing the complete system (&quot;Top&quot;)'''
+
 
: In UML-RT, the building blocks are capsules and there is always a top capsule that represents the system to be built. The complete set of capsules that are required to implement the system's functionality are then included by the containment hierarchy from this top capsule.
 
: In UML-RT, the building blocks are capsules and there is always a top capsule that represents the system to be built. The complete set of capsules that are required to implement the system's functionality are then included by the containment hierarchy from this top capsule.
 
= Create the Pinger Capsule =
 
 
Let's start by creating the &quot;Pinger&quot; capsule
 
  
 
== Create the Pinger capsule ==
 
== Create the Pinger capsule ==
  
# Right-click on the PingPong model in the Model Explorer and select &quot;'''UMLRealTime &gt; Capsule'''&quot;
+
This capsule will represent the starting player in the game. As such, it will be responsible for sending the first "ball" (message). It will also have to react when receiving the ball from the other player.
# Rick-click on the newly created capsule and select &quot;'''Rename'''&quot; to change its name to &quot;'''Pinger'''&quot;
+
  
[[Image:Papyrus-rt-create-pinger-capsule.png]]
+
=== Create the Pinger ("player 1") capsule ===
  
== Open Pinger's Composite Structure Diagram ==
+
Let's start by creating the Pinger capsule.
  
Because of the importance of capsule containment in UML-RT, and for the convenience of the user, a composite structure diagram is automatically created for each capsule.
+
# Right-click on the PingPong model in the Model Explorer and select "'''New UML-RT Child &gt; Capsule'''"
 +
# After the capsule is created, it's name is selected for edition, name it "'''Pinger'''"
  
# Click on the right-facing triangle to the left of the &quot;Pinger&quot; capsule to show its contents
+
[[Image:PRT09-10-CreatePingerCapsule.png]]
# The element displayed is Pinger's composite structure diagram. Double-click on it
+
# The diagram is now shown in the editor view
+
# A tab at the bottom indicating the diagram name. Tabs at the bottom of the editor view allow you to easily switch between open diagrams
+
  
[[Image:Papyrus-rt-open-pinger-csd.png]]
+
=== Look at the Pinger capsule and open it's diagram ===
  
== Add a port to Pinger and set its type ==
+
Now that we have a capsule, let's have a look at what it contains and at its diagram.
  
Pinger still needs to communicate with Ponger when it hits the ball. To do this, it needs a port that implements the protocol that we defined earlier.
+
* Expand the '''Pinger''' capsule in the model explorer by clicking on the triangle at the beginning of its Model Explorer entry. You will notice that there is already a contained element: '''Pinger''''s diagram link. In Papyrus-RT, every capsule has a capsule diagram, this link is a quick way to open it
 +
* That diagram link is also accessible from the "'''Editor'''" under the '''View''' heading.
  
# In the editor pane, select the '''Port''' entry in the &quot;'''Nodes'''&quot; section of the Palette, click on the right border of &quot;'''Pinger'''&quot; (on the diagram)
+
[[Image:PRT09-10PingerCapsuleDiagram.png]]
# In the resulting dialog, click on [...] to select the protocol
+
# Expand &quot;PingPong&quot;
+
# Select &quot;'''«Protocol» PingPong'''&quot;
+
# Click [OK]
+
# Click [OK]
+
  
[[Image:Papyrus-rt-add-port-to-pinger.png]]
+
One open, you will see:
  
== Rename the port ==
+
# The representation of the '''Pinger''' capsule. It does not contain much right now, but we will work on that in this tutorial.
 +
# A editor tab is added at the bottom of the editor. This is useful when you have multiple diagram open so you can easily navigate between them
 +
# A tool palette providing you with the various tools that are relevant when working on a diagram in the context of the capsule's structure (in this case).
  
By default, the port will be created with the name in edit mode. At this point, you can just type in its name:
+
=== Add an external port to Pinger ===
  
There are three other ways to rename the port:
+
In order to be able to communicate, Pinger will need an external port through which it can send messages to other capsules. Let's add this port now.
  
* Double-click on the port label and enter the new name
+
# Click on "'''Port'''" in the tool palette.
* Right click on the port in the Model Explorer, select &quot;Rename&quot;, and enter the new name
+
# Click on the right border of the '''Pinger''' capsule.
* Select the &quot;Name&quot; property in the Properties view and enter the new name
+
# In the resulting dialog, select "'''Port with Existing Protocol'''"
 +
# In the resulting dialog, expand the "'''PingPong'''" model entry and select the "'''PingPong'''" protocol that was created earlier.
 +
# Name the resulting port "'''pingPort'''". This can be done by using the direct editor available on the port name.
 +
# Since we have decided that '''Ping''' would be the "'''server'''" capsule, we also have to change the conjugation of its port. To do so, look in the '''Properties''' view just below the '''Editor''', and make sure that the "'''UML-RT'''" tab is selected
 +
# Click on the box to the left of "'''Is conjugated'''".
 +
# When the port is conjugated, you will notice that its graphical element will change from being all black to getting a white fill, graphically showing the conjugation state.
 +
{{note|Context menu|A quicker way to change the conjugation of a port is to right-click on the port and select UML-RT Properties > Is Conjugated}}
  
'''Note''': ports are properties of the capsule and are typically named with a leading lowercase character.
+
[[Image:PRT10add-an-external-port-to-pinger.png.png]]
  
[[Image:Papyrus-rt-rename-pinger-port.png]]
+
=== Add a log port ===
  
== Add IO libraries ==
+
In order to make sure that the model actually runs correctly, we will need to display some information to the user. The Papyrus-RT runtime provides a logging service that allows models to print out information to the standard output (e.g., the screen). In the current version, it only does this to stdout, but this capability is extensible to use other output targets.
  
In order to see the execution of the model, once generated and built, we will need to print something to the screen, i.e., to &quot;stdout&quot;. In order to do so, we will need to specify the header files that need to be included to give the capsule access to these C++ functions.
+
So all that is needed to be able to log event to the screen is to add a log port to the capsule.
  
This is accomplished though stereotype properties that are used by the code generator to create the correct includes in the generated code.
+
# Select the Port tool and create a port in the middle of the capsule
 +
# In the resulting dialog, select the "Log" entry
 +
# Leave the name as is. You have now create a log port through which you can print messages. We will see how to use it when we add the behaviour to the capsule.
  
# Make sure that the &quot;'''Pinger'''&quot; capsule is selected and its Properties displayed with its &quot;Profile&quot; tab selected.
+
[[Image:PRT009-10AddLogPort.png]]
# Click on the '''[+]''', right of &quot;'''Applied Stereotypes'''&quot;
+
# In the resulting dialog, double-lclick on the &quot;'''CapsuleProperties'''&quot; entry in the &quot;'''Applicable Stereotypes'''&quot; box to move it to the &quot;'''Applied Stereotypes'''&quot; and click '''[OK]''' to apply the stereotype. This stereotype allows the modeler to set C++ specific constructs to help in the development of the executable model.
+
# Expand the &quot;CapsuleProperties: stereotype to see its properties and select the &quot;implementationPreface&quot; property.
+
# In the &quot;Implementation box, type in the following: #include &lt;iostream&gt;
+
  
That's all we need for now, we will see how to use this import during the creation of the the capsule's behavior.
+
=== Create Pinger's state machine ===
  
[[Image:Papyrus-rt-add-pinger-io-libraries.png]]
+
As mentioned, the behaviour of a capsule is represented by a state machine, but one is not provided by default as some capsules may not need to have behaviour.Examples of capsules not needing behaviour are for container capsules, such as "Top", and some patterns, such as dynamic forwarding.
  
== Create Pinger's state machine ==
+
# Right-click on the '''Pinger''' capsule in the Model Explorer and select "'''New UML-RT Child &gt; StateMachine'''" to create the state machine.
 +
# The state machine is created and its diagram is available from the '''Editor''''s '''View''' list (click on the '''Welcome''' tab at the bottom of the editor area to display the information view).
  
In UML-RT, all behavior is modeled using hierarchical state machines.
+
[[Image:PRT09-10CreatePingerStateMachine.png]]
  
These state machines are dubbed &quot;reactive&quot; because actions (or chains of actions) can only be taken as a result of a message being received on the capsule's ports - so they always react to a message. Reception of a message typically results in one of the state machine's transitions being taken. Each transition exiting from a state has a trigger defined by a port and signal (i.e., protocol message for that port), determining when they can be taken (triggered). Fine-grained actions, typically as opaque expressions, can be provided for transitions, as well as for states' entry and exit.
+
=== Add the Pinger StateMachine behaviour ===
  
Pseudostates can also be used to implement logic (choice points), continuation (junction, state entry and exit points - limited to a single outgoing transition), and history (deep and shallow).
+
# Now that we have a state machine, let's add the behaviour to it: open the '''Pinger::StateMachine. '''You will notice that we already provide you with the initial pseudostate and a state ("State1") to get you started
 +
# Move these two initial elements to better positions, as shown and rename "'''State1'''" to "'''Playing'''" (hint: use the Properties tab or slowly click twice on the state's border)
 +
# We will also add a transition that will be taken when the other player returns the ball. Using the transition tool draw a transition from the "'''Playing'''" state to itself.
  
Each state machine has an initial pseudostate that is triggered when the state machine if first instantiated, providing initialization capability.
+
[[Image:PRT10-addPingerSMBehaviour.png]]
  
# Right-click on &quot;'''Pinger'''&quot; in the Model Explorer and select &quot;'''New Diagram &gt; StateMachine Diagram'''&quot;
+
=== Add initial transition action ===
# In the resulting dialog, name the state machine diagram &quot;'''Pinger'''&quot;
+
# Click '''[OK]'''
+
# [Optional] Rename the state machine to &quot;'''Pinger'''&quot;
+
# Both the state machine and its diagram are now available
+
  
[[Image:Papyrus-rt-create-pinger-state-machine.png]]
+
All that is now left is to add some triggers (which allow for transitions to be taken when a message is received) and code blocks (remember, we are using C++ as the "Action Language".
  
== Set the state machine's stereotype and properties ==
+
Let's start with the Initial Transition. Note that the initial transition is always taken once, when the capsule is instantiated, so it does not need an trigger.
  
'''Note''': The tooling does not yet set all the properties for a UML-RT state machine, so you will have to set them manually.
+
# Click on the '''Initial''' transition and then open the '''Code Snippet View'''" in the Properties View area. Make sure that the "'''Effect'''" tab is selected at the bottom of the view. ''(hint: As mentioned in a previous tip, you may want to move the code snippet view to the right of the properties view, especially if you have a large monitor)''
 +
# In the code snippet view, add the following code:
  
# Keeping the &quot;'''Pinger'''&quot; state machine selected in the Model Explorer, use the Profile tab of the Properties Explorer to add the &quot;'''RTStateMachine'''&quot; stereotype to the state machine.
+
<pre>
# Expand the &quot;'''Pinger'''&quot; state machine in the Model Explorer to show and select the contained &quot;'''Region1'''&quot; region and then add the &quot;'''RTRegion'''&quot; stereotype to it.
+
// Start the game by sending a "ping" to the other player
 +
log.log("Starting game");
 +
if ( pingPort.ping().send() ) {
 +
    log.log( "ping sent!");
 +
} else {
 +
    log.log( "Error sending Ping!");
 +
}
 +
</pre>
  
1.
+
[[Image:PRT10AddInitTransitionAction.png]]
  
[[Image:Papyrus-rt-set-pinger-state-machine-stereotype.png]]
+
=== Edit the trigger and code for self transition ===
  
== Create the state machine's content ==
+
# Select the transition in the diagram and switch to the '''Properties''' view.
  
The state machine for Pinger is rather simple. It consists of a single state &quot;'''Playing'''&quot; with a self-transition triggered on receiving the &quot;'''pong'''&quot; message on the &quot;'''pingPort'''&quot;.
+
[[Image:PRT09-10EditSelfTransitionTriggerAndCode.png]]
  
However, we will also want &quot;'''Pinger'''&quot; to start the match, so we will need to do so during or right after the initialisation of the capsule. We can do this because capsule behavior only starts after all static capsule parts are created, so the message queues are already in place to receive messages. Because we do not want to have to issue the same code twice, and since &quot;'''Pinger'''&quot; will send a ball each time it receives a pong message, we will use a junction point to be able to reuse a transition's code.
+
=== Add the transition trigger ===
  
# Using the Palette's &quot;'''Nodes'''&quot; drawer, add an &quot;'''Initial'''&quot; pseudostate to the top left of the capsule's state machine and apply the &quot;'''RTPseudostate'''&quot; stereotype to it. You can leave its name as is or change it as you please.
+
# Click on the [+] button in the '''Trigger''' section to create a new trigger.
# Using the Palette's &quot;'''Nodes'''&quot; drawer, add a &quot;'''State'''&quot; below and to the right of the &quot;'''Initial&quot;''' pseudostate, name it &quot;'''Playing'''&quot;, and apply the &quot;'''RTState'''&quot; stereotype to it.
+
# From the resulting dialog, select the '''pingPort'''.
# Using the Palette's &quot;Edges&quot; drawer, draw a &quot;'''Transition'''&quot; from &quot;'''Initial'''&quot; to &quot;'''Playing'''&quot; named &quot;'''initial'''&quot;, and another from &quot;'''Playing'''&quot; to itself named &quot;'''onPong'''&quot;. '''Note 1:''' The start and end are very important when drawing a transition and it defines the direction, the first click being the origin and the second the destination. '''Note 2:''' It is a good idea to name transitions as this helps in understanding the diagram and, also, in debugging later on - here, we have used a short form of the trigger event. '''Note 3:''' Setting the transition to be &quot;rectilinear&quot; is useful when drawing state machines: right-click on a transition and select &quot;Format &gt; Line Style &gt; Rectilinear Style Routing.
+
# From the list of protocol messages, select the '''pong''' protocol message.
 +
# Click OK to set the trigger.
 +
# You now have a trigger defined for this transition. When the model runs, any message received while in the '''Playing''' state will result in this transition being taken.
 +
# Notice that the transition name has be set to the name of the protocol message selected, providing a clue on the diagram as to when the transition is triggered.
  
[[Image:Papyrus-rt-create-pinger-state-machine-content.png]]
+
[[Image:PRT09-10AddTransitionTrigger.png]]
  
== Add "onPong:" transition trigger to the state machine ==
+
=== Add the code for the transition ===
  
As indicated previously, the &quot;'''Initial'''&quot; transition does not need a trigger as it is taken automatically when the state machine is first instantiated. However, for the &quot;'''onPong'''&quot; transition to be taken, we will need to define a trigger for the transition that will determine when the transition can be taken.
+
The only thing left to do for this transition is to add its code. The basic steps are the same as those taken previously to add the code for the initial transition
  
# Select the &quot;'''onPong'''&quot; transition. In the Properties view's UML Tab, click on the '''[+]''' to the right of the &quot;'''Trigger'''&quot; field to create a new Trigger.
+
# Click on the transition and the '''Code Snippet View''' to bring up the C++ editor for the transition. Make sure that the "'''Effect'''" tab is selected at the bottom of the view.
# In the resulting &quot;'''Create a new Trigger'''&quot; dialog, set the name to &quot;'''onPong'''&quot;.
+
# Type in the following code (you will notice that it is very similar to that of the initial transition):
# Click on the '''[+]''' to the right of the &quot;'''Port'''&quot;
+
# On the resulting dialog, find the &quot;'''pinger'''&quot; port under the &quot;'''Pinger'''&quot; capsule, double-click on it to transfer it to the right box
+
# Click '''[OK]''', closing the dialog and bringing back the &quot;'''Create a new Trigger'''&quot; dialog
+
# Click on the '''[...]''' to the right of &quot;'''Protocol message'''&quot; to bring up the &quot;'''Protocol Message'''&quot; dialog
+
# Select the &quot;'''pong'''&quot; protocol message.
+
# Click on '''[OK]''', closing the dialog and bringing back the &quot;'''Create a new Trigger'''&quot; dialog and then '''[OK]''' again to close that dialog
+
# The trigger is now complete.
+
  
[[Image:Papyrus-rt-add-onpong-transition-trigger-2.png]]
+
<pre>
 +
// Reply to a pong message by sending a ping.
 +
log.log("Pong received!");
 +
if ( pingPort.ping().send() ) {
 +
    log.log( "ping sent!");
 +
} else {
 +
    log.log( "Error sending Ping!");
 +
}
 +
</pre>
 +
[[Image:PRT09-10AddTransitionCode.png]]
  
== Add an effect to the "onPong" transition to log it was taken. ==
+
=== You are now done with the creation of the Pinger capsule! ===
  
So that we can be sure that the &quot;'''onPong'''&quot; is indeed taken, let's add an effect to log this.
+
== Create the "Ponger" capsule ==
  
# Select the &quot;'''OnPong'''&quot; transition. In the Properties view's UML Tab, click on the '''[+]''' to the right of the &quot;'''Effect'''&quot; field to create a new action and select &quot;'''Opaque behavior'''&quot;.
+
To create the "'''Ponger'''" capsule, simply follow the same steps as when '''Pinger''' was created, with the following differnces:
# In the resulting dialog, set the name to &quot;logTransition&quot;.
+
# Click on the '''[+]''' to the right of &quot;'''Language'''&quot; to bring up the language selection dialog
+
# Double-click on &quot;'''C++'''&quot; from the selection dialog to move it to the selected item box. We are using C++ as the coding language within the tool to match our C++ runtime service library
+
# Click '''[OK]'''
+
# In the blank box to the right of the language selection, type &quot;std::cout &lt;&lt; &quot;onPong transition taken!&quot; &lt;&lt; std::endl;&quot;. This log command will enable us to see when the transition is taken when running the resulting executable.
+
# Click '''[OK]'''.
+
# The transition now contains an effect that will be executed each time the transition is taken.
+
  
[[Image:Papyrus-rt-add-onpong-transition-effect.png]]
+
* The capsule will be named "'''Ponger'''" instead of "'''Pinger'''"
 +
* The port is named "pong" and is '''not''' conjugated.
 +
* You should place the port on the left edge of the capsule, instead of the right. This will allow us to put both capsules side by side so that their ports will be easy to connect.
 +
* We also need to restrict the game so it will not run forever. To do so, we will add an attribute count the number of ball hits. We will use this attribute to stop the match after 5 exchanges.
 +
*#Right-click on Ponger in the model explorer and select "'''New UML-RT Child > Attribute'''"
 +
*#Name the attribute '''"hitCount"''' and set its type to "'''unsigned int'''" from the "'''AnsiCLibrary'''"
 +
* The capsule's state machine will be different as it does not need to start the game and it will not return the fifth ball in order to stop the game.
  
== Add the "Playing" entry action behavior to the state machine ==
+
=== Create the "Ponger" capsule's structure ===
  
We will now create an action that happens each time the &quot;'''Playing'''&quot; state is entered. This approach allows us to have this code in a single location, whether the transition into the &quot;'''Playing'''&quot; state is from the &quot;'''initial'''&quot; or the &quot;'''OnPong'''&quot; transition, allowing this player to both start the game and keep on playing, as per our requirements. This action will consist in sending a &quot;'''ping'''&quot; message to the other player, represented by the &quot;'''Ponger'''&quot;capsule. To do this, we'll add an entry action to that state to handle that.
+
Create the '''Ponger''' capsule's structure using the same instructions as for the '''Pinger''' capsule structure, but with the following changes:
  
# Select the &quot;'''Playing'''&quot; state. In the Properties view's UML Tab, click on the '''[+]''' to the right of the &quot;'''Entry'''&quot; field to create a new entry action and select &quot;'''Opaque Behavior'''&quot;, just like you did int the previous step.
+
* The capsule is named "'''Ponger'''"
# In the resulting dialog, set the name to &quot;'''sendPing'''&quot;.
+
* The external port is placed on the left edge of the capsule, instead of the right. This will make it easier for us to connect the capsules when we put both side by side.
# Click on the '''[+]''' to the right of &quot;'''Language'''&quot;
+
* The external port is named "pongPort"
# In the resulting dialog, set &quot;'''C++'''&quot; as the language, clicking [OK] to get back to the opaque behavior creation dialog.
+
* The external port is '''not''' conjugated.
# In the blank box to the right of the language selection, type the following code: if ( pinger.ping().send() ) { std::cout &lt;&lt; &quot;Ping sent!&quot; &lt;&lt; std::endl; } else { std::cout &lt;&lt; &quot;Error sending Ping!&quot; &lt;&lt; std::endl; }
+
* The log port is created in the same way
# Click '''[OK]''' to get back to the Properties view
+
  
'''Note:''' the syntax to send a message on a port is &quot;'''().''''''('''''').send()'''&quot;. In the case above, no parameters were defined for the &quot;'''ping'''&quot; protocol message. There are other variants of the send command that allows, for example, to send a message to one slot of a replicated capsule part. The &quot;'''Send()'''&quot; operation returns the number of messages sent, so returning &quot;'''0'''&quot;, which is equivalent to &quot;'''false'''&quot;, indicates an error.
+
The result should be as shown below.
  
[[Image:Papyrus-rt-add-playing-state-entry-action.png]]
+
[[Image:PRT09-10CreatePongerCapsuleStructure.png]]
  
= Create the Ponger Capsule =
+
=== Add an attribute to Ponger ===
  
The &quot;'''Ponger'''&quot; capsule will be created in the same way as the &quot;'''Pinger'''&quot; capsule was in the previous step. So the instructions below should be familiar to you, even when abbreviated.
+
In order to limit the game (and not get a screenful of fast-streaming logs), we will add an attribute that will be used to limit the number of "pongs" that can be sent as a response to "pings", thereby allowing the game to end after a predetermined number of returns ("pongs").
  
== Create the Ponger capsule ==
+
# Select the Ponger capsule in the Model Explorer.
 +
# Click on the UML tab in the Properties view
 +
# Click on the [+] to the right of "Owned attribute" and select "Property."
 +
# In the resulting dialog, name the property "hitCount" and make its visibility "protected;"
 +
# set its type by clicking on the [...] next to "Type", expanding the "AnsiClibrary" entry and select "int;"
 +
# and set its default value to a Literal Integer "0" (zero) by clicking on the [+] next to "Default Value," selecting "Literal Integer," and accepting the default value of "0" (zero).
  
# Right-click on the PingPong model in the Model Explorer and select &quot;'''UMLRealTime &gt; Capsule'''&quot;
+
You can now see this attribute in the model explorer:
# Rick-click on the newly created capsule and select &quot;'''Rename'''&quot; to change its name to &quot;'''Ponger'''&quot;
+
  
[[Image:Papyrus-rt-create-ponger-capsule.png]]
+
<center>[[Image:PRT10CreatePongerAttribute.png]]</center>
  
== Open Ponger's Composite Structure Diagram ==
+
=== Create the Ponger Capsule's statemachine ===
  
# Expand &quot;Ponger&quot; in the model explorer and double-click on the &quot;Ponger&quot; composite structure diagram to open it in the editor view.
+
Create the '''Ponger''' capsule's statemachine using the same instructions as for the '''Pinger''' capsule structure, but with the following changes:
  
[[Image:Papyrus-rt-open-ponger-csd.png]]
+
* The intial transition code will simply log that '''Ponger''' is ready to play:
  
== Add a port to Ponger and set its type ==
+
<pre>log.log("Ponger is ready");</pre>
  
'''Ponger''' will need to communicate with '''Pinger''' when it receives the ball, that is, it will have to respond by sending the ball back. To do this, it needs a port that implements the &quot;'''PingPong'''&quot; protocol we defined earlier.
+
* The self-transition's trigger will be on '''PongPort''''s '''ping''' protocol message.
 +
* The self-transition's code will simply send a '''pong''' for every '''Ping''' received, until it "misses."
  
# In the Model Explorer, select the &quot;'''PingPong'''&quot; protocol and drag it to the left border of &quot;'''Ponger'''&quot; on the composite structure diagram.
+
<pre>
# In the resulting dialog, click on &quot;'''Protocol drop to create External Behavior Port'''&quot;
+
// Reply to a ping message by sending a pong.
 +
log.log("Ping received!");
 +
if (hitCount <=5){
 +
  if ( pongPort.pong().send() ){
 +
    log.log( "pong sent!");
 +
  } else {
 +
      log.log( "Error sending Pong!");
 +
  }
 +
} else { log.log( "Missed! Game over!");}
 +
      hitCount++;
 +
</pre>
  
[[Image:Papyrus-rt-add-port-to-ponger.png]]
+
The result should be as shown below.
  
== Rename the port and set its conjugation ==
+
[[Image:PRT10CreatePongerStateMachine.png|800px]]
  
In order to be able to communicate, connected ports must have opposite conjugation. Since we left the conjugation of the &quot;pinger&quot; port in &quot;Pinger&quot; to the default, we have to change this port to be conjugated.
+
== The "Top" system capsule ==
  
# Rename the port to &quot;ponger&quot;.
+
Although it is possible to generate the various capsules on their own, the interactions between them would not happen until their ports are connected.
# Click in the box to the left of &quot;Is conjugated&quot;
+
  
[[Image:Papyrus-rt-rename-ponger-port-and-set-conjugation.png]]
+
To do this, we create a "'''Top'''" capsule that will contain instances of both the Pinger and Ponger capsules so that we can connect their ports. Once this is done, we can generate the code for that "'''Top'''" capsule and execute it. Generating the code for "'''Top'''" will automatically bring in all the other related model elements.
 +
Note that, although it is not a requirement, the "'''Top'''" capsule we will create in here will be only structural, it will not, by itself, implement behaviour, other than that of its contained capsule parts.
  
== Add IO libraries ==
+
=== Create the "Top" capsule ===
  
Just like we did with &quot;Pinger&quot;, we will use the C++ standard &quot;cout&quot; to log messages, showing that the model is indeed executed.
+
# Create a new capsule in the model and name it "'''Top'''".
 +
# Open Top's capsule diagram.
 +
# From the model explorer, drag and drop a Pinger capsule into Top's compartment, on the left side.
 +
# From the model explorer, drag and drop a Ponger capsule into Top's compartment, on the right side. Aim to have their ports vertically aligned.
 +
# Use the Connector tool from the palette to draw a connector between each capsule part's ports.
 +
# That's it! You have created the Top capsule with two capsule parts that can now communicate with each other!
  
# Make sure that the &quot;'''Pinger'''&quot; capsule is selected and its Properties displayed with its &quot;Profile&quot; tab selected.
+
[[Image:PRT09-10CreateTopCapsule.png]]
# Click on the '''[+]''', right of &quot;'''Applied Stereotypes'''&quot;
+
# In the resulting dialog, double-lclick on the &quot;'''CapsuleProperties'''&quot; entry in the &quot;'''Applicable Stereotypes'''&quot; box to move it to the &quot;'''Applied Stereotypes'''&quot; and click '''[OK]''' to apply the stereotype. This stereotype allows the modeler to set C++ specific constructs to help in the development of the executable model.
+
# Expand the &quot;CapsuleProperties: stereotype to see its properties and select the &quot;implementationPreface&quot; property.
+
# In the &quot;Implementation box, type in the following: #include
+
  
That's all we need for now, we will see how to use this import during the creation of the the capsule's behavior.
+
== Execute the model ==
  
[[Image:Papyrus-rt-add-ponger-io-libraries.png]]
+
Now that the model is complete, we can execute it.
  
== Create Ponger's state machine ==
+
=== Top capsule ===
  
# Right-click on &quot;'''Ponger'''&quot; in the Model Explorer and select &quot;'''New Diagram &gt; StateMachine Diagram'''&quot;
+
In order to generate the code, we need to determine which capsule will be the"top" capsule, that is the capsule that will represent the system for the generated code. The code generator will recursively look at all the capsules that are used as part of this top capsule to generate the complete application. This is useful since each capsule can be executed on its own (e.g., for test purposes. This also allows for easy managements of "test harness" capsules for individual parts of the system. You can also set a default "Top" capsule that is reused by code generation commands.
# In the resulting dialog, name the state machine diagram &quot;'''Ponger'''&quot; and click '''[OK]'''
+
In this tutorial, we will simply generate the code for the selected capsule.
# Rename the state machine to &quot;'''Ponger'''&quot;
+
# Both the state machine and its diagram are now available
+
  
[[Image:Papyrus-rt-create-ponger-state-machine.png]]
+
=== Generate the model ===
  
== Set the state machine's stereotype and properties ==
+
# Right-click on the "'''Top'''" capsule in the Model Explorer to bring up the context menu
 +
# Select "'''Generate with this capsule as top'''"
  
'''Note''': The tooling does not yet set all the properties for a UML-RT state machine, so you will have to set them manually.
+
[[Image:PRT10GenerateAsTop.png]]
  
# Keeping the &quot;'''Ponger'''&quot; state machine selected in the Model Explorer, use the Profile tab of the Properties Explorer to add the &quot;'''RTStateMachine'''&quot; stereotype to the state machine.
+
===Alternative===
# Expand the &quot;'''Ponger'''&quot; state machine in the Model Explorer to show and select the contained &quot;'''Region1'''&quot; region and then add the &quot;'''RTRegion'''&quot; stereotype to it.
+
  
1.
+
If you will be generating the code often for a particular capsule, you can also designate a capsule as being the top capsule. You would then be able to just re-generate more easily.
  
[[Image:Papyrus-rt-set-ponger-state-machine-stereotype.png]]
+
=== Generated model code ===
  
== Create the state machine's content ==
+
When generating the code for the model, a CDT project is created to hold the code.
  
The &quot;Ponger&quot; state machine will greatly resemble the one that we created for &quot;'''Pinger'''&quot;. The main difference is that since &quot;'''Ponger'''&quot; will not be initiating the game, all its action can be defined as part of an &quot;'''onPing'''&quot; transition - there is no need to create an entry action in this case.
+
[[Image:PRT09-10GeneratedModel.png]]
  
Similarly to &quot;'''Pinger'''&quot;, the state machine for &quot;'''Ponger'''&quot; consists of a single state &quot;'''Playing'''&quot; with a self-transition triggered on receiving the &quot;'''ping'''&quot; message on the &quot;'''ponger'''&quot; port.
+
=== Compile the model ===
  
However, &quot;'''Ponger'''&quot; will not be initiating the game, so its action can be defined entirely as part of an &quot;'''onPing'''&quot; transition - there is no need to create an entry action in this case.
+
To compile and run the model, you will need a compatible build environment. At present, we support Linux as the primary target platform with more limited support for Windows and MacOS.
  
# Using the Palette's &quot;'''Nodes'''&quot; drawer, add an &quot;'''Initial'''&quot; pseudostate to the top left of the capsule's state machine and apply the &quot;'''RTPseudostate'''&quot; stereotype to it. You can leave its name as is or change it as you please.
+
{{Note|Use of command line| The integration with CDT is not yet complete. To build the system, you will have to go to the command line or, if you are familiar with setting project within the CDT, you can give try to configure the project yourself.}}
# Using the Palette's &quot;'''Nodes'''&quot; drawer, add a &quot;'''State'''&quot; below and to the right of the &quot;'''Initial&quot;''' pseudostate, name it &quot;'''Playing'''&quot;, and apply the &quot;'''RTState'''&quot; stereotype to it.
+
# Using the Palette's &quot;Edges&quot; drawer, draw a &quot;'''Transition'''&quot; from &quot;'''Initial'''&quot; to &quot;'''Playing'''&quot; named &quot;'''initial'''&quot;, and another from &quot;'''Playing'''&quot; to itself named &quot;'''onPing'''&quot;.
+
  
'''Note 1:''' The start and end are very important when drawing a transition and it defines the direction, the first click being the origin and the second the destination.''* Note 2:''* It is a good idea to name transitions as this helps in understanding the diagram and, also, in debugging later on - here, we have used a short form of the trigger event. '''Note 3:''' Setting the transition to be &quot;rectilinear&quot; is useful when drawing state machines: right-click on a transition and select &quot;Format &gt; Line Style &gt; Rectilinear Style Routing.
+
{{Note|Using an OS other than Linux| If you are using an operating system other than Linux, you can still compile and run your model. Go to [[Papyrus-RT/User_Guide/Compiling_and_running_Papyrus_for_Real_Time_applications | Compiling and running Papyrus for Real Time applications]] for alternatives}}
  
[[Image:Papyrus-rt-create-ponger-state-machine-s-content.png]]
+
# Open a terminal and go to the folder where the code was generated, in this case, the folder name would be '''''<workspace>''/PingPong_CDTProject/src''', replacing "''<workspace>''" with the path to your workspace location, e.g., "~/workspaces/GettingStarted".
 +
# Type "make" at the command prompt to compile and link the model's generated code.
  
== Add "onPing:" transition trigger to the state machine ==
+
[[Image:PRT10CompileModel.png]]
  
As indicated previously, the &quot;'''Initial'''&quot; transition does not need a trigger as it is taken automatically when the state machine is first instantiated. However, for the &quot;'''onPing'''&quot; transition to be taken, we will need to define a trigger for the transition that will determine when the transition can be taken.
+
=== Run the model's executable ===
  
# Select the &quot;'''onPing'''&quot; transition. In the Properties view's UML Tab, click on the '''[+]''' to the right of the &quot;'''Trigger'''&quot; field to create a new Trigger.
+
You can then run the executable to see the log showing the (short) game!
# In the resulting &quot;'''Create a new Trigger'''&quot; dialog, set the name to &quot;'''onPing'''&quot;.
+
# Click on the '''[+]''' to the right of the &quot;'''Port'''&quot;
+
# On the resulting dialog, find the &quot;'''ponger'''&quot; port under the &quot;'''Ponger'''&quot; capsule, double-click on it to transfer it to the right box
+
# Click '''[OK]''', closing the dialog and bringing back the &quot;'''Create a new Trigger'''&quot; dialog
+
# Click on the '''[...]''' to the right of &quot;'''Protocol message'''&quot; to bring up the &quot;'''Protocol Message'''&quot; dialog
+
# Select the &quot;'''ping'''&quot; protocol message.
+
# Click on '''[OK]''', closing the dialog and bringing back the &quot;'''Create a new Trigger'''&quot; dialog and then '''[OK]''' again to close that dialog
+
# The trigger is now complete and the results are shown below.
+
  
[[Image:Papyrus-rt-add-onping-transition-trigger.png]]
+
# At the command prompt, type "'''./TopMain'''"
 +
# Observe the results:
  
== Add an effect to the "onPing" transition to log it was taken. ==
+
[[Image:PRT10RunModelExecutable.png]]
  
So that we can be sure that the &quot;'''onPing'''&quot; is indeed taken, let's add an effect to log this.
+
== Congratulations! ==
  
# Select the &quot;'''OnPing'''&quot; transition. In the Properties view's UML Tab, click on the '''[+]''' to the right of the &quot;'''Effect'''&quot; field to create a new action and select &quot;'''Opaque behavior'''&quot;.
+
[[Image:Papyrus-rt-congratulations.png]]
# In the resulting dialog, set the name to &quot;logTransition&quot;.
+
# Click on the '''[+]''' to the right of &quot;'''Language'''&quot; to bring up the language selection dialog
+
# Double-click on &quot;'''C++'''&quot; from the selection dialog to move it to the selected item box. We are using C++ as the coding language within the tool to match our C++ runtime service library
+
# Click '''[OK]'''
+
# In the blank box to the right of the language selection, type the following code:
+
  
if ( ponger.pong().send() ) { std::cout &lt;&lt; &quot;Pong sent!&quot; &lt;&lt; std::endl; } else { std::cout &lt;&lt; &quot;Error sending Ping!&quot; &lt;&lt; std::endl; }
+
= Other Tutorial versions =
  
This will send back a pong message to &quot;Pinger&quot; and display a message indicating whether the send was successful or not. This enables us to see when the transition is taken when running the resulting executable. 1. Click '''[OK]'''. 1. The transition now contains an effect that will be executed each time the transition is taken and the results are shown below.
+
* [[Papyrus-RT/User/User Guide/Getting Started/v0.9 | Getting Started with Papyrus for Real Time version 0.9]]
 
+
* [[Papyrus-RT/User/User Guide/Getting Started/v0.7-8 | Getting Started with Papyrus for Real Time versions 0.7 and 0.8]]
[[Image:Papyrus-rt-add-onping-transition-effect.png]]
+
 
+
= Implement the System as the Top Capsule =
+
 
+
As described previously, the top capsule represents the system to be built. As such, it will not be contained in any other capsule and will contain the capsules required to implement its capabilities.
+
 
+
In the context of this tutorial, our Top capsule will contain instances of both &quot;'''Pinger'''&quot; and &quot;'''Ponger'''&quot; as well as the connection between them.
+
 
+
<code>'''Note''': At present, the top capsule '''''must''''' '''be named &quot;Top&quot;. This is a limitation until we complete the implementation of the build specification mechanism.'''</code>
+
 
+
== Create the Top capsule ==
+
 
+
Using the steps from the creation of the &quot;'''Pinger'''&quot; capsule, create the &quot;'''Top'''&quot; capsule and its composite structure diagram, but stop before the creation of the port as &quot;'''Top'''&quot; does not require any ports.
+
 
+
# Right-click on the PingPong model in the Model Explorer and select &quot;'''UMLRealTime &gt; Capsule'''&quot;
+
# Rick-click on the newly created capsule and select &quot;'''Rename'''&quot; to change its name to &quot;'''Top'''&quot;
+
# Open the composite structure diagram for &quot;'''Top'''&quot;
+
 
+
[[Image:Papyrus-rt-create-top-capsule.png]]
+
 
+
== Add Pinger to the Top Capsule Structure ==
+
 
+
We can now start populating the &quot;'''Top'''&quot; capsule by creating an instance of &quot;'''Pinger'''&quot; within its structure.
+
 
+
# Drag and drop &quot;'''Pinger'''&quot; from the Model Explorer inside of &quot;'''Top'''&quot;'s structure, on the left side.
+
# In the resulting dialog, click on &quot;'''Capsule drop to create CapsulePart'''&quot;.
+
# You will see that the &quot;instance&quot; is called &quot;'''pinger'''&quot;.
+
# Expanding &quot;'''Top'''&quot; in the Model Explorer reveals the new &quot;'''«CapsulePart» piner:Pinger'''&quot; property added to the capsule.
+
 
+
'''Fun fact''': <code>&quot;pinger&quot; is not an instance, but a &quot;part&quot;. In this case the part contains a single instance of &quot;Pinger&quot;. However, a part can have a multiplicity, and therefore contain multiple instances (or not if it's multiplicity has a lower bound of 0).</code>
+
 
+
[[Image:Papyrus-rt-add-pinger-to-top-capsule.png]]
+
 
+
== Adjust the representation of the pinger capsule part ==
+
 
+
'''Workaround''': The tooling does not yet automatically show the ports of capsule parts, so you will have to do that manually.
+
 
+
# In the Model Explorer, select the the &quot;pinger&quot; port under the &quot;Pinger&quot; capsule and drop it onto the &quot;pinger&quot; capsule part in Top.
+
# Move the port so it will be on the right side of the &quot;pinger&quot; capsule part.
+
 
+
[[Image:Papyrus-rt-adjust-pinger-capsule-part-representation.png]]
+
 
+
== Add Ponger to the Top capsule ==
+
 
+
# Repeat the steps you used to add &quot;'''Pinger'''&quot; to the &quot;'''Top'''&quot; capsule, but this time using the &quot;'''Ponger'''&quot; capsule.
+
 
+
[[Image:Papyrus-rt-add-ponger-to-top-capsule.png]]
+
 
+
== Connect the two capsule parts ==
+
 
+
# Select the &quot;'''Connector'''&quot; tool from the '''Palette'''
+
# Draw a connector from one port to the other (it does not matter from which port you start).
+
 
+
[[Image:Papyrus-rt-connect-the-two-capsule-parts.png]]
+
 
+
= Execute the model =
+
 
+
Now that the model is complete, we can execute it.
+
 
+
== Generate the code ==
+
 
+
Now that the model is complete, let's generate the code.
+
 
+
# Right-click on the model in the Model Explorer and select &quot;'''UML-RT Code Generator'''&quot;
+
# Click [OK] on the dialog that shows the results
+
# A CDT project is created and the C++ code is generated within it.
+
 
+
[[Image:Papyrus-rt-generate-the-code.png]]
+
== Setup the Build environment ==
+
 
+
In order to be able to compile and link the generated code, the build environment must be set up. The first requirement is regarding the compiler version supported out of the box by the RTS. Within Papyrus for Real Time v0.7.0, the RTS library was pre-built using g++ 4.7.2 (even though the configuration says 4.6.3...), so it is recommended to have that version installed as the default.
+
 
+
If you do not have g++ 4.7.2 installed and do not wish to install it, you can follow the instructions at [[Papyrus-RT/User_Guide/Building_the_RTS | Building the RTS]]
+
 
+
==  Compile the model ==
+
 
+
To compile and run the model, you will need a compatible build environment. At present, we support Linux.
+
 
+
The integration with CDT is not yet complete. To build the system, you will have to go to the command line.
+
 
+
# Open a terminal and go to the folder where the code was generated, in this case, the folder name would be '''/PingPong_CDTProject/src''', replacing &quot;&quot; with the path to your workspace location, e.g., &quot;~/workspaces/GettingStarted&quot;.
+
# If there is no &quot;'''umlrt.rts'''&quot; folder in that location, you will need to create a link using ln -s /plugins/org.eclipse.papyrusrt.rts_/umlrts ./umlrts.rt where:  is the path to the folder where Eclipse is installed, e.g. &quot;~/Apps/Eclipse&quot;  is the latest version of the plugin, e.g., &quot;0.5.0.201506181214&quot;
+
# Type &quot;make&quot; at the command prompt to compile and link the model's generated code.
+
 
+
[[Image:Papyrus-rt-compile-the-model.png]]
+
 
+
==  Run the model's executable ==
+
 
+
You can then run the executable, making sure to kill it soon after it starts, else it'll run forever...
+
 
+
# At the command prompt, type &quot;'''./main'''&quot;
+
# Quickly type &quot;Ctrl-c&quot; to kill the execution
+
 
+
[[Image:Papyrus-rt-run-the-model-executable.png]]
+
 
+
= Congratulations! =
+
 
+
[[Image:Papyrus-rt-congratulations.png]]
+

Latest revision as of 10:15, 22 September 2017

PapyrusForRealTime-Logo-Icon.png


Getting Started with Papyrus for Real Time v1.0


Introduction

This tutorial will show the creation of a simple model using Papyrus for Real Time version 1.0 (based on Eclipse Oxygen).

Warning2.png
Installation
As a precondition to going through this tutorial, you must have Papyrus for Real Time installed. Please see the Papyrus-RT User installation page for information on installing Papyrus for Real Time. — We recommend using the RCP installation as it is the easiest way to get started.


Note.png
Linux
The instructions in this tutorial are illustrated using Linux. Steps and images may differ slightly if the installation is done on a different operating system (both Windows and Mac OS are supported for developing models). Some of these differences have been indicated when known and some may be missing.


Note.png
PDF Version
A PDF version of this tutorial is also available.


This exercise will show the creation of a project and model and how UML-RT concepts can be used to easily create the application's structure and behavior.

At its base, a UML-RT model consists of capsules (UML active classes with composite structure) that communicate through ports defined by protocols (collaboration specifications) These protocols specify the messages (signals) that can be exchanged between capsules, as well as their payloads. Hierarchical state machines are used to represent the behavior of capsules, where transitions between states are triggered by messages received on the capsule's ports.

If you are not familiar with UML-RT and want to know a bit more, you should take a look at the initial Papyrus-RT Overview page. Note that this page reflects an early version of Papyrus-RT and visual elements shown on that page may not completely match those of this tutorial. The concepts, however, ar the same).

The model that will be created as part of this tutorial is a simple "PingPong" model. In this model, implemented using UML-RT, two players will be playing a limited game of ping pong.

It is a very simple model that will show how a UML-RT model is constructed. Players will each be portrayed using a UML-RT capsule and a common UML-RT protocol will be used to define how the ball is exchanged between players through ports on each player capsule.

Note.png
Use of Papyrus-RT
For brevity, "Papyrus-RT," the short form of "Papyrus for Real time," will be used throughout this document.


Starting Papyrus-RT

Start Papyrus for Real Time. This is typically done by double-clicking on its executable (on some platforms, the executable may be found under the "*papyrusrt*" folder).

As it starts, the launcher will display the Papyrus for Real Time splash screen.

PRT10Splash.png

Creating a workspace

Workspaces are Eclipse's way of creating development environments for various tasks. You can use workspace for different projects, different aspects of a project, or different tasks.

After the launch splash screen is dismissed, you will be asked to specify a workspace.

  1. You can opt for the provided default location or substitute your own.
  2. Click on [Launch] to continue.

PRT10CreateWorkspace.png

The workspace

After starting Papyrus-RT and dismissing the welcome screen, you are presented with the actual Papyrus-RT workspace

GSwPRT10WorkspaceDesc.png

Create a Papyrus for Real Time Project containing a UML-RT model

Papyrus for Real Time is a Domain-Specific Modeling Language (DSML) tool based on Papyrus. We will use the Papyrus Project creation wizard to create a project configured for Papyrus for Real Time.

Select File -> New -> Papyrus Project

RT10NewPapyrusProject.png

Select the architecture context for the model

The architecture context defines the type of model you will be using to build you application. Papyrus can support various architecture model and provides extension points to add more if needed.

In the displayed dialog:

  1. Select the UML-RT architecture context
  2. Notice that the by clicking on UML-RT, both the architecture context and the viewpoints change to the ones required for UML-RT modeling.
  3. Click on [Next].

You will notice that there are two "UML-RT Modeling" viewpoints. The difference between the two is in the amount of information displayed to the user, e.g., in the model explorer. Users who intend to only use Papyrus-RT for UML-RT would typically only need to use the "Basic" variant. Users who would like to mix in other diagrams, such as class diagrams, as well as "toolsmiths" and some "super-users" could benefit from the added information and capabilities from the Advanced UML-RT viewpoint. In the context of this tutorial, we will stay with the Basic UML-RT Modeling Viewpoint.

PRT10RT10ArchitectureContext.png

Define the project

You can now define the project's name and its location, as well as the name of the model file that will be created.

  1. Enter the name for the project. 1. This project can hold multiple artefacts and will contain a Papyrus model by default. For this tutorial, we will use the name "PingPong."
  2. As you type the name of the project, you will note that the model file name is filled with the same information. It is common to to use the same name for both. If you do need to have a different name for the model file, you can change it from the "Model file name" entry field.
  3. By default, the project will be created in the current workspace. You can, however, select an alternative location if, for example, you wish to store your project under source control.
  4. Click on [Next]

PRT10DefineProject.png

Provide model initialization information

There is more information that can be provided to create a useful model.

  1. The "Root model element" is a representation of the model itself. For this tutorial, and for consistency, we will name it "PingPong."
  2. Typically, for UML-RT modeling, we would not start from a diagram. In addition, the two basic diagrams for UML-RT will be created automatically as part of the modeling workflow. As such, we will not select any "Representation Kind."
  3. The wizard let's you select a template of the model you are creating, select "UML-RT for C++."
  4. We will also not select to apply any profile. The project/model creation wizard automatically applies those that are required to create a Papyrus-RT model. This part of the dialog could be used to add other profiles that deployed in your environment or that are provided by other add-ons.
  5. Click on [Finish] to create the model.

PRT10ModelInit.png

Note that there are three templates that you can select in the v1.0 version of Papyrus-RT:

  1. UML-RT for structural modelling: only provides support for capsule, ports, and protocol. Capsule state machines cannot be created when this template is used.
  2. UML-RT basic: provides all UML-RT capabilities, including the creation of capsule state machines to express the behaviour of capsules. However, no target language is set for code generation.
  3. UML-RT for C++: provides all the capabilities to create UML-RT models that can generate C++ code. This includes the the UML-RT RTS and C++ primitive types libraries.

Note that these templates build on top of each other, so even if you select one of the first two template, you can still add the profiles and libraries to get to the "UML-RT for C++" configuration later, once you are in the tool.

Project and Model Created

You now have an empty model ready to be populated!

PRT10ProjectModelCreated.png

Our project: PingPong

For this tutorial, we will be creating a simple model of a ping pong game, with two players.

The system will consist of two capsules ("active classes) that will communicate to show whose turn it is to hit the ball. Because the system is run by computer, no errors will be made playing so the game could go on forever... To prevent this, we will add a check to ensure that the game only runs for a pre-determined number of exchanges.

So let's get started!

Create a protocol

Let's start by determining how the PingPong ball will go from one player to the other. To do this, we can think of the ping pong ball as a message to the other player to which they need to reply (hit the ball back). In UML-RT, the structure that governs the messages that can be exchanged between entities (players in this case) is a protocol. Protocols contain protocol messages that define how messages can be sent and received between model elements (called "Capsules" in UML-RT - more on that later). These protocol messages can be incoming, outgoing, or symmetrical (i.e., both ingoing and outgoing). In the case of protocols that are not purely symmetric, i.e., that have either or both incoming and outgoing messages, there is also a need for the concept of conjugation, i.e., of reversing the role of the protocol, a concept that will be addressed further when used later in this tutorial. In the case of this Getting Started tutorial, we could create a symmetric protocol where there would be a single symmetrical protocol message called, for example, "ball". However, to better explore the concept of protocols, we will define our "PingPong" protocol to have one outgoing protocol message called "ping" and one incoming protocol message called "pong".

Protocol Creation

The first step is to create the protocol itself.

  1. Right-click on the "PingPong" model in the Model Explorer and select "New UML-RT Child > Protocol"
  2. The name of the protocol is highlighted, name the protocol "PingPongProtocol" and hit return.
  3. You can also see the protocol and its messages in the Properties view. As the protocol was just created, it does not yet contain any protocol messages.

You now have a "protocol" in the Model Explorer.

PRT10CreateProtocol.png

Add protocol messages to the protocol

As mentioned previously, a protocol may contain many different "protocol messages" that specify "operations" and their associated data.

Our protocol will "ping" its opponent and, in return, will respond to a "pong" sent to it. This tells us that there will be a "ping" outgoing protocol message and a "pong" incoming protocol message.

Idea.png
Protocol perspective
Protocols should be defined from the client's perspective. In practice, this means that the provider of the service defined by the protocol will have their ports conjugated and the client's ports will by un-conjugated. This makes sense as there will typically be more clients than service providers, so adopting this best practice will reduce the number of ports that need to be conjugated.


In the case of this model, it does not matter as there is no distinct service provider or client. After all, in a game of ping pong, both sides "serve"! For this tutorial, we will consider that the player that starts the game will be sending the "ping" and will therefore be the "server" / "Service Provider."

  1. Right-click on the protocol
  2. Select to create a "New UML-RT Child > InProtocolMessage".
  3. The protocol message is created and its name is ready to be edited in the model explorer in the model explorer .
  4. Rename the protocol message to "ping" (remember, as the server, the port will be conjugated, so it will have to be the opposite of the action we expect, so incoming).

PRT10ProtocolMsgs2Prot.png

Add the "pong" Protocol Message

To create the "pong" message, use the same process as for the creation of the "ping" protocol message, above, except that you will instead create a "ProtocolMessageOut" and name the protocol message "pong"

  1. Right-click on the PingPong protocol and select "New UML-RT Child > OutProtocolMessage"
  2. Rename the resulting protocol message to "pong"
  3. You now have a "pong" protocol message in addition to "ping".

PRT10AddPongPMsg.png

The "PingPong" protocol is now available

The protocol and its protocol messages can now be seen in both the Model Explorer and the Properties view and is available for modeling.

PRT10WholeProtocolAvailable.png

Defining the Tutorial's "PingPong" System's Structure

Now that we have a protocol, we can move on to creating the structure of the "PingPong System."

We will need to create three capsules for this tutorial model:

  • Two capsules that will be representing the two players: "Pinger" ("player 1") and "Ponger ("player 2")
We will be creating two capsules to highlight some aspects of the communication mechanisms, especially related to how ports are used with asymmetric protocols. If we had a symmetric protocol, we could simply use two instances of the same capsule, but that would be a less interesting model for a tutorial. Also note that, in this example, the two capsules will be slightly different as one has the added responsibility to start the game
  • A top capsule representing the complete system ("Top")
In UML-RT, the building blocks are capsules and there is always a top capsule that represents the system to be built. The complete set of capsules that are required to implement the system's functionality are then included by the containment hierarchy from this top capsule.

Create the Pinger capsule

This capsule will represent the starting player in the game. As such, it will be responsible for sending the first "ball" (message). It will also have to react when receiving the ball from the other player.

Create the Pinger ("player 1") capsule

Let's start by creating the Pinger capsule.

  1. Right-click on the PingPong model in the Model Explorer and select "New UML-RT Child > Capsule"
  2. After the capsule is created, it's name is selected for edition, name it "Pinger"

PRT09-10-CreatePingerCapsule.png

Look at the Pinger capsule and open it's diagram

Now that we have a capsule, let's have a look at what it contains and at its diagram.

  • Expand the Pinger capsule in the model explorer by clicking on the triangle at the beginning of its Model Explorer entry. You will notice that there is already a contained element: Pinger's diagram link. In Papyrus-RT, every capsule has a capsule diagram, this link is a quick way to open it
  • That diagram link is also accessible from the "Editor" under the View heading.

PRT09-10PingerCapsuleDiagram.png

One open, you will see:

  1. The representation of the Pinger capsule. It does not contain much right now, but we will work on that in this tutorial.
  2. A editor tab is added at the bottom of the editor. This is useful when you have multiple diagram open so you can easily navigate between them
  3. A tool palette providing you with the various tools that are relevant when working on a diagram in the context of the capsule's structure (in this case).

Add an external port to Pinger

In order to be able to communicate, Pinger will need an external port through which it can send messages to other capsules. Let's add this port now.

  1. Click on "Port" in the tool palette.
  2. Click on the right border of the Pinger capsule.
  3. In the resulting dialog, select "Port with Existing Protocol"
  4. In the resulting dialog, expand the "PingPong" model entry and select the "PingPong" protocol that was created earlier.
  5. Name the resulting port "pingPort". This can be done by using the direct editor available on the port name.
  6. Since we have decided that Ping would be the "server" capsule, we also have to change the conjugation of its port. To do so, look in the Properties view just below the Editor, and make sure that the "UML-RT" tab is selected
  7. Click on the box to the left of "Is conjugated".
  8. When the port is conjugated, you will notice that its graphical element will change from being all black to getting a white fill, graphically showing the conjugation state.
Note.png
Context menu
A quicker way to change the conjugation of a port is to right-click on the port and select UML-RT Properties > Is Conjugated


PRT10add-an-external-port-to-pinger.png.png

Add a log port

In order to make sure that the model actually runs correctly, we will need to display some information to the user. The Papyrus-RT runtime provides a logging service that allows models to print out information to the standard output (e.g., the screen). In the current version, it only does this to stdout, but this capability is extensible to use other output targets.

So all that is needed to be able to log event to the screen is to add a log port to the capsule.

  1. Select the Port tool and create a port in the middle of the capsule
  2. In the resulting dialog, select the "Log" entry
  3. Leave the name as is. You have now create a log port through which you can print messages. We will see how to use it when we add the behaviour to the capsule.

PRT009-10AddLogPort.png

Create Pinger's state machine

As mentioned, the behaviour of a capsule is represented by a state machine, but one is not provided by default as some capsules may not need to have behaviour.Examples of capsules not needing behaviour are for container capsules, such as "Top", and some patterns, such as dynamic forwarding.

  1. Right-click on the Pinger capsule in the Model Explorer and select "New UML-RT Child > StateMachine" to create the state machine.
  2. The state machine is created and its diagram is available from the Editor's View list (click on the Welcome tab at the bottom of the editor area to display the information view).

PRT09-10CreatePingerStateMachine.png

Add the Pinger StateMachine behaviour

  1. Now that we have a state machine, let's add the behaviour to it: open the Pinger::StateMachine. You will notice that we already provide you with the initial pseudostate and a state ("State1") to get you started
  2. Move these two initial elements to better positions, as shown and rename "State1" to "Playing" (hint: use the Properties tab or slowly click twice on the state's border)
  3. We will also add a transition that will be taken when the other player returns the ball. Using the transition tool draw a transition from the "Playing" state to itself.

PRT10-addPingerSMBehaviour.png

Add initial transition action

All that is now left is to add some triggers (which allow for transitions to be taken when a message is received) and code blocks (remember, we are using C++ as the "Action Language".

Let's start with the Initial Transition. Note that the initial transition is always taken once, when the capsule is instantiated, so it does not need an trigger.

  1. Click on the Initial transition and then open the Code Snippet View" in the Properties View area. Make sure that the "Effect" tab is selected at the bottom of the view. (hint: As mentioned in a previous tip, you may want to move the code snippet view to the right of the properties view, especially if you have a large monitor)
  2. In the code snippet view, add the following code:
// Start the game by sending a "ping" to the other player
log.log("Starting game");
if ( pingPort.ping().send() ) {
    log.log( "ping sent!");
} else {
    log.log( "Error sending Ping!");
}

PRT10AddInitTransitionAction.png

Edit the trigger and code for self transition

  1. Select the transition in the diagram and switch to the Properties view.

PRT09-10EditSelfTransitionTriggerAndCode.png

Add the transition trigger

  1. Click on the [+] button in the Trigger section to create a new trigger.
  2. From the resulting dialog, select the pingPort.
  3. From the list of protocol messages, select the pong protocol message.
  4. Click OK to set the trigger.
  5. You now have a trigger defined for this transition. When the model runs, any message received while in the Playing state will result in this transition being taken.
  6. Notice that the transition name has be set to the name of the protocol message selected, providing a clue on the diagram as to when the transition is triggered.

PRT09-10AddTransitionTrigger.png

Add the code for the transition

The only thing left to do for this transition is to add its code. The basic steps are the same as those taken previously to add the code for the initial transition

  1. Click on the transition and the Code Snippet View to bring up the C++ editor for the transition. Make sure that the "Effect" tab is selected at the bottom of the view.
  2. Type in the following code (you will notice that it is very similar to that of the initial transition):
// Reply to a pong message by sending a ping.
log.log("Pong received!");
if ( pingPort.ping().send() ) {
    log.log( "ping sent!");
} else {
    log.log( "Error sending Ping!");
}

PRT09-10AddTransitionCode.png

You are now done with the creation of the Pinger capsule!

Create the "Ponger" capsule

To create the "Ponger" capsule, simply follow the same steps as when Pinger was created, with the following differnces:

  • The capsule will be named "Ponger" instead of "Pinger"
  • The port is named "pong" and is not conjugated.
  • You should place the port on the left edge of the capsule, instead of the right. This will allow us to put both capsules side by side so that their ports will be easy to connect.
  • We also need to restrict the game so it will not run forever. To do so, we will add an attribute count the number of ball hits. We will use this attribute to stop the match after 5 exchanges.
    1. Right-click on Ponger in the model explorer and select "New UML-RT Child > Attribute"
    2. Name the attribute "hitCount" and set its type to "unsigned int" from the "AnsiCLibrary"
  • The capsule's state machine will be different as it does not need to start the game and it will not return the fifth ball in order to stop the game.

Create the "Ponger" capsule's structure

Create the Ponger capsule's structure using the same instructions as for the Pinger capsule structure, but with the following changes:

  • The capsule is named "Ponger"
  • The external port is placed on the left edge of the capsule, instead of the right. This will make it easier for us to connect the capsules when we put both side by side.
  • The external port is named "pongPort"
  • The external port is not conjugated.
  • The log port is created in the same way

The result should be as shown below.

PRT09-10CreatePongerCapsuleStructure.png

Add an attribute to Ponger

In order to limit the game (and not get a screenful of fast-streaming logs), we will add an attribute that will be used to limit the number of "pongs" that can be sent as a response to "pings", thereby allowing the game to end after a predetermined number of returns ("pongs").

  1. Select the Ponger capsule in the Model Explorer.
  2. Click on the UML tab in the Properties view
  3. Click on the [+] to the right of "Owned attribute" and select "Property."
  4. In the resulting dialog, name the property "hitCount" and make its visibility "protected;"
  5. set its type by clicking on the [...] next to "Type", expanding the "AnsiClibrary" entry and select "int;"
  6. and set its default value to a Literal Integer "0" (zero) by clicking on the [+] next to "Default Value," selecting "Literal Integer," and accepting the default value of "0" (zero).

You can now see this attribute in the model explorer:

PRT10CreatePongerAttribute.png

Create the Ponger Capsule's statemachine

Create the Ponger capsule's statemachine using the same instructions as for the Pinger capsule structure, but with the following changes:

  • The intial transition code will simply log that Ponger is ready to play:
log.log("Ponger is ready");
  • The self-transition's trigger will be on PongPort's ping protocol message.
  • The self-transition's code will simply send a pong for every Ping received, until it "misses."
// Reply to a ping message by sending a pong.
log.log("Ping received!");
if (hitCount <=5){
  if ( pongPort.pong().send() ){
    log.log( "pong sent!");
  } else {
      log.log( "Error sending Pong!");
  }
} else { log.log( "Missed! Game over!");}
  	  	  hitCount++;

The result should be as shown below.

PRT10CreatePongerStateMachine.png

The "Top" system capsule

Although it is possible to generate the various capsules on their own, the interactions between them would not happen until their ports are connected.

To do this, we create a "Top" capsule that will contain instances of both the Pinger and Ponger capsules so that we can connect their ports. Once this is done, we can generate the code for that "Top" capsule and execute it. Generating the code for "Top" will automatically bring in all the other related model elements. Note that, although it is not a requirement, the "Top" capsule we will create in here will be only structural, it will not, by itself, implement behaviour, other than that of its contained capsule parts.

Create the "Top" capsule

  1. Create a new capsule in the model and name it "Top".
  2. Open Top's capsule diagram.
  3. From the model explorer, drag and drop a Pinger capsule into Top's compartment, on the left side.
  4. From the model explorer, drag and drop a Ponger capsule into Top's compartment, on the right side. Aim to have their ports vertically aligned.
  5. Use the Connector tool from the palette to draw a connector between each capsule part's ports.
  6. That's it! You have created the Top capsule with two capsule parts that can now communicate with each other!

PRT09-10CreateTopCapsule.png

Execute the model

Now that the model is complete, we can execute it.

Top capsule

In order to generate the code, we need to determine which capsule will be the"top" capsule, that is the capsule that will represent the system for the generated code. The code generator will recursively look at all the capsules that are used as part of this top capsule to generate the complete application. This is useful since each capsule can be executed on its own (e.g., for test purposes. This also allows for easy managements of "test harness" capsules for individual parts of the system. You can also set a default "Top" capsule that is reused by code generation commands. In this tutorial, we will simply generate the code for the selected capsule.

Generate the model

  1. Right-click on the "Top" capsule in the Model Explorer to bring up the context menu
  2. Select "Generate with this capsule as top"

PRT10GenerateAsTop.png

Alternative

If you will be generating the code often for a particular capsule, you can also designate a capsule as being the top capsule. You would then be able to just re-generate more easily.

Generated model code

When generating the code for the model, a CDT project is created to hold the code.

PRT09-10GeneratedModel.png

Compile the model

To compile and run the model, you will need a compatible build environment. At present, we support Linux as the primary target platform with more limited support for Windows and MacOS.

Note.png
Use of command line
The integration with CDT is not yet complete. To build the system, you will have to go to the command line or, if you are familiar with setting project within the CDT, you can give try to configure the project yourself.


Note.png
Using an OS other than Linux
If you are using an operating system other than Linux, you can still compile and run your model. Go to Compiling and running Papyrus for Real Time applications for alternatives


  1. Open a terminal and go to the folder where the code was generated, in this case, the folder name would be <workspace>/PingPong_CDTProject/src, replacing "<workspace>" with the path to your workspace location, e.g., "~/workspaces/GettingStarted".
  2. Type "make" at the command prompt to compile and link the model's generated code.

PRT10CompileModel.png

Run the model's executable

You can then run the executable to see the log showing the (short) game!

  1. At the command prompt, type "./TopMain"
  2. Observe the results:

PRT10RunModelExecutable.png

Congratulations!

Papyrus-rt-congratulations.png

Other Tutorial versions

Back to the top