Created
June 26, 2017 12:34
-
-
Save mcahriman/3a4f51ea0b9078a61d08346dd924facc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RoomModel TrafficLight { | |
import room.basic.service.timing.* from "../../../org.eclipse.etrice.modellib.c/model/TimingService.room" | |
import room.basic.service.tcp.* from "../../../org.eclipse.etrice.modellib.c/model/TcpService.room" | |
import room.basic.types.* from "../../../org.eclipse.etrice.modellib.c/model/Types.room" | |
ActorClass TestApplication ["The TestApplication contains the PedestrianTrafficLightController and its test harness."] { | |
Structure { | |
ActorRef controller: PedestrianTrafficLightController | |
ActorRef controllerTestHarness: TrafficLightControllerTestHarness | |
Binding controllerTestHarness.fct and controller.fct | |
Binding controller.tlInterface and controllerTestHarness.tlInterface | |
} | |
Behavior { } | |
} | |
ActorClass SingleTrafficLight ["OneTrafficLight contains the PedestrianTrafficLightController which is connected via a SocketClient Actor to the traffic light GUI."] { | |
Structure { | |
ActorRef controller: PedestrianTrafficLightController | |
ActorRef headquarters1: TrafficLightHeadquarters | |
ActorRef tcpClient: ATcpClient | |
ActorRef ref0: TrafficLightInterface | |
Binding headquarters1.controllers and controller.fct | |
Binding ref0.ctrl and tcpClient.controlPort | |
Binding ref0.payload and tcpClient.payloadPort | |
Binding ref0.fct and controller.tlInterface | |
} | |
Behavior { } | |
} | |
ActorClass FlatReplication ["FlatReplication uses several replicated Actors in a row to control 2 traffic lights."] { | |
Structure { | |
ActorRef controller [2]: PedestrianTrafficLightController | |
ActorRef headquarters1: TrafficLightHeadquarters | |
ActorRef tlInterface [2]: TrafficLightInterface | |
ActorRef tcpClient [2]: ATcpClient | |
Binding headquarters1.controllers and controller.fct | |
Binding controller.tlInterface and tlInterface.fct | |
Binding tlInterface.ctrl and tcpClient.controlPort | |
Binding tlInterface.payload and tcpClient.payloadPort | |
} | |
Behavior { } | |
} | |
ActorClass HierarchicalReplication ["HierarchicalReplication structural hierarchy to combine several actors and replicate them 'en bloc'. It controls 2 traffic lights."] { | |
Structure { | |
ActorRef controllerWithInfrastructure [2]: TrafficLightControllerWithInfrastructure ["This is replicated "] | |
ActorRef headquarters2: TrafficLightHeadquarters | |
Binding controllerWithInfrastructure.fct and headquarters2.controllers | |
} | |
Behavior { } | |
} | |
ActorClass TrafficLightControllerWithInfrastructure ["The TrafficLightControllerWithInfrastructure encapsulates the PedestrianTrafficLightController, the TrafficLightInterface and the SocketClient."] { | |
Interface { | |
Port fct: PTrafficLightController | |
} | |
Structure { | |
ActorRef controller: PedestrianTrafficLightController | |
ActorRef tlInterface: TrafficLightInterface | |
ActorRef tcpClient: ATcpClient | |
Binding controller.tlInterface and tlInterface.fct | |
Binding fct and controller.fct | |
Binding tlInterface.ctrl and tcpClient.controlPort | |
Binding tlInterface.payload and tcpClient.payloadPort | |
} | |
Behavior { } | |
} | |
ActorClass TrafficLightControllerTestHarness [ | |
"Test harness for the TrafficLightController. It has the same ports, but conjugated. It can run test cases for the TrafficLightController by completely simulating its environment." | |
] { | |
Interface { | |
conjugated Port fct: PTrafficLightController | |
Port tlInterface: PTrafficLightInterface | |
} | |
Structure { | |
external Port fct | |
external Port tlInterface | |
SAP to: PTimer | |
Attribute counter: int32 ["FEATURE: Attribute of an ActorClass"] | |
} | |
Behavior { | |
StateMachine { | |
Transition init: initial -> SetStandby | |
Transition tr0: SetStandby -> InStandby { | |
triggers { | |
<doneStandby: fct> | |
} | |
action { | |
"counter=0;" | |
} | |
} | |
Transition tr1: InStandby -> SetStart { | |
triggers { | |
<setCarYellow: tlInterface guard { | |
"++counter==5" | |
}> | |
} | |
} | |
Transition tr2: SetStart -> InRunning { | |
triggers { | |
<doneStart: fct> | |
} | |
} | |
Transition tr3: InRunning -> CarGreen { | |
triggers { | |
<setCarGreen: tlInterface guard { | |
"status==1" | |
}> | |
} | |
} | |
Transition tr4: CarGreen -> PressButton { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr5: PressButton -> CarGreenAgain { | |
triggers { | |
<setCarGreen: tlInterface guard { | |
"status==1" | |
}> | |
} | |
} | |
Transition tr6: CarGreenAgain -> CarYellow { | |
triggers { | |
<setCarYellow: tlInterface guard { | |
"status==1" | |
}> | |
} | |
action { | |
"counter=0;" | |
} | |
} | |
Transition tr7: CarYellow -> SetStop { | |
triggers { | |
<setPedRed: tlInterface guard { | |
"++counter==5" | |
}> | |
} | |
} | |
Transition tr8: SetStop -> Done { | |
triggers { | |
<doneStop: fct> | |
} | |
} | |
State SetStandby { | |
entry { | |
"fct.standby(0); // dummy port not used" | |
} | |
} | |
State InStandby | |
State SetStart { | |
entry { | |
"fct.start();" | |
} | |
} | |
State InRunning | |
State CarGreen { | |
entry { | |
"to.startTimeout(1*10);" | |
} | |
} | |
State PressButton { | |
entry { | |
"tlInterface.pressedRequestButton();" | |
} | |
} | |
State CarGreenAgain { | |
entry { | |
"fct.standby(0); // dummy port" | |
} | |
} | |
State CarYellow | |
State SetStop { | |
entry { | |
"fct.stop();" | |
} | |
} | |
State Done | |
} | |
} | |
} | |
ActorClass PedestrianTrafficLightController [ | |
"Control of a traffic light at a pedestrian crossing with one car traffic light and one pedestrian traffic light." ] | |
{ | |
Interface { | |
Port fct: PTrafficLightController | |
conjugated Port tlInterface: PTrafficLightInterface | |
} | |
Structure { | |
external Port fct | |
external Port tlInterface | |
SAP to: PTimer | |
Attribute timeBase: int32 | |
} | |
Behavior { | |
StateMachine { | |
Transition init: initial -> Stopped { | |
action { | |
"timeBase = 100;" | |
} | |
} | |
Transition tr0: Stopped -> Connecting { | |
triggers { | |
<standby: fct> | |
} | |
action { | |
"printf(\"ptlc: connecting to port %d\\n\", (int)port);" | |
"tlInterface.connect(port);" | |
} | |
} | |
Transition tr1: Standby -> tpStart of Running { | |
triggers { | |
<start: fct> | |
} | |
} | |
Transition tr2: Running -> AllRedBeforeStandby { | |
triggers { | |
<standby: fct> | |
} | |
} | |
Transition tr3: tpStandby of Running -> AllRedBeforeStandby | |
Transition tr4: AllRedBeforeStandby -> tp0 of Standby { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr5: Standby -> Stopped { | |
triggers { | |
<stop: fct> | |
} | |
} | |
Transition tr6: Connecting -> tp0 of Standby { | |
triggers { | |
<connected: tlInterface> | |
} | |
} | |
State Stopped { | |
entry { | |
"tlInterface.setCarRed(0);" | |
"tlInterface.setCarYellow(0);" | |
"tlInterface.setCarGreen(0);" | |
"tlInterface.setPedRed(0);" | |
"tlInterface.setPedGreen(0);" | |
"fct.doneStop();" | |
} | |
} | |
State Standby { | |
entry { | |
"fct.doneStandby();" | |
} | |
subgraph { | |
Transition tr0: my tp0 -> On | |
Transition tr1: On -> Off { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr2: Off -> On { | |
triggers { | |
<timeout: to> | |
} | |
} | |
EntryPoint tp0 | |
State On { | |
entry { | |
"// turn two lights on" | |
"tlInterface.setCarYellow(1);" | |
"tlInterface.setPedRed(1);" | |
"" | |
"// start timeout (fire once) for blinking" | |
"// startTimer would start a cyclic timer" | |
"to.startTimeout(5*timeBase);" | |
} | |
exit { | |
"// TIP: turn off lights here in the exit code of state On instead of the entry code of state Off " | |
"// to make sure they are turned off if the superstate Standby is left by a group transition" | |
"tlInterface.setCarYellow(0);" | |
"tlInterface.setPedRed(0);" | |
"" | |
"// TIP: kill timer here to make sure it is killed if the state is left by a group transition or any other transition than a timeout" | |
"// ALTERNATIVE: kill() could also be placed in the exit code of the superstate StandbyBlinking and so replacing the two calls in On:exit and Off:exit" | |
"to.kill();" | |
} | |
} | |
State Off { | |
entry { | |
"to.startTimeout(5*timeBase);" | |
} | |
exit { | |
"to.kill();" | |
} | |
} | |
} | |
} | |
State Running { | |
entry { | |
"fct.doneStart();" | |
} | |
exit { | |
"to.kill();" | |
} | |
subgraph { | |
Transition tr0: my tpStart -> AllRed | |
Transition tr1: AllRed -> CarRedYellow { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr2: CarGreen -> CarYellow { | |
triggers { | |
<pressedRequestButton: tlInterface> | |
} | |
} | |
Transition tr3: CarYellow -> CarRed { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr4: CarRed -> PedGreen { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr5: PedGreen -> AllRed { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr6: CarGreen -> CarYellowBeforeStandby { | |
triggers { | |
<standby: fct> | |
} | |
} | |
Transition tr7: CarYellowBeforeStandby -> my tpStandby { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr8: CarRedYellow -> CarGreen { | |
triggers { | |
<timeout: to> | |
} | |
} | |
EntryPoint tpStart | |
ExitPoint tpStandby | |
State AllRed { | |
entry { | |
"tlInterface.setCarRed(1);" | |
"tlInterface.setPedRed(1);" | |
"tlInterface.setPedGreen(0);" | |
"" | |
"to.startTimeout(10*timeBase);" | |
} | |
} | |
State CarYellow { | |
entry { | |
"tlInterface.setCarGreen(0);" | |
"tlInterface.setCarYellow(1);" | |
"to.startTimeout(10*timeBase);" | |
} | |
} | |
State CarGreen { | |
entry { | |
"tlInterface.setCarRed(0);" | |
"tlInterface.setCarYellow(0);" | |
"tlInterface.setCarGreen(1);" | |
} | |
} | |
State CarRed { | |
entry { | |
"tlInterface.setCarYellow(0);" | |
"tlInterface.setCarRed(1);" | |
"to.startTimeout(10*timeBase);" | |
} | |
} | |
State PedGreen { | |
entry { | |
"tlInterface.setPedRed(0);" | |
"tlInterface.setPedGreen(1);" | |
"to.startTimeout(20*timeBase);" | |
} | |
} | |
State CarYellowBeforeStandby { | |
entry { | |
"tlInterface.setCarGreen(0);" | |
"tlInterface.setCarYellow(1);" | |
"to.startTimeout(10*timeBase);" | |
} | |
} | |
State CarRedYellow { | |
entry { | |
"tlInterface.setCarYellow(1);" | |
"to.startTimeout(10*timeBase);" | |
} | |
} | |
} | |
} | |
State AllRedBeforeStandby { | |
entry { | |
"tlInterface.setCarRed(1);" | |
"tlInterface.setPedRed(1);" | |
"to.startTimeout(30*timeBase);" | |
} | |
} | |
State Connecting | |
} | |
} | |
} | |
ActorClass TrafficLightInterface { | |
Interface { | |
Port fct: PTrafficLightInterface | |
conjugated Port ctrl: PTcpControl | |
conjugated Port payload: PTcpPayload | |
} | |
Structure { | |
external Port fct | |
external Port ctrl | |
external Port payload | |
} | |
Behavior { | |
Operation sendPayloadString(data: char ref){ | |
"DTcpPayload package;" | |
"DTcpPayload_setAsString(&package, data);" | |
"payload.dataPackage(&package);" | |
} | |
Operation sendOnOffCommand(lightString: char ref, status: boolean){ | |
"DTcpPayload package;" | |
"strcpy(package.data, lightString);" | |
"if (status==0){" | |
" strcat(package.data, \"=off\\n\");" | |
"}" | |
"else {" | |
" strcat(package.data, \"=on\\n\");" | |
"}" | |
"printf(\"package=%s\", package.data);" | |
"package.length = strlen(package.data);" | |
"payload_dataPackage(&package);" | |
} | |
StateMachine { | |
Transition init: initial -> Disconnected | |
Transition tr0: Connected -> Connected { | |
triggers { | |
<setCarRed: fct> | |
} | |
action { | |
"sendOnOffCommand(\"setCarLightRed\", status);" | |
} | |
} | |
Transition tr1: Connecting -> Connected { | |
triggers { | |
<connected: ctrl> | |
} | |
action { | |
"fct.connected();" | |
} | |
} | |
Transition tr2: Disconnected -> Connecting { | |
triggers { | |
<connect: fct> | |
} | |
action { | |
"printf(\"tli: connecting to port %d\\n\", (int)port);" | |
"DTcpControl config = {\"localhost\", port};" | |
"ctrl.connect(&config);" | |
} | |
} | |
Transition tr3: Connected -> Connected { | |
triggers { | |
<setCarYellow: fct> | |
} | |
action { | |
"sendOnOffCommand(\"setCarLightYellow\", status);" | |
} | |
} | |
Transition tr4: Connected -> Connected { | |
triggers { | |
<setCarGreen: fct> | |
} | |
action { | |
"sendOnOffCommand(\"setCarLightGreen\", status);" | |
} | |
} | |
Transition tr5: Connected -> Connected { | |
triggers { | |
<setPedRed: fct> | |
} | |
action { | |
"sendOnOffCommand(\"setPedLightRed\", status);" | |
} | |
} | |
Transition tr6: Connected -> Connected { | |
triggers { | |
<setPedGreen: fct> | |
} | |
action { | |
"sendOnOffCommand(\"setPedLightGreen\", status);" | |
} | |
} | |
Transition tr7: Connected -> Connected { | |
triggers { | |
<dataPackage: payload> | |
} | |
action { | |
"char *pressedRequestButtonString = {\"pressedRequestButton\\n\"};" | |
"int32 len = strlen(pressedRequestButtonString);" | |
"if ( (data->length == len) && memcmp(data->data, \"pressedRequestButton\", len)){" | |
"\tfct.pressedRequestButton();" | |
"}" | |
} | |
} | |
Transition tr8: Connected -> Connected { | |
triggers { | |
<setRequestButtonActive: fct> | |
} | |
action { | |
"sendOnOffCommand(\"setRequestButtonActive\", status);" | |
} | |
} | |
State Connecting | |
State Connected | |
State Disconnected | |
} | |
} | |
} | |
ActorClass TrafficLightInterfaceStub { | |
Interface { | |
Port fct: PTrafficLightInterface | |
} | |
Structure { | |
external Port fct | |
SAP to: PTimer | |
} | |
Behavior { | |
StateMachine { | |
Transition init: initial -> WaitingABit | |
Transition tr0: WaitingABit -> PressButton { | |
triggers { | |
<timeout: to> | |
} | |
} | |
State WaitingABit { | |
entry { | |
"to.startTimeout(80*10);" | |
} | |
} | |
State PressButton { | |
entry { | |
"fct.pressedRequestButton();" | |
"fct.releasedRequestButton();" | |
} | |
} | |
} | |
} | |
} | |
ActorClass TrafficLightHeadquarters { | |
Interface { | |
conjugated Port controllers [2]: PTrafficLightController | |
} | |
Structure { | |
external Port controllers | |
SAP to: PTimer | |
} | |
Behavior { | |
StateMachine { | |
Transition init: initial -> Standby | |
Transition tr0: Standby -> Running { | |
triggers { | |
<timeout: to> | |
} | |
} | |
Transition tr1: Running -> Stopped { | |
triggers { | |
<timeout: to> | |
} | |
} | |
State Standby { | |
entry { | |
"int n = PTrafficLightControllerReplPort_getReplication(&self->constData->controllers);" | |
"int i;" | |
"" | |
"printf(\"hq: number of connections is %d\\n\", n);" | |
"" | |
"for (i=0; i<n; ++i)" | |
"\tcontrollers[i].standby(4441+i);" | |
"" | |
"to.startTimeout(200*10);" | |
} | |
} | |
State Running { | |
entry { | |
"controllers.start();" | |
"to.startTimeout(200*10);" | |
} | |
} | |
State Stopped { | |
entry { | |
"controllers.stop();" | |
} | |
} | |
} | |
} | |
} | |
ProtocolClass PTrafficLightController { | |
incoming { | |
Message standby(port: int32) | |
Message start() | |
Message stop() | |
} | |
outgoing { | |
Message doneStandby() | |
Message doneStart() | |
Message doneStop() | |
} | |
} | |
ProtocolClass PTrafficLightInterface { | |
incoming { | |
Message connect(port: int32) | |
Message setCarRed(status: boolean) | |
Message setCarYellow(status: boolean) | |
Message setCarGreen(status: boolean) | |
Message setPedRed(status: boolean) | |
Message setPedGreen(status: boolean) | |
Message setRequestButtonActive(status: boolean) | |
} | |
outgoing { | |
Message connected() | |
Message pressedRequestButton() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment