|
|
|
nodename: NodeClass(constructor_args) [initializers]All the elements except the NodeClass are optional. Node classes must begin with a capital letter; node names should begin with a lowercase letter. The shorthand for a transition definition looks like this:
sourcenodeAll components except the source node and transition class are optional, as are the spaces between them. A source node can be either a node definition or the name of a previously-defined node. If the target node is omitted, the next defined node is used as the target. Thus, node and transition definitions can be conveniently interleaved, forming a chain. Initializers are used to set parameters of a node or transition, such as modifying a motion command contained inside a motion command node. (LedNode is an example of a motion command node; it is actually an alias for MCNode<LedMC>.) Special notation is used to add additional source or target nodes to a previously-defined transition. To add a source node, use:==transname: TransitionClass(constructor_args) [initializers]==>targetnode
sourcenode == transname
To add a destination node, use:
transname ==> targetnode
To prevent these or any other expressions from inappropriately
chaining with others, put blank lines around them.
Finally, if you leave off the constructor arguments to a node, the
first argument, which is a string specifying the node name, will be
supplied automatically. If you do specify constructor args you can
write "$" in quotes (because the first argument is supposed to be a
string), and the translator will replace this with the name assigned
to the node. This could be either the name you assigned, in which
case it simply keeps you from having to write the name twice, or it
can be an automatically generated name if you did not assign one
yourself. So writing foo:StateNode is equivalent to
writing foo:StateNode("$"), which would expand to
foo:StaetNode("foo").
The first argument to a transition constructor is always the
destination node. If you leave off the constructor arguments, the
first argument, will be supplied automatically based on what appears
after the ==>. If you need to specify transition
constructor arguments, you can use a $ (without quotes) for the first
argument, and the translater will replaced it with the name of the
destination node.
Here is an example of the bark/howl state machine written as simply as
possible in the shorthand notation. Notice the use of blank lines
between declarations since we're not chaining them together.
bark: SoundNode("$","barkmed.wav")
wait: StateNode
bark == EventTrans($,
EventBase::buttonEGID,
RobotInfo::HeadFrButOffset,
EventBase::activateETID) [setSound("ping.wav");] ==> wait
wait ==TimeOutTrans($,15000)==> bark
howl: SoundNode("$","howl.wav")
bark ==TimeOutTrans($,500)==> howl
howl ==CompletionTrans==> wait
|
launch:StateNode ==n:NullTrans==> bark
n ==> LedNode [setPriority(MotionManager::kBackgroundPriority);
getMC()->set(RobotInfo::FaceLEDMask,0.0);]
bark: SoundNode("$","barkmed.wav")
== EventTrans($,
EventBase::buttonEGID,
RobotInfo::HeadFrButOffset,
EventBase::activateETID) [setSound("ping.wav");] ==>
wait: StateNode == TimeOutTrans($,15000) ==> bark
bark ==tooLate: TimeOutTrans($,5000)==> SoundNode("$","howl.wav")
==howlDone: CompletionTrans($,1)==> wait
tooLate ==> LedNode [getMC()->cycle(RobotInfo::FaceLEDMask,1500,1.0);] == howlDone
|
#statemachine and terminated by
#endstatemachine. The Tekkotsu make file will read the
fsm file and create xxx.h or xxx.cc for you, but this derived file
will be hidden away in the build directory so that you don't
accidentally edit it instead of the fsm file.
Here is an example of the full implementation of the bark/howl/blink
state machine:
//-*-c++-*-
#ifndef INCLUDED_DstBehavior_h_
#define INCLUDED_DstBehavior_h_
#include "Behaviors/StateNode.h"
#include "Behaviors/Nodes/SoundNode.h"
#include "Behaviors/Nodes/LedNode.h"
#include "Behaviors/Transitions/CompletionTrans.h"
#include "Behaviors/Transitions/EventTrans.h"
#include "Behaviors/Transitions/NullTrans.h"
#include "Behaviors/Transitions/TimeOutTrans.h"
#include "Events/EventRouter.h"
class DstBehavior : public StateNode {
public:
DstBehavior() : StateNode("DstBehavior") {}
virtual void setup() {
StateNode::setup();
#statemachine
|
|
|
|