Skip to content

Generated and glue code from the State Machines (Distributed Logic)

Benedek Horvath edited this page May 25, 2016 · 4 revisions

Generated and glue code from the State Machines (Distributed Logic)


If you regenerate the code for the statecharts, please consider the important notes in the connecting glue code with generated code section.

Originally the state machines where designed in a hierarchical way. It means different classes were introduced that showed extra information about the unit (e.g. Section → OccupiedSection, FreeSection) and all the state machines were in a big composition. It was the times when we used BridgePoint.

But when we switched for Yakindu Statechart Tools, then the composition was blown up and separate statecharts were introduced instead. It means we have a composite statechart for Sections, Turnout that can be either a NormalTurnout or an EnglishTurnout. (Note: the latter ones are not separated in their names for the statecharts or the generated code itself, because it was easier to call it just Turnout. However, it may be changed in the future.)

In the following paragraphs each concept (Section, Turnout) will be introduced, including what properties they store and how the code from the statecharts is interconnected with the Java glue code.

Concepts

This paragraph contains some details about what properties are stored in the different statecharts.

Section

Constants for differentiating between the section to turnout connection directions:

  • var readonly STRAIGHT: integer = 0

  • var readonly DIVERGENT: integer = 1

  • var readonly TOP: integer = 2

Properties:

  • var id: integer: the ID of the section, based on the track layout.

  • var direction: integer: the direction from which the section connects to its turnout.

Turnout

Constants for differentiating between the section to turnout connection directions:

  • var readonly STRAIGHT: integer = 0

  • var readonly DIVERGENT: integer = 1

  • var readonly TOP: integer = 2

Common properties for Normal Turnout and English Turnout:

  • var id: integer: the ID of the turnout, based on the track layout.

  • var isOccupied: boolean: indicates whether the turnout is occupied or not.

Normal Turnout

Extra properties:

  • var topExists: boolean: indicates whether a section connects to the turnout from top.

  • var divergentExists: boolean: indicates whether a section connects to the turnout from divergent.

  • var straightExists: boolean: indicates whether a section connects to the turnout from straight.

  • var remDivergentIsPrior: boolean: indicates whether the remote turnout connecting from divergent direction has higher priority than the local turnout.

  • var remStraightIsPrior: boolean: indicates whether the remote turnout connecting from straight direction has higher priority than the local turnout.

  • var remTopIsPrior: boolean: indicates whether the remote turnout connecting from top direction has higher priority than the local turnout.

Connecting glue code with generated code

Codes generated by Yakindu Statechart Tools

Yakindu Statechart Tools generate Java code from the statecharts. We use thread-safe implementation for the statecharts, but as of writing this documentation (25.05.2016) only the not fully implemented thread-safe wrapper is generated by the Yakindu’s own code generator.

All the functions are inlined in the generated code, and a runtime service is generated too. For these concepts first have a look at the Yakindu Statechart Tools tutorial and documentation, and please exhaustively study it, especially the parts regarding how to run statechart from Java code!

The respective settings in the .sgen files are the following:

GeneratorModel for yakindu::java {

	statechart <statechart-name> {

		feature Outlet {
			targetProject = "<target-project>"
			targetFolder = "src-gen"
		}

		feature GeneralFeatures {
			InterfaceObserverSupport = true
			RuntimeService = true
		}

		feature FunctionInlining {
			inlineChoices = true
			inlineEnterRegion = true
			inlineEnterSequences = true
			inlineEntries = true
			inlineEntryActions = true
			inlineExitActions = true
			inlineExitRegion = true
			inlineExitSequences = true
			inlineReactions = true
		}

		feature RunnableWrapper {
			namePrefix=""
			nameSuffix = "Wrapper"
		}
	}
}

The generated code is in the org.yakindu.scr package. As an example in the following paragraphs I will use the Turnout’s statechart.

The generated code consists of a generate statechart interface and a runtime service. For details have a look at the Yakindu Statechart Tools documentation.

  • org.yakindu.scr.IStatemachine.java

  • org.yakindu.scr.RuntimeService.java

Inside the org.yakindu.scr.turnout package there are several intefaces and classes:

  • ITurnoutStatemachine.java: an interface that declares methods for the incoming and outgoing events (signals), according to the one that is used in the statechart designer itself (the interface and event delcaration are of the designer — rectangle with the white background).

  • TurnoutStatemachine.java: a not thread-safe implementation of the statechart.

Important notes: for each incoming event’s generated function (starting with get and the return type is a long value) an exception-throwing row should be commented (deleted) otherwise we will receive runtime exception. That is neccessary, because of some glitches in the code-generator or the way we used the generated code (automatic execution, but I have not debugged it yet).

The respective row should look like this (after applying the comment):

//throw new IllegalStateException("Illegal event value acces. Event <event name that is replaced here> is not raised!");

Implementing the declared interfaces

