00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 #include "garcia_mixed.h"
00120 
00121 #define DEG2RAD(x) (((double)(x))*0.01745329251994)
00122 #define RAD2DEG(x) (((double)(x))*57.29577951308232)
00123 
00124 #include <unistd.h>
00125 #include <string.h>
00126 #include <stdint.h>
00127 #include <sys/time.h>
00128 #include <time.h>
00129 #include <assert.h>
00130 #include <math.h>
00131 #include <stdio.h>
00132 using namespace std;
00133 
00134 #include <iostream> 
00135 
00136 const timespec NSLEEP_TIME = {0, 20000000}; 
00137 
00139 
00140 
00141 
00142 
00143 
00144 
00145 Driver*
00146 GarciaDriver_Init(ConfigFile* cf, int section)
00147 {
00148   
00149   return ((Driver*)(new GarciaDriver(cf, section)));
00150 
00151 }
00152 
00153 
00154 
00155 
00156 
00157 void
00158 GarciaDriver_Register(DriverTable* table)
00159 {
00160   table->AddDriver("garcia", GarciaDriver_Init);
00161 }
00162 
00164 
00165 
00166 GarciaDriver::GarciaDriver(ConfigFile* cf, int section)
00167     : Driver(cf, section),
00168       mLength(0.28),
00169       mWidth(0.20),
00170       mWheelBase(0.182),
00171       mWheelRadius(0.1)
00172 {
00173   
00174   if (0 != cf->ReadDeviceAddr(&mPos2dAddr, section, "provides",
00175                               PLAYER_POSITION2D_CODE, -1, NULL))
00176   {
00177     PLAYER_ERROR("Could not read position2d ID ");
00178     SetError(-1);
00179     return;
00180   }
00181   if (0 != AddInterface(mPos2dAddr))
00182   {
00183     PLAYER_ERROR("Could not add position2d interface ");
00184     SetError(-1);
00185     return;
00186   }
00187 
00188   
00189   if (0 != cf->ReadDeviceAddr(&mIrAddr, section, "provides",
00190                               PLAYER_IR_CODE, -1, NULL))
00191   {
00192     PLAYER_ERROR("Could not read ir ID ");
00193     SetError(-1);
00194     return;
00195   }
00196   if (0 != AddInterface(mIrAddr))
00197   {
00198     PLAYER_ERROR("Could not add ir interface ");
00199     SetError(-1);
00200     return;
00201   }
00202 
00203   
00204   if (0 != cf->ReadDeviceAddr(&mSpeechAddr, section, "provides",
00205                               PLAYER_SPEECH_CODE, -1, NULL))
00206   {
00207     PLAYER_ERROR("Could not read speech ID ");
00208     SetError(-1);
00209     return;
00210   }
00211   if (0 != AddInterface(mSpeechAddr))
00212   {
00213     PLAYER_ERROR("Could not add speech interface ");
00214     SetError(-1);
00215     return;
00216   }
00217 
00218   
00219   if (0 != cf->ReadDeviceAddr(&(mDioAddr),section,"provides",
00220                               PLAYER_DIO_CODE,-1,NULL))
00221   {
00222     PLAYER_ERROR("Could not read dio ID ");
00223     SetError(-1);
00224     return;
00225   }
00226   if (0 != AddInterface(mDioAddr))
00227   {
00228     PLAYER_ERROR("Could not add dio interface ");
00229     SetError(-1);
00230     return;
00231   }
00232 
00233   
00234   if (0 != cf->ReadDeviceAddr(&mPowerAddr,
00235                             section,
00236                             "provides",
00237                             PLAYER_POWER_CODE,
00238                             -1,
00239                             NULL))
00240   {
00241     PLAYER_ERROR("could not read power address");
00242     SetError(-1);
00243     return;
00244   }
00245 
00246   if (0 != AddInterface(mPowerAddr))
00247   {
00248     PLAYER_ERROR("could not add power interface");
00249     SetError(-1);
00250     return;
00251   }
00252 
00253   
00254   const char* portname = cf->ReadFilename(section, "portname", "ttyS0");
00255   int baudrate = cf->ReadInt(section, "baudrate", 38400);
00256 
00257   
00258   static FILE* config_file;
00259   config_file = fopen("garcia_api.config", "a+");
00260 
00261   fprintf(config_file, "portname=%s\n", portname);
00262   fprintf(config_file, "baudrate=%i\n", baudrate);
00263 
00264   mSpeed = static_cast<float>(cf->ReadFloat(section, "speed", 0.7f));
00265   mPitch = static_cast<float>(cf->ReadFloat(section, "pitch", 0.6f));
00266   mVolume = static_cast<float>(cf->ReadFloat(section, "volume", 1.0f));
00267 
00268   fclose(config_file);
00269 
00270   return;
00271 }
00272 
00273 GarciaDriver::~GarciaDriver()
00274 {
00275   
00276   
00277 }
00278 
00280 
00281 int
00282 GarciaDriver::Setup()
00283 {
00284 
00285   cout << "Setting up Garcia driver" << flush;
00286   mGarcia = new acpGarcia;
00287 
00288   while (!mGarcia->getNamedValue("active")->getBoolVal())
00289   {
00290     cout << "." << flush;
00291     nanosleep(&NSLEEP_TIME, NULL);
00292   }
00293 
00294   
00295   acpValue enable(1);
00296   mGarcia->setNamedValue("front-ranger-enable", &enable);
00297   mGarcia->setNamedValue("side-ranger-enable", &enable);
00298   mGarcia->setNamedValue("rear-ranger-enable", &enable);
00299 
00300 
00301   puts("finished!");
00302 
00303   
00304   
00305   StartThread();
00306 
00307   return(0);
00308 }
00309 
00310 
00312 
00313 int
00314 GarciaDriver::Shutdown()
00315 {
00316   puts("Shutting Garcia driver down");
00317 
00318   
00319   StopThread();
00320 
00321   
00322   
00323 
00324   delete mGarcia;
00325 
00326   puts("Garcia driver has been shutdown");
00327 
00328   return(0);
00329 }
00330 
00332 
00333 void
00334 GarciaDriver::Main()
00335 {
00336 
00337   
00338   for(;;)
00339   {
00340     
00341     pthread_testcancel();
00342 
00343     
00344     nanosleep(&NSLEEP_TIME, NULL);
00345 
00346     
00347     ProcessMessages();
00348 
00349     
00350     RefreshData();
00351 
00352   }
00353   return;
00354 }
00355 
00356 
00357 int
00358 GarciaDriver::ProcessMessage(QueuePointer & resp_queue,
00359                              player_msghdr* hdr,
00360                              void* data)
00361 {
00362   assert(resp_queue);
00363   assert(hdr);
00364   assert(data);
00365 
00366   if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00367                            PLAYER_POSITION2D_CMD_POS, mPos2dAddr))
00368   {
00369     assert(hdr->size == sizeof(player_position2d_cmd_pos_t));
00370     ProcessPos2dPosCmd(hdr, *reinterpret_cast<player_position2d_cmd_pos_t *>(data));
00371     return(0);
00372   }
00373   if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00374                            PLAYER_POSITION2D_CMD_VEL, mPos2dAddr))
00375   {
00376     assert(hdr->size == sizeof(player_position2d_cmd_vel_t));
00377     ProcessPos2dVelCmd(hdr, *reinterpret_cast<player_position2d_cmd_vel_t *>(data));
00378     return(0);
00379   }
00380   else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00381                                 PLAYER_SPEECH_CMD_SAY, mSpeechAddr))
00382   {
00383     assert(hdr->size == sizeof(player_speech_cmd_t));
00384     ProcessSpeechCommand(hdr, *reinterpret_cast<player_speech_cmd_t *>(data));
00385     return(0);
00386   }
00387   else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,
00388                                 PLAYER_DIO_CMD_VALUES, mDioAddr))
00389   {
00390     assert(hdr->size == sizeof(player_dio_cmd_t));
00391     ProcessDioCommand(hdr, *reinterpret_cast<player_dio_cmd_t *>(data));
00392     return(0);
00393   }
00394   else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
00395                                 PLAYER_POSITION2D_REQ_GET_GEOM, mPos2dAddr))
00396   {
00397     ProcessPos2dGeomReq(hdr);
00398     return(0);
00399   }
00400   else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
00401                                 PLAYER_IR_REQ_POSE, mIrAddr))
00402   {
00403     ProcessIrPoseReq(hdr);
00404     return(0);
00405   }
00406   else
00407   {
00408     PLAYER_ERROR1("GarciaDriver received unknown message: %s", hdr->type);
00409   }
00410 
00411   return -1;
00412 }
00413 
00414 void
00415 GarciaDriver::ProcessPos2dPosCmd(player_msghdr_t* hdr,
00416                                  player_position2d_cmd_pos_t &data)
00417 {
00418   printf("Position commands currently not implemented\n");
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 }
00473 
00474 void
00475 GarciaDriver::ProcessPos2dVelCmd(player_msghdr_t* hdr,
00476                                  player_position2d_cmd_vel_t &data)
00477 {
00478   double v(data.vel.px);
00479   double omega(data.vel.pa);
00480 
00481   acpValue vl(static_cast<float>(v - mWheelBase*omega/2.0));
00482   acpValue vr(static_cast<float>(v + mWheelBase*omega/2.0));
00483 
00484   mGarcia->setNamedValue("damped-speed-left", &vl);
00485   mGarcia->setNamedValue("damped-speed-right", &vr);
00486 
00487   
00488   acpObject* behavior;
00489   behavior = mGarcia->createNamedBehavior("null", "vel");
00490   mGarcia->queueBehavior(behavior);
00491 }
00492 
00493 void
00494 GarciaDriver::ProcessSpeechCommand(player_msghdr_t* hdr,
00495                                    player_speech_cmd_t &data)
00496 {
00497   
00498   cout << data.string << endl;
00499 
00500   acpValue phrase(data.string);
00501   acpObject* behavior;
00502 
00503   behavior = mGarcia->createNamedBehavior("say", data.string);
00504   behavior->setNamedValue("phrase", &phrase);
00505   behavior->setNamedValue("speed", &mSpeed);
00506   behavior->setNamedValue("pitch", &mPitch);
00507   behavior->setNamedValue("volume", &mVolume);
00508   mGarcia->queueBehavior(behavior);
00509 }
00510 
00511 void
00512 GarciaDriver::ProcessDioCommand(player_msghdr_t* hdr,
00513                                 player_dio_cmd_t &data)
00514 {
00515   PLAYER_WARN("Garcia driver currently doesn't support DIO commands");
00516 }
00517 
00518 void
00519 GarciaDriver::ProcessPos2dGeomReq(player_msghdr_t* hdr)
00520 {
00521   player_position2d_geom_t geom;
00522 
00523   geom.pose.px = 0.03; 
00524   geom.pose.py = 0.00; 
00525   geom.pose.pa = 0;    
00526   geom.size.sl = mLength;  
00527   geom.size.sw = mWidth;  
00528 
00529   Publish(mPos2dAddr,
00530           PLAYER_MSGTYPE_RESP_ACK,
00531           PLAYER_POSITION2D_REQ_GET_GEOM,
00532           &geom, sizeof(geom), NULL);
00533 }
00534 
00535 void
00536 GarciaDriver::ProcessIrPoseReq(player_msghdr_t* hdr)
00537 {
00538   player_pose_t poses[6] = {{ 0.105, 0.045, M_PI/6}, 
00539                             { 0.105,-0.045,-M_PI/6}, 
00540                             { 0.080, 0.020, M_PI_2}, 
00541                             { 0.080,-0.020,-M_PI_2}, 
00542                             {-0.050, 0.070, M_PI},   
00543                             {-0.050,-0.070,-M_PI}};  
00544 
00545   player_ir_pose_t pose;
00546   pose.poses_count = 6;
00547   pose.poses = new double[pose.poses_count];
00548   memcpy(pose.poses, poses, 6*sizeof(player_pose3d_t));
00549 
00550   Publish(mIrAddr,
00551           PLAYER_MSGTYPE_RESP_ACK,
00552           PLAYER_IR_REQ_POSE,
00553           &pose);
00554   delete [] pose.poses;
00555 
00556 }
00557 
00558 void
00559 GarciaDriver::RefreshData()
00560 {
00561   
00562   mPos2dData.pos.px  = 0.0;
00563   mPos2dData.pos.py  = 0.0;
00564   mPos2dData.pos.pa  = 0.0;
00565 
00566   mPos2dData.vel.px  = 0.0;
00567   mPos2dData.vel.py  = 0.0;
00568   mPos2dData.vel.pa  = 0.0;
00569 
00570   Publish(mPos2dAddr,
00571           PLAYER_MSGTYPE_DATA, PLAYER_POSITION2D_DATA_STATE,
00572           reinterpret_cast<void*>(&mPos2dData), sizeof(mPos2dData), NULL);
00573 
00574   
00575   mIrData.voltages_count = 0;
00576   mIrData.ranges_count = 6;
00577   mIrData.ranges = new double[mIrData.ranges_count];
00578   
00579   mIrData.ranges[0] = mGarcia->getNamedValue("front-ranger-left")->getFloatVal();
00580   mIrData.ranges[1] = mGarcia->getNamedValue("front-ranger-right")->getFloatVal();
00581   mIrData.ranges[2] = mGarcia->getNamedValue("side-ranger-left")->getFloatVal();
00582   mIrData.ranges[3] = mGarcia->getNamedValue("side-ranger-right")->getFloatVal();
00583   mIrData.ranges[4] = mGarcia->getNamedValue("rear-ranger-left")->getFloatVal();
00584   mIrData.ranges[5] = mGarcia->getNamedValue("rear-ranger-right")->getFloatVal();
00585 
00586   Publish(mIrAddr,
00587           PLAYER_MSGTYPE_DATA, PLAYER_IR_DATA_RANGES,
00588           reinterpret_cast<void*>(&mIrData));
00589   delete [] mIrData.ranges;
00590 
00591   
00592   static int dio_test = 0;
00593   mDioData.count = 16;
00594   mDioData.digin = ++dio_test;
00595 
00596   Publish(mDioAddr,
00597           PLAYER_MSGTYPE_DATA, PLAYER_DIO_DATA_VALUES,
00598           reinterpret_cast<void*>(&mDioData), sizeof(mDioData), NULL);
00599 
00600   mPowerData.valid = PLAYER_POWER_MASK_VOLTS | PLAYER_POWER_MASK_PERCENT;
00601   mPowerData.volts = mGarcia->getNamedValue("battery-voltage")->getFloatVal();
00602   mPowerData.percent = mGarcia->getNamedValue("battery-level")->getFloatVal();
00603 
00604   Publish(mPowerAddr,
00605           PLAYER_MSGTYPE_DATA, PLAYER_POWER_DATA_STATE,
00606           reinterpret_cast<void*>(&mPowerData), sizeof(mPowerData), NULL);
00607 }