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

ArForbiddenRangeDevice.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 
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   //startingTime.setToNow();
00144   // now see if the end points of the segments are too close to us
00145   for (it = mySegments.begin(); it != mySegments.end(); it++)
00146   {
00147     segment = (*it);
00148     // if either end point or some perpindicular point is close to us
00149     // add the line's data
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       // first put in the start point if we should
00167       if (ArMath::squaredDistanceBetween(
00168           startX, startY, robotX, robotY) < maxSquared)
00169     myCurrentBuffer.redoReading(start.getX(), start.getY());
00170       // now walk the length of the line and see if we should put the points in
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       // now check the end point
00180       if (end.squaredFindDistanceTo(myRobot->getPose()) < maxSquared)
00181     myCurrentBuffer.redoReading(end.getX(), end.getY());
00182     }
00183   }
00184   myDataMutex.unlock();
00185   // and we're done
00186   myCurrentBuffer.endRedoBuffer();
00187   unlockDevice();
00188   //printf("%d\n", startingTime.mSecSince());
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 }

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