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