00001 #include "Raster/Raster.H" 00002 #include "Robots/Beobot2/Hardware/BeoPilot.H" 00003 #include "Ice/BeobotEvents.ice.H" 00004 #include "Component/ModelParam.H" 00005 #include "Component/ModelOptionDef.H" 00006 #include "Util/sformat.H" 00007 #include "Util/MathFunctions.H" 00008 #include "Image/ShapeOps.H" // for rescale() 00009 #include <iostream> 00010 #include <stdio.h> 00011 #include <sys/types.h> 00012 #include <sys/stat.h> 00013 #include <dirent.h> 00014 #include <unistd.h> 00015 #define LOG_FOLDER "../data/logs/IROS10_Equad" 00016 const ModelOptionCateg MOC_BeoPilot = { 00017 MOC_SORTPRI_3, "Beobot Pilot Related Options" }; 00018 00019 const ModelOptionDef OPT_MinimumSafeDistance = 00020 { MODOPT_ARG(float), "MinimumSafeDistance", &MOC_BeoPilot, OPTEXP_CORE, 00021 "The minimum distance (in meters) to objects we can allow before cutting off the motors.", 00022 "min-distance", '\0', "float", ".5"}; 00023 00024 const ModelOptionDef OPT_MaxSpeed = 00025 { MODOPT_ARG(float), "MaxSpeed", &MOC_BeoPilot, OPTEXP_CORE, 00026 "The maximum speed of the robot (from [0 .. 1]).", 00027 "max-speed", '\0', "float", "1.0"}; 00028 00029 const ModelOptionDef OPT_IgnoreSonar = 00030 { MODOPT_ARG(bool), "IgnoreSonar", &MOC_BeoPilot, OPTEXP_CORE, 00031 "Do we want to ignore the sonar for proximity warnings. Use this with caution, as someone could get hurt!?", 00032 "ignore-sonar", '\0', "true | false", "true"}; 00033 00034 const ModelOptionDef OPT_LogFile = 00035 { MODOPT_ARG(std::string), "LogFile", &MOC_BeoPilot, OPTEXP_CORE, 00036 "There are 3 mode for input log file name \n" 00037 "you can enter\n" 00038 "1) ./bin/app-BeoPilot --log-file=<Full Log File Path>\n" 00039 " it will open the file directly\n" 00040 "2) ./bin/app-BeoPilot --log-file=<date>\n" 00041 " it will look for ../data/logs/<date>/Log_<date>.txt\n" 00042 " The date formate can be flexible.\n" 00043 " You can enter full date such as 2009_11_03__14_03_49\n" 00044 " or 20091103 or 091103 or 1403 or 140349. \n" 00045 " If there are more than one match, \n" 00046 " it will list all options for choosen.\n" 00047 "3) ./bin/app-BeoPilot --log-file=search\n" 00048 " it will look for all directory under ../data/logs/\n" 00049 " and list all files for choosen\n", 00050 "log-file", '\0', "<string>", "NULL"}; 00051 00052 00053 const ModelOptionDef OPT_ReplaySpeed= 00054 { MODOPT_ARG(int), "ReplaySpeed", &MOC_BeoPilot, OPTEXP_CORE, 00055 "The replay speed from the Log file,default is 1x. To speed up the speed, using --speed=2 or faster", 00056 "speed", '\0', "int", "1"}; 00057 // ###################################################################### 00058 BeoPilot::BeoPilot(int id, OptionManager& mgr, 00059 const std::string& descrName, const std::string& tagName) : 00060 RobotBrainComponent(mgr, descrName, tagName), 00061 itsSerial(new Serial(mgr)), 00062 itsSerialTimer(1000000), 00063 itsCurrMessageID(0), 00064 itsCurrentTimeIndex(0), 00065 itsLogTimer(1000000), 00066 itsLoadFromLogFile(false), 00067 itsLogLeftMotorVelocity(0.0), 00068 itsLogRightMotorVelocity(0.0), 00069 itsLogPosition(0.0,0.0,0.0), 00070 itsLogDiffPosition(0.0,0.0,0.0), 00071 itsRCChannels(7, -1), 00072 itsEmergencyMode(-1), 00073 itsPosition(0.0,0.0,0.0), 00074 itsDiffPosition(0.0,0.0,0.0), 00075 itsMapImage(800-320,344,ZEROS), 00076 itsEncoderTimer(1000000), 00077 itsLeftMotorVelocity(0.0), 00078 itsRightMotorVelocity(0.0), 00079 itsPidLeft(0.3,0.000,0.00,0.0,0.0,0,0,0,1.0,-1.0), 00080 itsPidRight(0.0,0.000,0.00,0.0,0.0,0,0,0,1.0,-1.0), 00081 itsSonarTimeout(.5), 00082 itsControlImage(512,256,ZEROS), 00083 itsDispImage(800,600,ZEROS), 00084 itsDispCameraImage(320,240,ZEROS), 00085 itsMeterXwin(itsDispImage,"Pilot Control"), 00086 //itsMapXwin(itsMapImage,"Map Control"), 00087 itsDisplayUpdateRate(.05), 00088 itsMapScale(100.0), 00089 itsChannelMeters(7, SimpleMeter(20, 60, 1040,1921)), 00090 itsVelocityQue(50), 00091 itsVelocityTargetQue(50), 00092 itsMinimumSafeDistance(&OPT_MinimumSafeDistance, this, 0), 00093 itsMaxSpeed(&OPT_MaxSpeed, this, 0), 00094 itsIgnoreSonar(&OPT_IgnoreSonar, this, 0), 00095 itsLogFile(&OPT_LogFile, this, 0), 00096 itsReplaySpeed(&OPT_ReplaySpeed, this, 0) 00097 { 00098 addSubComponent(itsSerial); 00099 //Connect to the serial motor board 00100 itsSerial->configureSearch ("motorboard", 115200); 00101 } 00102 00103 void BeoPilot::checkLogFile() 00104 { 00105 if(itsLogFile.getVal() =="NULL"){ 00106 LINFO("Start BeoPilot with real device"); 00107 }else if(itsLogFile.getVal() =="search"){ 00108 LINFO("Search for all log file"); 00109 DIR *dir_p; 00110 struct dirent *entry_p; 00111 dir_p = ::opendir(LOG_FOLDER); 00112 if(dir_p == NULL) 00113 LFATAL("Can Not Open ../data/logs directory"); 00114 //uint i = 1; 00115 00116 std::vector<std::string> subdir; 00117 while((entry_p = ::readdir(dir_p))) 00118 { 00119 std::string subdirname(entry_p->d_name); 00120 if(subdirname != "." && subdirname !="..") 00121 { 00122 //LINFO("File[%d]:[%s]",i++,subdirname.c_str()); 00123 subdir.push_back(subdirname); 00124 } 00125 } 00126 (void)::closedir(dir_p); 00127 00128 //sort filename 00129 std::sort(subdir.begin(),subdir.end()); 00130 for(int i = 0;i < (int)subdir.size();i++) 00131 { 00132 LINFO("File[%d]:[%s]",i+1,subdir[i].c_str()); 00133 } 00134 00135 int option; 00136 do{ 00137 LINFO("Please Choose a File Number:"); 00138 scanf("%d",&option);//FIXX Any better idea? 00139 if(option <1 ||option >int(subdir.size())) 00140 LINFO("Option Invalid, please try again"); 00141 }while(option < 1 || option > int(subdir.size())); 00142 LINFO("Your Choose is [%d] filename[%s] ",option,subdir[option-1].c_str()); 00143 // int run,segt; 00144 // char buf[255]; 00145 //sscanf(subdir[option-1].c_str(),"S%d_R%d_%s",&run,&segt,buf); 00146 std::string logFileName( 00147 sformat("%s/%s/%s.txt", 00148 LOG_FOLDER, 00149 subdir[option-1].c_str(), 00150 subdir[option-1].c_str() 00151 //buf 00152 )); 00153 itsLogFile.setVal(logFileName); 00154 loadFromLogFile(); 00155 }else{ 00156 LINFO("LogFileName:[%s]",itsLogFile.getVal().c_str()); 00157 loadFromLogFile(); 00158 } 00159 00160 00161 } 00162 00163 void BeoPilot::loadFromLogFile() 00164 { 00165 00166 00167 FILE *logFile = fopen(itsLogFile.getVal().c_str(),"r"); 00168 if(logFile == NULL) 00169 { 00170 LFATAL("can't not open file: %s",itsLogFile.getVal().c_str()); 00171 }else 00172 { 00173 char line[512]; 00174 while(fgets(line,sizeof line,logFile)!= NULL) 00175 { 00176 float time,transVel,rotVel,encoderX,encoderY,encoderOri,rcTransVel,rcRotVel; 00177 int rcMode; 00178 int ret = sscanf (line,"[%f] MTR rcMode: %d, transVel: %f rotVel: %f encoderX: %f encoderY: %f encoderOri: %f rcTransVel: %f rcRotVel: %f", 00179 &time, &rcMode, &transVel, &rotVel, &encoderX, &encoderY, &encoderOri, &rcTransVel, &rcRotVel); 00180 if(ret == 9){ 00181 motorData tmp; 00182 tmp.time = time; 00183 tmp.rcMode = rcMode; 00184 tmp.transVel = transVel; 00185 tmp.rotVel = rotVel; 00186 tmp.encoderX = encoderX; 00187 tmp.encoderY = encoderY; 00188 tmp.encoderOri = encoderOri; 00189 tmp.rcTransVel = rcTransVel; 00190 tmp.rcRotVel = rcRotVel; 00191 itsLogData.push_back(tmp); 00192 LINFO("Got Motor Data %f %d",time,rcMode); 00193 00194 } 00195 00196 std::string imagePath; 00197 char imgPath[256]; 00198 ret = sscanf(line,"[%f] CAM filename: %s", &time, imgPath); 00199 if(ret == 2) 00200 { 00201 imageData imgData; 00202 imgData.time = time; 00203 imgData.imagePath = imgPath; 00204 itsLogImageData.push_back(imgData); 00205 LINFO("Got Image at %f path=%s",time,imgPath); 00206 } 00207 00208 } 00209 LINFO("Load Log file with %d motor command lines",(int)itsLogData.size()); 00210 LINFO("Load Log file with %d Images",(int)itsLogImageData.size()); 00211 itsLoadFromLogFile = true; 00212 itsLogTimer.reset(); 00213 //drawAllMap(); 00214 } 00215 00216 00217 00218 } 00219 00220 00221 void BeoPilot::start3() 00222 { 00223 checkLogFile(); 00224 //while(!itsSerial->isSerialOk()){ 00225 // LINFO("Can't not open serial port,keep try"); 00226 // itsSerial->enablePort(itsSerial->getDevName().c_str());///dev/ttyUSB0 00227 //} 00228 if(itsSerial->isSerialOk()) 00229 LINFO("%s found on %s", itsSerial->getDeviceDescriptor().c_str(), itsSerial->getDevName().c_str()); 00230 resetEncoder(); 00231 //Check our command line options to ensure that they are sane 00232 if(itsMinimumSafeDistance.getVal() < 0) 00233 LFATAL("Invalid Minimum Safe Distance (%f). Must be > 0!", itsMinimumSafeDistance.getVal()); 00234 if(itsMaxSpeed.getVal() > 1.0 || itsMaxSpeed.getVal() < 0) 00235 LFATAL("Invalid Maximum Speed Distance (%f). Must be > 0 && < 1.0!", itsMaxSpeed.getVal()); 00236 } 00237 00238 // ###################################################################### 00239 BeoPilot::~BeoPilot() 00240 { 00241 //Kill the motors on exit 00242 SetMotors(0,0); 00243 } 00244 00245 00246 void BeoPilot::registerTopics() 00247 { 00248 registerSubscription("MotorRequestTopic"); 00249 registerSubscription("SonarMessageTopic"); 00250 registerPublisher("MotorMessageTopic"); 00251 } 00252 00253 00254 void BeoPilot::evolve() 00255 { 00256 00257 //Recieve telemetry from the propeller 00258 UpdateRCStatus(); 00259 itsVelocityTargetQue.add(itsRcTransSpeedCapped); 00260 //itsVelocityQue.add(randomDouble()*2 -1.0); 00261 //itsVelocityTargetQue.add(randomDouble()); 00262 00263 //Check if it is in log file replay mode and also make sure emergency mode is off 00264 if(itsLoadFromLogFile){ 00265 //No RC(Emergency = -1): getCurrentLogData and timer resume but no set Motor 00266 //With RC: 00267 // Emergency is off (Emergency = 0) 00268 // 1) Mode 1,2 :timer pause 00269 // 2) Mode 3 timer resume and run log file,set motor 00270 // Emergency is on (Emergency = 255) 00271 // 1) Timer pause 00272 if(itsEmergencyMode == -1||itsEmergencyMode == 255) 00273 { 00274 itsLogTimer.resume(); 00275 getCurrentLogData(); 00276 } 00277 else if(itsEmergencyMode == 0 && itsRemoteMode == 3) 00278 { 00279 itsLogTimer.resume(); 00280 getCurrentLogData(); 00281 SetMotors(itsRotationalSpeed,itsForwardSpeed); 00282 } 00283 else{ 00284 itsLogTimer.pause(); 00285 LINFO("Wait for RC mode 3"); 00286 } 00287 uint64 time = itsLogTimer.get()/1000.0; 00288 LDEBUG("Current Log Timer is %f",(double)time); 00289 } 00290 else{ 00291 //Local copies of all shared data that we deal with so that we can 00292 //hold onto our locks for as short a time as possible 00293 float loc_rotVel; 00294 float loc_transVel; 00295 bool loc_sonarProxAlert; 00296 00297 //Check to make sure that we have heard from our sonar recently, and that it has 00298 //reported all sonars to be reading past the minimum safe distance. If we are in 00299 //a dangerous situation, then set the itsSonarProxAlert 00300 itsSonarMutex.lock(); 00301 { 00302 if(itsSonarReadings.size() > 0) 00303 { 00304 float minSonarReading = *(std::min_element(itsSonarReadings.begin(), itsSonarReadings.end())); 00305 if(itsSonarTimer.getSecs() > itsSonarTimeout || minSonarReading < itsMinimumSafeDistance.getVal()) 00306 itsSonarProxAlert = true; 00307 else 00308 itsSonarProxAlert = false; 00309 } 00310 else 00311 itsSonarProxAlert = true; 00312 00313 loc_sonarProxAlert = itsSonarProxAlert; 00314 } 00315 itsSonarMutex.unlock(); 00316 00317 //Set the current speed of the robot by either clamping it to the requested speed, or killing it 00318 //if we are in a dangerous situation 00319 itsSpeedMutex.lock(); 00320 { 00321 itsRotationalSpeed = itsRotationalSpeedReq; 00322 itsForwardSpeed = itsForwardSpeedReq; 00323 //If we haven't heard from the sonar or things are getting too close, 00324 //then let's kill the motors 00325 if((itsIgnoreSonar.getVal() == false) && loc_sonarProxAlert) 00326 { 00327 LINFO("SONAR ERROR!"); 00328 itsRotationalSpeed = 0; 00329 itsForwardSpeed = 0; 00330 } 00331 00332 //Clamp the latest movement requests to the maximum speed as 00333 //specified by the command line 00334 if(itsRotationalSpeed > itsMaxSpeed.getVal()) 00335 itsRotationalSpeed = itsMaxSpeed.getVal(); 00336 else if(itsRotationalSpeed < -itsMaxSpeed.getVal()) 00337 itsRotationalSpeed = -itsMaxSpeed.getVal(); 00338 00339 if(itsForwardSpeed > itsMaxSpeed.getVal()) 00340 itsForwardSpeed = itsMaxSpeed.getVal(); 00341 else if(itsForwardSpeed < -itsMaxSpeed.getVal()) 00342 itsForwardSpeed = -itsMaxSpeed.getVal(); 00343 00344 //Set our local copies to the newly clamped requested speeds 00345 loc_rotVel = itsRotationalSpeed; 00346 loc_transVel = itsForwardSpeed; 00347 //LINFO("Set Local Rot/TranVel (%f, %f)", loc_rotVel, loc_transVel); 00348 } 00349 itsSpeedMutex.unlock(); 00350 //Move motor in manual mode 00351 if(itsRemoteMode == 1 ||itsRemoteMode == 3) 00352 { 00353 //Send the actual motor commands to the motor driver/propeller 00354 SetMotors(loc_rotVel, loc_transVel); 00355 }else if(itsRemoteMode == 2) 00356 { 00357 double m1velReq = (itsRcTransSpeedCapped + itsRcRotSpeedCapped)*3.0; 00358 double m2velReq = (itsRcTransSpeedCapped - itsRcRotSpeedCapped)*3.0; 00359 00360 float leftPWM = itsPidLeft.update(m1velReq,itsLeftMotorVelocity); 00361 float rightPWM = itsPidRight.update(itsRightMotorVelocity,m2velReq); 00362 00363 double transPWM = leftPWM;// (leftPWM+rightPWM)/2.0; 00364 double rotPWM = 0.0;//(leftPWM-rightPWM)/2.0; 00365 00366 LINFO("LEFT PWM %f, RIGT PWM %f",leftPWM,rightPWM); 00367 LINFO("LEFT Request %f, LEFT Cur %f",m1velReq,itsLeftMotorVelocity); 00368 LINFO("RIGT Request %f, RIGT Cur %f",m2velReq,itsRightMotorVelocity); 00369 LINFO("Rc Tran %f Rc Rot %f",itsRcTransSpeedCapped,itsRcRotSpeedCapped); 00370 LINFO("Pwm Tran %f Pwm Rot %f",transPWM,rotPWM); 00371 LINFO("====================================================="); 00372 SetMotors(rotPWM,transPWM) ; 00373 } 00374 00375 //Report the current motor speeds to IceStorm 00376 BeobotEvents::MotorMessagePtr msg = new BeobotEvents::MotorMessage; 00377 00378 msg->RequestID = itsCurrMessageID; 00379 00380 msg->transVel = loc_transVel; 00381 msg->rotVel = loc_rotVel; 00382 msg->motor1 = Ice::Int(itsMotor1Speed); 00383 msg->motor2 = Ice::Int(itsMotor2Speed); 00384 00385 msg->encoderX = itsDiffPosition.x; 00386 msg->encoderY = itsDiffPosition.y; 00387 msg->encoderOri = itsDiffPosition.z; 00388 00389 msg->rcTransVel = itsRcTransSpeed; 00390 msg->rcRotVel = itsRcRotSpeed; 00391 msg->rcMode = itsRemoteMode; 00392 00393 this->publish("MotorMessageTopic", msg); 00394 //FIXX LINFO("MotorMessageTopic: %d", itsCurrMessageID); 00395 00396 00397 itsCurrMessageID++; 00398 usleep(10000); 00399 } 00400 //Draw the GUI to the screen 00401 updateGUI(); 00402 00403 00404 double locSerialTime = (double) itsSerialTimer.get()/1000000.0;//sec 00405 int code = itsSerial->getSerialErrno(); 00406 if(code==0||code==15){//FIXXX 15 is serialErrReadTimedOut 00407 itsSerialTimer.reset(); 00408 }else if(locSerialTime > 3.0){ 00409 LINFO("Try reconnect Timer:%f",locSerialTime); 00410 itsSerialTimer.reset(); 00411 itsSerial->enablePort(itsSerial->getDevName().c_str());///dev/ttyUSB0 00412 LINFO("Tried Reconnect"); 00413 usleep(100000); 00414 }else{ 00415 LINFO("Serial Timer:%f",locSerialTime); 00416 LINFO("Serial Error Number:[%d]",itsSerial->getSerialErrno()); 00417 } 00418 } 00419 00420 void BeoPilot::UpdateRCStatus() 00421 { 00422 unsigned char cmd = 107; 00423 itsSerial->write(cmd); 00424 std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 255, -1, .2);//FIXXX Serial Crash Here 00425 00426 00427 if(frame.size() == 26) 00428 { 00429 itsRCChannels[0] = ((0x0FF & frame[ 0]) << 8) | 00430 ((0x0FF & frame[ 1]) << 0); 00431 00432 itsRCChannels[1] = ((0x0FF & frame[ 2]) << 8) | 00433 ((0x0FF & frame[ 3]) << 0); 00434 00435 itsRCChannels[2] = ((0x0FF & frame[ 4]) << 8) | 00436 ((0x0FF & frame[ 5]) << 0); 00437 00438 itsRCChannels[3] = ((0x0FF & frame[ 6]) << 8) | 00439 ((0x0FF & frame[ 7]) << 0); 00440 00441 itsRCChannels[4] = ((0x0FF & frame[ 8]) << 8) | 00442 ((0x0FF & frame[ 9]) << 0); 00443 00444 itsRCChannels[5] = ((0x0FF & frame[10]) << 8) | 00445 ((0x0FF & frame[11]) << 0); 00446 00447 itsRCChannels[6] = ((0x0FF & frame[12]) << 8) | 00448 ((0x0FF & frame[13]) << 0); 00449 00450 itsEmergencyMode = frame[14]; 00451 if(itsRCChannels[2] > 1800) 00452 itsEmergencyMode = 255; 00453 itsRemoteMode = frame[15]; 00454 itsMotor1Speed = (frame[16] - 64.0) / 64.0; 00455 itsMotor2Speed = (frame[17] - 64.0) / 64.0; 00456 00457 00458 itsLastLeftEncoder = itsLeftEncoder; 00459 itsLeftEncoder = ((0x0FF & frame[18]) << 24) | 00460 ((0x0FF & frame[19]) << 16) | 00461 ((0x0FF & frame[20]) << 8) | 00462 ((0x0FF & frame[21]) << 0); 00463 00464 itsLastRightEncoder = itsRightEncoder; 00465 itsRightEncoder = 00466 ((0x0FF & frame[22]) << 24) | 00467 ((0x0FF & frame[23]) << 16) | 00468 ((0x0FF & frame[24]) << 8) | 00469 ((0x0FF & frame[25]) << 0); 00470 if(itsRCChannels[2] < 1800){ 00471 itsRcTransSpeed = (200 - ((itsRCChannels[1] - 1041) * 200)/(1874 - 1041)) -100; 00472 //if it's mode 1 00473 if( itsRCChannels[6] > 1800) 00474 itsRcRotSpeed = (200 - ((itsRCChannels[0] - 963) * 200)/(1775 -963)) -100; 00475 else 00476 itsRcRotSpeed = (200 - ((itsRCChannels[0] - 1105) * 200)/(1928 -1105)) -100; 00477 double speed_cap = 100 - ((itsRCChannels[2] - 1041) * 100)/(1750 -1041); 00478 double rot_vel_cap = ((itsRCChannels[5] -900)* 100)/(2073 -900); 00479 itsTransCap = speed_cap; 00480 itsRotCap = rot_vel_cap; 00481 if(speed_cap > 100)speed_cap = 100; 00482 if(speed_cap < 0)speed_cap = 0; 00483 if(rot_vel_cap > 100)rot_vel_cap= 100; 00484 if(rot_vel_cap < 0)rot_vel_cap= 0; 00485 00486 if(itsRcTransSpeed > 100)itsRcTransSpeed = 100; 00487 if(itsRcTransSpeed < -100)itsRcTransSpeed = -100; 00488 if(itsRcRotSpeed > 100)itsRcRotSpeed= 100; 00489 if(itsRcRotSpeed < -100)itsRcRotSpeed= -100; 00490 00491 itsRcTransSpeedCapped =itsRcTransSpeed* speed_cap/100; 00492 itsRcRotSpeedCapped = itsRcRotSpeed * rot_vel_cap/-100; 00493 itsRcTransSpeed /=100.0; 00494 itsRcRotSpeed /= 100.0; 00495 itsRcTransSpeedCapped /= 100.0; 00496 itsRcRotSpeedCapped /= 100.0; 00497 LDEBUG("RC cap %f Rc rot cap %f", speed_cap,rot_vel_cap); 00498 LDEBUG("RC trans%f Rc rot %f", itsRcTransSpeed,itsRcRotSpeed); 00499 }else{ 00500 itsRcTransSpeed = 0; 00501 itsRcRotSpeed = 0; 00502 itsRcTransSpeedCapped = 0; 00503 itsRcRotSpeedCapped = 0; 00504 } 00505 00506 //After Get RC update,we update encoder value 00507 UpdatePosition(); 00508 00509 00510 } 00511 else 00512 { 00513 //LERROR("BAD FRAME RECIEVED!"); 00514 } 00515 00516 } 00517 00518 // We have 10 inch diameter wheel 00519 // Motor Shaft will turn 21 times for one wheel spin 00520 // The encoder have 4000 tick per revolution 00521 // When the wheel have one revolution, it travels 10 * pi inch 00522 // 00523 // 10* pi inch = 0.797964534 meters 00524 // Which have 1000 * 21 ticks 00525 // (10 * pi)/84,000 * 0.0254 = 9.49957779 * 10^(-6) = 0.000009.49957779 meter 00526 // Which means for every tick, 00527 // the wheel will move meter 00528 // 00529 // Width between two wheel W = 510 mm = 0.51m 00530 // To convert odometry data to position, we need do some math again... 00531 // Ot+1 = Ot + (Dr - Dl) / W 00532 // Dt,t+1 = (Dr + Dl) / 2 00533 // Xt+1 = Xt + Dt,t+1 * cos(Ot+1) 00534 // Yt+1 = Yt + Dt,t+1 * sin(Ot+1) 00535 void BeoPilot::UpdatePosition(void) 00536 { 00537 if(itsLastRightEncoder == 0.0 && itsLastLeftEncoder == 0.0) 00538 itsEncoderTimer.reset(); 00539 00540 double time = (double) itsEncoderTimer.getReset()/1000000.0;//sec 00541 00542 // double meterPerTick = 0.00000949957779 ; 00543 double ticksPerMeter = 105267.836; 00544 double dr = (itsRightEncoder - itsLastRightEncoder) / ticksPerMeter; 00545 double dl = (itsLeftEncoder - itsLastLeftEncoder) / ticksPerMeter; 00546 double w = 0.51; 00547 double ot = itsPosition.z + ((dr - dl) / w ); 00548 double dt = (dr + dl)/2; 00549 double xt = itsPosition.x + dt * cos(ot); 00550 double yt = itsPosition.y + dt * sin(ot); 00551 00552 00553 // compute motor velocity 00554 if(time != 0.0){ 00555 itsLeftMotorVelocity = -(dl/time); 00556 if(itsRemoteMode == 1) 00557 itsVelocityQue.add(itsLeftMotorVelocity/3.0); 00558 else 00559 itsVelocityQue.add(itsLeftMotorVelocity); 00560 00561 itsRightMotorVelocity = -(dr/time); 00562 } 00563 LDEBUG("Time[%f] Left V %f Right V %f,dl %f,dr %f",time,itsLeftMotorVelocity, 00564 itsRightMotorVelocity,dl,dr); 00565 00566 // the difference in position between the current and previous time step 00567 itsDiffPosition.x = dt * cos(ot); 00568 itsDiffPosition.y = dt * sin(ot); 00569 itsDiffPosition.z = ((dr - dl) / w ); //use z as orientation data 00570 00571 itsPosition.x = xt; 00572 itsPosition.y = yt; 00573 itsPosition.z = ot;//use z as orientation data 00574 00575 if(itsRemoteMode == 1) 00576 itsPosition.color = PixRGB<byte>(255,0,0); 00577 else 00578 itsPosition.color = PixRGB<byte>(0,255,0); 00579 } 00580 00581 unsigned int BeoPilot::getRCChannel(int channel) 00582 { 00583 if(channel < 0 || channel > 7) 00584 return 0; 00585 00586 unsigned char cmd[2] = {104, channel}; 00587 00588 itsSerial->write(cmd, 2); 00589 std::vector<unsigned char> frame = itsSerial->readFrame(cmd[0], 255); 00590 00591 if(frame.size() == 4) 00592 { 00593 unsigned int val = ((0x0FF & frame[0]) << 24) | 00594 ((0x0FF & frame[1]) << 16) | 00595 ((0x0FF & frame[2]) << 8) | 00596 ((0x0FF & frame[3]) << 0); 00597 return val; 00598 } 00599 else 00600 LINFO("Bad Frame Size! (%lu)", frame.size()); 00601 00602 return 0; 00603 00604 } 00605 00606 unsigned char BeoPilot::getRCStatus() 00607 { 00608 unsigned char cmd = 103; 00609 00610 itsSerial->write(cmd); 00611 std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 255); 00612 00613 if(frame.size() == 1) 00614 return frame[0]; 00615 00616 else 00617 LERROR("Bad Frame Size! (%lu)", frame.size()); 00618 return 0; 00619 00620 } 00621 00622 unsigned char BeoPilot::getRCEnabled() 00623 { 00624 unsigned char cmd = 105; 00625 00626 itsSerial->write(cmd); 00627 std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 255); 00628 00629 if(frame.size() == 1) 00630 return frame[0]; 00631 00632 else 00633 LERROR("Bad Frame Size! (%lu)", frame.size()); 00634 return 0; 00635 00636 } 00637 00638 unsigned int BeoPilot::getRCSpeed() 00639 { 00640 unsigned char cmd = 106; 00641 00642 itsSerial->write(cmd); 00643 std::vector<unsigned char> frame = itsSerial->readFrame(cmd, 255); 00644 00645 if(frame.size() == 4) 00646 { 00647 unsigned int val = ((0x0FF & frame[0]) << 24) | 00648 ((0x0FF & frame[1]) << 16) | 00649 ((0x0FF & frame[2]) << 8) | 00650 ((0x0FF & frame[3]) << 0); 00651 return val; 00652 } 00653 else 00654 LINFO("Bad Frame Size! (%lu)", frame.size()); 00655 00656 return 0; 00657 00658 } 00659 void BeoPilot::resetEncoder() 00660 { 00661 00662 unsigned char cmd = 108; 00663 itsSerial->write(cmd); 00664 00665 itsPosition.x = 0; 00666 itsPosition.y = 0; 00667 itsPosition.z = 0; 00668 itsDiffPosition.x = 0; 00669 itsDiffPosition.y = 0; 00670 itsDiffPosition.z = 0; 00671 00672 00673 } 00674 // ###################################################################### 00675 void BeoPilot::SetMotors(float rotationalSpeed, float translationalSpeed) 00676 { 00677 //Clamp the motor speeds to [-1 .. 1] 00678 if(rotationalSpeed > 1.0) 00679 rotationalSpeed = 1.0; 00680 if(rotationalSpeed < -1.0) 00681 rotationalSpeed = -1.0; 00682 if(translationalSpeed > 1.0) 00683 translationalSpeed = 1.0; 00684 if(translationalSpeed < -1.0) 00685 translationalSpeed = -1.0; 00686 00687 // //Convert the motor speeds to [1 .. 127] so that 64 is full stop for a motor 00688 // unsigned char motor1speedbyte = ((0x00FF & int(std::floor(motor1speed * 64.0))) + 64); 00689 // unsigned char motor2speedbyte = ((0x00FF & int(std::floor(motor2speed * 64.0))) + 64); 00690 00691 char rotSpeed = char(rotationalSpeed * 100.0); 00692 char tranSpeed = char(translationalSpeed * 100.0); 00693 00694 //Send the command for the first motor 00695 unsigned char cmd[3]; 00696 cmd[0] = 100; //Command: Set Motor 1 00697 cmd[1] = rotSpeed; //Command: Rotational Speed? 00698 // itsSerialMutex.lock(); 00699 itsSerial->write(cmd, 2); 00700 // itsSerialMutex.unlock(); 00701 usleep(10000); 00702 00703 //Send the command for the second motor 00704 cmd[0] = 101; //Command: Set Motor 2 00705 cmd[1] = tranSpeed; //Command: Translational Speed? 00706 // itsSerialMutex.lock(); 00707 itsSerial->write(cmd, 2); 00708 // itsSerialMutex.unlock(); 00709 usleep(10000); 00710 } 00711 00712 00713 00714 // ###################################################################### 00715 void BeoPilot::updateGUI() 00716 { 00717 if(itsDisplayTimer.getSecs() > itsDisplayUpdateRate) 00718 { 00719 itsDisplayTimer.reset(); 00720 //Grab the last key pressed by the user 00721 int key = itsMeterXwin.getLastKeyPress(); 00722 00723 float loc_forwardSpeed = 0; 00724 float loc_rotationalSpeed = 0; 00725 bool loc_sonarProxAlert = true; 00726 float loc_sonarTime; 00727 00728 itsSpeedMutex.lock(); 00729 { 00730 //Handle user input to manually drive the robot around using wasd keys 00731 switch(key) 00732 { 00733 case -1: 00734 break; 00735 case 25: //w 00736 itsForwardSpeed += .05; 00737 break; 00738 case 39: //s 00739 itsForwardSpeed -= .05; 00740 break; 00741 case 38: //a 00742 itsRotationalSpeed -= .05; 00743 break; 00744 case 40: //d 00745 itsRotationalSpeed += .05; 00746 break; 00747 case 65: //space 00748 itsForwardSpeed = 0; 00749 itsRotationalSpeed = 0; 00750 break; 00751 case 9: //esc 00752 exit(0); 00753 break; 00754 default: 00755 LINFO("Undefined Key: %d", key); 00756 break; 00757 } 00758 if(itsMeterXwin.pressedCloseButton()) exit(0); 00759 00760 loc_forwardSpeed = itsForwardSpeed; 00761 loc_rotationalSpeed = itsRotationalSpeed; 00762 } 00763 itsSpeedMutex.unlock(); 00764 00765 //Check on the sonar 00766 itsSonarMutex.lock(); 00767 { 00768 loc_sonarProxAlert = itsSonarProxAlert; 00769 loc_sonarTime = itsSonarTimer.getSecs(); 00770 } 00771 itsSonarMutex.unlock(); 00772 00773 //Update the display 00774 itsControlImage = Image<PixRGB<byte> >(512,256,ZEROS); 00775 writeText(itsControlImage, Point2D<int>(0,0), "Commands:", PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00776 writeText(itsControlImage, Point2D<int>(0,8), "w: Forwards", PixRGB<byte>(180,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00777 writeText(itsControlImage, Point2D<int>(0,16), "s: Backwards", PixRGB<byte>(180,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00778 writeText(itsControlImage, Point2D<int>(0,24), "a: Left", PixRGB<byte>(180,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00779 writeText(itsControlImage, Point2D<int>(0,32), "d: Right", PixRGB<byte>(180,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00780 writeText(itsControlImage, Point2D<int>(0,40), "space: STOP", PixRGB<byte>(180,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00781 writeText(itsControlImage, Point2D<int>(0,48), "esc: quit", PixRGB<byte>(180,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00782 00783 char buffer[128]; 00784 sprintf(buffer, "Forward Speed: %2.2f%% Right: %1.3f m/s Left: %1.3f m/s", loc_forwardSpeed*100.0,itsRightMotorVelocity,itsLeftMotorVelocity); 00785 writeText(itsControlImage, Point2D<int>(0,60), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00786 00787 sprintf(buffer, "Rotational Speed: %0.2f -> %0.2f", loc_rotationalSpeed, 00788 loc_rotationalSpeed *itsRotCap/100.0); 00789 writeText(itsControlImage, Point2D<int>(0,75), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00790 00791 sprintf(buffer, "Right Encoder: %d", itsRightEncoder); 00792 writeText(itsControlImage, Point2D<int>(0,90), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00793 00794 sprintf(buffer, "Left Encoder: %d", itsLeftEncoder); 00795 writeText(itsControlImage, Point2D<int>(0,98), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00796 00797 sprintf(buffer, "Enc X: %fm",itsPosition.x ); 00798 writeText(itsControlImage, Point2D<int>(0,116), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00799 00800 sprintf(buffer, "Enc Y: %fm",itsPosition.y ); 00801 writeText(itsControlImage, Point2D<int>(0,124), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00802 00803 sprintf(buffer, "Enc R: %f",itsPosition.z ); 00804 writeText(itsControlImage, Point2D<int>(0,132), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00805 00806 if(itsLoadFromLogFile){ 00807 sprintf(buffer, "LEn X: %fm",itsLogPosition.x ); 00808 writeText(itsControlImage, Point2D<int>(0,140), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00809 00810 sprintf(buffer, "LEn Y: %fm",itsLogPosition.y ); 00811 writeText(itsControlImage, Point2D<int>(0,148), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00812 00813 sprintf(buffer, "LEn R: %f",itsLogPosition.z ); 00814 writeText(itsControlImage, Point2D<int>(0,156), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00815 } 00816 00817 00818 00819 sprintf(buffer, "Sonar Timer: %0.2fs", loc_sonarTime); 00820 writeText(itsControlImage, Point2D<int>(256,0), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00821 00822 PixRGB<byte> proxAlertColor; 00823 if(loc_sonarProxAlert) 00824 { 00825 sprintf(buffer, "Proximity Alert!"); 00826 proxAlertColor = PixRGB<byte>(255,0,0); 00827 } 00828 else 00829 { 00830 sprintf(buffer, "Sonar OK"); 00831 proxAlertColor = PixRGB<byte>(20,128,20); 00832 } 00833 writeText(itsControlImage, Point2D<int>(256,15), buffer, proxAlertColor, PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00834 00835 00836 PixRGB<byte> serialOkColor; 00837 int code = itsSerial->getSerialErrno(); 00838 if(code==0||code==15) 00839 { 00840 sprintf(buffer, "Serial OK"); 00841 serialOkColor = PixRGB<byte>(20,128,20); 00842 } 00843 else 00844 { 00845 sprintf(buffer, "Serial Disconnected!"); 00846 serialOkColor = PixRGB<byte>(255,0,0); 00847 } 00848 writeText(itsControlImage, Point2D<int>(256,30), buffer, serialOkColor, PixRGB<byte>(0,0,0),SimpleFont::FIXED(8)); 00849 00850 00851 for(size_t i=0; i<itsChannelMeters.size(); i++) 00852 { 00853 00854 sprintf(buffer, "Channel%lu: %d", i+1, itsRCChannels[i]); 00855 00856 Point2D<int> pastePoint = Point2D<int>( 00857 int(itsChannelMeters[0].getWidth()*itsChannelMeters.size()*1.05+20), 00858 itsControlImage.getHeight() - itsChannelMeters[i].getHeight() - 10 + i*8 00859 ); 00860 00861 writeText(itsControlImage, pastePoint, buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00862 00863 pastePoint = Point2D<int>( 00864 int(10+itsChannelMeters[i].getWidth()*i*1.05), 00865 itsControlImage.getHeight() - itsChannelMeters[i].getHeight() - 10 00866 ); 00867 inplacePaste(itsControlImage, itsChannelMeters[i].render(itsRCChannels[i]), pastePoint ); 00868 } 00869 00870 sprintf(buffer, "Emergency Mode: %d", itsEmergencyMode); 00871 writeText(itsControlImage, Point2D<int>(256,88), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00872 00873 sprintf(buffer, "RemoteMode: %d", itsRemoteMode); 00874 writeText(itsControlImage, Point2D<int>(256,96), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00875 00876 if(itsLoadFromLogFile){ 00877 sprintf(buffer, "Log Mode: %d", itsLogRemoteMode); 00878 writeText(itsControlImage, Point2D<int>(340,96), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00879 } 00880 sprintf(buffer, "Motor 1 Speed: %0.2f", itsMotor1Speed); 00881 writeText(itsControlImage, Point2D<int>(256,104), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00882 00883 sprintf(buffer, "Motor 2 Speed: %0.2f", itsMotor2Speed); 00884 writeText(itsControlImage, Point2D<int>(256,112), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00885 00886 sprintf(buffer, "RC Speed : %0.2f -> %0.2f", itsRcTransSpeed,itsRcTransSpeedCapped); 00887 writeText(itsControlImage, Point2D<int>(256,120), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00888 00889 sprintf(buffer, "RC Rotation: %0.2f -> %0.2f", itsRcRotSpeed,itsRcRotSpeedCapped); 00890 writeText(itsControlImage, Point2D<int>(256,128), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00891 00892 00893 00894 //sprintf(buffer, "RCSpeed: %d", getRCSpeed()); 00895 //writeText(itsControlImage, Point2D<int>(256,104), buffer, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0),SimpleFont::FIXED(6)); 00896 00897 inplacePaste(itsDispImage,itsControlImage,Point2D<int>(0,0)); 00898 00899 00900 //Draw The Map 00901 //float replayspeed = itsReplaySpeed.getVal(); 00902 int w = itsMapImage.getWidth(); 00903 int h = itsMapImage.getHeight(); 00904 double scaleRate = 0.9; 00905 Point2D<int> drawPos( 00906 int(itsPosition.x*itsMapScale + w/2), 00907 int(itsPosition.y*itsMapScale + h/2) 00908 ); 00909 if(itsMapImage.coordsOk(drawPos)) 00910 { 00911 itsPositionMap.push_back(itsPosition); 00912 }else 00913 { 00914 //Find New Scale 00915 do{ 00916 itsMapScale *= scaleRate; 00917 drawPos = Point2D<int>( 00918 int(itsPosition.x*itsMapScale + w/2), 00919 int(itsPosition.y*itsMapScale + h/2) 00920 ); 00921 }while(!itsMapImage.coordsOk(drawPos)); 00922 reDrawMap(itsMapScale); 00923 } 00924 itsMapImage.setVal(drawPos, itsPosition.color); 00925 00926 Image<PixRGB<byte> > itsDrawMapImage(itsMapImage); 00927 drawCircle(itsDrawMapImage, drawPos, 7, PixRGB<byte>(255,255,255)); 00928 drawLine(itsDrawMapImage, drawPos,-itsPosition.z, 7, PixRGB<byte>(255,255,255)); 00929 00930 if(itsLoadFromLogFile){ 00931 Point2D<int> drawPos2( 00932 int(itsLogPosition.x*itsMapScale + w/2), 00933 int(itsLogPosition.y*itsMapScale + h/2) 00934 ); 00935 if(!itsMapImage.coordsOk(drawPos2)) 00936 { 00937 //Find New Scale 00938 do{ 00939 itsMapScale *= scaleRate; 00940 drawPos2 = Point2D<int>( 00941 int(itsLogPosition.x*itsMapScale + w/2), 00942 int(itsLogPosition.y*itsMapScale + h/2) 00943 ); 00944 }while(!itsMapImage.coordsOk(drawPos2)); 00945 reDrawMap(itsMapScale); 00946 } 00947 //redraw it every time since we fastward the speed 00948 if(itsReplaySpeed.getVal() != 1) 00949 reDrawMap(itsMapScale); 00950 itsMapImage.setVal(drawPos2, itsLogPosition.color); 00951 drawCircle(itsDrawMapImage, drawPos2, 7, PixRGB<byte>(0,255,0)); 00952 drawLine(itsDrawMapImage, drawPos2,-itsLogPosition.z, 7, PixRGB<byte>(255,255,255)); 00953 } 00954 inplacePaste(itsDispImage,itsDrawMapImage,Point2D<int>(0,256)); 00955 00956 std::vector<std::vector<float> > lines; 00957 lines.push_back(itsVelocityQue.getVector()); 00958 lines.push_back(itsVelocityTargetQue.getVector()); 00959 00960 std::vector<PixRGB<byte> > linesColor; 00961 linesColor.push_back(PixRGB<byte>(255,0,0)); 00962 linesColor.push_back(PixRGB<byte>(255,165,0)); 00963 00964 Image<PixRGB<byte> > plotImage = multilinePlot( 00965 lines, 00966 288+70,256, 00967 -1.0f,1.0f, 00968 "velocity","m/s","", 00969 linesColor, 00970 PixRGB<byte>(255,255,255), 00971 PixRGB<byte>(0,0,0) 00972 00973 ); 00974 inplacePaste(itsDispImage,plotImage,Point2D<int>(512-70,0)); 00975 00976 //Draw Divide Line 00977 drawLine(itsDispImage,Point2D<int>(0,255),Point2D<int>(800,255),PixRGB<byte>(255,255,255));//HR 00978 drawLine(itsDispImage,Point2D<int>(512-70,0),Point2D<int>(512-70,255),PixRGB<byte>(255,255,255));//VT 00979 00980 00981 inplacePaste(itsDispImage,itsDispCameraImage,Point2D<int>(itsDispImage.getWidth()-320,itsDispImage.getHeight()-240)); 00982 00983 itsMeterXwin.drawImage(itsDispImage); 00984 00985 } 00986 } 00987 void BeoPilot::reDrawMap(double scale) 00988 { 00989 00990 //Clean up the old images 00991 itsMapImage = Image<PixRGB<byte> >(800,344,ZEROS); 00992 00993 int w = itsMapImage.getWidth(); 00994 int h = itsMapImage.getHeight(); 00995 00996 //Redraw all points with new scale 00997 for(int i = 0;i < (int)itsLogPositionMap.size();i++) 00998 { 00999 Point2D<int> tmp( 01000 01001 int(itsLogPositionMap[i].x*scale + w/2), 01002 int(itsLogPositionMap[i].y*scale + h/2) 01003 ); 01004 if(itsMapImage.coordsOk(tmp)) 01005 itsMapImage.setVal(tmp, itsLogPositionMap[i].color); 01006 } 01007 for(int i = 0;i < (int)itsPositionMap.size();i++) 01008 { 01009 Point2D<int> tmp( 01010 01011 int(itsPositionMap[i].x*scale + w/2), 01012 int(itsPositionMap[i].y*scale + h/2) 01013 ); 01014 if(itsMapImage.coordsOk(tmp)) 01015 itsMapImage.setVal(tmp, itsPositionMap[i].color); 01016 } 01017 01018 } 01019 // ###################################################################### 01020 void BeoPilot::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg, 01021 const Ice::Current&) 01022 { 01023 if(eMsg->ice_isA("::BeobotEvents::MotorRequest")) 01024 { 01025 itsSpeedMutex.lock(); 01026 { 01027 BeobotEvents::MotorRequestPtr mrMsg = BeobotEvents::MotorRequestPtr::dynamicCast(eMsg); 01028 itsForwardSpeedReq = mrMsg->transVel; 01029 itsRotationalSpeedReq = mrMsg->rotVel; 01030 } 01031 itsSpeedMutex.unlock(); 01032 LINFO("Received Motor Request Speed:[%f] Rotation:[%f]",itsForwardSpeedReq,itsRotationalSpeedReq); 01033 } 01034 else if(eMsg->ice_isA("::BeobotEvents::SonarMessage")) 01035 { 01036 itsSonarMutex.lock(); 01037 { 01038 itsSonarTimer.reset(); 01039 BeobotEvents::SonarMessagePtr srMsg = BeobotEvents::SonarMessagePtr::dynamicCast(eMsg); 01040 itsSonarReadings = srMsg->distances; 01041 itsSonarAngles = srMsg->angles; 01042 } 01043 itsSonarMutex.unlock(); 01044 } 01045 } 01046 01047 // ###################################################################### 01048 void BeoPilot::getCurrentLogData() 01049 { 01050 uint64 time = itsLogTimer.get()/1000.0; 01051 if(itsReplaySpeed.getVal()==1) 01052 { 01053 do{ 01054 if(itsLogData[itsCurrentTimeIndex].time < time && itsCurrentTimeIndex < (int)itsLogData.size()) 01055 itsCurrentTimeIndex++; 01056 }while(itsLogData[itsCurrentTimeIndex].time < time && itsCurrentTimeIndex < (int)itsLogData.size()); 01057 } 01058 if((int)itsLogImageData.size() != 0){ 01059 do{ 01060 if(itsLogImageData[itsCurrentTimeIndex2].time < time && itsCurrentTimeIndex2 < (int)itsLogImageData.size()) 01061 itsCurrentTimeIndex2++; 01062 }while(itsLogImageData[itsCurrentTimeIndex2].time < time && itsCurrentTimeIndex2 < (int)itsLogImageData.size()); 01063 imageData img = itsLogImageData[itsCurrentTimeIndex2]; 01064 if(file_exists(img.imagePath.c_str())) 01065 itsDispCameraImage = Raster::ReadRGB(img.imagePath); 01066 LINFO("Found Index[%d] with Image[%f],Path %s",itsCurrentTimeIndex2,itsLogImageData[itsCurrentTimeIndex2].time,itsLogImageData[itsCurrentTimeIndex2].imagePath.c_str()) ; 01067 } 01068 LINFO("Current Time[%f] Found Index[%d] with LogTimeStamp[%f]",(double)time,itsCurrentTimeIndex,itsLogData[itsCurrentTimeIndex].time) ; 01069 01070 for(int i = 0;i < itsReplaySpeed.getVal();i++) 01071 { 01072 if(itsReplaySpeed.getVal() !=1 && itsCurrentTimeIndex < (int)itsLogData.size()) 01073 itsCurrentTimeIndex++; 01074 01075 motorData tmp = itsLogData[itsCurrentTimeIndex]; 01076 01077 // if(img.time != 0.0) 01078 01079 01080 01081 //itsForwardSpeed = tmp.transVel; 01082 //itsRotationalSpeed = tmp.rotVel; 01083 itsForwardSpeed = tmp.rcTransVel; 01084 itsRotationalSpeed = tmp.rcRotVel; 01085 01086 itsLogDiffPosition.x = tmp.encoderX; 01087 itsLogDiffPosition.y = tmp.encoderY; 01088 itsLogDiffPosition.z = tmp.encoderOri; 01089 01090 itsLogPosition.x += itsLogDiffPosition.x; 01091 itsLogPosition.y += itsLogDiffPosition.y; 01092 itsLogPosition.z += itsLogDiffPosition.z; 01093 01094 itsRcTransSpeed = tmp.rcTransVel; 01095 itsRcRotSpeed = tmp.rcRotVel ; 01096 itsLogRemoteMode = tmp.rcMode ; 01097 01098 itsMotor1Speed = itsForwardSpeed - itsRotationalSpeed; 01099 itsMotor2Speed = itsForwardSpeed + itsRotationalSpeed; 01100 if(itsLogRemoteMode == 1) 01101 itsLogPosition.color = PixRGB<byte>(255,0,0); 01102 else 01103 itsLogPosition.color = PixRGB<byte>(0,255,0); 01104 01105 if(itsCurrentTimeIndex <(int)itsLogData.size()) 01106 itsLogPositionMap.push_back(itsLogPosition); 01107 } 01108 } 01109 void BeoPilot::drawAllMap(void) 01110 { 01111 for(int i = 0;i < (int)itsLogData.size();i++){ 01112 motorData tmp = itsLogData[i]; 01113 itsLogDiffPosition.x = tmp.encoderX; 01114 itsLogDiffPosition.y = tmp.encoderY; 01115 itsLogDiffPosition.z = tmp.encoderOri; 01116 01117 itsLogPosition.x += itsLogDiffPosition.x; 01118 itsLogPosition.y += itsLogDiffPosition.y; 01119 itsLogPosition.z += itsLogDiffPosition.z; 01120 itsLogPositionMap.push_back(itsLogPosition); 01121 } 01122 }