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