In the designer of the statecharts there are several interfaces declared. They are necessary for grouping the events, and declaring functions (outgoing events) that shall be implemented by the generated code. The respective interfaces are: Section, Sections, Turnout. The latter ones are used by the Turnout, the first one is used by the Section statechart.

Their implementations are:

  • SectionEventListener.java: that implements the (SCI)Section interface, resp. #1 (english turnout code base), resp #2 (normal turnout code base).

  • TurnoutEventListener.java: that implements the (SCI)Sections and the (SCI)Turnout intrafeces, resp. #1 (english turnout code base), #2 (normal turnout code base).

Defects in the generated code

  1. If you regenerate the code for the statecharts, please consider the important notes in the connecting glue code with generated code section.

  2. In version Yakindu SCT 2.5 it does not support enums in the designer yet. So constants had to be introduced to make difference between the directions (divergent, straight, top). However, in the Java glue code I can use enums they have to be converted to the respective constant for Yakindu. The conversion is done by the hu.bme.mit.inf.yakindu.sc.english.control.sm.handler.DirectionConverter class. Resp. #1 (english turnout code base), #2 (normal turnout code base).

Glue code base

The glue code base is pretty the same as for the english turnout and the normal turnout. That is because they use the same classes almost, and there are just minor changes (e.g. statechart instantiation and initialization, generated statechart codes) between them.

Please note that both code base contains auto-generated parts (packages starting with org.yakindu.scr) that are generated by Yakindu from the respective statecharts. Also note that the Section statechart and the respective classes for that are the same.

Besides, the hu.bme.mit.inf.yakindu.mqtt.client module contains the MQTT related parts, which are neccessary for the statecharts to communicate with each other in case of neighbouring (remote) turnouts.

Each code base is structured as follows:

The prefix of the packages are hu.bme.mit.inf.yakindu.sc.normal.control (normal turnout) and hu.bme.mit.inf.yakindu.sc.english.control (english turnout) respectively.

  • controller: the entry point of the code base from the command-line perspective.

    • Simulator.java: that receives the command-line arguments, instantiates, configures and starts the respective statechart

    • StatemachineInitializer.java: initializes the respective turnout statechart along with the connecting sections statecharts.

    • YakinduSMRunner.java: starts and runs the statecharts.

  • helper: helper classes.

    • Commands.java: stores constants that are used in the local statemachine to remote statemachine communication via MQTT.

    • NullSection.java: Nullable design pattern implementation for Section.

    • YakinduSMConfiguration.java: stores the turnout’s and the respective sections' statecharts that were instantiated by YakinduSMRUnner.java.

  • sm: helper classes for the statecharts to store additional configuration information.

    • RemoteTurnout.java: stores information about the neighbouring turnout. Pay extra attention to its remoteDirection (the LOCAL turnout can reach the REMOTE turnout from this direction) and localDirection (the REMOTE turnout can reach the LOCAL turnout from this direction) fields.

    • Section.java: stores information about the Section itself (ID and its statechart).

  • sm.handler: helper classes that implement the abstract interfaces (listeners for the outgoing events of the statecharts), and a class that workarounds the missing enum concepts of statechart.

    • DirectionConverterHelper.java: converts the long constants used in the statecharts to respective Java enums and vice versa. (There is no enum as of 25.05.2016 in the Yakindu Statechart Tools editor.)

    • SectionEventListener.java: implements the SCISection interface of the Section’s statechart.

    • TurnoutEventListener.java: implements the SCISections and SCITurnout interfaces of the Turnout’s statechart.

  • trace: helps tracking the trace of statecharts. Only the states are stored, the events are not, because for the latter ones the generated Java code should be modified extensively.

    • StatemachineTraceBuilder.java: builds a trace for the statechart. It is used by the class called Turnout|SectionWrapperWithListeners in the org.yakindu.scr.turnout|section package.

    • StatemachineTraceNode.java: a node in the trace that stores the recently active states of the statechart.

  • transmitter:

    • DistributedMessageTransmitter.java: forwards the events received from the MQTT client to the statecharts internal event queue.

    • GeneralTransmitter.java: generates events based on the sensors information about the model railway track (e.g. section/turnout occupancy, turnout direction, revoking the locked sections).

Deploying the code base

The code base is deployed onto the embedded controllers (as of 25.05.2016 the Beagle Bone Black units) as Java jars. The entrance point of the code base is the Simulator.java class in the hu.bme.mit.inf.yakindu.sc.normal.control.controller package. (It instantiates, configures, and starts the respective statecharts based on the received command-line arguments.)

On an embedded controller always the respective Turnout's statechart is instantiated, and the connecting Sections statecharts are instantiated as well. They are instantiated (ID, direction) according to the physical track layout, and the Sections statecharts are connected with the Turnout's statechart through Java glue code, and the event listeners (out event handlers implemented in Java) mentioned above.

The initial start and runCycle methods calls are done in the YakinduSMRunner class that is responsible for starting and running the statecharts along with the external information and message listeners (GeneralTransmitter and DistributedMessageTransmitter).

Clone this wiki locally