00001 /*!@file Robots2/Beobot2/Hardware/LRF_Occupancy.C Ice Module to log data */ 00002 // //////////////////////////////////////////////////////////////////// // 00003 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00004 // University of Southern California (USC) and the iLab at USC. // 00005 // See http://iLab.usc.edu for information about this project. // 00006 // //////////////////////////////////////////////////////////////////// // 00007 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00008 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00009 // in Visual Environments, and Applications'' by Christof Koch and // 00010 // Laurent Itti, California Institute of Technology, 2001 (patent // 00011 // pending; application number 09/912,225 filed July 23, 2001; see // 00012 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00013 // //////////////////////////////////////////////////////////////////// // 00014 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00015 // // 00016 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00017 // redistribute it and/or modify it under the terms of the GNU General // 00018 // Public License as published by the Free Software Foundation; either // 00019 // version 2 of the License, or (at your option) any later version. // 00020 // // 00021 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00022 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00023 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00024 // PURPOSE. See the GNU General Public License for more details. // 00025 // // 00026 // You should have received a copy of the GNU General Public License // 00027 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00028 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00029 // Boston, MA 02111-1307 USA. // 00030 // //////////////////////////////////////////////////////////////////// // 00031 // 00032 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu> 00033 // $HeadURL: svn://ilab.usc.edu/trunk/saliency/src/Robots/Beobot2/LRF_Occupancy.C 00034 // $ $Id: LRF_Occupancy.C 12962 2010-03-06 02:13:53Z irock $ 00035 // 00036 ////////////////////////////////////////////////////////////////////////// 00037 00038 00039 #include "Image/MatrixOps.H" 00040 #include "Component/ModelComponent.H" 00041 #include "Component/ModelOptionDef.H" 00042 #include "Ice/BeobotEvents.ice.H" 00043 #include "Ice/IceImageUtils.H" 00044 #include "Image/ShapeOps.H" 00045 #include "Image/Image.H" 00046 #include "Image/DrawOps.H" 00047 #include "Image/MorphOps.H" 00048 #include "Image/Kernels.H" 00049 #include "Raster/Raster.H" 00050 #include "Robots/Beobot2/LowLevelControl/LRF_Occupancy/LRF_Occupancy.H" 00051 #include "Util/sformat.H" 00052 00053 const ModelOptionCateg MOC_LRF_Occupancy = { 00054 MOC_SORTPRI_3, "LRF Occupancy Grid Related Options" }; 00055 00056 const ModelOptionDef OPT_GridDims = 00057 { MODOPT_ARG(Dims), "Grid Dimensions", &MOC_LRF_Occupancy, OPTEXP_CORE, 00058 "The size of the occupancy grid in centimeters. Note that the resolution is 1cm", 00059 "grid-dims", '\0', "<w x h>", "300x500"}; 00060 00061 // ###################################################################### 00062 LRF_Occupancy::LRF_Occupancy(OptionManager& mgr, 00063 const std::string& descrName, const std::string& tagName) : 00064 RobotBrainComponent(mgr, descrName, tagName), 00065 itsOfs(new OutputFrameSeries(mgr)), 00066 itsOccupancyMapDims(&OPT_GridDims, this, 0) 00067 { 00068 addSubComponent(itsOfs); 00069 } 00070 00071 // ###################################################################### 00072 LRF_Occupancy::~LRF_Occupancy() 00073 { } 00074 00075 // ###################################################################### 00076 void LRF_Occupancy::start1() 00077 { 00078 } 00079 00080 // ###################################################################### 00081 void LRF_Occupancy::registerTopics() 00082 { 00083 // subscribe to all laser range finder data 00084 this->registerSubscription("LRFMessageTopic"); 00085 // this->registerPublisher("MotorRequestTopic"); 00086 } 00087 00088 // ###################################################################### 00089 void LRF_Occupancy::evolve() 00090 { 00091 std::vector<double> distances; 00092 std::vector<double> angles; 00093 00094 itsLRFDataMutex.lock(); 00095 { 00096 distances = itsDistances; 00097 angles = itsAngles; 00098 } 00099 itsLRFDataMutex.unlock(); 00100 00101 computeOccupancy(distances, angles); 00102 } 00103 00104 00105 00106 // ###################################################################### 00107 Image<bool> LRF_Occupancy::computeOccupancy(std::vector<double> distances, std::vector<double> angles) 00108 { 00109 ASSERT(distances.size() == angles.size()); 00110 00111 //Clear out the old occupancy grid 00112 Image<byte> occupancyMap(itsOccupancyMapDims.getVal(), ZEROS); 00113 00114 std::vector<double>::iterator distIt = distances.begin(); 00115 std::vector<double>::iterator angleIt = angles.begin(); 00116 00117 float angle, distance, x, y; 00118 00119 int mapW = occupancyMap.getWidth(); 00120 00121 Image<byte> se = twofiftyfives(3); 00122 00123 for(;distIt != distances.end() && angleIt != angles.end(); ++distIt, ++angleIt) 00124 { 00125 angle = (*angleIt)*M_PI/180.0 - M_PI/2.0; 00126 distance = *distIt; 00127 00128 if(distance == -1) 00129 continue; 00130 00131 //Find the (x,y) coordinates of the lrf reading in millimeters, 00132 //and convert to centimeters 00133 x = distance*cos(angle)/10.0; 00134 y = distance*sin(angle)/10.0; 00135 00136 //Offest the x by half the grid size 00137 x += itsOccupancyMapDims.getVal().w()/2.0; 00138 y += itsOccupancyMapDims.getVal().h(); 00139 00140 //Convert to centimeters. 00141 00142 if(occupancyMap.coordsOk(x,y)) 00143 { 00144 // occupancyMap.setVal(x,y,255); 00145 00146 00147 //Draw a ray from the detected point to the bounds of the image. 00148 //If the point is to the left of the center of the image, then 00149 //draw the ray to the left, and same for the right. 00150 Point2D<int> end; 00151 if(abs(x - mapW/2.0) < 1) 00152 end = Point2D<int>(mapW/2,0); 00153 else if(x>mapW/2.0) 00154 end = Point2D<int>(mapW-1, y+(mapW-x)*tan(angle)); 00155 else if(x<mapW/2.0) 00156 end = Point2D<int>(0, y-x*tan(angle)); 00157 00158 drawLine(occupancyMap, Point2D<int>(x,y), end, byte(255), 5); 00159 } 00160 00161 } //End LRF Data 00162 occupancyMap = flipHoriz(occupancyMap); 00163 00164 Image<byte> scaledOccMap = rescaleNI(occupancyMap, occupancyMap.getDims()/10); 00165 dilateImg(scaledOccMap, se); 00166 00167 00168 00169 scaledOccMap = rescaleNI(scaledOccMap, occupancyMap.getDims()/3); 00170 00171 if(!itsOfs->isVoid()) 00172 { 00173 itsOfs->writeGray(scaledOccMap,"occupancy map"); 00174 itsOfs->updateNext(); 00175 } 00176 00177 00178 00179 return occupancyMap; 00180 } 00181 00182 // ###################################################################### 00183 void LRF_Occupancy::updateMessage 00184 (const RobotSimEvents::EventMessagePtr& eMsg, const Ice::Current&) 00185 { 00186 // LRF message 00187 if(eMsg->ice_isA("::BeobotEvents::LRFMessage")) 00188 { 00189 // we got LRF data 00190 BeobotEvents::LRFMessagePtr lrfMsg = 00191 BeobotEvents::LRFMessagePtr::dynamicCast(eMsg); 00192 00193 //Set the class distance and angle measures 00194 //so that the evolve loop can work on them 00195 itsLRFDataMutex.lock(); 00196 { 00197 itsDistances = lrfMsg->distances; 00198 itsAngles = lrfMsg->angles; 00199 } 00200 itsLRFDataMutex.unlock(); 00201 } 00202 } 00203 00204 // ###################################################################### 00205 00206 /* So things look consistent in everyone's emacs... */ 00207 /* Local Variables: */ 00208 /* indent-tabs-mode: nil */ 00209 /* End: */