Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

WalkController.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_WalkController_h_
00003 #define INCLUDED_WalkController_h_
00004 
00005 #include "Behaviors/BehaviorBase.h"
00006 #include "Motion/MotionManager.h"
00007 #include "Motion/WalkMC.h"
00008 #include "Motion/MMAccessor.h"
00009 #include "Events/EventRouter.h"
00010 #include "Events/EventBase.h"
00011 #include "Shared/Config.h"
00012 #include "Wireless/Wireless.h"
00013 #include "IPC/SharedObject.h"
00014 
00015 #include <iostream>
00016 
00017 //! Listens to control commands coming in from the command port for remotely controlling the walk
00018 /*! The communication protocol is a very simple binary format, shared
00019  *  with HeadPointControllerBehavior.  Each command is sent as a
00020  *  5-byte group.  The first byte is a command selector, and the
00021  *  following 4 bytes are a floating point argument:
00022  *
00023  *  - <@c char: command indicator>
00024  *  - <@c float: value>
00025  *  
00026  *  The valid values for command indicator are given by #CMD_fwd,
00027  *  #CMD_roto, or #CMD_side ('f', 'r', or 's' respectively).  Others
00028  *  are listed below, but are not currently used.
00029  */  
00030 class WalkController : public BehaviorBase {
00031 
00032  public:  
00033   //! Points to the one WalkController object that the input
00034   //! command stream is talking to. A kludge. Dunno how you're gonna
00035   //! make sure you're not using this uninitialized.
00036   static WalkController * theOne;
00037   static int mechacmd_callback(char *buf, int bytes); //!< called by wireless when there's new data
00038 
00039  protected:
00040   enum { TIMER_COMM_CHECK, TIMER_COMM_TIMEOUT };
00041   SharedObject<WalkMC> shared_walker; //!< the WalkMC to use
00042  
00043  private:
00044   //!@name Command Bytes
00045   static const char CMD_fwd  = 'f'; //!< handy symbol for matching incoming communication
00046   static const char CMD_roto = 'r';
00047   static const char CMD_side = 's';
00048   static const char CMD_opt0 = '0';
00049   static const char CMD_opt1 = '1';
00050   static const char CMD_opt2 = '2';
00051   static const char CMD_opt3 = '3';
00052   static const char CMD_opt4 = '4';
00053   static const char CMD_opt5 = '5';
00054   static const char CMD_opt6 = '6';
00055   static const char CMD_opt7 = '7';
00056   static const char CMD_opt8 = '8';
00057   static const char CMD_opt9 = '9';
00058   //@}
00059 
00060   float dx; //!< Motion parameter
00061   float dy; //!< Motion parameter
00062   float da; //!< Motion parameter
00063   
00064   bool keepGUI; //!< if set to true (default false) then the closeGUI call will be skipped on doStop()
00065 
00066   //! The last WCB object that was theOne, so we can restore it
00067   //! to prominence when we die. This is a nice gesture, but it doesn't
00068   //! really make sense since we're all using the same port. But just
00069   //! in case something changes and we don't do that, this mechanism
00070   //! is in place.
00071   WalkController *theLastOne;
00072 
00073   //! The input command stream socket
00074   Socket *cmdsock;
00075   //! So we can test for remote closure
00076   int sock;
00077 
00078   //! Executes a command. Called by mechacmd_callback.
00079   void runCommand(unsigned char *command);
00080   
00081   //! closes server socket, but skips sending close GUI command
00082   void shutdown();
00083 
00084   WalkController(const WalkController&); //!< don't call
00085   WalkController operator=(const WalkController&); //!< don't call
00086 
00087  public:
00088   //! constructor
00089   WalkController() :
00090     BehaviorBase("WalkController"),
00091     shared_walker(),
00092     dx(0), dy(0), da(0), keepGUI(false),
00093     theLastOne(theOne),
00094     cmdsock(NULL), sock(-1)
00095   {}
00096   //! destructor
00097   virtual ~WalkController() { theOne = theLastOne; }
00098 
00099   virtual void doStart();
00100 
00101   virtual void doStop();
00102   
00103   void setKeepGUI(bool b=true) { keepGUI = b; }
00104 
00105   virtual WalkMC * getWalkMC() { return &(*shared_walker); }  //!< returns the WalkMC which [will be|is being] used
00106 
00107   virtual MotionManager::MC_ID getWalkID() { return shared_walker->getID(); } //!< returns the current Walk's MotionCommand ID
00108 
00109   //! The only event we could possibly receive is the stop-if-no-heartbeat timer.
00110   virtual void doEvent() {
00111     if(event->getGeneratorID()==EventBase::runtimeEGID && event->getTypeID()==EventBase::deactivateETID) {
00112       shutdown();
00113       BehaviorBase::doStop();
00114       return;
00115     }
00116     if(event->getSourceID()==TIMER_COMM_TIMEOUT) {
00117       MMAccessor<WalkMC> walker(getWalkID());
00118       walker->setTargetVelocity(0,0,0);
00119     }
00120     if(cmdsock!=NULL && !wireless->isConnected(sock))
00121       stop();
00122   }
00123 
00124   static std::string getClassDescription() {
00125     char tmp[20];
00126     sprintf(tmp,"%d",*config->main.walkControl_port);
00127     return std::string("Listens to walk control commands coming in from port ")+tmp;
00128   }
00129   virtual std::string getDescription() const { return getClassDescription(); }
00130 };
00131 
00132 /*! @file
00133  * @brief Describes WalkController, listens to control commands coming in from the command port for remotely controlling the walk
00134  * @author tss (Creator)
00135  * @author ejt (modifications)
00136  * @author PA Gov. School for the Sciences 2003 Team Project - Haoqian Chen, Yantian Martin, Jon Stahlman (modifications)
00137  */
00138 
00139 #endif 

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:52 2016 by Doxygen 1.6.3