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 }