跳到主要内容

Start to use Sim4Sys with a simple model (whitebox)

PRESENTATION

This tutorial is based on the previous tutorial: Start to use Sim4Sys with a simple model (blackbox).

Retrieve the model of the previous tutorial (File > New > Example > Sim4Sys Examples > Sim4Sys – Quick Start > Tutorial 1) or continue your own model.

In this tutorial, we will be implementing the function part of the previous tutorial. The function part allows you to split the behavior of a service in more precise functions. Here we will be introducing one way of implementing it, however, keep in mind that it is not the only way.

Prerequisites

Have done the previous tutorial.

News skills that you will acquire

On Designer:

  • Import an existing model,
  • Create Functions (whitebox level),
  • Complete a User Story at the functional level,
  • Add Function Life Lines,
  • Reuse a Service Level Interface,
  • Use the Overview and the Assistant tabs,
  • Move from a service level to a function level (and vice versa),
  • Deal with two States or more in a State Machine.

Duration

2h

CREATE NEEDED FUNCTIONS

  • Switch to the Function tab in the Overview
“Function” tab
  • Double Click on the structure diagram Speed_ManagementWB of the service to open it.
备注

WB stands for "White Box", we will explain our service through functions, as opposite to BB, which stands for "Black Box", where all the logic is simplified as it was hidden.

Speed_ManagementWB Speed_ManagementWB Diagram
  • Drag&Drop a New Function on the diagram
New Function
  • Type the name of the new function: Request_a_dynamic_change
  • Repeat the operation to create four other functions: Accelerate, Brake, Inform_of_car_speed, Acquire_car_speed.
Speed_ManagementWB Diagram

User story "The driver accelerates_Analysed"

  • Double Click on the user story The driver accelerates_Analysed in the Overview (Speed_Management > Standard Use > Accelerate) to open the corresponding sequence diagram
The driver accelerates_Analysed

The driver accelerates_Analysed Sequence Diagram
  • Drag&Drop a New Lifeline on the diagram
  • Select Request_a_dynamic_change and Accelerate (by maintaining Ctrl).
  • Click on Ok
  • Arrange the diagram as follow by Dragging the lifelines
The driver accelerates_Analysed Sequence Diagram with lifelines
  • Drag&Drop a New State on each function lifeline and rename them as follow
The driver accelerates_Analysed Sequence Diagram with states
  • Before anything, open the assistant tab (bottom-left corner), as shown:
Assistant tab

备注

The assistant tab is here to help you. Elements will automatically appear in this tab because you will probably need access to it. In our case, we will need to duplicate an existing interface from one function to another. To help you, the assistant will automatically keep a reference to this interface so you can use it easily.

  • Drag&Drop a New Message between the user and the function Request_a_dynamic_change
Flow Selection
  • Select the_driver_requests_to_accelerate

  • Click on Ok

  • Read the dialog and the instructions (Be sure the Assistant View is open)

Provided Interfaces Pop-up

You can drag & drop a reference of an already existing interface, from the assistant tab.

Drag and Drop interface

Here, the Assistant tab should display I_the_driver_requests_to_accelerate, an interface that you should use here.

  • Drag&Drop the interface in the Class Diagram, and select the option Existing interface drag and drop in Class Diagram.

This step ensures that the function can realize the interface I_the_driver_requests_to_accelerate

提示

In the next steps, the Assistant Tab will be used again. When using the assistant more than once, the previous elements are still there and can confuse you if you don't need them anymore. Therefore, you should clear the assistant by clicking on Clear.

Clearing interface
  • Create an Interface I_the_driver_has_accelerated and a flow the_driver_has_accelerated (with an argument value whose name is coef and type is AccelerationType) between Request_a_dynamic_change and Accelerate and trace it on the analysed user story.

  • Drag&Drop the newly created interface I_the_driver_has_accelerated in the Class Diagram FunctionRequiredInterfaces from the Assistant tab, as you have done before.

Trace the_driver_has_accelerated
  • Create an intern activity named compute_acceleration on Accelerate
Trace compute_acceleration
  • Create a Variable car_accel with type AccelerationType in the function Accelerate and set value to 0.0 (right click on the “Accelerate” lifeline, or on the compute_acceleration intern activity, and select Edit -> Create Variable)
