Orocos Real-Time Toolkit  2.9.0
StateMachineService.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Wed Jan 18 14:11:40 CET 2006 StateMachineService.cpp
3 
4  StateMachineService.cpp - description
5  -------------------
6  begin : Wed January 18 2006
7  copyright : (C) 2006 Peter Soetens
8  email : peter.soetens@mech.kuleuven.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 
40 #include "StateMachineService.hpp"
41 
42 #include "../Attribute.hpp"
43 #include "../FactoryExceptions.hpp"
44 #include "../TaskContext.hpp"
45 #include "../OperationCaller.hpp"
46 #include "SendHandleAlias.hpp"
47 
48 namespace RTT
49 {
50 
51  using namespace detail;
52 
53  void StateMachineService::createOperationFactory() {
54  // Add the state specific methods :
55  // Special trick : we store the 'this' pointer in a DataSource, such that when
56  // the created commands are copied, they also get the new this pointer.
57  // This requires template specialisations on the TemplateFactory level.
58  DataSource<StateMachinePtr>* ptr = _this.get();
59 
60  // I had to make activate() a command because the entry {}
61  // may contain commands upon which the state machine is
62  // not strictly active (entry executed and no transition
63  // in progress) when activate() returns, hence activate()
64  // takes time and is thus a method. This is however in
65  // violation with the concept of 'initialisation of the
66  // SM' which may contain non-rt safe code. When activate() is
67  // called directly upon the SM in C++, it _is_ a method, but
68  // with the same deficiencies.
69  addOperationDS("trace", &StateMachine::trace,ptr).doc("Trace the execution of this StateMachine. *Not* Real-Time.");
70  addOperationDS("activate", &StateMachine::activate,ptr).doc("Activate this StateMachine to initial state and enter request Mode.");
71  addOperationDS("deactivate", &StateMachine::deactivate,ptr).doc("Deactivate this StateMachine");
72  addOperationDS("start", &StateMachine::automatic,ptr).doc("Start this StateMachine, enter automatic Mode.");
73  addOperationDS("automatic", &StateMachine::automatic,ptr).doc("Start this StateMachine, enter automatic Mode.");
74  addOperationDS("pause", &StateMachine::pause,ptr).doc("Pause this StateMachine, enter paused Mode.");
75  addOperationDS("step", &StateMachine::step,ptr).doc(
76  "Step this StateMachine. When paused, step a single instruction or transition evaluation. \n"
77  "When in reactive mode, evaluate transitions and go to a next state, or if none, run handle.");
78  addOperationDS("reset", &StateMachine::reset,ptr).doc("Reset this StateMachine to the initial state");
79  addOperationDS("stop", &StateMachine::stop,ptr).doc("Stop this StateMachine to the final state and enter request Mode.");
80  addOperationDS("reactive", &StateMachine::reactive,ptr).doc("Enter reactive mode (see requestState() and step() ).\n OperationCaller is done if ready for requestState() or step() method.");
81  addOperationDS("requestState", &StateMachine::requestState,ptr).doc("Request to go to a particular state. Will succeed if there exists a valid transition from this state to the requested state.").arg("State", "The state to make the transition to.");
82 
83  addOperationDS("inState", &StateMachine::inState,ptr).doc("Is the StateMachine in a given state ?").arg("State", "State Name");
84  addOperationDS("inError", &StateMachine::inError,ptr).doc("Is this StateMachine in error ?");
85  addOperationDS("getState", &StateMachine::getCurrentStateName,ptr).doc("The name of the current state. An empty string if not active.");
86  addOperationDS("isActive", &StateMachine::isActive,ptr).doc("Is this StateMachine activated (possibly in transition) ?");
87  addOperationDS("isRunning", &StateMachine::isAutomatic,ptr).doc("Is this StateMachine running in automatic mode ?");
88  addOperationDS("isReactive", &StateMachine::isReactive,ptr).doc("Is this StateMachine ready and waiting for requests or events ?");
89  addOperationDS("isPaused", &StateMachine::isPaused,ptr).doc("Is this StateMachine paused ?");
90  addOperationDS("inInitialState", &StateMachine::inInitialState,ptr).doc("Is this StateMachine in the initial state ?");
91  addOperationDS("inFinalState", &StateMachine::inFinalState,ptr).doc("Is this StateMachine in the final state ?");
92  addOperationDS("inTransition", &StateMachine::inTransition,ptr).doc("Is this StateMachine executing a entry|handle|exit program ?");
93  }
94 
95  StateMachineServicePtr StateMachineService::copy(ParsedStateMachinePtr newsc, std::map<const DataSourceBase*, DataSourceBase*>& replacements, bool instantiate )
96  {
97  // if this gets copied, all created methods will use the new instance of StateMachineService to
98  // call the member functions. Further more, all future methods for the copy will also call the new instance
99  // while future methods for the original will still call the original.
100  StateMachineServicePtr tmp( new StateMachineService( newsc, this->mtc ) );
101  replacements[ _this.get() ] = tmp->_this.get(); // put 'newsc' in map
102 
103  if (instantiate) {
104  // Remove any remaining SendHandleAlias attributes, since they are not allowed for an instantiate...
105  // See SendHandleAlias::copy() for more details.
106  for ( ConfigurationInterface::map_t::iterator it = values.begin(); it != values.end(); ) {
107  if (dynamic_cast<SendHandleAlias*>(*it)) {
108  it = values.erase(it);
109  } else {
110  ++it;
111  }
112  }
113  }
114 
115  ConfigurationInterface* dummy = ConfigurationInterface::copy( replacements, instantiate );
116  tmp->loadValues( dummy->getValues());
117  delete dummy;
118 
119  return tmp;
120  }
121 
123  : Service( statem->getName() ),
124  _this( new ValueDataSource<StateMachinePtr>( statem ) ),
125  statemachine(statem),
126  mtc(tc)
127  {
128  this->createOperationFactory();
129  this->setOwner( tc );
130  }
131 
133  {
134  // When the this Service is deleted, make sure the program does not reference us.
135  if ( statemachine ) {
136  statemachine->setService( StateMachineServicePtr() );
137  }
138  }
139  //ExecutionEngine* StateMachineService::engine() const { return mtc->engine(); }
140 
141 }
142 
const std::string & getName() const
Returns the name of this service instance.
Definition: Service.hpp:139
boost::shared_ptr< StateMachineService > StateMachineServicePtr
boost::shared_ptr< ParsedStateMachine > ParsedStateMachinePtr
bool isAutomatic() const
Query if the state machine is reacting to events and evaluating transition conditions.
bool inState(const std::string &state) const
Check if the state machine is in a given state.
bool deactivate()
Stop this StateMachine.
bool reset()
Reset the state machine from the final state to the initial state and wait for events or requests...
StateMachineServicePtr copy(ParsedStateMachinePtr newsc, std::map< const base::DataSourceBase *, base::DataSourceBase * > &replacements, bool instantiate)
bool pause()
Pause the state machine.
This class allows storage and retrieval of operations, ports, attributes and properties provided by a...
Definition: Service.hpp:93
bool inInitialState() const
Inspect if we are in the initial state.
bool step()
Execute a single action if the state machine is paused or evaluate the transition conditions if the s...
StateMachineService(ParsedStateMachinePtr statemachine, TaskContext *tc)
By constructing this object, a stateMachine can be added to a taskcontext as a Service, with its operations.
const std::string & getCurrentStateName() const
Return name of current state, empty string if not active.
AttributeObjects const & getValues() const
Returns all attributes in this repository.
bool inError() const
Get the error status of this StateMachine.
bool requestState(const std::string &statename)
Request a transition to a given state.
void trace(bool on_off)
Turn log(Debug) messages on or off to track state transitions.
boost::shared_ptr< StateMachine > StateMachinePtr
A class for keeping track of Attribute, Constant and Property objects of a TaskContext.
bool inFinalState() const
Inspect if we are in the final state.
bool activate()
Start this StateMachine.
bool isReactive() const
Query if the state machine is currently reacting only to events.
DataSource< T >::result_t get() const
Return the data as type T.
Definition: DataSources.hpp:78
The TaskContext is the C++ representation of an Orocos component.
Definition: TaskContext.hpp:93
Operation< typename internal::GetSignatureDS< Func >::Signature > & addOperationDS(const std::string &name, Func func, internal::DataSource< boost::shared_ptr< ObjT > > *sp, ExecutionThread et=ClientThread)
For internal use only.
Definition: Service.hpp:506
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
ConfigurationInterface * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &repl, bool instantiate) const
Return a new copy of this repository with the copy operation semantics.
void setOwner(TaskContext *new_owner)
Sets the owning TaskContext that will execute the operations in this service.
Definition: Service.cpp:254
A simple, yet very useful DataSource, which keeps a value, and returns it in its get() method...
Definition: DataSources.hpp:60
bool isActive() const
Returns true if the state machine is activated.
bool isPaused() const
Query if the state machine is paused.
bool reactive()
Switch to reactive mode from automatic mode.
bool inTransition() const
Inspect if the StateMachine is performing a state transition.
bool automatic()
Enter automatic mode: evaluating the transition conditions continuously.
bool stop()
Bring the state machine to the safe final state and wait for events or requests.