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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "Component/ModelManager.H"
00040 #include "Util/log.H"
00041 #include "rutz/shared_ptr.h"
00042
00043
00044 #include "Raster/Raster.H"
00045 #include "Raster/GenericFrame.H"
00046 #include "Image/Image.H"
00047 #include "Image/PixelsTypes.H"
00048 #include "Transport/FrameIstream.H"
00049 #include "Transport/FrameInfo.H"
00050 #include "GUI/XWinManaged.H"
00051 #include "GUI/XWindow.H"
00052 #include "Media/FrameSeries.H"
00053
00054
00055 #include "Devices/FrameGrabberConfigurator.H"
00056 #include "Devices/DeviceOpts.H"
00057 #include "Media/FrameSeries.H"
00058
00059
00060 #include "Devices/PingSonar.H"
00061
00062
00063 #include "Util/Timer.H"
00064 #include "Util/Types.H"
00065 #include "Util/log.H"
00066 #include "Util/sformat.H"
00067 #include <cstdio>
00068 #include <cstdlib>
00069 #include <signal.h>
00070
00071
00072 #include "Image/CutPaste.H"
00073 #include "Image/vec2.h"
00074 #include "Image/DrawOps.H"
00075
00076
00077 #include "Robots/LoBot/control/VectorHistField.H"
00078
00079 #include "Robots/IRobot/Roomba.H"
00080
00081
00082 #define NAVG 20
00083
00084 static bool goforever = true;
00085
00086 using namespace geom;
00087
00088 #define MAXVEL 100
00089 #define INPLACEVEL 50
00090
00091 typedef struct robotCmd
00092 {
00093 int motor;
00094 int radius;
00095
00096 } robotCmd;
00097
00098
00099 void terminate(int s)
00100 { LERROR("*** INTERRUPT ***"); goforever = false; }
00101
00102
00103
00104
00105
00106 Image<PixRGB<byte> > vizDist(std::vector<int> dists,int divisions)
00107 {
00108
00109 Image<PixRGB<byte> > img(800,800,ZEROS);
00110 int startAng = 0;
00111 int increment = 180/dists.size();
00112 int beginAng=startAng, endAng=increment;
00113
00114 for(uint s=0;s<dists.size();s++)
00115 {
00116
00117 for(int i=1; i<=divisions;i++)
00118 for (int ang=beginAng;ang<=endAng;ang++)
00119 {
00120 int rad = i*5;
00121 Point2D<int> pt;
00122 pt.i = 200+100*s - (int) (rad*cos(ang*M_PI/180.0));
00123 pt.j = 400 - (int) (rad*sin(ang*M_PI/180.0));
00124
00125 if(dists.at(s) <= i*250)
00126 drawPoint(img,pt.i,pt.j,PixRGB<byte>(255,0,0));
00127 else
00128 drawPoint(img,pt.i,pt.j,PixRGB<byte>(0,0,255));
00129
00130 writeText(img,Point2D<int>(10+100*s,10),
00131 sformat("%i--%d ",s,dists.at(s)).c_str(),
00132 PixRGB<byte>(255),PixRGB<byte>(0));
00133
00134 }
00135 beginAng = endAng;
00136 endAng = endAng + increment;
00137 }
00138
00139 return img;
00140
00141 }
00142
00143
00144
00145
00146
00147 robotCmd vec2motor(geom::vec2f a)
00148 {
00149
00150
00151
00152
00153
00154
00155
00156
00157 float ang = (int)a.theta_deg();
00158 LINFO("ang %f",ang);
00159 int tmpRad;
00160 robotCmd cmd1;
00161
00162 cmd1.radius = 0;
00163 cmd1.motor = 0;
00164
00165
00166 if(ang == 90.0)
00167 {
00168 cmd1.radius = 0;
00169 cmd1.motor = MAXVEL;
00170 }
00171
00172 if(ang > 90 && ang <=180)
00173 {
00174 LINFO("quadrant--2");
00175 tmpRad=(int)((ang-181.0) * 2000/90.0);
00176
00177 if(tmpRad >= 0)
00178 {
00179 cmd1.radius = 23;
00180 cmd1.motor = INPLACEVEL;
00181 }
00182
00183 else
00184 {
00185 cmd1.radius = tmpRad;
00186 cmd1.motor = (int)(MAXVEL/2000)*fabs(tmpRad);
00187 cmd1.motor = 100;
00188 }
00189
00190 }
00191
00192
00193
00194 if(ang >= 0 && ang <90)
00195 {
00196 LINFO("quadrant--1--ang %f",ang);
00197 tmpRad = 2000-(int)((89.0-ang) * 2000/90.0);
00198
00199 if(tmpRad > 2000)
00200 {
00201 cmd1.radius = 0.0;
00202 cmd1.motor = MAXVEL;
00203 }
00204
00205 if(tmpRad <= 0)
00206 {
00207 cmd1.radius = 23;
00208 cmd1.motor = 100;
00209 }
00210
00211 else
00212 {
00213 cmd1.radius = tmpRad;
00214 cmd1.motor = (int)(MAXVEL/2000)*fabs(tmpRad);
00215 cmd1.motor = 100;
00216 }
00217
00218 }
00219
00220
00221 if(ang < 0 && ang >= -90)
00222 {
00223 LINFO("quadrant--3");
00224 cmd1.radius = 250;
00225 cmd1.motor = INPLACEVEL;
00226 }
00227
00228
00229 if(ang < -90 && ang >= -180)
00230 {
00231 LINFO("quadrant--4 , clockwise");
00232 cmd1.radius = -250;
00233 cmd1.motor = INPLACEVEL;
00234 }
00235
00236 if (cmd1.radius > 2000)
00237 cmd1.radius =2000;
00238 if (cmd1.radius < -2000)
00239 cmd1.radius =-2000;
00240
00241 return cmd1;
00242 }
00243
00244
00245
00246
00247 int main(const int argc, const char **argv)
00248 {
00249
00250
00251 MYLOGVERB = LOG_INFO;
00252
00253 ModelManager manager( "Avoid Collisions " );
00254
00255 int itsDim = 30;
00256 int itsSpacing = 15;
00257
00258
00259
00260
00261 manager.setOptionValString(&OPT_FrameGrabberMode, "RGB24");
00262 manager.setOptionValString(&OPT_FrameGrabberDims, "320x240");
00263 manager.setOptionValString(&OPT_FrameGrabberFPS, "30");
00264
00265 nub::soft_ref<PingSonar> pingSonar(new PingSonar(manager,"PingSonar", "PingSonar","/dev/ttyUSB0",3));
00266
00267 nub::soft_ref<VectorHistField> vectorHistField(new VectorHistField
00268 (manager,"VectorHistField",
00269 "VectorHistField",itsDim,itsDim));
00270
00271
00272 nub::soft_ref<Roomba> roomba(new Roomba(manager,"Roomba",
00273 "Roomba","/dev/ttyUSB1"));
00274
00275 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00276 manager.addSubComponent(roomba);
00277 manager.addSubComponent(ofs);
00278 manager.addSubComponent(pingSonar);
00279 manager.addSubComponent(vectorHistField);
00280
00281 manager.exportOptions(MC_RECURSE);
00282
00283
00284 if( manager.parseCommandLine( argc, argv, "", 0, 0 ) == false ) return(1);
00285
00286
00287 signal(SIGHUP, terminate); signal(SIGINT, terminate);
00288 signal(SIGQUIT, terminate); signal(SIGTERM, terminate);
00289
00290 manager.start();
00291
00292 LINFO("starting roomba....");
00293 roomba->sendStart();
00294 LINFO("setting to full mode....");
00295 roomba->setMode(2);
00296
00297
00298 roomba->setSpeed(0);
00299 sleep(1);
00300
00301 Timer tim;
00302 tim.reset();
00303
00304 Image<PixRGB<byte> > dispImg(itsDim*itsSpacing, itsDim*itsSpacing,ZEROS);
00305 Point2D<int> itsFixedRobotPos(itsDim/2,itsDim-5);
00306
00307 static int dist=0;
00308 static int ang=0;
00309
00310
00311 float sigma = 5.5;
00312 float amp= 45.0;
00313 Image<geom::vec2f> obsTemplate = vectorHistField->obstacleTemplate(sigma,amp);
00314
00315
00316
00317 while (goforever)
00318 {
00319
00320 std::vector<int> dists = pingSonar->getDists();
00321 std::vector<Point2D<float> > sensor;
00322
00323 LINFO("getting dists %d,%d,%d",dists.at(0),dists.at(1),dists.at(2));
00324
00325 sensor.push_back(Point2D<float> ((float)(dists.at(0)*itsDim/3000),150.0));
00326 sensor.push_back(Point2D<float> ((float)(dists.at(1)*itsDim/3000),90.0));
00327 sensor.push_back(Point2D<float> ((float)(dists.at(2)*itsDim/3000),30.0));
00328
00329 roomba->getDistanceAngle(dist,ang);
00330 LINFO("dist travelled %d, angle turned %d",roomba->getDist(),roomba->getAngle());
00331
00332 Image<PixRGB<byte> > blobs = vectorHistField->updateField(sensor, Point2D<int>(0,0), ang, dist, Point2D<int> (15,90),obsTemplate);
00333
00334 dispImg = vectorHistField->plotGridField(itsSpacing);
00335 ofs->writeRGB(dispImg,"Output",FrameInfo("output",SRC_POS));
00336
00337
00338
00339 geom::vec2f a;
00340 a = vectorHistField->getVectorAt(itsFixedRobotPos);
00341
00342 robotCmd cmd = vec2motor(a);
00343
00344
00345
00346
00347 try
00348 {
00349 roomba->setSpeed(cmd.motor);
00350 roomba->setRadius(cmd.radius);
00351 }
00352 catch (...) {}
00353
00354
00355 if(tim.getSecs() > 65.0)
00356 goforever=false;
00357
00358
00359 usleep(100 * 1000);
00360
00361 }
00362
00363
00364 roomba->setSpeed(0);
00365
00366 manager.stop();
00367
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377