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

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

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