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

ArP2Arm.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 "ArP2Arm.h"
00029 #include "ariaUtil.h"
00030 #include "ArLog.h"
00031 #include "ariaInternal.h"
00032 
00033 int ArP2Arm::NumJoints=6;
00034 const unsigned int ArP2Arm::ARMpac=0xa0;
00035 const unsigned int ArP2Arm::ARMINFOpac=0xa1;
00036 const unsigned char ArP2Arm::ComArmInfo=70;
00037 const unsigned char ArP2Arm::ComArmStats=71;
00038 const unsigned char ArP2Arm::ComArmInit=72;
00039 const unsigned char ArP2Arm::ComArmCheckArm=73;
00040 const unsigned char ArP2Arm::ComArmPower=74;
00041 const unsigned char ArP2Arm::ComArmHome=75;
00042 const unsigned char ArP2Arm::ComArmPark=76;
00043 const unsigned char ArP2Arm::ComArmPos=77;
00044 const unsigned char ArP2Arm::ComArmSpeed=78;
00045 const unsigned char ArP2Arm::ComArmStop=79;
00046 const unsigned char ArP2Arm::ComArmAutoPark=80;
00047 const unsigned char ArP2Arm::ComArmGripperPark=81;
00048 const int ArP2Arm::ArmJoint1=0x1;
00049 const int ArP2Arm::ArmJoint2=0x2;
00050 const int ArP2Arm::ArmJoint3=0x4;
00051 const int ArP2Arm::ArmJoint4=0x8;
00052 const int ArP2Arm::ArmJoint5=0x10;
00053 const int ArP2Arm::ArmJoint6=0x20;
00054 const int ArP2Arm::ArmGood=0x100;
00055 const int ArP2Arm::ArmInited=0x200;
00056 const int ArP2Arm::ArmPower=0x400;
00057 const int ArP2Arm::ArmHoming=0x800;
00058 
00059 
00060 AREXPORT ArP2Arm::ArP2Arm() :
00061   myInited(false),
00062   myRobot(0),
00063   //  myModel(),
00064   myLastStatusTime(),
00065   myLastInfoTime(),
00066   myVersion(),
00067   myStatusRequest(ArP2Arm::StatusOff),
00068   myLastStatus(0),
00069   myStatus(0),
00070   myCon(),
00071   myAriaUninitCB(this, &ArP2Arm::uninit),
00072   myArmPacketHandler(this, &ArP2Arm::armPacketHandler),
00073   myPacketCB(0),
00074   myStoppedCB(0)
00075 {
00076   myArmPacketHandler.setName("ArP2Arm");
00077 }
00078 
00079 AREXPORT ArP2Arm::~ArP2Arm()
00080 {
00081   //uninit();
00082   if (myRobot != NULL)
00083     myRobot->remPacketHandler(&myArmPacketHandler);
00084 }
00085 
00093 AREXPORT ArP2Arm::State ArP2Arm::init()
00094 {
00095   ArLog::log(ArLog::Normal, "Initializing the arm.");
00096 
00097   ArTime now;
00098 
00099   if (myInited)
00100     return(ALREADY_INITED);
00101 
00102   if (!myRobot || !myRobot->isRunning() || !myRobot->isConnected())
00103     return(ROBOT_NOT_SETUP);
00104 
00105   Aria::addUninitCallBack(&myAriaUninitCB, ArListPos::FIRST);
00106   ArLog::log(ArLog::Verbose, "Adding the P2 Arm packet handler.");
00107   myRobot->addPacketHandler(&myArmPacketHandler, ArListPos::FIRST);
00108   now.setToNow();
00109   if (!comArmStats(StatusSingle))
00110     return(COMM_FAILED);
00111   ArUtil::sleep(100);
00112   if (!comArmInfo())
00113     return(COMM_FAILED);
00114   ArUtil::sleep(300);
00115 
00116   if (!now.isAfter(myLastStatusTime) || !now.isAfter(myLastInfoTime))
00117     return(COMM_FAILED);
00118 
00119   if (!(myStatus & ArmGood))
00120     return(NO_ARM_FOUND);
00121 
00122   myInited=true;
00123 
00124   return(SUCCESS);
00125 }
00126 
00132 AREXPORT ArP2Arm::State ArP2Arm::uninit()
00133 {
00134   bool ret;
00135 
00136   if (!myInited)
00137     return(NOT_INITED);
00138 
00139   ret=comArmPark();
00140 
00141   myInited=false;
00142   myVersion="";
00143   myStatusRequest=ArP2Arm::StatusOff;
00144   myLastStatus=0;
00145   myStatus=0;
00146   if (ret)
00147     return(SUCCESS);
00148   else
00149     return(COMM_FAILED);
00150 }
00151 
00159 AREXPORT ArP2Arm::State ArP2Arm::powerOn(bool doSleep)
00160 {
00161   if (isGood())
00162   {
00163     ArLog::log(ArLog::Normal, "ArP2Arm::powerOn: Powering arm.");
00164     if (!comArmPower(true))
00165       return(COMM_FAILED);
00166     // Sleep for 2 seconds to wait for the arm to stop shaking from the
00167     // effort of turning on
00168     if (doSleep)
00169       ArUtil::sleep(2000);
00170     return(SUCCESS);
00171   }
00172   else
00173     return(NOT_CONNECTED);
00174 }
00175 
00183 AREXPORT ArP2Arm::State ArP2Arm::powerOff()
00184 {
00185   if (isGood())
00186   {
00187     ArLog::log(ArLog::Normal, "ArP2Arm::powerOff: Powering off arm.");
00188     if (comArmPower(false))
00189       return(SUCCESS);
00190     else
00191       return(COMM_FAILED);
00192   }
00193   else
00194     return(NOT_CONNECTED);
00195 }
00196 
00204 AREXPORT ArP2Arm::State ArP2Arm::requestInfo()
00205 {
00206   if (isGood())
00207   {
00208     if (comArmInfo())
00209       return(SUCCESS);
00210     else
00211       return(COMM_FAILED);
00212   }
00213   else
00214     return(NOT_CONNECTED);
00215 }
00216 
00224 AREXPORT ArP2Arm::State ArP2Arm::requestStatus(StatusType status)
00225 {
00226   if (isGood())
00227   {
00228     if (comArmStats(status))
00229       return(SUCCESS);
00230     else
00231       return(COMM_FAILED);
00232   }
00233   else
00234     return(NOT_CONNECTED);
00235 }
00236 
00254 AREXPORT ArP2Arm::State ArP2Arm::requestInit()
00255 {
00256   if (isGood())
00257   {
00258     if (comArmInit())
00259       return(SUCCESS);
00260     else
00261       return(COMM_FAILED);
00262   }
00263   else
00264     return(NOT_CONNECTED);
00265 }
00266 
00288 AREXPORT ArP2Arm::State ArP2Arm::checkArm(bool waitForResponse)
00289 {
00290   ArTime now;
00291 
00292   if (isGood())
00293   {
00294     now.setToNow();
00295     if (!comArmInfo())
00296       return(COMM_FAILED);
00297     if (waitForResponse)
00298     {
00299       ArUtil::sleep(300);
00300       if (!myLastInfoTime.isAfter(now))
00301     return(COMM_FAILED);
00302       if (isGood())
00303     return(SUCCESS);
00304       else
00305     return(NO_ARM_FOUND);
00306     }
00307     else
00308       return(SUCCESS);
00309   }
00310   else
00311     return(NOT_CONNECTED);
00312 }
00313 
00323 AREXPORT ArP2Arm::State ArP2Arm::home(int joint)
00324 {
00325   if (!isGood())
00326     return(NOT_INITED);
00327 
00328   if ((joint < 0) && !comArmHome(0xff))
00329     return(COMM_FAILED);
00330   else if ((joint > 0) && (joint <= NumJoints) && !comArmHome(joint))
00331     return(COMM_FAILED);
00332   else
00333     return(INVALID_JOINT);
00334 
00335   return(SUCCESS);
00336 }
00337 
00353 AREXPORT ArP2Arm::State ArP2Arm::moveTo(int joint, float pos,  unsigned char vel)
00354 {
00355   unsigned char ticks;
00356 
00357   if (!isGood())
00358     return(NOT_INITED);
00359   else if ((joint <= 0) || (joint > NumJoints))
00360     return(INVALID_JOINT);
00361 
00362   //  if ((vel < 0) && !comArmSpeed(joint, 0-vel))
00363   //  return(COMM_FAILED);
00364   else if ((vel > 0) && !comArmSpeed(joint, vel))
00365     return(COMM_FAILED);
00366 
00367   if (!convertDegToTicks(joint, pos, &ticks))
00368     return(INVALID_POSITION);
00369 
00370   return(moveToTicks(joint, ticks));
00371 }
00372 
00388 AREXPORT ArP2Arm::State ArP2Arm::moveToTicks(int joint, unsigned char pos)
00389 {
00390   if (!isGood())
00391     return(NOT_INITED);
00392   else if ((joint <= 0) || (joint > NumJoints))
00393     return(INVALID_JOINT);
00394 
00395   if (!comArmPos(joint, pos))
00396     return(COMM_FAILED);
00397 
00398   return(SUCCESS);
00399 }
00400 
00414 AREXPORT ArP2Arm::State ArP2Arm::moveStep(int joint, float pos, unsigned char vel)
00415 {
00416   unsigned char ticks;
00417 
00418   if (!isGood())
00419     return(NOT_INITED);
00420   else if ((joint <= 0) || (joint > NumJoints))
00421     return(INVALID_JOINT);
00422 
00423   //  if ((vel < 0) && !comArmSpeed(joint, 0-vel))
00424   //  return(COMM_FAILED);
00425   else if ((vel > 0) && !comArmSpeed(joint, vel))
00426     return(COMM_FAILED);
00427 
00428   if (!convertDegToTicks(joint, pos, &ticks))
00429     return(INVALID_POSITION);
00430 
00431   return(moveStepTicks(joint, ticks));
00432 }
00433 
00449 AREXPORT ArP2Arm::State ArP2Arm::moveStepTicks(int joint, signed char pos)
00450 {
00451   if (!isGood())
00452     return(NOT_INITED);
00453   else if ((joint <= 0) || (joint > NumJoints))
00454     return(INVALID_JOINT);
00455 
00456   if (!comArmPos(joint, getJoint(joint)->myPos + pos))
00457     return(COMM_FAILED);
00458 
00459   return(SUCCESS);
00460 }
00461 
00474 AREXPORT ArP2Arm::State ArP2Arm::moveVel(int joint, int vel)
00475 {
00476   if (!isGood())
00477     return(NOT_INITED);
00478   else if ((joint <= 0) || (joint > NumJoints))
00479     return(INVALID_JOINT);
00480 
00481   if ((vel < 0) && (!comArmSpeed(joint, 0-vel) || !comArmPos(joint, 0)))
00482     return(COMM_FAILED);
00483   else if ((vel > 0) && (!comArmSpeed(joint, vel) || !comArmPos(joint, 255)))
00484     return(COMM_FAILED);
00485 
00486   return(SUCCESS);
00487 }
00488 
00493 AREXPORT ArP2Arm::State ArP2Arm::stop()
00494 {
00495   if (!isGood())
00496     return(NOT_INITED);
00497 
00498   if (!comArmStop())
00499     return(COMM_FAILED);
00500 
00501   return(SUCCESS);
00502 }
00503 
00504 AREXPORT float ArP2Arm::getJointPos(int joint)
00505 {
00506   float val;
00507 
00508   if (isGood() && (joint > 0) && (joint <= NumJoints) &&
00509       convertTicksToDeg(joint, getJoint(joint)->myPos, &val))
00510     return(val);
00511   else
00512     return(0.0);
00513 }
00514 
00515 AREXPORT unsigned char ArP2Arm::getJointPosTicks(int joint)
00516 {
00517   if (isGood() && (joint > 0) && (joint <= NumJoints))
00518     return(getJoint(joint)->myPos);
00519   else
00520     return(0);
00521 }
00522 
00523 AREXPORT P2ArmJoint * ArP2Arm::getJoint(int joint)
00524 {
00525   if ((joint > 0) && (joint <= NumJoints))
00526     return(&myJoints[joint-1]);
00527   else
00528     return(0);
00529 }
00530 
00531 bool ArP2Arm::armPacketHandler(ArRobotPacket *packet)
00532 {
00533   bool doWake;
00534   int i;
00535 
00536   if (packet->getID() == ARMpac)
00537   {
00538     myLastStatusTime.setToNow();
00539     myLastStatus=myStatus;
00540     myStatus=packet->bufToUByte2();
00541     for (i=1; i<=NumJoints; ++i)
00542       getJoint(i)->myPos=packet->bufToUByte();
00543 
00544     // Wake up all threads waiting for the arm to stop moving
00545     for (doWake=false, i=0; i<8; ++i)
00546     {
00547       if (((myLastStatus & (1 << i)) != (myStatus & (1 << i))) &&
00548       (myStatus & (1 << i)))
00549     doWake=true;
00550     }
00551     if (doWake && myStoppedCB)
00552       myStoppedCB->invoke();
00553     if (myPacketCB)
00554       myPacketCB->invoke(StatusPacket);
00555     return(true);
00556   }
00557   else if (packet->getID() == ARMINFOpac)
00558   {
00559     char version[512];
00560     myLastInfoTime.setToNow();
00561     packet->bufToStr(version, 512);
00562     myVersion=version;
00563     NumJoints=packet->bufToUByte();
00564     for (i=1; i<=NumJoints; ++i)
00565     {
00566       getJoint(i)->myVel=packet->bufToUByte();
00567       getJoint(i)->myHome=packet->bufToUByte();
00568       getJoint(i)->myMin=packet->bufToUByte();
00569       getJoint(i)->myCenter=packet->bufToUByte();
00570       getJoint(i)->myMax=packet->bufToUByte();
00571       getJoint(i)->myTicksPer90=packet->bufToUByte();
00572     }
00573     if (myPacketCB)
00574       myPacketCB->invoke(InfoPacket);
00575     return(true);
00576     }
00577   else
00578     return(false);
00579 }
00580 
00581 bool ArP2Arm::comArmInfo()
00582 {
00583   return(myRobot->com(ComArmInfo));
00584 }
00585 
00586 bool ArP2Arm::comArmStats(StatusType stats)
00587 {
00588   return(myRobot->comInt(ComArmStats, (int)stats));
00589 }
00590 
00591 bool ArP2Arm::comArmInit()
00592 {
00593   return(myRobot->com(ComArmInit));
00594 }
00595 
00596 bool ArP2Arm::comArmCheckArm()
00597 {
00598   return(myRobot->com(ComArmCheckArm));
00599 }
00600 
00601 bool ArP2Arm::comArmPower(bool on)
00602 {
00603   if (on)
00604     return(myRobot->comInt(ComArmPower, 1));
00605   else
00606     return(myRobot->comInt(ComArmPower, 0));
00607 }
00608 
00609 bool ArP2Arm::comArmHome(unsigned char joint)
00610 {
00611   return(myRobot->comInt(ComArmHome, joint));
00612 }
00613 
00614 bool ArP2Arm::comArmPos(unsigned char joint, unsigned char pos)
00615 {
00616   return(myRobot->com2Bytes(ComArmPos, joint, pos));
00617 }
00618 
00619 bool ArP2Arm::comArmSpeed(unsigned char joint, unsigned char speed)
00620 {
00621   return(myRobot->com2Bytes(ComArmSpeed, joint, speed));
00622 }
00623 
00624 bool ArP2Arm::comArmStop(unsigned char joint)
00625 {
00626   return(myRobot->comInt(ComArmStop, joint));
00627 }
00628 
00629 bool ArP2Arm::comArmPark()
00630 {
00631   return(myRobot->com(ComArmPark));
00632 }
00633 
00634 bool ArP2Arm::comArmAutoPark(int waitSecs)
00635 {
00636   return(myRobot->comInt(ComArmAutoPark, waitSecs));
00637 }
00638 
00639 bool ArP2Arm::comArmGripperPark(int waitSecs)
00640 {
00641   return(myRobot->comInt(ComArmGripperPark, waitSecs));
00642 }
00643 
00644 AREXPORT bool ArP2Arm::getMoving(int joint)
00645 {
00646   if ((joint < 0) && (myStatus & 0xf))
00647     return(true);
00648   else if (myStatus & (1 << joint))
00649     return(true);
00650   else
00651     return(false);
00652 }
00653 
00654 AREXPORT bool ArP2Arm::isPowered()
00655 {
00656   if (myStatus & ArmPower)
00657     return(true);
00658   else
00659     return(false);
00660 }
00661 
00662 AREXPORT bool ArP2Arm::isGood()
00663 {
00664   if (myRobot && myRobot->isRunning() && myRobot->isConnected() &&
00665       myInited && (myStatus & ArmGood) && (myStatus & ArmInited))
00666     return(true);
00667   else
00668     return(false);
00669 }
00670 
00671 AREXPORT ArP2Arm::State ArP2Arm::park()
00672 {
00673   if (!isGood())
00674     return(NOT_INITED);
00675 
00676   if (comArmPark())
00677     return(SUCCESS);
00678   else
00679     return(COMM_FAILED);
00680 }
00681 
00690 AREXPORT ArP2Arm::State ArP2Arm::setAutoParkTimer(int waitSecs)
00691 {
00692   if (!isGood())
00693     return(NOT_INITED);
00694 
00695   if (comArmAutoPark(waitSecs))
00696     return(SUCCESS);
00697   else
00698     return(COMM_FAILED);
00699 }
00700 
00710 AREXPORT ArP2Arm::State ArP2Arm::setGripperParkTimer(int waitSecs)
00711 {
00712   if (!isGood())
00713     return(NOT_INITED);
00714 
00715   if (comArmGripperPark(waitSecs))
00716     return(SUCCESS);
00717   else
00718     return(COMM_FAILED);
00719 }
00720 
00721 AREXPORT bool ArP2Arm::convertDegToTicks(int joint, float pos,
00722                        unsigned char *ticks)
00723 {
00724   long val;
00725 
00726   if ((joint <= 0) || (joint > NumJoints))
00727     return(false);
00728 
00729   if (joint == 6)
00730     *ticks=(unsigned char)pos;
00731   else
00732   {
00733     val=ArMath::roundInt(getJoint(joint)->myTicksPer90*(pos/90.0));
00734     if ((joint >= 1) && (joint <= 3))
00735       val=-val;
00736     val+=getJoint(joint)->myCenter;
00737     if (val < getJoint(joint)->myMin)
00738       *ticks=getJoint(joint)->myMin;
00739     else if (val > getJoint(joint)->myMax)
00740       *ticks=getJoint(joint)->myMax;
00741     else
00742       *ticks=val;
00743   }
00744 
00745   return(true);
00746 }
00747 
00748 AREXPORT bool ArP2Arm::convertTicksToDeg(int joint, unsigned char pos,
00749                        float *degrees)
00750 {
00751   long val;
00752 
00753   if ((joint <= 0) || (joint > NumJoints))
00754     return(false);
00755 
00756   if (joint == 6)
00757     *degrees=pos;
00758   else
00759   {
00760     val=ArMath::roundInt(90.0/getJoint(joint)->myTicksPer90*
00761              (pos-getJoint(joint)->myCenter));
00762     if ((joint >= 1) && (joint <= 3))
00763       val=-val;
00764     *degrees=val;
00765   }
00766 
00767   return(true);
00768 }
00769 
00770 AREXPORT P2ArmJoint::P2ArmJoint() :
00771   myPos(0),
00772   myVel(0),
00773   myHome(0),
00774   myMin(0),
00775   myCenter(0),
00776   myMax(0),
00777   myTicksPer90(0)
00778 {
00779 }
00780 
00781 AREXPORT P2ArmJoint::~P2ArmJoint()
00782 {
00783 }
00784 

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