00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "WorldModel2.h"
00017
00018
00019 #include <cmath>
00020 #include <vector>
00021 #include <deque>
00022 #include "Events/EventRouter.h"
00023 #include "Events/VisionEvent.h"
00024 #include "Events/LocomotionEvent.h"
00025 #include "Shared/WorldState.h"
00026 #include "Vision/Vision.h"
00027 #include "Wireless/Wireless.h"
00028 #include "Shared/Config.h"
00029
00030
00031 #include "FastSLAM/afsMain.h"
00032 #include "Maps/almMain.h"
00033 #include "Maps/agmMain.h"
00034 #include "Maps/almStructures.h"
00035
00036 #include "FastSLAM/Configuration.h"
00037
00038 #include "FastSLAM/afsParticle.h"
00039
00040 #include "Maps/Configuration.h"
00041
00042 #include "Poses.h"
00043
00044
00045 #include "Shared/get_time.h"
00046
00047
00048 #define UNLESS(item) if(!( (item) ))
00049
00050
00051
00052
00053
00054 #define TIMER_SID_GPA 0 // sid for ground plane assumption timer
00055 #define TIMER_SID_SRL 1 // sid for serializer
00056
00057 using namespace std;
00058
00059
00060
00061
00062 bool WorldModel2::locked = false;
00063
00064
00065
00066 WorldModel2::WorldModel2()
00067
00068
00069 : kludges(0),
00070
00071 moving(true),
00072
00073 enabledIR(false), enabledGPA(false),
00074
00075
00076 dx(0.0), dy(0.0), da(0.0), movingSince(0),
00077
00078
00079
00080
00081
00082
00083 sockDM(wireless->socket(SocketNS::SOCK_STREAM, 1024,
00084 DM_CELL_COUNT*sizeof(dm_cell))),
00085 sockHM(wireless->socket(SocketNS::SOCK_STREAM, 1024,
00086 HM_CELL_COUNT*sizeof(hm_cell)))
00087 #ifdef WANT_GLOBAL_MAP
00088 ,
00089 sockGM(wireless->socket(SocketNS::SOCK_STREAM, 1024,
00090 GM_CELL_COUNT*sizeof(hm_cell))),
00091 sockFS(wireless->socket(SocketNS::SOCK_STREAM, 1024,
00092 AFS_NUM_PARTICLES*sizeof(afsPose) + sizeof(afsParticle))),
00093 enabledMarkers(false),
00094 fs_updates()
00095 #endif
00096 {
00097
00098 if(locked) return;
00099
00100 locked = true;
00101
00102 #ifdef WANT_GLOBAL_MAP
00103
00104 for(int i=0; i<AFS_NUM_LANDMARKS; ++i) haveSeenMarker[i] = false;
00105 #endif
00106
00107
00108 wireless->listen(sockDM->sock, config->worldmodel2.dm_port);
00109 wireless->listen(sockHM->sock, config->worldmodel2.hm_port);
00110 #ifdef WANT_GLOBAL_MAP
00111 wireless->listen(sockGM->sock, config->worldmodel2.gm_port);
00112 wireless->listen(sockFS->sock, config->worldmodel2.fs_port);
00113 #endif
00114
00115
00116 resetWorldModel();
00117
00118
00119 erouter->addListener(this,EventBase::locomotionEGID);
00120
00121
00122 erouter->addTimer(this, TIMER_SID_SRL, SRLdelay, true);
00123 }
00124
00125
00126 WorldModel2::~WorldModel2()
00127 {
00128
00129 disableIR();
00130 disableGPA();
00131 #ifdef WANT_GLOBAL_MAP
00132 disableMarkers();
00133 #endif
00134 erouter->forgetListener(this);
00135
00136
00137 wireless->close(sockDM);
00138 wireless->close(sockHM);
00139 #ifdef WANT_GLOBAL_MAP
00140 wireless->close(sockGM);
00141 wireless->close(sockFS);
00142 #endif
00143
00144
00145 locked = false;
00146 }
00147
00148
00149
00150
00151
00152 void WorldModel2::enableIR()
00153 {
00154
00155 erouter->addListener(this, EventBase::sensorEGID, SensorSourceID::UpdatedSID);
00156 enabledIR = true;
00157 }
00158 void WorldModel2::disableIR()
00159 {
00160
00161 erouter->removeListener(this, EventBase::sensorEGID,
00162 SensorSourceID::UpdatedSID);
00163 enabledIR = false;
00164 }
00165
00166
00167
00168
00169
00170 void WorldModel2::enableGPA()
00171 {
00172
00173
00174
00175 if(movingSince && !moving)
00176 erouter->addTimer(this, TIMER_SID_GPA, GPAdelay, true);
00177
00178 enabledGPA = true;
00179 }
00180 void WorldModel2::disableGPA()
00181 {
00182
00183 erouter->removeTimer(this, TIMER_SID_GPA);
00184
00185 enabledGPA = false;
00186 }
00187
00188
00189
00190
00191 void WorldModel2::enableKludge(unsigned int kludge)
00192 {
00193 kludges |= kludge;
00194 }
00195
00196
00197 void WorldModel2::disableKludge(unsigned int kludge)
00198 {
00199 kludges &= ~kludge;
00200 }
00201
00202
00203 #ifdef WANT_GLOBAL_MAP
00204
00205 void WorldModel2::enableMarkers()
00206 {
00207
00208
00209 if(movingSince && !moving)
00210 erouter->addListener(this,EventBase::visionEGID, VisionEventNS::MarkersSID);
00211 enabledMarkers = true;
00212 }
00213 void WorldModel2::disableMarkers()
00214 {
00215
00216 vision->disableEvents(VisionEventNS::MarkersSID);
00217 erouter->removeListener(this, EventBase::visionEGID,
00218 VisionEventNS::MarkersSID);
00219 enabledMarkers = false;
00220 }
00221 #endif
00222
00223
00224
00225
00226 void WorldModel2::resetWorldModel()
00227 {
00228
00229 ALM::init();
00230 #ifdef WANT_GLOBAL_MAP
00231
00232 AGM::init();
00233
00234 afsInit();
00235 #endif
00236 }
00237
00238 #ifdef WANT_GLOBAL_MAP
00239
00240
00241 void WorldModel2::setLandmark(int landmark,
00242 double x, double y, double covariance)
00243 {
00244 afsSetLandmark(landmark, x, y, covariance);
00245 }
00246
00247
00248
00249
00250
00251 void WorldModel2::fsDistribute(double lx, double ty, double rx, double by)
00252 {
00253 afsDistribute(lx, ty, rx, by);
00254 }
00255 #endif
00256
00257
00258 void WorldModel2::processEvent(const EventBase& event)
00259 {
00260
00261 switch(event.getGeneratorID()) {
00262
00263 case EventBase::sensorEGID: processSensors(); break;
00264 #ifdef WANT_GLOBAL_MAP
00265
00266 case EventBase::visionEGID: processVision(event); break;
00267 #endif
00268
00269 case EventBase::locomotionEGID: processLocomotion(event); break;
00270
00271
00272 case EventBase::timerEGID:
00273 if(event.getSourceID() == TIMER_SID_GPA) processGround();
00274 else if(event.getSourceID() == TIMER_SID_SRL) serialize();
00275 break;
00276
00277 default:
00278 cerr << "warning: WorldModel2 receved unrequested event" << endl;
00279 }
00280 }
00281
00282
00283 void WorldModel2::getRequests(MRvector &requests)
00284 {
00285 ALM::genRequests(requests);
00286 #ifdef WANT_GLOBAL_MAP
00287 AGM::genRequests(requests);
00288 #endif
00289 }
00290
00291
00292
00293
00294 void WorldModel2::pickDMData(dmPicker &p, float *dest)
00295 {
00296
00297 dm_cell *DMp = ALM::getDM();
00298 for(int i=0; i<DM_CELL_COUNT; ++i) dest[i] = p(DMp[i]);
00299 }
00300 dm_cell *WorldModel2::invadeDMData(void) { return ALM::getDM(); }
00301
00302
00303
00304 void WorldModel2::pickHMData(hmPicker &p, float *dest)
00305 {
00306
00307 hm_cell *HMp = ALM::getHM();
00308 for(int i=0; i<HM_CELL_COUNT; ++i) dest[i] = p(HMp[i]);
00309 }
00310 hm_cell *WorldModel2::invadeHMData(void) { return ALM::getHM(); }
00311
00312 #ifdef WANT_GLOBAL_MAP
00313
00314
00315 void WorldModel2::pickGMData(hmPicker &p, float *dest)
00316 {
00317
00318
00319
00320
00321
00322 }
00323 hm_cell *WorldModel2::invadeGMData(void) { return NULL; }
00324 #endif
00325
00326
00327
00328 void WorldModel2::processSensors()
00329 {
00330
00331 UNLESS(enabledIR) {
00332 cerr << "warning: WorldModel2 handling IR event w/o authorization" << endl;
00333 return;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342 double depth = state->sensors[IRDistOffset];
00343 double azimuth = state->outputs[HeadOffset+PanOffset];
00344 double altitude = state->outputs[HeadOffset+TiltOffset];
00345
00346 ALM::registerDepth(depth, altitude, azimuth, kludges);
00347 }
00348
00349 #ifdef WANT_GLOBAL_MAP
00350
00351 void WorldModel2::processVision(const EventBase& event)
00352 {
00353
00354
00355
00356 static int curr_img_width = 0;
00357 static float cam_depth_wpix = 0;
00358 static float ciw_2 = 0;
00359
00360
00361 UNLESS(enabledMarkers) {
00362 cerr << "warning: WorldModel2 handling markers w/o authorization" << endl;
00363 return;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 UNLESS((event.getTypeID() == EventBase::statusETID) &&
00378 (event.getSourceID() == VisionEventNS::MarkersSID)) return;
00379
00380
00381 float x = static_cast<const VisionEvent*>(&event)->getCenterX();
00382 int whichMarker = static_cast<const VisionEvent*>(&event)->getProperty();
00383
00384
00385 if((whichMarker < 0) || (whichMarker >= AFS_NUM_LANDMARKS)) return;
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 if(vision->width != curr_img_width) {
00396 curr_img_width = vision->width;
00397 ciw_2 = ((float)curr_img_width) / 2.0;
00398
00399
00400
00401 cam_depth_wpix = ((double) ciw_2)*tan(AIBO_CAM_H_FOV/2);
00402 }
00403
00404
00405 float theta = atan2(ciw_2-x, cam_depth_wpix);
00406
00407
00408
00409 if(theta*theta > maxMarkerAngle*maxMarkerAngle) return;
00410
00411
00412 theta += state->outputs[HeadOffset+PanOffset];
00413
00414
00415 afsMeasurement(whichMarker, theta);
00416
00417 #ifdef DEBUG_WM2
00418
00419 cout << " OBS: " << whichMarker << " at " << theta
00420 << "\t (" << theta*180/M_PI << ")" << endl;
00421 #endif
00422
00423
00424 haveSeenMarker[whichMarker] = true;
00425 }
00426 #endif
00427
00428
00429 void WorldModel2::processLocomotion(const EventBase& event)
00430 {
00431 long currTime = get_time();
00432
00433
00434
00435 if(movingSince) {
00436 long timeDiff = currTime - movingSince;
00437
00438 if(moving) {
00439 ALM::move(dx, dy, da, timeDiff);
00440 #ifdef WANT_GLOBAL_MAP
00441
00442
00443
00444
00445 FastSLAM_update fsu;
00446 fsu.type = FastSLAM_update::MOTION;
00447 fsu.dx = dx;
00448 fsu.dy = dy;
00449 fsu.da = da;
00450 fsu.time = timeDiff;
00451 fs_updates.push_back(fsu);
00452 #endif
00453 }
00454 }
00455
00456
00457 movingSince = currTime;
00458
00459
00460 dx = static_cast<const LocomotionEvent*>(&event)->x;
00461 dy = static_cast<const LocomotionEvent*>(&event)->y;
00462 da = static_cast<const LocomotionEvent*>(&event)->a;
00463
00464
00465
00466 if(movingSince && (dx == 0.0) && (dy == 0.0) && (da == 0.0)) moving = false;
00467 else moving = true;
00468
00469
00470 if(moving) {
00471
00472
00473 if(enabledGPA) erouter->removeTimer(this);
00474 #ifdef WANT_GLOBAL_MAP
00475
00476
00477 if(enabledMarkers) erouter->removeListener(this, EventBase::visionEGID);
00478
00479 #endif
00480
00481 if(enabledIR) erouter->removeListener(this, EventBase::sensorEGID,
00482 SensorSourceID::UpdatedSID);
00483 }
00484
00485 else {
00486
00487 if(enabledGPA) erouter->addTimer(this, 0, GPAdelay, true);
00488 #ifdef WANT_GLOBAL_MAP
00489
00490
00491 if(enabledMarkers) erouter->addListener(this, EventBase::visionEGID);
00492
00493 #endif
00494 if(enabledIR) erouter->addListener(this, EventBase::sensorEGID,
00495 SensorSourceID::UpdatedSID);
00496 }
00497
00498 #ifdef WANT_GLOBAL_MAP
00499
00500
00501
00502 int numMarkersSeen = 0;
00503 for(int i=0; i<AFS_NUM_LANDMARKS; ++i)
00504 if(haveSeenMarker[i]) {
00505 ++numMarkersSeen;
00506 haveSeenMarker[i] = false;
00507 }
00508
00509 if(numMarkersSeen >= minMarkersForFastSLAM) {
00510 FastSLAM_update fsu;
00511 fsu.type = FastSLAM_update::LANDMARK;
00512 fsu.dx = fsu.dy = fsu.da = 0;
00513 fsu.time = 0;
00514 fs_updates.push_back(fsu);
00515 }
00516
00517
00518
00519
00520 if(moving && (kludges & WM2Kludge::LazyFastSLAM)) return;
00521
00522 while(!fs_updates.empty()) {
00523 FastSLAM_update fsu = fs_updates.front();
00524
00525
00526 if(fsu.type == FastSLAM_update::MOTION) {
00527 #ifdef DEBUG_WM2
00528 cout << "MOTION RESAMPLE <" << fsu.dx << ',' << fsu.dy << ',' << fsu.da
00529 << ' ' << fsu.time << ">... " << flush;
00530 #endif
00531 afsMotion(fsu.dx, fsu.dy, fsu.da, fsu.time);
00532 #ifdef DEBUG_WM2
00533 cout << "done." << endl;
00534 afsWhatsUp(NULL);
00535 #endif
00536 }
00537 else if(fsu.type == FastSLAM_update::LANDMARK) {
00538 #ifdef DEBUG_WM2
00539 cout << "LANDMARK RESAMPLE... " << flush;
00540 #endif
00541 afsResample();
00542 #ifdef DEBUG_WM2
00543 cout << "done." << endl;
00544 afsWhatsUp(NULL);
00545 #endif
00546 }
00547
00548
00549 fs_updates.pop_front();
00550 }
00551 #endif
00552 }
00553
00554
00555 void WorldModel2::processGround()
00556 {
00557
00558 UNLESS(enabledGPA) {
00559 cerr << "warning: WorldModel2 doing GPA w/o authorization" << endl;
00560 return;
00561 }
00562
00563 UNLESS(aiboIsErect() && aiboStaresDeadAhead()) return;
00564
00565
00566 erouter->removeTimer(this);
00567
00568
00569 ALM::registerGround();
00570 }
00571
00572 #ifdef WANT_GLOBAL_MAP
00573
00574 void WorldModel2::getFastSLAMMap(afsParticle &p)
00575 {
00576 afsParticle *best = afsWhatsUp(NULL);
00577
00578 p = *best;
00579 }
00580 #endif
00581
00582
00583 void WorldModel2::serialize()
00584 {
00585 char *buf;
00586
00587
00588 buf = (char *)sockDM->getWriteBuffer(DM_CELL_COUNT*sizeof(dm_cell));
00589 if(buf) {
00590 dm_cell *DMp = ALM::getDM();
00591
00592 for(int i=0; i<DM_CELL_COUNT; ++i) {
00593 dm_cell *cel = &DMp[i];
00594 encode(&buf, cel->depth);
00595 encode(&buf, cel->confidence);
00596 encode(&buf, cel->color);
00597 }
00598 sockDM->write(DM_CELL_COUNT*(sizeof(float)*2 + sizeof(colortype)));
00599 }
00600
00601
00602 buf = (char *)sockHM->getWriteBuffer(HM_CELL_COUNT*sizeof(hm_cell));
00603 if(buf) {
00604 hm_cell *HMp = ALM::getHM();
00605
00606 for(int i=0; i<HM_CELL_COUNT; ++i) {
00607 hm_cell *cel = &HMp[i];
00608 encode(&buf, cel->height);
00609 encode(&buf, cel->trav);
00610 encode(&buf, cel->confidence);
00611 encode(&buf, cel->color);
00612 }
00613
00614 sockHM->write(HM_CELL_COUNT*(sizeof(float)*3 + sizeof(colortype)));
00615 }
00616
00617 #ifdef WANT_GLOBAL_MAP
00618
00619 buf = (char *)sockGM->getWriteBuffer(GM_CELL_COUNT*sizeof(hm_cell));
00620 if(buf) {
00621 hm_cell *GMp = AGM::getGM();
00622
00623 for(int i=0; i<GM_CELL_COUNT; ++i) {
00624 hm_cell *cel = &GMp[i];
00625 encode(&buf, cel->height);
00626 encode(&buf, cel->trav);
00627 encode(&buf, cel->confidence);
00628 encode(&buf, cel->color);
00629 }
00630
00631 sockGM->write(GM_CELL_COUNT*(sizeof(float)*3 + sizeof(colortype)));
00632 }
00633
00634
00635 buf = (char *)sockFS->getWriteBuffer(AFS_NUM_PARTICLES*sizeof(afsPose) +
00636 sizeof(afsParticle));
00637 if(buf) {
00638
00639 afsParticle *Particles = afsInvadeFSData();
00640 for(int i=0; i<AFS_NUM_PARTICLES; ++i) {
00641 encode(&buf, (float) Particles[i].pose.x);
00642 encode(&buf, (float) Particles[i].pose.y);
00643 encode(&buf, (float) Particles[i].pose.theta);
00644 }
00645
00646
00647 afsParticle *p = afsWhatsUp(NULL);
00648
00649 encode(&buf, (float) p->pose.x);
00650 encode(&buf, (float) p->pose.y);
00651 encode(&buf, (float) p->pose.theta);
00652 for(int i=0; i<AFS_NUM_LANDMARKS; ++i) {
00653 afsLandmarkLoc *l = &p->landmarks[i];
00654
00655
00656
00657
00658 if(l->state == PRIMING) {
00659 encode(&buf, (float) HUGE_VAL);
00660 encode(&buf, (float) HUGE_VAL);
00661 encode(&buf, (float) HUGE_VAL);
00662 encode(&buf, (float) HUGE_VAL);
00663 encode(&buf, (float) HUGE_VAL);
00664 }
00665 else {
00666 encode(&buf, (float) l->mean.x);
00667 encode(&buf, (float) l->mean.y);
00668 encode(&buf, (float) l->variance.x);
00669 encode(&buf, (float) l->variance.xy);
00670 encode(&buf, (float) l->variance.y);
00671 }
00672 }
00673 sockFS->write(AFS_NUM_PARTICLES*(3*sizeof(float)) +
00674 (3*sizeof(float)) + AFS_NUM_LANDMARKS*(5*sizeof(float)));
00675 }
00676 #endif
00677 }
00678
00679
00680
00681 bool aiboIsErect()
00682 {
00683 double diff;
00684
00685 diff = SP_LFR_JOINT - state->outputs[LFrLegOffset+RotatorOffset];
00686 if(diff*diff > SP_TOLERANCE) return false;
00687 diff = SP_LFR_SHLDR - state->outputs[LFrLegOffset+ElevatorOffset];
00688 if(diff*diff > SP_TOLERANCE) return false;
00689 diff = SP_LFR_KNEE - state->outputs[LFrLegOffset+KneeOffset];
00690 if(diff*diff > SP_TOLERANCE) return false;
00691
00692 diff = SP_RFR_JOINT - state->outputs[RFrLegOffset+RotatorOffset];
00693 if(diff*diff > SP_TOLERANCE) return false;
00694 diff = SP_RFR_SHLDR - state->outputs[RFrLegOffset+ElevatorOffset];
00695 if(diff*diff > SP_TOLERANCE) return false;
00696 diff = SP_RFR_KNEE - state->outputs[RFrLegOffset+KneeOffset];
00697 if(diff*diff > SP_TOLERANCE) return false;
00698
00699 diff = SP_LFR_JOINT - state->outputs[LBkLegOffset+RotatorOffset];
00700 if(diff*diff > SP_TOLERANCE) return false;
00701 diff = SP_LFR_SHLDR - state->outputs[LBkLegOffset+ElevatorOffset];
00702 if(diff*diff > SP_TOLERANCE) return false;
00703 diff = SP_LFR_KNEE - state->outputs[LBkLegOffset+KneeOffset];
00704 if(diff*diff > SP_TOLERANCE) return false;
00705
00706 diff = SP_RFR_JOINT - state->outputs[RBkLegOffset+RotatorOffset];
00707 if(diff*diff > SP_TOLERANCE) return false;
00708 diff = SP_RFR_SHLDR - state->outputs[RBkLegOffset+ElevatorOffset];
00709 if(diff*diff > SP_TOLERANCE) return false;
00710 diff = SP_RFR_KNEE - state->outputs[RBkLegOffset+KneeOffset];
00711 if(diff*diff > SP_TOLERANCE) return false;
00712
00713 return true;
00714 }
00715
00716
00717
00718 bool aiboStaresDeadAhead()
00719 {
00720 double diff;
00721
00722 diff = DA_TILT - state->outputs[HeadOffset+TiltOffset];
00723 if(diff*diff > DA_TOLERANCE) return false;
00724 diff = DA_PAN - state->outputs[HeadOffset+PanOffset];
00725 if(diff*diff > DA_TOLERANCE) return false;
00726 diff = DA_ROLL - state->outputs[HeadOffset+RollOffset];
00727 if(diff*diff > DA_TOLERANCE) return false;
00728
00729 return true;
00730 }
00731
00732
00733
00734 bool aiboIsLevelHeaded()
00735 {
00736 double diff;
00737
00738 diff = DA_TILT - state->outputs[HeadOffset+TiltOffset];
00739 if(diff*diff > DA_TOLERANCE) return false;
00740 diff = DA_ROLL - state->outputs[HeadOffset+RollOffset];
00741 if(diff*diff > DA_TOLERANCE) return false;
00742
00743 return true;
00744 }