NimbRo ROS Soccer Package
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
state_controller.h
Go to the documentation of this file.
1 // State Controller Library
2 // Author: Philipp Allgeuer <pallgeuer@ais.uni-bonn.de>
3 
364 // Ensure header is only included once
365 #ifndef STATE_CONTROLLER_H
366 #define STATE_CONTROLLER_H
367 
368 // Includes
369 #include <boost/shared_ptr.hpp>
370 #include <boost/make_shared.hpp>
371 #include <boost/type_traits/is_base_of.hpp>
372 #include <boost/static_assert.hpp>
373 #include <cstddef> // For std::size_t
374 #include <vector> // For std::vector
375 #include <string> // For std::string
376 
377 // Macro to create a new state instance
378 // Use like this: StatePtr s = NewStateInstance<MyState>(arg1, arg2, ...);
379 // Note: MyState should be a class derived either directly or indirectly from the State class.
380 // arg1, arg2, ... is the parameter list to pass to the MyState constructor. arg1 will
381 // generally be 'this' (when used from inside a state controller) or 'sc' (when used from
382 // within another state instance), as it is generally used by the constructor to pass a
383 // pointer to the owning state controller object.
384 #define NewStateInstance boost::make_shared
385 
393 namespace statecontroller
394 {
395  // Class declarations
396  class State;
397  template <class SCClass> class GenState;
398  class StateQueue;
399  class StateController;
400 
401  // Enumerations
403  { // Programming hint: If foo() returns a ret_t then if(foo()) {...} executes when the return was *not* SCR_OK
404  SCR_OK = 0,
409  };
410 
411  // Type definitions
412  typedef boost::shared_ptr<State> StatePtr;
413  typedef boost::shared_ptr<State const> StateConstPtr;
414  typedef std::size_t index_t;
415  typedef unsigned int cycle_t;
416  typedef bool action_t;
417  typedef int ret_t;
418 
419  // Constants
420  const StatePtr nullStatePtr = boost::shared_ptr<State>();
421  const index_t nullIndex = (index_t) -1;
422  const action_t HOLD_THIS_STATE = true;
423  const action_t PROCEED_NEXT_STATE = false;
424 
432  class State
433  {
434  public:
435  // Constructors
436  State(int id, const std::string& name, const std::string& scname)
437  : id(id)
438  , name(name)
439  , scname(scname)
440  , m_wasActivated(false)
441  , m_wasExecuted(false)
442  , m_wasDeactivated(false)
443  , m_firstExecCycle(0)
444  {}
445  virtual ~State() { callDeactivate(0); }
446 
447  // State properties
448  const int id;
449  const std::string name;
450  const std::string scname;
451 
452  // Helper functions
453  static bool isNull(StateConstPtr state) { return !((bool) state); }
454 
455  protected:
456  // Friend classes
457  friend class StateController;
458 
459  // Protected state properties
460  virtual StateController* scref() const = 0;
461 
462  // State callbacks
463  virtual void activate(cycle_t cyc) {}
464  virtual action_t execute(cycle_t cyc) = 0;
465  virtual void deactivate(cycle_t cyc, bool wasExecuted) {}
466 
467  // Get functions
468  inline StateQueue* Queue() const;
469  cycle_t firstExecCycle() const { return m_firstExecCycle; }
470  cycle_t execCycleNum(cycle_t cyc) const { return cyc - m_firstExecCycle + 1; }
471 
472  private:
473  // State callback wrappers
474  void callActivate(cycle_t cyc);
475  action_t callExecute(cycle_t cyc);
476  void callDeactivate(cycle_t cyc);
477 
478  // Callback execution flags
479  bool m_wasActivated;
480  bool m_wasExecuted;
481  bool m_wasDeactivated;
482 
483  // Cycle of first call to execute()
484  cycle_t m_firstExecCycle; // Equals zero before the first call to execute()
485  };
486 
495  template <class SCClass>
496  class GenState : public State
497  {
498  public:
499  // Ensure SCClass is a derived class of StateController
500  typedef boost::is_base_of<StateController, SCClass> Assert;
501  BOOST_STATIC_ASSERT_MSG(Assert::value, "SCClass template parameter must be a derived class of statecontroller::StateController");
502 
503  // Constructors
504  GenState(SCClass* sc, int id, const std::string& name) : State(id, name, sc->name), sc(sc) {}
505  virtual ~GenState() {}
506 
507  protected:
508  // Protected state properties
509  virtual StateController* scref() const { return static_cast<StateController*>(sc); }
510 
511  // State controller pointer
512  SCClass* const sc;
513  };
514 
523  {
524  public:
525  // Constants
526  static const index_t DEF_QUEUE_CAPACITY = 16;
527 
528  // Constructors
529  StateQueue() { reset(); }
530  virtual ~StateQueue() { clear_hard(); }
531 
532  // Reset function
533  void reset();
534 
535  //
536  // Queue manipulation functions
537  //
538 
539  // Clearing
540  void clear() { QueueVec.resize(0); }
541  void clear_hard() { QueueVec.clear(); }
542  void reserveCapacity(index_t n) { if(n <= QueueVec.max_size()) QueueVec.reserve(n); }
543 
544  // Get and set
545  StatePtr get(index_t ind) const { return (ind < QueueVec.size() ? QueueVec.at(ind) : nullStatePtr); }
546  void set(index_t ind, StatePtr state) { if(ind < QueueVec.size()) QueueVec.at(ind) = state; }
547 
548  // Element insertion and removal
549  void setNextState(StatePtr state) { QueueVec.assign(1,state); }
550  StatePtr getNextState() const { return (QueueVec.size() > 0 ? QueueVec.at(0) : nullStatePtr); }
551  void append (StatePtr state) { QueueVec.push_back(state); }
552  void prepend(StatePtr state) { QueueVec.insert(QueueVec.begin(), state); }
553  void insertBefore(index_t ind, StatePtr state) { if(ind <= QueueVec.size()) QueueVec.insert(QueueVec.begin() + ind, state); }
554  void insertAfter (index_t ind, StatePtr state) { if(ind < QueueVec.size()) QueueVec.insert(QueueVec.begin() + ind + 1, state); }
555  void remove(index_t ind) { if(ind < QueueVec.size()) QueueVec.erase (QueueVec.begin() + ind); }
556 
557  // Queue information
558  index_t length() const { return QueueVec.size(); }
559  bool isEmpty() const { return QueueVec.empty(); }
560  bool validIndex(index_t ind) const { return ind < QueueVec.size(); }
561 
562  // Head and tail items
563  index_t headIndex() const { return (QueueVec.size() > 0 ? 0 : nullIndex); }
564  index_t tailIndex() const { return (QueueVec.size() > 0 ? QueueVec.size()-1 : nullIndex); }
565  StatePtr headItem() const { return (QueueVec.size() > 0 ? QueueVec.at(0) : nullStatePtr); }
566  StatePtr tailItem() const { return (QueueVec.size() > 0 ? QueueVec.at(QueueVec.size()-1) : nullStatePtr); }
567 
568  // Queue advance function (pops and returns the state sitting at the head of the queue)
569  StatePtr advance();
570 
571  // Queue state and index search functions
572  bool containsID(int id) const { return (indexOf(id) != nullIndex); }
573  bool containsState(StatePtr state) const { return (indexOf(state) != nullIndex); }
574 
575  // Queue state and index retrieval functions
576  StatePtr stateOf(int id, index_t start = 0) const;
577  index_t indexOf(int id, index_t start = 0) const;
578  index_t indexOf(StatePtr state, index_t start = 0) const;
579 
580  private:
581  // Internal queue vector object
582  std::vector<StatePtr> QueueVec;
583  };
584 
594  {
595  public:
596  //
597  // Constructors
598  //
599 
600  // Constructors and destructors
601  explicit StateController(const std::string& name) : name(name), m_inCallback(false) { reset(); }
602  virtual ~StateController() { freeResources(); }
603 
604  // State controller properties
605  const std::string name;
606 
607  //
608  // Public functions (permitted in callbacks)
609  //
610 
611  // State control functions
612  action_t goToState(StatePtr state);
613  action_t terminate();
614 
615  // Helper functions
616  bool belongsToMe(StateConstPtr state) const { return (state->scref() == this); }
617  bool isActive() const { return !State::isNull(m_curState); }
618  cycle_t getCycle() const { return m_cycle; }
619  StateConstPtr getCurState() const { return m_curState; }
620 
621  //
622  // Public functions (callback-protected)
623  //
624 
625  // Initialisation and state change functions
626  ret_t init(StatePtr state);
627  ret_t forceState(StatePtr state);
628 
629  // Step functions
630  ret_t step();
631  ret_t loop();
632 
633  protected:
634  //
635  // Callbacks
636  //
637 
638  // Step callbacks
639  virtual bool preStepCallback() { return false; }
640  virtual void preActivateCallback(bool willCallActivate) {}
641  virtual void preExecuteCallback() {}
642  virtual bool postExecuteCallback() { return false; }
643  virtual void onTerminateCallback() {}
644  virtual void postStepCallback() {}
645 
646  private:
647  //
648  // Private members
649  //
650 
651  // Friend classes
652  friend class State; // However, all derived classes of State are NOT friends for privacy reasons!
653 
654  // Internal functions
655  ret_t reset();
656  void freeResources(); // This function clears m_curState, m_stateAction, m_inCallback and Q, but not anything else. In particular, m_cycle retains its value, so getCycle() can still be used. Calling step() again after the resources have been freed returns SCR_TERMINATED (but still increments m_cycle). The user needs to call init() again (or forceState()) in order to be able to step() again.
657  void setCurState(StatePtr state, action_t hold = PROCEED_NEXT_STATE);
658 
659  // Internal variables
660  bool m_terminate;
661  bool m_inCallback;
662  action_t m_stateAction;
663  cycle_t m_cycle;
664 
665  // Current state
666  StatePtr m_curState;
667 
668  // State queue
669  StateQueue Q;
670  };
671 
672  //
673  // State class
674  //
675 
676  // Get functions
677  inline StateQueue* State::Queue() const // Defined here as inline (but cannot be defined before StateController class)
678  {
679  // Return the required reference
680  return &(scref()->Q);
681  }
682 }
683 
684 #endif /* STATE_CONTROLLER_H */
685 // EOF
StatePtr tailItem() const
Returns nullStatePtr if queue is empty.
Definition: state_controller.h:566
void reset()
Reinitialise the StateQueue object.
Definition: state_controller.cpp:55
void append(StatePtr state)
Always successful.
Definition: state_controller.h:551
StatePtr getNextState() const
Returns nullStatePtr if queue is empty.
Definition: state_controller.h:550
StatePtr advance()
Returns nullStatePtr if queue is empty.
Definition: state_controller.cpp:62
virtual ~GenState()
Destructor.
Definition: state_controller.h:505
void insertBefore(index_t ind, StatePtr state)
Does nothing if ind is out of range or nullIndex (in this case the allowed range is up to QueueVec...
Definition: state_controller.h:553
bool containsState(StatePtr state) const
Always successful.
Definition: state_controller.h:573
StateController(const std::string &name)
Default constructor.
Definition: state_controller.h:601
StateQueue()
Default constructor.
Definition: state_controller.h:529
bool belongsToMe(StateConstPtr state) const
Check whether a state is owned by the calling state controller.
Definition: state_controller.h:616
virtual void onTerminateCallback()
A callback that is executed in the step() function (before the resources are freed) when a state cont...
Definition: state_controller.h:643
void reserveCapacity(index_t n)
Increase the queue capacity so that it is at least n (does nothing if the capacity is already at leas...
Definition: state_controller.h:542
GenState(SCClass *sc, int id, const std::string &name)
Default constructor that takes a pointer to the owning state controller class (SCClass must be a deri...
Definition: state_controller.h:504
bool validIndex(index_t ind) const
Always successful (function returns false for nullIndex)
Definition: state_controller.h:560
action_t goToState(StatePtr state)
Transition to the specified next state (for callback)
Definition: state_controller.cpp:119
StateQueue * Queue() const
Return pointer to the StateQueue of the owning state controller.
Definition: state_controller.h:677
SCClass *const sc
Pointer to the owning state controller (required in order to be able to access the StateQueue and man...
Definition: state_controller.h:512
index_t indexOf(int id, index_t start=0) const
Returns nullIndex if the given ID is not found.
Definition: state_controller.cpp:87
boost::shared_ptr< State > StatePtr
Used to represent a Boost shared pointer to a State object.
Definition: state_controller.h:412
virtual ~StateController()
Destructor.
Definition: state_controller.h:602
Signals successful execution of function.
Definition: state_controller.h:404
const std::string scname
The human-friendly name of the owning state controller.
Definition: state_controller.h:450
void prepend(StatePtr state)
Always successful.
Definition: state_controller.h:552
index_t length() const
Always successful.
Definition: state_controller.h:558
void insertAfter(index_t ind, StatePtr state)
Does nothing if ind is out of range or nullIndex.
Definition: state_controller.h:554
ret_t step()
Execute a single step of the state controller (callback-protected)
Definition: state_controller.cpp:237
action_t terminate()
Terminate the execution of the state controller (for callback)
Definition: state_controller.cpp:145
index_t headIndex() const
Returns nullIndex if queue is empty.
Definition: state_controller.h:563
Signals a clean termination of the state controller.
Definition: state_controller.h:405
ret_t forceState(StatePtr state)
Force a change of state of the state controller (callback-protected)
Definition: state_controller.cpp:212
boost::shared_ptr< State const > StateConstPtr
Used to represent a Boost shared pointer to a constant State object.
Definition: state_controller.h:413
const int id
The unique numeric ID of the state type.
Definition: state_controller.h:448
Base class for all state controllers.
Definition: state_controller.h:593
Implements a state that a state controller can be in.
Definition: state_controller.h:432
cycle_t execCycleNum(cycle_t cyc) const
The number of cycles since the first call to execute(), including the initial call cycle and the curr...
Definition: state_controller.h:470
const std::string name
The human-friendly name of the state type.
Definition: state_controller.h:449
unsigned int cycle_t
Used to count the number of executed state controller cycles.
Definition: state_controller.h:415
const action_t HOLD_THIS_STATE
Specifies that the state controller should remain in its current state in the next step...
Definition: state_controller.h:422
void set(index_t ind, StatePtr state)
Does nothing if ind is out of range or nullIndex.
Definition: state_controller.h:546
void clear()
For use by state controller states (guaranteed not to cause vector reallocation)
Definition: state_controller.h:540
virtual action_t execute(cycle_t cyc)=0
State execution callback.
void clear_hard()
For use during reset/initialisation (may trigger vector reallocation)
Definition: state_controller.h:541
bool action_t
Used to represent the state transition actions (HOLD_THIS_STATE and PROCEED_NEXT_STATE) ...
Definition: state_controller.h:416
StateConstPtr getCurState() const
Return a constant reference to the current state.
Definition: state_controller.h:619
cycle_t firstExecCycle() const
The cycle ID of the first call to execute() for this state instance.
Definition: state_controller.h:469
virtual StateController * scref() const =0
Return pointer to owning state controller.
virtual void preExecuteCallback()
A callback that is executed in the step() function immediately prior to the execution of the current ...
Definition: state_controller.h:641
ret_t init(StatePtr state)
Reset and initialise the state controller with a particular state (callback-protected) ...
Definition: state_controller.cpp:176
int ret_t
Used to represent the return codes from state controller functions.
Definition: state_controller.h:417
static bool isNull(StateConstPtr state)
Return whether a StatePtr is null.
Definition: state_controller.h:453
virtual void preActivateCallback(bool willCallActivate)
A callback that is executed in the step() function immediately prior to the activation of a state (ca...
Definition: state_controller.h:640
StatePtr headItem() const
Returns nullStatePtr if queue is empty.
Definition: state_controller.h:565
Implements a dynamic State queue.
Definition: state_controller.h:522
bool containsID(int id) const
Always successful.
Definition: state_controller.h:572
ret_t loop()
Execute state controller steps until either an error or clean termination occurs (callback-protected)...
Definition: state_controller.cpp:311
cycle_t getCycle() const
Return the current cycle count (zero after reset)
Definition: state_controller.h:618
const std::string name
The human-friendly name of the state controller.
Definition: state_controller.h:605
virtual ~State()
Destructor.
Definition: state_controller.h:445
Specialises the State class using templates to take care of the most common overloads.
Definition: state_controller.h:397
bool isEmpty() const
Always successful.
Definition: state_controller.h:559
static const index_t DEF_QUEUE_CAPACITY
Default queue capacity to reserve in memory on reset.
Definition: state_controller.h:526
void setNextState(StatePtr state)
Clears the entire queue and sets the next state to the given state instance (use only with simple nex...
Definition: state_controller.h:549
virtual ~StateQueue()
Destructor.
Definition: state_controller.h:530
State(int id, const std::string &name, const std::string &scname)
Default constructor.
Definition: state_controller.h:436
Signals that a state was encountered that belongs to another state controller instance (or none at al...
Definition: state_controller.h:407
const StatePtr nullStatePtr
Null StatePtr.
Definition: state_controller.h:420
std::size_t index_t
Used to represent an array/vector/queue index (this MUST be an unsigned type)
Definition: state_controller.h:414
virtual void deactivate(cycle_t cyc, bool wasExecuted)
State deactivation callback.
Definition: state_controller.h:465
index_t tailIndex() const
Returns nullIndex if queue is empty.
Definition: state_controller.h:564
Signals that a callback tried to call a function in StateController that it isn't supposed to...
Definition: state_controller.h:408
virtual void activate(cycle_t cyc)
State activation callback.
Definition: state_controller.h:463
Signals that a null state was encountered (where it wasn't expected)
Definition: state_controller.h:406
virtual StateController * scref() const
Return pointer to owning state controller.
Definition: state_controller.h:509
SCReturnID
Used to specify return values and error codes of state controller functions.
Definition: state_controller.h:402
StatePtr stateOf(int id, index_t start=0) const
Returns nullStatePtr if the given ID is not found.
Definition: state_controller.cpp:76
const action_t PROCEED_NEXT_STATE
Specifies that the state controller should advance the queue and retrieve a new State in the next ste...
Definition: state_controller.h:423
virtual bool postExecuteCallback()
A callback that is executed in the step() function immediately after the execution of the current sta...
Definition: state_controller.h:642
virtual void postStepCallback()
A callback that is executed at the very end of the step() function whenever the current state is not ...
Definition: state_controller.h:644
virtual bool preStepCallback()
A callback that is executed at the very beginning of the step() function, right after the cycle count...
Definition: state_controller.h:639
const index_t nullIndex
Null index_t (nullIndex is guaranteed to exceed std::vector::max_size(), so there is no loss here) ...
Definition: state_controller.h:421
bool isActive() const
Return whether the state controller is active or not.
Definition: state_controller.h:617