Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

ArmController.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_ArmController_h_
00003 #define INCLUDED_ArmController_h_
00004 
00005 #include <iostream>
00006 #include "Wireless/Wireless.h"
00007 #include "Behaviors/BehaviorBase.h"
00008 #include "Motion/MotionManager.h"
00009 #include "Events/EventRouter.h"
00010 #include "Events/EventBase.h"
00011 #include "Shared/Config.h"
00012 #include "Motion/PIDMC.h"
00013 #include "Motion/MotionSequenceMC.h"
00014 #include "IPC/SharedObject.h"
00015 #include "Events/EventRouter.h"
00016 #include "Motion/KinematicJoint.h"
00017 #include "Shared/TimeET.h"
00018 
00019 //! Listens to control commands coming in from the command port for remotely controlling the arm.
00020 /*! The communication protocol is a very simple binary format, shared
00021  *  with WalkControllerBehavior.  Each command is sent as a 5-byte
00022  *  group.  The first byte is a command selector, and the following 4
00023  *  bytes are a floating point argument:
00024  *
00025  *  - <@c char: command indicator>
00026  *  - <@c float: value>
00027  *  
00028  *  The valid values for command indicator are given by #CMD_shoulder,
00029  *  #CMD_elbow, or #CMD_wrist ('s', 'e', or 'w' respectively).
00030  */  
00031 class ArmController : public BehaviorBase {
00032   
00033 public: 
00034   //! Points to the one ArmController object that the input command stream is talking to.
00035   /*! A kludge. Dunno how you're going to make sure you're not using this uninitialized. */
00036   static ArmController * theOne;
00037   static int mechacmd_callback(char *buf, int bytes); //!< called by wireless when there's new data
00038   
00039 protected:
00040   //! The ArmMC, for moving individual joints
00041   MotionManager::MC_ID armMCID;
00042   
00043   //! The PIDMC
00044   MotionManager::MC_ID pidMCID;
00045   
00046   //! Used to run motion sequences for smooth paths to points picked in the ArmGUI
00047   MotionManager::MC_ID seqMCID;
00048   
00049   //! Kinematic Joint for the Gripper Frame
00050   KinematicJoint* gripperFrameKJ;
00051   
00052   //! To test for valid points, we use a separate kinematic chain
00053   KinematicJoint* successJ;
00054   
00055   //! All of the joints in the arm
00056   KinematicJoint* KJjoints[NumArmJoints];
00057   
00058   //! Horizontal scaling factor for the Point Picker
00059   float horScale;
00060   
00061   //! Vertical scaling factor for the Point Picker
00062   float verScale;
00063   
00064   //! Number of interpolation steps to take when moving from one point to the next
00065   unsigned int numSteps;
00066   
00067   //! Interpolation steps: every time we receive a joint update, we fire another.
00068   std::queue<fmat::Column<3> > steps;
00069   
00070   //! Controls whether we have one or two Point Pickers, and which kind.
00071   enum DisplayMode_t {
00072     pitchAndYaw = 0,
00073     yawOnly,
00074     pitchOnly
00075   } displayMode;
00076   
00077   //! @name Command Bytes        
00078   static const char cmdUnrelax     = 'u';
00079   static const char cmdRelax       = 'v';
00080   static const char cmdGripper     = 'w';
00081   static const char cmdPoint       = 'x';
00082   static const char cmdSpeed       = 'y';
00083   static const char cmdConnect     = 'z';
00084   static const char cmdOrientation = 'o';
00085   
00086   //! Angle between base horizontal joint and gripper, as from a bird's eye view
00087   /*! To be kept constant between point picks. */
00088   float theta;
00089   
00090   //! Height of point picked
00091   /*! To be kept constant between point picks. */
00092   float z;
00093   
00094   //! First horizontal joint location, relative to base
00095   fmat::Column<3> horToBase;
00096   
00097   //! First vertical joint location, relative to base
00098   fmat::Column<3> verToBase;
00099   
00100   //! Maximum speed for every joint
00101   float speed;
00102   
00103   //! Target arm orientations for IKSolver
00104   fmat::Quaternion orientation[2];
00105   
00106   //! Currently selected orientation (0 - side, 1 - overhead)
00107   int orientationIndex;
00108   
00109   //! Number of yaw joints
00110   unsigned int numYawJoints;
00111   
00112   //! Number of pitch joints
00113   unsigned int numPitchJoints;
00114   
00115   //! Total number of links to display (@a numYawJoints + @a numPitchJoints)
00116   unsigned int linksToDisplay;
00117   
00118   //! Delay between sending reachable points
00119   TimeET reachablePointsDelay;
00120   
00121   //! Whether each joint is horizontal or vertical
00122   char armConfig[NumArmJoints];
00123   
00124   //! Horizontal joint coordinates
00125   float yawCoords[NumArmJoints][2];
00126   
00127   //! Vertical joint coordinates
00128   float pitchCoords[NumArmJoints][2];
00129   
00130   //! The last HPCB object that was theOne.
00131   /*! So we can restore it to prominence when we die.
00132    *  This is a nice gesture, but it doesn't
00133    *  really make sense since we're all using the same port. But just
00134    *  in case something changes and we don't do that, this mechanism
00135    *  is in place. */
00136   ArmController *theLastOne;
00137   
00138   //! The input command stream socket
00139   Socket *cmdsock;
00140   
00141   //! Executes a command. Called by mechacmd_callback.
00142   void runCommand(unsigned char *command);
00143   void doEvent();
00144   
00145   //! Possible commands from ArmGUI
00146   void connect();
00147   void pointPicked(float param, float param2, float param3, int cmdno);
00148   void gripper(float param, int cmdno);
00149   void relax();
00150   void unrelax();
00151   void setJoint(unsigned int joint, float param);
00152   
00153   ArmController(const ArmController&); //!< don't call
00154   ArmController operator=(const ArmController&); //!< don't call
00155   
00156 public:
00157   //! constructor
00158   ArmController() : BehaviorBase("ArmController"),
00159   armMCID(MotionManager::invalid_MC_ID),
00160   pidMCID(MotionManager::invalid_MC_ID),
00161   seqMCID(MotionManager::invalid_MC_ID),
00162   gripperFrameKJ(NULL),
00163   successJ(NULL),
00164   KJjoints(),
00165   horScale(0),
00166   verScale(0),
00167   numSteps(40),
00168   steps(),
00169   displayMode(),
00170   theta(0),
00171   z(0),
00172   horToBase(),
00173   verToBase(),
00174   speed(0.4f),
00175   orientation(),
00176   orientationIndex(0),
00177   numYawJoints(0),
00178   numPitchJoints(0),
00179   linksToDisplay(0),
00180   reachablePointsDelay(),
00181   yawCoords(),
00182   pitchCoords(),
00183   theLastOne(theOne), /* Set the default to the robot last joint before the gripper */
00184   cmdsock(NULL) {
00185     for(unsigned int i =0; i < (NumArmJoints+1); i++)
00186       armConfig[i] = '\0';
00187     gripperFrameKJ = kine->getKinematicJoint(GripperFrameOffset)->cloneBranch();
00188     successJ = kine->getKinematicJoint(GripperFrameOffset)->cloneBranch();
00189     
00190 #ifdef TGT_IS_CALLIOPE5
00191     orientation[0] = fmat::Quaternion::aboutY(M_PI_2);
00192     orientation[1] = fmat::Quaternion::aboutY(M_PI);
00193 #else
00194     orientation[0] = orientation[1] = fmat::Quaternion::IDENTITY;
00195 #endif
00196   }
00197   
00198   //! destructor
00199   virtual ~ArmController() {
00200     theOne = theLastOne;
00201     delete gripperFrameKJ;
00202     gripperFrameKJ = NULL;
00203   }
00204   
00205   //! Setup the scale and the joints quantity to display
00206   virtual void doStart();
00207   
00208   virtual void doStop();
00209   
00210   //! Compute the joint positions
00211   void computeCoords();
00212   
00213   //! Send the joint positions to the ArmGUI
00214   void sendCoords();
00215   
00216   //! Compute and send reachable points w/ given orientation
00217   /*! Only applicable for robots with vertical joints. param = 1.0 for horizontal
00218    *  and 2.0 for vertical. */
00219   void sendReachablePoints(DisplayMode_t d);
00220   
00221   static std::string getClassDescription() {
00222     char tmp[20];
00223     sprintf(tmp,"%d",*config->main.armControl_port);
00224     return std::string("Listens to arm control commands coming in from port ")+tmp;
00225   }
00226   
00227   virtual std::string getDescription() const { return getClassDescription(); }
00228 };
00229 
00230 /*! @file
00231  * @brief Describes ArmController, listens to control commands coming in from the command port for remotely controlling the head
00232  * @author tss (Creator)
00233  */
00234 
00235 #endif 

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