Even it’s holiday, what’s more it’s sunday, we can’t stop working on our project, because we are so excited!
I’m Benedek, the ‘state machine expert’ of the team. I’m responsible for the so-called ‘safety logic’. That is a statechart based control, which supervises the trains and intervenes to prevent collision.
The safety logic was designed in xtUML BridgePoint Editor. It offers a model-driven design environment for developing embedded software. It is based on the xtUML methodology, which means that the created UML models are executable and translatable. This way direct translation from UML to a target language and platform, for example C, C++, Java can be easily achieved. The best comes yet: it’s free and open source! Check it out at xtuml.org!
The class diagram is depicted here:
It is quite complicated, so I describe it in short. Section and Turnout (or switch in better terminology) were differentiated.
Section can be FreeSection if no train is on it, otherwise it’s OccupiedSection.
The behaviour of the FreeSection is quite simple, it simply allows any train to come to the section. Because its so simple, it is not depicted now. 🙂
But, the OccupiedSection is more interesting, because it contains a more complex logic in itself:
As you may see, there is some text in the squares, that are called states. The edges connecting the states are called transitions, which have events or triggers written on them. If an event is occured in a state, then the respective transition is fired, which means the state machine moves from one state to another.
As an illustration: in BridgePoint one can write platform independent actions, in the BridgePoint’s own language, called OAL (Object Action Language). With the help of actions, we can create and fire events, instantiate new state machines, create references between objects, and so on. Actions can be written within edges and states as well.
E.g. in the BecomesLocked state the next OAL code is written:
select one section related by self->Section[R1];
send Port1::setSection(sectionId: section.id, isEnabled: false);
It gathers a reference for a section, and sends a setSection event with several parameters through Port1.
A Turnout can either be Straight, or Divergent. It is illustrated on the following picture (the recent direction is marked with black):
The logic for the Turnout was designed in a three-level hiearchy (see the high-level class diagram on the top of this post!). Only one column of the hierarchy exists at a time, depending on the recent direction of the turnout (or switch).
The first level is responsible for rejecting new events that are received while a former event is being handled by the hierarchy.
The second level is responsible for handling events which are received from perpendicular direction than the turnout’s recent one.
The third level is actually responsible for what we call safety logic itself.
It is quite complex, but on high-level it can be described easily; we have to stop trains if they are close to each other. On this level we are prepared for the worst-case scenario, which means the trains are approaching to each other!
Trains are either in the territory of the local turnout, or a remote one. Thus turnouts have to communicate with each other, whcih adds an extra complexity to the system.
Wrapping up this long post
Ugh, it was quite a long post, but we hope you liked it, and found the state machines fascinating.
New posts are coming soon about the hardware architecture and the safety logic, which are being developed at the moment! 🙂