00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "slam2d_viewer.h"
00020
00021 #include "draw_helpers.h"
00022 #include "g2o/types/slam2d/vertex_se2.h"
00023 #include "g2o/types/slam2d/vertex_point_xy.h"
00024 #include "g2o/core/graph_optimizer_sparse.h"
00025
00026 #include <Eigen/Core>
00027 #include <iostream>
00028 using namespace std;
00029
00030 namespace g2o {
00031
00032 namespace {
00033
00037 class StandardCamera : public qglviewer::Camera
00038 {
00039 public:
00040 StandardCamera() : _standard(true) {};
00041
00042 float zNear() const {
00043 if (_standard)
00044 return 0.001;
00045 else
00046 return Camera::zNear();
00047 }
00048
00049 float zFar() const
00050 {
00051 if (_standard)
00052 return 1000.0;
00053 else
00054 return Camera::zFar();
00055 }
00056
00057 const bool& standard() const {return _standard;}
00058 bool& standard() {return _standard;}
00059
00060 private:
00061 bool _standard;
00062 };
00063
00064 void drawSE2(const VertexSE2* v)
00065 {
00066 static const double len = 0.2;
00067 static Eigen::Vector2d p1( 0.75 * len, 0.);
00068 static Eigen::Vector2d p2(-0.25 * len, 0.5 * len);
00069 static Eigen::Vector2d p3(-0.25 * len, -0.5 * len);
00070
00071 const SE2& pose = v->estimate();
00072
00073 Eigen::Vector2d aux = pose * p1;
00074 glVertex3f(aux[0], aux[1], 0.f);
00075 aux = pose * p2;
00076 glVertex3f(aux[0], aux[1], 0.f);
00077 aux = pose * p3;
00078 glVertex3f(aux[0], aux[1], 0.f);
00079 }
00080
00081 template <typename Derived>
00082 void drawCov(const Eigen::Vector2d& p, const Eigen::MatrixBase<Derived>& cov)
00083 {
00084 const double scalingFactor = 1.;
00085
00086 glPushMatrix();
00087 glTranslatef(p.x(), p.y(), 0.f);
00088
00089 const typename Derived::Scalar& a = cov(0, 0);
00090 const typename Derived::Scalar& b = cov(0, 1);
00091 const typename Derived::Scalar& d = cov(1, 1);
00092
00093
00094 double D = a*d - b*b;
00095 double T = a+d;
00096 double h = sqrt(0.25*(T*T) - D);
00097 double lambda1 = 0.5*T + h;
00098 double lambda2 = 0.5*T - h;
00099
00100 double theta = 0.5 * atan2(2.0 * b, a - d);
00101 double majorAxis = 3.0 * sqrt(lambda1);
00102 double minorAxis = 3.0 * sqrt(lambda2);
00103
00104
00105 glRotatef(RAD2DEG(theta), 0.f, 0.f, 1.f);
00106 glScalef(majorAxis * scalingFactor, minorAxis * scalingFactor, 1.f);
00107 glColor4f(1.0f, 1.f, 0.f, 0.4f);
00108 drawDisk(1.f);
00109 glColor4f(0.f, 0.f, 0.f, 1.0f);
00110 drawCircle(1.f);
00111 glPopMatrix();
00112 }
00113
00114 }
00115
00116 Slam2DViewer::Slam2DViewer(QWidget* parent, const QGLWidget* shareWidget, Qt::WFlags flags) :
00117 QGLViewer(parent, shareWidget, flags),
00118 graph(0), drawCovariance(false)
00119 {
00120 }
00121
00122 Slam2DViewer::~Slam2DViewer()
00123 {
00124 }
00125
00126 void Slam2DViewer::draw()
00127 {
00128 if (! graph)
00129 return;
00130
00131
00132 glColor4f(0.00f, 0.67f, 1.00f, 1.f);
00133 glBegin(GL_TRIANGLES);
00134 for (SparseOptimizer::VertexIDMap::iterator it = graph->vertices().begin(); it != graph->vertices().end(); ++it) {
00135 VertexSE2* v = dynamic_cast<VertexSE2*>(it->second);
00136 if (v) {
00137 drawSE2(v);
00138 }
00139 }
00140 glEnd();
00141
00142 glColor4f(1.00f, 0.67f, 0.00f, 1.f);
00143 glPointSize(2.f);
00144 glBegin(GL_POINTS);
00145 for (SparseOptimizer::VertexIDMap::iterator it = graph->vertices().begin(); it != graph->vertices().end(); ++it) {
00146 VertexPointXY* v = dynamic_cast<VertexPointXY*>(it->second);
00147 if (v) {
00148 glVertex3f(v->estimate()(0), v->estimate()(1), 0.f);
00149 }
00150 }
00151 glEnd();
00152 glPointSize(1.f);
00153
00154 if (drawCovariance) {
00155 for (SparseOptimizer::VertexIDMap::iterator it = graph->vertices().begin(); it != graph->vertices().end(); ++it) {
00156 VertexSE2* v = dynamic_cast<VertexSE2*>(it->second);
00157 if (v) {
00158 drawCov(v->estimate().translation(), v->uncertainty());
00159 }
00160 }
00161 }
00162 }
00163
00164 void Slam2DViewer::init()
00165 {
00166 QGLViewer::init();
00167
00168
00169 glEnable(GL_LINE_SMOOTH);
00170 glEnable(GL_BLEND);
00171 glEnable(GL_DEPTH_TEST);
00172 glShadeModel(GL_SMOOTH);
00173 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00174
00175 setAxisIsDrawn();
00176
00177
00178 setStateFileName(QString::null);
00179
00180
00181 setMouseBinding(Qt::RightButton, CAMERA, ZOOM);
00182 setMouseBinding(Qt::MidButton, CAMERA, TRANSLATE);
00183
00184
00185 setShortcut(CAMERA_MODE, 0);
00186 setShortcut(EXIT_VIEWER, 0);
00187
00188
00189
00190 qglviewer::Camera* oldcam = camera();
00191 qglviewer::Camera* cam = new StandardCamera();
00192 setCamera(cam);
00193 cam->setPosition(qglviewer::Vec(0., 0., 75.));
00194 cam->setUpVector(qglviewer::Vec(0., 1., 0.));
00195 cam->lookAt(qglviewer::Vec(0., 0., 0.));
00196 delete oldcam;
00197 }
00198
00199 }