Create car_accel
  • Trace a New Message between the function Accelerate and the environment.

  • Select the flow send_car_acceleration and select car_accel on the value field.

Select send_car_acceleration
  • As done before, Drag&Drop the interface I_send_car_acceleration in the Class Diagram from the Assistant tab.

  • Complete the internal activity compute_acceleration (Right click on the activity then select Edit -> Complete Activity):

car_accel = the_driver_has_accelerated_coef;
  • Generate the state machines
    • Select the diagram in the overview and click on Generate StateMachine
    • OR Right click on the diagram and Select > Generate > Generate State Machine
Generate State Machine

User story "The driver is informed of the car speed_Analysed"

  • Double Click on the user story The driver is informed of the car speed_Analysed in the Overview (Speed_Management > Standard Use > Inform of car speed) to open the corresponding sequence diagram
The driver is informed of the car speed_Analysed
  • Drag&Drop a New Lifeline on the diagram
  • Select both Inform_of_car_speed and Acquire_car_speed (holding Ctrl)
  • Click on Ok
  • Drag&Drop a New State on both lifelines that you can rename "Active"
The_driver_is_informed_of_the_car_speed_Analysed Sequence Diagram with state
  • Trace a New Message between the environment and the function Acquire_car_speed
  • Select the_car_speed_is_received
  • Click on Ok
  • Drag&Drop the interface I_the_car_speed_is_received in the Class Diagram, from the Assistant tab.
The_driver_is_informed_of_the_car_speed_Analysed Sequence Diagram with flow from the environment
  • Trace a New Message between the function Acquire_car_speed and Inform_of_car_speed, and click on Create a new flow
  • Create a new interface, and name it I_transmit_car_speed
  • In this interface, add a flow whose name is transmit_car_speed, with a parameter called value of type SpeedType.
  • Trace this flow on the sequence diagram, select the_car_speed_is_received_value as transmitted value by this flow, and drag&drop the needed interface as done before.

Now, let's send the speed information to the user:

  • Trace a New Message between the function Inform_of_car_speed and the user
  • Select the flow inform_the_driver_of_the_car_speed, with transmit_car_speed_value as transmitted value.
  • Click on Ok
  • Drag&Drop the interface I_inform_the_driver_of_the_car_speed in the Class Diagram, from the Assistant tab.
The_driver_is_informed_of_the_car_speed_Analysed Sequence Diagram full
  • Generate the state machine.

As the same mapping is used for the simulation, only the level of simulation (Service or Function) must be specified.

SWITCH BETWEEN SERVICE SIMULATION AND FUNCTION SIMULATION

  • Go back to Service tab in the Overview,
Car Structure
  • Open the structure diagram of the Product (the one named Car Structure),

  • Select the Speed_Management Service box,

  • Highlight the Properties view (bottom right of the window) and set the "Type" of the service on Speed_ManagementWB (WB for WhiteBox):

Car Structure Diagram

Type of the service on Speed_ManagementWB
  • Come back to the function tab, so you don't forget to work on the right level of simulation.

NOW LET'S DO THE SAME THING FOR THE BRAKE FUNCTION

  • Double Click on the user story The driver brakes_Analysed in the Overview (Speed_Management > Standard Use > Brake) to open the corresponding sequence diagram
The driver brakes_Analysed
  • Drag&Drop a New Lifeline on the diagram
  • Select Request_a_dynamic_change, Brake and Acquire_car_speed (by holding Ctrl).
  • Click on Ok
  • Arrange the diagram as follow by dragging the lifelines
The driver brakes_Analysed Sequence Diagram with lifelines
  • Drag&Drop a New State on each function lifeline
The driver brakes_Analysed Sequence Diagram with states

In this part we will need to access the speed of the vehicle. Remember that we've previously acquired the speed thanks to a flow (that will be continuously sent by the simulation) between the environment and the function Acquire_car_speed. We're going to trace the same process again, to add the transmission of the speed to the Brake function, triggered by the acquisition of the car speed.

  • Trace a New Message between the environment and the function Acquire_car_speed and select the_car_speed_is_received as used before.
Selection of the_car_speed_is_received
  • Trace a message between Acquire_car_speed and Brake, and use the same transmit_car_speed flow as before too, with the_car_speed_is_received_value as transmitted value.

  • The already existing interface will need to be drag&dropped from the Assistant tab.

