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

ArP2Arm.cpp

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

Generated on Wed Oct 19 12:56:36 2005 for Aria by  doxygen 1.4.0