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
00027
00028 #include "ArExport.h"
00029 #include "ariaOSDef.h"
00030 #include "ArRobot.h"
00031 #include "ariaUtil.h"
00032 #include "ArForbiddenRangeDevice.h"
00033
00046 ArForbiddenRangeDevice::ArForbiddenRangeDevice(
00047 ArMap *armap, double distanceIncrement, unsigned int maxRange,
00048 const char *name) :
00049 ArRangeDevice(32000, 0, name, maxRange),
00050 myProcessCB(this, &ArForbiddenRangeDevice::processReadings),
00051 myMapChangedCB(this, &ArForbiddenRangeDevice::processMap) ,
00052 myEnableCB(this, &ArForbiddenRangeDevice::enable),
00053 myDisableCB(this, &ArForbiddenRangeDevice::disable)
00054 {
00055 myIsEnabled = true;
00056 myMap = armap;
00057 myDistanceIncrement = distanceIncrement;
00058 myMapChangedCB.setName("ArForbiddenRangeDevice");
00059 }
00060
00061 ArForbiddenRangeDevice::~ArForbiddenRangeDevice()
00062 {
00063
00064 }
00065
00066 void ArForbiddenRangeDevice::processMap(void)
00067 {
00068 std::list<ArMapObject *>::const_iterator it;
00069 ArMapObject *obj;
00070
00071 myDataMutex.lock();
00072 ArUtil::deleteSet(mySegments.begin(), mySegments.end());
00073 mySegments.clear();
00074
00075 for (it = myMap->getMapObjects()->begin();
00076 it != myMap->getMapObjects()->end();
00077 it++)
00078 {
00079 obj = (*it);
00080 if (strcmp(obj->getType(), "ForbiddenLine") == 0 &&
00081 obj->hasFromTo())
00082 {
00083 mySegments.push_back(new ArLineSegment(obj->getFromPose(),
00084 obj->getToPose()));
00085 }
00086 if (strcmp(obj->getType(), "ForbiddenArea") == 0 &&
00087 obj->hasFromTo())
00088 {
00089 mySegments.push_back(new ArLineSegment(obj->getFromPose().getX(),
00090 obj->getFromPose().getY(),
00091 obj->getToPose().getX(),
00092 obj->getFromPose().getY()));
00093 mySegments.push_back(new ArLineSegment(obj->getToPose().getX(),
00094 obj->getFromPose().getY(),
00095 obj->getToPose().getX(),
00096 obj->getToPose().getY()));
00097 mySegments.push_back(new ArLineSegment(obj->getToPose().getX(),
00098 obj->getToPose().getY(),
00099 obj->getFromPose().getX(),
00100 obj->getToPose().getY()));
00101 mySegments.push_back(new ArLineSegment(obj->getFromPose().getX(),
00102 obj->getToPose().getY(),
00103 obj->getFromPose().getX(),
00104 obj->getFromPose().getY()));
00105
00106
00107 }
00108 }
00109 myDataMutex.unlock();
00110 }
00111
00112 void ArForbiddenRangeDevice::processReadings(void)
00113 {
00114 ArPose intersection;
00115 std::list<ArLineSegment *>::iterator it;
00116
00117 lockDevice();
00118 myDataMutex.lock();
00119
00120 myCurrentBuffer.beginRedoBuffer();
00121
00122 if (!myIsEnabled)
00123 {
00124 myCurrentBuffer.endRedoBuffer();
00125 myDataMutex.unlock();
00126 unlockDevice();
00127 return;
00128 }
00129
00130 ArLineSegment *segment;
00131 ArPose start;
00132 double startX;
00133 double startY;
00134 ArPose end;
00135 double angle;
00136 double length;
00137 double gone;
00138 double sin;
00139 double cos;
00140 double atX;
00141 double atY;
00142 double robotX = myRobot->getX();
00143 double robotY = myRobot->getY();
00144 double max = (double) myMaxRange;
00145 double maxSquared = (double) myMaxRange * (double) myMaxRange;
00146 ArTime startingTime;
00147
00148
00149 for (it = mySegments.begin(); it != mySegments.end(); it++)
00150 {
00151 segment = (*it);
00152
00153
00154 if (ArMath::squaredDistanceBetween(
00155 segment->getX1(), segment->getY1(),
00156 myRobot->getX(), myRobot->getY()) < maxSquared ||
00157 ArMath::squaredDistanceBetween(
00158 segment->getX2(), segment->getY2(),
00159 myRobot->getX(), myRobot->getY()) < maxSquared ||
00160 segment->getPerpDist(myRobot->getPose()) < max)
00161 {
00162 start.setPose(segment->getX1(), segment->getY1());
00163 end.setPose(segment->getX2(), segment->getY2());
00164 angle = start.findAngleTo(end);
00165 cos = ArMath::cos(angle);
00166 sin = ArMath::sin(angle);
00167 startX = start.getX();
00168 startY = start.getY();
00169 length = start.findDistanceTo(end);
00170
00171 if (ArMath::squaredDistanceBetween(
00172 startX, startY, robotX, robotY) < maxSquared)
00173 myCurrentBuffer.redoReading(start.getX(), start.getY());
00174
00175 for (gone = 0; gone < length; gone += myDistanceIncrement)
00176 {
00177 atX = startX + gone * cos;
00178 atY = startY + gone * sin;
00179 if (ArMath::squaredDistanceBetween(
00180 atX, atY, robotX, robotY) < maxSquared)
00181 myCurrentBuffer.redoReading(atX, atY);
00182 }
00183
00184 if (end.squaredFindDistanceTo(myRobot->getPose()) < maxSquared)
00185 myCurrentBuffer.redoReading(end.getX(), end.getY());
00186 }
00187 }
00188 myDataMutex.unlock();
00189
00190 myCurrentBuffer.endRedoBuffer();
00191 unlockDevice();
00192
00193 }
00194
00195 void ArForbiddenRangeDevice::setRobot(ArRobot *robot)
00196 {
00197 myRobot = robot;
00198 if (myRobot != NULL)
00199 myRobot->addSensorInterpTask(myName.c_str(), 20, &myProcessCB);
00200 ArRangeDevice::setRobot(robot);
00201 myMap->lock();
00202 myMap->addMapChangedCB(&myMapChangedCB);
00203 processMap();
00204 myMap->unlock();
00205 }
00206
00207 void ArForbiddenRangeDevice::enable(void)
00208 {
00209 myDataMutex.lock();
00210 myIsEnabled = true;
00211 myDataMutex.unlock();
00212 }
00213
00214 void ArForbiddenRangeDevice::disable(void)
00215 {
00216 myDataMutex.lock();
00217 myIsEnabled = false;
00218 myDataMutex.unlock();
00219 }