Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages | Examples

ArActionRobotJoydrive.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArActionRobotJoydrive.h"
00029 #include "ArRobot.h"
00030 #include "ariaInternal.h"
00031 #include "ArCommands.h"
00032 
00039 AREXPORT ArActionRobotJoydrive::ArActionRobotJoydrive(
00040     const char *name, bool requireDeadmanPushed) :
00041   ArAction(name, "This action reads the joystick on the robot and sets the translational and rotational velocities based on this."),
00042   myHandleJoystickPacketCB(this, &ArActionRobotJoydrive::handleJoystickPacket),
00043   myConnectCB(this, &ArActionRobotJoydrive::connectCallback)
00044 {
00045   myRequireDeadmanPushed = requireDeadmanPushed;
00046   setNextArgument(ArArg("whether to require the deadman to be pushed or not", &myRequireDeadmanPushed, "If this is true then deadman will need to be pushed to drive, if false we'll drive based on the joystick all the time"));
00047   myDeadZoneLast = false;
00048   myHandleJoystickPacketCB.setName("ArActionRobotJoydrive");
00049 }
00050 
00051 AREXPORT ArActionRobotJoydrive::~ArActionRobotJoydrive()
00052 {
00053 
00054 }
00055 
00056 AREXPORT void ArActionRobotJoydrive::setRobot(ArRobot *robot)
00057 {
00058   ArAction::setRobot(robot);
00059   if (myRobot != NULL)
00060   {
00061     myRobot->addConnectCB(&myConnectCB);
00062     myRobot->addPacketHandler(&myHandleJoystickPacketCB);
00063     if (robot->isConnected())
00064       connectCallback();
00065   }
00066 }
00067 
00068 AREXPORT void ArActionRobotJoydrive::connectCallback(void)
00069 {
00070   myRobot->comInt(ArCommands::JOYINFO, 2);
00071 }
00072 
00073 AREXPORT bool ArActionRobotJoydrive::handleJoystickPacket(
00074     ArRobotPacket *packet)
00075 {
00076   if (packet->getID() != 0xF8)
00077     return false;
00078   
00079   myPacketReceivedTime.setToNow();
00080 
00081   myButton1 = packet->bufToUByte();
00082   myButton2 = packet->bufToUByte();
00083   myJoyX = packet->bufToUByte2();
00084   myJoyY = packet->bufToUByte2();
00085   myThrottle = packet->bufToUByte2();
00086 
00087   //printf("%d %d %d %d %d\n", myButton1, myButton2, myJoyX, myJoyY, myThrottle);
00088   return true;
00089 }
00090 
00091 AREXPORT ArActionDesired *ArActionRobotJoydrive::fire(ArActionDesired currentDesired)
00092 {
00093   bool printing = false;
00094   myDesired.reset();
00095   // if we need the deadman to activate and it isn't pushed just bail
00096   if (myRequireDeadmanPushed && !myButton1)
00097   {
00098     if (printing)
00099       printf("ArActionRobotJoydrive: Nothing\n");
00100     myDeadZoneLast = false;
00101     return NULL;
00102   }
00103 
00104   // these should vary between 1 and -1
00105   double ratioRot = -(myJoyX - 512) / 512.0;
00106   double ratioTrans = (myJoyY - 512) / 512.0;
00107   double ratioThrottle = myThrottle / 1024.0;
00108   
00109   bool doTrans = ArMath::fabs(ratioTrans) > .33;
00110   bool doRot = ArMath::fabs(ratioRot) > .33;
00111 
00112   if (0)
00113     printf("%.0f %.0f (x %.3f y %.3f throttle %.3f)\n", ratioTrans * ratioThrottle * 1000,
00114        ratioRot * ratioThrottle * 50, ratioTrans, ratioRot, ratioThrottle);
00115   if (!doTrans && !doRot)
00116   {
00117     // if the joystick is in the center, we don't need the deadman,
00118     // and we were stopped lasttime, then just let other stuff go
00119     if (myDeadZoneLast && !myRequireDeadmanPushed) 
00120     {
00121       if (printing)
00122     printf("ArActionRobotJoydrive: deadzone Nothing\n");
00123       return NULL;
00124     }
00125     // if the deadman doesn't need to be pushed let something else happen here
00126     if (printing)
00127       printf("ArActionRobotJoydrive: deadzone\n");
00128     myDesired.setVel(0);
00129     myDesired.setDeltaHeading(0);
00130     myDeadZoneLast = true;
00131     return &myDesired;
00132   }
00133 
00134   myDeadZoneLast = false;
00135   // if they have the stick the opposite direction of the velocity
00136   // then let people crank up the deceleration
00137   if (doTrans && ((myRobot->getVel() > 0 && ratioTrans < -0.5) || 
00138           (myRobot->getVel() < 0 && ratioTrans > 0.5)))
00139   {
00140     if (printing)
00141       printf("ArActionRobotJoydrive: Decelerating trans more\n");
00142     myDesired.setTransDecel(myRobot->getTransDecel() * 3);
00143   }
00144 
00145   // if they have the stick the opposite direction of the velocity
00146   // then let people crank up the deceleration
00147   if (doRot && ((myRobot->getRotVel() > 0 && ratioRot < -0.5) || 
00148           (myRobot->getRotVel() < 0 && ratioRot > 0.5)))
00149   {
00150     if (printing)
00151       printf("ArActionRobotJoydrive: Decelerating rot more\n");
00152     myDesired.setRotDecel(myRobot->getRotDecel() * 3);
00153   }
00154 
00155   if (doTrans)
00156     myDesired.setVel(ratioTrans * ratioThrottle * myRobot->getTransVelMax());
00157   else
00158     myDesired.setVel(0);
00159 
00160   printf("%.0f %.0f\n", ratioTrans * ratioThrottle * myRobot->getTransVelMax(),
00161      ratioRot * ratioThrottle * myRobot->getRotVelMax());
00162 
00163   
00164   if (doRot)
00165     myDesired.setRotVel(ratioRot * ratioThrottle * myRobot->getRotVelMax());
00166   else
00167     myDesired.setRotVel(0);
00168 
00169   if(printing)
00170     printf("ArActionRobotJoydrive: (%ld ms ago) we got %d %d %.2f %.2f %.2f (speed %.0f %.0f)\n", 
00171      myPacketReceivedTime.mSecSince(),
00172      myButton1, myButton2, ratioTrans, ratioRot, ratioThrottle,
00173      myRobot->getVel(), myRobot->getRotVel());
00174   return &myDesired;
00175 }

Generated on Tue Feb 20 10:51:38 2007 for Aria by  doxygen 1.4.0