SRBA: Sparser Relative Bundle Adjustment
srba/impl/export_opengl_landmark_renderers.h
00001 /* +---------------------------------------------------------------------------+
00002    |                     Mobile Robot Programming Toolkit (MRPT)               |
00003    |                          http://www.mrpt.org/                             |
00004    |                                                                           |
00005    | Copyright (c) 2005-2015, Individual contributors, see AUTHORS file        |
00006    | See: http://www.mrpt.org/Authors - All rights reserved.                   |
00007    | Released under BSD License. See details in http://www.mrpt.org/License    |
00008    +---------------------------------------------------------------------------+ */
00009 
00010 #pragma once
00011 #include <mrpt/opengl/CSetOfObjects.h>
00012 #include <mrpt/opengl/stock_objects.h>
00013 #include <mrpt/opengl/CSetOfLines.h>
00014 #include <mrpt/opengl/CPointCloud.h>
00015 #include <mrpt/opengl/CEllipsoid.h>
00016 #include <mrpt/opengl/CText3D.h>
00017 #include <mrpt/math/lightweight_geom_data.h>
00018 #include <srba/landmark_render_models.h>
00019 
00020 namespace srba {
00021 
00022 // Specializations for rendering each kind of landmark:
00023 template <class landmark_t>
00024 struct LandmarkRendererBase { };
00025 
00027 template <> struct LandmarkRendererBase<landmark_rendering_as_point>
00028 {
00029     template <class RBA>
00030     static void render(
00031         const RBA &rba,
00032         const srba::TKeyFrameID root_keyframe,
00033         const typename RBA::frameid2pose_map_t  &spantree,
00034         const typename RBA::TOpenGLRepresentationOptions &options,
00035         mrpt::opengl::CSetOfObjects& scene)
00036     {
00037         using namespace mrpt::math;
00038         using mrpt::utils::DEG2RAD;
00039         using mrpt::poses::CPose3D;
00040 
00041         // For each fixed known LM, add a point to a point cloud
00042         //  and a text label with the landmark ID:
00043         mrpt::opengl::CPointCloudPtr  gl_lms = mrpt::opengl::CPointCloud::Create();
00044         gl_lms->setPointSize(5);
00045         gl_lms->setColor(0,0,1);
00046 
00047         scene.insert(gl_lms);
00048 
00049         vector<typename RBA::TRelativeLandmarkPosMap::const_iterator> lms_to_draw;
00050         vector<const typename RBA::hessian_traits_t::TSparseBlocksHessian_f::matrix_t *> lms_to_draw_inf_covs;
00051 
00052         for (typename RBA::TRelativeLandmarkPosMap::const_iterator itLM = rba.get_rba_state().known_lms.begin();itLM != rba.get_rba_state().known_lms.end();++itLM)
00053         {
00054             lms_to_draw.push_back(itLM);
00055             lms_to_draw_inf_covs.push_back( NULL );
00056         }
00057 
00058         const size_t nKnown = lms_to_draw.size();
00059 
00060         if (options.draw_unknown_feats)
00061         {
00062             for (typename RBA::TRelativeLandmarkPosMap::const_iterator itLM = rba.get_rba_state().unknown_lms.begin();itLM != rba.get_rba_state().unknown_lms.end();++itLM)
00063             {
00064                 lms_to_draw.push_back(itLM);
00065 
00066                 typename RBA::hessian_traits_t::landmarks2infmatrix_t::const_iterator it_inf = rba.get_rba_state().unknown_lms_inf_matrices.find(itLM->first);
00067 
00068                 if (it_inf != rba.get_rba_state().unknown_lms_inf_matrices.end())
00069                         lms_to_draw_inf_covs.push_back( &it_inf->second );
00070                 else    lms_to_draw_inf_covs.push_back(NULL);
00071             }
00072         }
00073 
00074         const mrpt::utils::TColorf col_known_lms(1.f,1.f,0.f);
00075         const mrpt::utils::TColorf col_unknown_lms(1.f,0.f,0.f);
00076 
00077         for (size_t i=0;i<lms_to_draw.size();i++)
00078         {
00079             const typename RBA::TRelativeLandmarkPosMap::const_iterator &itLM = lms_to_draw[i];
00080             const bool is_known = (i<nKnown);
00081 
00082             // Don't draw those unknown LMs which hasn't been estimated not even once:
00083             //if (!is_known && lms_to_draw_inf_covs[i]==NULL) continue;
00084 
00085             mrpt::poses::CPose3D base_pose;
00086             if (itLM->second.id_frame_base!=root_keyframe)
00087             {
00088                 typename RBA::frameid2pose_map_t::const_iterator itBaseNode = spantree.find(itLM->second.id_frame_base);
00089                 if(itBaseNode==spantree.end())
00090                     continue;
00091                 base_pose = itBaseNode->second.pose; // Inverse!
00092             }
00093             else
00094             {
00095                 // It's the origin.
00096             }
00097 
00098             // If landmark_t defines this kind of renderer, we
00099          mrpt::math::TPoint3D p_wrt_base;
00100             RBA::landmark_t::relativeEuclideanLocation(itLM->second.pos, p_wrt_base);
00101 
00102          mrpt::math::TPoint3D p_global;
00103             base_pose.composePoint(p_wrt_base,p_global);
00104 
00105             gl_lms->insertPoint(p_global.x,p_global.y,p_global.z);
00106 
00107             if( options.show_unknown_feats_ids )
00108             {
00109                 // Add text label:
00110                 mrpt::opengl::CText3DPtr  gl_txt = mrpt::opengl::CText3D::Create(
00111                     mrpt::format("%u",static_cast<unsigned int>( itLM->first)),
00112                     "mono", 0.15,
00113                     mrpt::opengl::NICE );
00114                 gl_txt->setPose(CPose3D(p_global.x,p_global.y,p_global.z,DEG2RAD(-90),DEG2RAD(0),DEG2RAD(90)));
00115                 gl_txt->setColor( is_known ? col_known_lms : col_unknown_lms );
00116 
00117                 scene.insert(gl_txt);
00118             }
00119 
00120             // Uncertainty ellipse?
00121             if (options.draw_unknown_feats_ellipses && lms_to_draw_inf_covs[i] )
00122             {
00123                 double min_inf_diag=std::numeric_limits<double>::max();
00124                 for (size_t k=0;k<RBA::LM_DIMS;k++)
00125                     mrpt::utils::keep_min(min_inf_diag, (*lms_to_draw_inf_covs[i])(k,k));
00126                 if (min_inf_diag<1e-5) continue; // Too large covariance!
00127 
00128                 mrpt::math::CMatrixFixedNumeric<double,RBA::LM_DIMS,RBA::LM_DIMS> cov(mrpt::math::UNINITIALIZED_MATRIX);
00129                 lms_to_draw_inf_covs[i]->inv(cov);
00130 
00131                 mrpt::opengl::CEllipsoidPtr gl_ellip = mrpt::opengl::CEllipsoid::Create();
00132                 gl_ellip->setQuantiles( options.draw_unknown_feats_ellipses_quantiles );
00133                 gl_ellip->enableDrawSolid3D(false);
00134 
00135                 gl_ellip->setCovMatrix(cov);
00136                 CPose3D ellip_pose = base_pose;
00137                 ellip_pose.x(p_global.x);
00138                 ellip_pose.y(p_global.y);
00139                 ellip_pose.z(p_global.z);
00140 
00141                 gl_ellip->setPose(ellip_pose);
00142                 scene.insert(gl_ellip);
00143             }
00144         }
00145     }
00146 };
00147 
00149 template <> struct LandmarkRendererBase<landmark_rendering_as_pose_constraints>
00150 {
00151     template <class RBA>
00152     static void render(
00153         const RBA &rba,
00154         const srba::TKeyFrameID root_keyframe,
00155         const typename RBA::frameid2pose_map_t  &spantree,
00156         const typename RBA::TOpenGLRepresentationOptions &options,
00157         mrpt::opengl::CSetOfObjects& scene)
00158     {
00159         MRPT_UNUSED_PARAM(options);
00160         MRPT_UNUSED_PARAM(root_keyframe);
00161         using namespace mrpt::math;
00162 
00163         mrpt::opengl::CSetOfLinesPtr gl_edges = mrpt::opengl::CSetOfLines::Create();
00164         gl_edges->setLineWidth(1);
00165         gl_edges->setColor(0,0,1);
00166 
00167         scene.insert(gl_edges);
00168 
00169         // For each KF: check all its "observations"
00170         for (typename RBA::frameid2pose_map_t::const_iterator it=spantree.begin();it!=spantree.end();++it)
00171         {
00172             const TKeyFrameID kf_id = it->first;
00173             const typename RBA::pose_flag_t & pf = it->second;
00174 
00175             const typename RBA::keyframe_info &kfi = rba.get_rba_state().keyframes[kf_id];
00176 
00177             for (size_t i=0;i<kfi.adjacent_k2f_edges.size();i++)
00178             {
00179                 const typename RBA::k2f_edge_t * k2f = kfi.adjacent_k2f_edges[i];
00180                 const TKeyFrameID other_kf_id = k2f->feat_rel_pos->id_frame_base;
00181                 if (kf_id==other_kf_id)
00182                     continue; // It's not an constraint with ANOTHER keyframe
00183 
00184                 // Is the other KF in the spanning tree?
00185                 typename RBA::frameid2pose_map_t::const_iterator other_it=spantree.find(other_kf_id);
00186                 if (other_it==spantree.end()) continue;
00187 
00188                 const typename RBA::pose_flag_t & other_pf = other_it->second;
00189 
00190                 // Add edge between the two KFs to represent the pose constraint:
00191                 mrpt::poses::CPose3D p1 = mrpt::poses::CPose3D(pf.pose);  // Convert to 3D
00192                 mrpt::poses::CPose3D p2 = mrpt::poses::CPose3D(other_pf.pose);
00193 
00194                 gl_edges->appendLine( p1.x(),p1.y(),p1.z()+0.10, p2.x(),p2.y(),p2.z()+0.10 );
00195             }
00196 
00197         } // end for each KF
00198     }
00199 };
00200 
00202 template <> struct LandmarkRendererBase<landmark_rendering_none>
00203 {
00204     template <class RBA>
00205     static void render(
00206         const RBA &rba,
00207         const srba::TKeyFrameID root_keyframe,
00208         const typename RBA::frameid2pose_map_t  &spantree,
00209         const typename RBA::TOpenGLRepresentationOptions &options,
00210         mrpt::opengl::CSetOfObjects& scene)
00211     {
00212         MRPT_UNUSED_PARAM(rba);
00213         MRPT_UNUSED_PARAM(root_keyframe);
00214         MRPT_UNUSED_PARAM(spantree);
00215         MRPT_UNUSED_PARAM(options);
00216         MRPT_UNUSED_PARAM(scene);
00217         // Nothing to render
00218     }
00219 };
00220 
00221 } // End of namespaces
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends