00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArRobot.h"
00029 #include "ArBumpers.h"
00030
00039 AREXPORT ArBumpers::ArBumpers(size_t currentBufferSize, size_t cumulativeBufferSize,
00040 const char *name, int maxSecondsToKeepCurrent, double angleRange) :
00041 ArRangeDevice(currentBufferSize, cumulativeBufferSize, name, 5000, maxSecondsToKeepCurrent),
00042 myProcessCB(this, &ArBumpers::processReadings)
00043 {
00044 myBumpMask = (ArUtil::BIT1 | ArUtil::BIT2 | ArUtil::BIT3 | ArUtil::BIT4 |
00045 ArUtil::BIT5 | ArUtil::BIT6 | ArUtil::BIT7 | ArUtil::BIT8);
00046
00047 myAngleRange = angleRange;
00048
00049 setCurrentDrawingData(new ArDrawingData("polyDots", ArColor(0, 0, 0),
00050 120,
00051 83),
00052 true);
00053 }
00054
00055 AREXPORT ArBumpers::~ArBumpers()
00056 {
00057 if (myRobot != NULL)
00058 {
00059 myRobot->remSensorInterpTask(&myProcessCB);
00060 myRobot->remRangeDevice(this);
00061 }
00062 }
00063
00064 AREXPORT void ArBumpers::setRobot(ArRobot *robot)
00065 {
00066 myRobot = robot;
00067 if (myRobot != NULL)
00068 myRobot->addSensorInterpTask(myName.c_str(), 10, &myProcessCB);
00069 ArRangeDevice::setRobot(robot);
00070 }
00071
00075 AREXPORT void ArBumpers::processReadings(void)
00076 {
00077 int frontBump;
00078 int rearBump;
00079 int whichBumper;
00080
00081 if (myRobot->hasFrontBumpers())
00082 frontBump = ((myRobot->getStallValue() & 0xff00) >> 8) & myBumpMask;
00083 else
00084 {
00085 frontBump = 0;
00086 }
00087 if (myRobot->hasRearBumpers())
00088 rearBump = (myRobot->getStallValue() & 0xff) & myBumpMask;
00089 else
00090 {
00091 rearBump = 0;
00092 }
00093
00094 if(frontBump!= 0)
00095 {
00096 whichBumper = 1;
00097 addBumpToBuffer(frontBump, whichBumper);
00098 }
00099
00100 if(rearBump != 0)
00101 {
00102 whichBumper = 2;
00103 addBumpToBuffer(rearBump, whichBumper);
00104 }
00105
00106 }
00107
00112 AREXPORT void ArBumpers::addBumpToBuffer(int bumpValue, int whichBumper)
00113 {
00114 int numBumpers;
00115 double x;
00116 double y;
00117 double degree;
00118 double radius;
00119
00120 const ArRobotParams *params;
00121 params = myRobot->getRobotParams();
00122
00123 radius = params->getRobotRadius();
00124
00125 if(whichBumper == 1) numBumpers = myRobot->getNumFrontBumpers();
00126 else numBumpers = myRobot->getNumRearBumpers();
00127
00128 for (int i = 0; i < numBumpers; i++)
00129 {
00130 if((i == 0 && (bumpValue & ArUtil::BIT1)) ||
00131 (i == 1 && (bumpValue & ArUtil::BIT2)) ||
00132 (i == 2 && (bumpValue & ArUtil::BIT3)) ||
00133 (i == 3 && (bumpValue & ArUtil::BIT4)) ||
00134 (i == 4 && (bumpValue & ArUtil::BIT5)) ||
00135 (i == 5 && (bumpValue & ArUtil::BIT6)) ||
00136 (i == 6 && (bumpValue & ArUtil::BIT7)) ||
00137 (i == 7 && (bumpValue & ArUtil::BIT8)))
00138 {
00139 degree = -1 * (i * (myAngleRange / (double)numBumpers) +
00140 ((myAngleRange / (double)numBumpers) / 2) - (myAngleRange / 2));
00141
00142 if(whichBumper == 2) degree = degree + 180;
00143
00144 x = radius * ArMath::cos(degree);
00145 y = radius * ArMath::sin(degree);
00146
00147 ArPose pose;
00148 pose.setX(x);
00149 pose.setY(y);
00150
00151 ArTransform global = myRobot->getToGlobalTransform();
00152 pose = global.doTransform(pose);
00153
00154 ArLog::log(ArLog::Verbose, "Bumpers: recording %s bumper hit (bumpflags=%d)", (whichBumper==1?"front":"rear"), bumpValue);
00155
00156 myCurrentBuffer.addReading(pose.getX(), pose.getY());
00157 }
00158 }
00159 }