Drag&Drop of I_transmit_car_speed
  • Trace a new Message between the user and the function Request_a_dynamic_change
Selection of the_driver_requests_to_brake
  • Select the_driver_requests_to_brake and Click Ok

  • Drag&Drop the interface I_the_driver_requests_to_brake in the Class Diagram, from the Assistant tab.

  • Trace a new message between Request_a_dynamic_change and Brake

  • Create a new Interface I_the_driver_has_braked and create a new Flow the_driver_has_braked with an argument value whose name is coef and type is AccelerationType

Create “I_the_driver_has_braked”
  • Trace the newly created flow between Request_a_dynamic_change and Brake on the analysed user story, with the_driver_requests_to_brake_coef as transmitted value
  • Drag&Drop the Interface I_the_driver_has_braked from CIL4Sys Assistant to the FunctionRequiredInterface
drop I_the_driver_has_braked in Required Interfaces Diagram
  • Create an internal Activity named compute_deceleration on Brake
Trace “compute_deceleration”
  • Create a Variable car_accel with type AccelerationType in the function Brake and set value to 0.0 (Right click on the Lifeline Brake and select Edit -> Create Variable)
  • Complete the internal activity compute_deceleration (Right click on the activity then select Edit -> Complete Activity):
car_accel = the_driver_has_braked_coef;
  • Trace a New Message between the function Brake and the environment.

  • Select the flow send_car_acceleration and select car_accel on the value field, as done before with the Accelerate function.

  • Drag&Drop the interface I_send_car_acceleration in the Class Diagram from the Assistant tab.

  • Create a new constant in the Brake function (right click on the function Edit -> Create Constant) called NULL_SPEED, of type SpeedType and set value to 0.0.

  • Create a Guard Condition on the analysed user story

  • Select the trigger of the guard condition: the_driver_has_braked(the_driver_requests_to_brake_coef).

  • Set the condition as followed:

Guard Condition

You should obtain a diagram like the following one :

The driver brakes Sequence Diagram first part

Now, repeat the same process but with a different guard condition, handling the opposite condition:

提示

Before creating the guard condition, you should trace a new message between User and Request_a_dynamic_change and between Request_a_dynamic_change and Brake. If you do so, the correct trigger will be available at the creation of the guard condition.

Guard Condition

You should obtain this:

The driver brakes Sequence Diagram second part
  • Create a new internal activity in the Brake function and call it set_acceleration_value_to_zero
  • Complete the internal activity as follow :
car_accel = NULL_SPEED;
  • Then finish the diagram with send_car_acceleration as previously done with the first guard condition. You should obtain a diagram like this :
The driver brakes Sequence Diagram complete

提示

To increase the size of the different lifelines,and be able to draw more sequences, you can select all of them, select the balck square at the bottom of one of the lifeline then pull it down.

  • Generate the state machines
    • Select the diagram in the overview and click on Generate State Machine
    • OR Right click on the diagram and Select > Edit > Generate State Machine

GENERATE CODE

备注

If you have the community version of Designer (free version), please build the executable via Hub4sys as shown on this page.

  • Click on Generate code in CIL4Sys Overview
Generate Code
  • Select Car
  • Click on OK
Code Generation
  • Select Cygwin GCC (Cygwin 64 must be installed, for Windows only)
Cygwin
  • Click on Finish
  • Click on OK in the confirmation dialog box
警告

Building using cygwin is easier to set up, however, it seems that the stability of the executables can sometimes cause issues (e.g. the executable stops working right after it is launched) That is why it is often better to build using the minGW parameters on this link.

  • Right Click on the newly created C++ project
  • Select Build Project
Build Project
  • Right Click on the C++ project
  • Select RunAs > C/C++ Application
  • Go to the Sim4Sys Virtual Bench: https://sim4sys.com/
  • Re-open the exact same project as for previous tutorial.
警告

The mapping should not be changed! The goal here is to have the same behavior even though you got deeper into the function part.

  • Connect the executable with the simulation with the WebSocket button in the top right (red_websocket to green_websocket).

  • Play the simulation

The gauge should increase, decrease, and then stop at 0. On the scene2D context, the car should start moving while the speed increases and then slow until complete stop during the braking phase.