00001
00022 #include "MapView.h"
00023 #include "../HelperFunctions.h"
00024 #include <cvd/gl_helpers.h>
00025 #include <gvars3/GStringUtil.h>
00026 #include "Predictor.h"
00027 #include <gvars3/instances.h>
00028 #include "DroneKalmanFilter.h"
00029 #include "PTAMWrapper.h"
00030 #include "EstimationNode.h"
00031
00032 pthread_mutex_t MapView::trailPointsVec_CS = PTHREAD_MUTEX_INITIALIZER;
00033
00034 MapView::MapView(DroneKalmanFilter* f, PTAMWrapper* p, EstimationNode* nde)
00035 {
00036 filter = f;
00037 ptamWrapper = p;
00038 node = nde;
00039 drawUI = UI_PRES;
00040 resetRequested = false;
00041 trailPoints = std::vector<TrailPoint>();
00042 predConvert = new Predictor();
00043 clearTrail = false;
00044 resetMapViewFlag = true;
00045
00046 }
00047
00048 void MapView::ResetInternal()
00049 {
00050 trailPoints.clear();
00051 }
00052
00053
00054 MapView::~MapView(void)
00055 {
00056 delete predConvert;
00057
00058 }
00059
00060 void MapView::startSystem()
00061 {
00062 keepRunning = true;
00063 changeSizeNextRender = false;
00064
00065 start();
00066 }
00067
00068 void MapView::stopSystem()
00069 {
00070 keepRunning = false;
00071 join();
00072 }
00073
00074
00075 void MapView::run()
00076 {
00077 sleep(1000);
00078 myGLWindow = new GLWindow2(CVD::ImageRef(640,480), "PTAM Drone Map View",this);
00079 myGLWindow->set_title("PTAM Drone Map View");
00080
00081 while(keepRunning)
00082 {
00083 Render();
00084 usleep(30000);
00085 }
00086
00087 delete myGLWindow;
00088 }
00089
00090
00091 void MapView::Render()
00092 {
00093
00094
00095 pthread_mutex_lock(&filter->filter_CS);
00096 lastFramePoseSpeed = filter->getCurrentPoseSpeedAsVec();
00097 pthread_mutex_unlock(&filter->filter_CS);
00098
00099
00100
00101
00102 if(clearTrail)
00103 {
00104 trailPoints.clear();
00105 clearTrail = false;
00106 }
00107
00108
00109 bool addTrail;
00110 if(trailPoints.size() == 0)
00111 addTrail = true;
00112 else
00113 {
00114 TooN::Vector<3> distToLast = lastFramePoseSpeed.slice<0,3>() - trailPoints[trailPoints.size()-1].pointFilter;
00115 double d = distToLast[0]*distToLast[0] + distToLast[1]*distToLast[1]+distToLast[2]*distToLast[2];
00116 addTrail = d > 0.1*0.1;
00117 }
00118
00119
00120
00121
00122
00123
00124 if(addTrail)
00125 {
00126 if(ptamWrapper->PTAMStatus == ptamWrapper->PTAM_BEST ||
00127 ptamWrapper->PTAMStatus == ptamWrapper->PTAM_TOOKKF ||
00128 ptamWrapper->PTAMStatus == ptamWrapper->PTAM_GOOD)
00129 {
00130 if(ptamWrapper->PTAMInitializedClock != 0 && getMS() - ptamWrapper->PTAMInitializedClock > 200)
00131 {
00132 TooN::Vector<3> PTAMScales = filter->getCurrentScales();
00133 TooN::Vector<3> PTAMOffsets = filter->getCurrentOffsets().slice<0,3>();
00134
00135 TooN::Vector<3> ptamPointPos = lastFramePoseSpeed.slice<0,3>();
00136 ptamPointPos -= PTAMOffsets;
00137 ptamPointPos /= PTAMScales[0];
00138
00139 trailPoints.push_back(TrailPoint(
00140 lastFramePoseSpeed.slice<0,3>(),
00141 ptamPointPos
00142 ));
00143 }
00144 }
00145 else if(ptamWrapper->PTAMStatus == ptamWrapper->PTAM_LOST ||
00146 ptamWrapper->PTAMStatus == ptamWrapper->PTAM_FALSEPOSITIVE)
00147 {
00148 if(ptamWrapper->PTAMInitializedClock != 0 && getMS() - ptamWrapper->PTAMInitializedClock > 200)
00149 {
00150 TooN::Vector<3> PTAMScales = filter->getCurrentScales();
00151 TooN::Vector<3> PTAMOffsets = filter->getCurrentOffsets().slice<0,3>();
00152
00153 TooN::Vector<3> ptamPointPos = lastFramePoseSpeed.slice<0,3>();
00154 ptamPointPos -= PTAMOffsets;
00155 ptamPointPos /= PTAMScales[0];
00156
00157 trailPoints.push_back(TrailPoint(
00158 lastFramePoseSpeed.slice<0,3>(),
00159 ptamPointPos
00160 ));
00161 }
00162 }
00163 else
00164 {
00165 trailPoints.push_back(TrailPoint(
00166 lastFramePoseSpeed.slice<0,3>()
00167 ));
00168 }
00169 }
00170
00171
00172
00173
00174
00175 if(resetMapViewFlag)
00176 {
00177 resetMapView();
00178 resetMapViewFlag = false;
00179 }
00180
00181
00182 lineWidthFactor = sqrt((float)(myGLWindow->size()[0] * myGLWindow->size()[1] / (640*480)));
00183
00184
00185
00186 plotGrid();
00187
00188 pthread_mutex_lock(&ptamWrapper->shallowMapCS);
00189 std::vector<tse3>* kfl = &(ptamWrapper->keyFramesTransformed);
00190
00191
00192 for(unsigned int i=0;i<kfl->size();i++)
00193 {
00194 plotCam((*kfl)[i],false,2,0.04f,1);
00195 }
00196
00197
00198 drawTrail();
00199
00200
00201 plotMapPoints();
00202 pthread_mutex_unlock(&ptamWrapper->shallowMapCS);
00203
00204
00205
00206
00207
00208 predConvert->setPosRPY(lastFramePoseSpeed[0], lastFramePoseSpeed[1], lastFramePoseSpeed[2], lastFramePoseSpeed[3], lastFramePoseSpeed[4], lastFramePoseSpeed[5]);
00209 plotCam(predConvert->droneToGlobal,true,5.0f,0.2f,1);
00210
00211
00212
00213 msg = "";
00214 TooN::Vector<6> of = filter->getCurrentOffsets();
00215 TooN::Vector<3> sc = filter->getCurrentScales();
00216
00217
00218 if(drawUI == UI_DEBUG)
00219 {
00220 snprintf(charBuf,1000,"Pose: ");
00221 snprintf(charBuf+10,800, "x: %.2f ",lastFramePoseSpeed[0]);
00222 snprintf(charBuf+20,800, "y: %.2f ",lastFramePoseSpeed[1]);
00223 snprintf(charBuf+30,800, "z: %.2f ",lastFramePoseSpeed[2]);
00224 snprintf(charBuf+40,800, "r: %.2f ",lastFramePoseSpeed[3]);
00225 snprintf(charBuf+50,800, "p: %.2f ",lastFramePoseSpeed[4]);
00226 snprintf(charBuf+60,800, "y: %.2f ",lastFramePoseSpeed[5]);
00227 snprintf(charBuf+70,800, "vx: %.2f ",lastFramePoseSpeed[6]);
00228 snprintf(charBuf+80,800, "vy: %.2f ",lastFramePoseSpeed[7]);
00229 snprintf(charBuf+90,800, "vz: %.2f ",lastFramePoseSpeed[8]);
00230 snprintf(charBuf+100,800, "vy: %.2f",lastFramePoseSpeed[9]);
00231 msg += charBuf;
00232
00233
00234 snprintf(charBuf,1000,"\nSync: ");
00235 snprintf(charBuf+10,800, "ox: %.2f ",of[0]);
00236 snprintf(charBuf+20,800, "oy: %.2f ",of[1]);
00237 snprintf(charBuf+30,800, "oz: %.2f ",of[2]);
00238 snprintf(charBuf+40,800, "or: %.2f ",of[3]);
00239 snprintf(charBuf+50,800, "op: %.2f ",of[4]);
00240 snprintf(charBuf+60,800, "oy: %.2f ",of[5]);
00241 snprintf(charBuf+70,800, "Sx: %.2f ",sc[0]);
00242 snprintf(charBuf+80,800, "Sy: %.2f ",sc[1]);
00243 snprintf(charBuf+90,800, "Sz: %.2f",sc[2]);
00244 msg += charBuf;
00245
00246
00247 snprintf(charBuf,1000,"\nStDvs: ");
00248 snprintf(charBuf+10,800, "x: %.2f ",std::sqrt((double)lastFramePoseSpeed[0]));
00249 snprintf(charBuf+20,800, "y: %.2f ",std::sqrt((double)lastFramePoseSpeed[1]));
00250 snprintf(charBuf+30,800, "z: %.2f ",std::sqrt((double)lastFramePoseSpeed[2]));
00251 snprintf(charBuf+40,800, "r: %.2f ",std::sqrt((double)lastFramePoseSpeed[3]));
00252 snprintf(charBuf+50,800, "p: %.2f ",std::sqrt((double)lastFramePoseSpeed[4]));
00253 snprintf(charBuf+60,800, "y: %.2f ",std::sqrt((double)lastFramePoseSpeed[5]));
00254 snprintf(charBuf+70,800, "vx: %.2f ",std::sqrt((double)lastFramePoseSpeed[6]));
00255 snprintf(charBuf+80,800, "vy: %.2f ",std::sqrt((double)lastFramePoseSpeed[7]));
00256 snprintf(charBuf+90,800, "vz: %.2f ",std::sqrt((double)lastFramePoseSpeed[8]));
00257 snprintf(charBuf+100,800, "vy: %.2f",std::sqrt((double)lastFramePoseSpeed[9]));
00258 msg += charBuf;
00259 }
00260 else
00261 {
00262 snprintf(charBuf,1000,"Drone Pose: ");
00263 snprintf(charBuf+13,800, "xyz=(%.2f, ",lastFramePoseSpeed[0]);
00264 snprintf(charBuf+25,800, "%.2f, ",lastFramePoseSpeed[1]);
00265 snprintf(charBuf+32,800, "%.2f), ",lastFramePoseSpeed[2]);
00266 snprintf(charBuf+42,800, "rpy=(%.2f, ",lastFramePoseSpeed[3]);
00267 snprintf(charBuf+54,800, "%.2f, ",lastFramePoseSpeed[4]);
00268 snprintf(charBuf+61,800, "%.2f) ",lastFramePoseSpeed[5]);
00269 msg += charBuf;
00270 }
00271
00272
00273 myGLWindow->GetMousePoseUpdate();
00274
00275
00276
00277 CVD::glSetFont("sans");
00278 if(drawUI != UI_NONE)
00279 myGLWindow->DrawCaption(msg);
00280
00281 if(drawUI == UI_DEBUG)
00282 {
00283 glMatrixMode(GL_PROJECTION);
00284 glPushMatrix();
00285 glTranslatef((float)0, (float)100, 0.0);
00286 glScalef(45,-45,1);
00287 snprintf(charBuf,1000,"xyz: %.2f %.2f %.2f",lastFramePoseSpeed[0],lastFramePoseSpeed[1],lastFramePoseSpeed[2]);
00288 CVD::glDrawText(charBuf, CVD::NICE, 1.6, 0.1);
00289 glPopMatrix();
00290 }
00291 myGLWindow->swap_buffers();
00292 myGLWindow->HandlePendingEvents();
00293
00294 }
00295
00296
00297 void MapView::drawTrail()
00298 {
00299 glEnable(GL_DEPTH_TEST);
00300
00301
00302 glMatrixMode(GL_MODELVIEW);
00303 glLoadIdentity();
00304 glScaled(0.1,0.1,0.1);
00305 CVD::glMultMatrix(mse3ViewerFromWorld);
00306 SetupFrustum();
00307 glEnable(GL_BLEND);
00308 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00309 glLineWidth(3*lineWidthFactor);
00310 glBegin(GL_LINES);
00311 glColor4f(0,1,0,0.6);
00312
00313 TooN::Vector<3> PTAMScales = filter->getCurrentScales();
00314 TooN::Vector<3> PTAMOffsets = filter->getCurrentOffsets().slice<0,3>();
00315
00316 for(unsigned int i=1;i<trailPoints.size();i++)
00317 {
00318 if(trailPoints[i].PTAMValid)
00319 {
00320 trailPoints[i].pointFilter = trailPoints[i].pointPTAM;
00321 trailPoints[i].pointFilter[0] *= PTAMScales[0];
00322 trailPoints[i].pointFilter[1] *= PTAMScales[1];
00323 trailPoints[i].pointFilter[2] *= PTAMScales[2];
00324 trailPoints[i].pointFilter += PTAMOffsets;
00325 }
00326 if(i > 1 && i < trailPoints.size()-1)
00327 glVertex3f((float)trailPoints[i].pointFilter[0], (float)trailPoints[i].pointFilter[1], (float)trailPoints[i].pointFilter[2]);
00328 glVertex3f((float)trailPoints[i].pointFilter[0], (float)trailPoints[i].pointFilter[1], (float)trailPoints[i].pointFilter[2]);
00329 }
00330
00331 glEnd();
00332
00333
00334 glDisable(GL_DEPTH_TEST);
00335 glMatrixMode(GL_MODELVIEW);
00336 glLoadIdentity();
00337 }
00338
00339
00340 void MapView::plotMapPoints()
00341 {
00342
00343 glEnable(GL_DEPTH_TEST);
00344
00345
00346 glMatrixMode(GL_MODELVIEW);
00347 glLoadIdentity();
00348 glScaled(0.1,0.1,0.1);
00349 CVD::glMultMatrix(mse3ViewerFromWorld);
00350 SetupFrustum();
00351 float width = 1.0f;
00352 float len = 0.02f;
00353
00354 glLineWidth(width*lineWidthFactor);
00355 glBegin(GL_LINES);
00356 glColor3f(1,0,0);
00357
00358 std::vector<tvec3>* mpl = &(ptamWrapper->mapPointsTransformed);
00359
00360 for(unsigned int i=0;i<mpl->size();i++)
00361 {
00362 TooN::Vector<3> pos = (*mpl)[i];
00363
00364 glVertex3f((float)pos[0]-len, (float)pos[1], (float)pos[2]);
00365 glVertex3f((float)pos[0]+len, (float)pos[1], (float)pos[2]);
00366 glVertex3f((float)pos[0], (float)pos[1]-len, (float)pos[2]);
00367 glVertex3f((float)pos[0], (float)pos[1]+len, (float)pos[2]);
00368 glVertex3f((float)pos[0], (float)pos[1], (float)pos[2]-len);
00369 glVertex3f((float)pos[0], (float)pos[1], (float)pos[2]+len);
00370 }
00371
00372 glEnd();
00373
00374
00375 glDisable(GL_DEPTH_TEST);
00376 glMatrixMode(GL_MODELVIEW);
00377 glLoadIdentity();
00378
00379 }
00380
00381 void MapView::plotCam(TooN::SE3<> droneToGlobal, bool xyCross, float thick, float len, float alpha)
00382 {
00383 glEnable(GL_DEPTH_TEST);
00384
00385
00386 glMatrixMode(GL_MODELVIEW);
00387 glLoadIdentity();
00388 glScaled(0.1,0.1,0.1);
00389 CVD::glMultMatrix(mse3ViewerFromWorld * droneToGlobal);
00390 SetupFrustum();
00391
00392
00393 glLineWidth(thick*lineWidthFactor);
00394
00395 if(alpha < 1)
00396 {
00397 glEnable(GL_BLEND);
00398 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00399 }
00400 else
00401 glDisable(GL_BLEND);
00402
00403
00404 glBegin(GL_LINES);
00405 glColor4f(1,0,0,alpha);
00406 glVertex3f(-len, 0.0f, 0.0f);
00407 glVertex3f(len, 0.0f, 0.0f);
00408 glVertex3f(0.0f, 0.0f, 0.0f);
00409 glVertex3f(0.0f, -len, 0.0f);
00410
00411 glColor4f(0,1,0,alpha);
00412 glVertex3f(0.0f, 0.0f, 0.0f);
00413 glVertex3f(0.0f, len, 0.0f);
00414
00415 glColor4f(1,1,1,alpha);
00416 glVertex3f(0.0f, 0.0f, 0.0f);
00417 glVertex3f(0.0f, 0.0f, len);
00418 glEnd();
00419
00420
00421 if(xyCross)
00422 {
00423 glLineWidth(1*lineWidthFactor);
00424 glColor4f(1,1,1, alpha);
00425 SetupModelView();
00426 TooN::Vector<2> v2CamPosXY = droneToGlobal.get_translation().slice<0,2>();
00427 glBegin(GL_LINES);
00428 glColor4f(1,1,1, alpha);
00429 glVertex2d(v2CamPosXY[0] - 0.04, v2CamPosXY[1] + 0.04);
00430 glVertex2d(v2CamPosXY[0] + 0.04, v2CamPosXY[1] - 0.04);
00431 glVertex2d(v2CamPosXY[0] - 0.04, v2CamPosXY[1] - 0.04);
00432 glVertex2d(v2CamPosXY[0] + 0.04, v2CamPosXY[1] + 0.04);
00433 glEnd();
00434 }
00435 glDisable(GL_BLEND);
00436 glDisable(GL_DEPTH_TEST);
00437 glMatrixMode(GL_MODELVIEW);
00438 glLoadIdentity();
00439 }
00440
00441 void MapView::resetMapView()
00442 {
00443 mse3ViewerFromWorld = TooN::SE3<>::exp(TooN::makeVector(0,0,4,0,0,0)) * TooN::SE3<>::exp(TooN::makeVector(0,0,0,0.8 * M_PI,0,0));
00444 }
00445
00446 void MapView::plotGrid()
00447 {
00448
00449
00450 std::pair<TooN::Vector<6>, TooN::Vector<6> > pv6 = myGLWindow->GetMousePoseUpdate();
00451 TooN::SE3<> se3CamFromMC;
00452 se3CamFromMC.get_translation() = mse3ViewerFromWorld * TooN::makeVector(0,0,0);
00453 mse3ViewerFromWorld = TooN::SE3<>::exp(pv6.first) *
00454 se3CamFromMC * TooN::SE3<>::exp(pv6.second).inverse() * se3CamFromMC.inverse() * mse3ViewerFromWorld;
00455
00456 myGLWindow->SetupViewport();
00457 glClearColor(0,0,0,0);
00458 glClearDepth(1);
00459 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00460 glMatrixMode(GL_PROJECTION);
00461 glLoadIdentity();
00462 glEnable(GL_POINT_SMOOTH);
00463
00464 glEnable(GL_BLEND);
00465 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00466 glColorMask(1,1,1,1);
00467 glDisable(GL_DEPTH_TEST);
00468
00469
00470 SetupFrustum();
00471 SetupModelView();
00472 glLineWidth(1*lineWidthFactor);
00473
00474 double gridBigSpacing = 1;
00475 double gridSmallSpacing = 0.2;
00476 double gridBigMax = 30;
00477 double gridSmallMax = 5;
00478
00479
00480 glBegin(GL_LINES);
00481 for(double x=-gridSmallMax; x<=gridSmallMax;x+=gridSmallSpacing)
00482 {
00483 if(x != 0 && (x-floor(x)) > 0.1)
00484 {
00485 glColor3f(0.2f,0.2f,0.2f);
00486 glVertex3d(x, -gridSmallMax, 0.0);
00487 glVertex3d(x, gridSmallMax, 0.0);
00488 }
00489 }
00490 for(double y=-gridSmallMax; y<=gridSmallMax;y+=gridSmallSpacing)
00491 {
00492 if(y != 0 && (y-floor(y)) > 0.1)
00493 {
00494 glColor3f(0.25f,0.25f,0.25f);
00495 glVertex3d(-gridSmallMax,y, 0.0);
00496 glVertex3d(gridSmallMax,y, 0.0);
00497 }
00498 }
00499 glEnd();
00500
00501
00502
00503 glLineWidth(2*lineWidthFactor);
00504 glBegin(GL_LINES);
00505 for(double x=-gridBigMax; x<=gridBigMax;x+=gridBigSpacing)
00506 {
00507 if(x != 0)
00508 {
00509 glColor3f(0.6f,0.6f,0.6f);
00510 glVertex3d(x, -gridBigMax, 0.0);
00511 glVertex3d(x, gridBigMax, 0.0);
00512 }
00513 }
00514 for(double y=-gridBigMax; y<=gridBigMax;y+=gridBigSpacing)
00515 {
00516 if(y != 0)
00517 {
00518 glColor3f(0.6f,0.6f,0.6f);
00519 glVertex3d(-gridBigMax,y, 0.0);
00520 glVertex3d(gridBigMax,y, 0.0);
00521 }
00522 }
00523 glEnd();
00524
00525
00526
00527 glLineWidth(2.5*lineWidthFactor);
00528 glBegin(GL_LINES);
00529
00530 glColor3f(1,1,1);
00531 glVertex3d(-gridBigMax,0, 0.0);
00532 glVertex3d(gridBigMax,0, 0.0);
00533 glVertex3d(0,-gridBigMax, 0.0);
00534 glVertex3d(0,gridBigMax, 0.0);
00535
00536
00537 glColor3f(1,0,0);
00538 glVertex3d(0,0,0);
00539 glVertex3d(1,0,0);
00540 glColor3f(0,1,0);
00541 glVertex3d(0,0,0);
00542 glVertex3d(0,1,0);
00543 glColor3f(1,1,1);
00544 glVertex3d(0,0,0);
00545 glVertex3d(0,0,1);
00546 glEnd();
00547
00548
00549
00550 }
00551
00552 void MapView::SetupFrustum()
00553 {
00554 glMatrixMode(GL_PROJECTION);
00555 glLoadIdentity();
00556 double zNear = 0.03;
00557 glFrustum(-zNear, zNear, 0.75*zNear,-0.75*zNear,zNear,50);
00558 glScalef(1,1,-1);
00559 return;
00560 };
00561
00562 void MapView::SetupModelView(TooN::SE3<> se3WorldFromCurrent)
00563 {
00564 glMatrixMode(GL_MODELVIEW);
00565 glLoadIdentity();
00566 CVD::glMultMatrix(mse3ViewerFromWorld * se3WorldFromCurrent);
00567 return;
00568 };
00569
00570 void MapView::on_key_down(int key)
00571 {
00572 if(key == 114)
00573 {
00574 node->publishCommand("f reset");
00575 }
00576 if(key == 117)
00577 {
00578 node->publishCommand("m toggleUI");
00579 }
00580 if(key == 118)
00581 {
00582 node->publishCommand("m resetView");
00583 }
00584 if(key == 108)
00585 {
00586 node->publishCommand("toggleLog");
00587 }
00588 if(key == 116)
00589 {
00590 node->publishCommand("m clearTrail");
00591 }
00592 }
00593
00594
00595
00596
00597 bool MapView::handleCommand(std::string s)
00598 {
00599 if(s.length() == 8 && s.substr(0,8) == "toggleUI")
00600 {
00601 if(drawUI == UI_NONE) drawUI = UI_DEBUG;
00602 else if(drawUI == UI_DEBUG) drawUI = UI_PRES;
00603 else if(drawUI == UI_PRES) drawUI = UI_NONE;
00604 }
00605 if(s.length() == 9 && s.substr(0,9) == "resetView")
00606 {
00607 resetMapViewFlag = true;
00608 }
00609 if(s.length() == 10 && s.substr(0,10) == "clearTrail")
00610 {
00611 clearTrail = true;
00612 }
00613
00614
00615 if(s.length() == 5 && s.substr(0,5) == "reset")
00616 {
00617 filter->reset();
00618 ptamWrapper->Reset();
00619 clearTrail = true;
00620 }
00621 return true;
00622 }