Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include "mrpt_ekf_slam_3d/mrpt_ekf_slam_3d.h"
00008 #include <ros/console.h>
00009 #if MRPT_VERSION >= 0x150
00010 #include <mrpt_bridge/utils.h>
00011 #endif
00012
00013 EKFslam::EKFslam()
00014 {
00015 #if MRPT_VERSION >= 0x150
00016 motion_model_options_.modelSelection = CActionRobotMovement3D::mm6DOF;
00017
00018 motion_model_options_.mm6DOFModel.nParticlesCount = 100;
00019 motion_model_options_.mm6DOFModel.a1 = 0.114;
00020 motion_model_options_.mm6DOFModel.a2 = 0.1114;
00021 motion_model_options_.mm6DOFModel.a3 = 0.114;
00022 motion_model_options_.mm6DOFModel.a4 = 0.114;
00023 motion_model_options_.mm6DOFModel.a5 = 0.13;
00024 motion_model_options_.mm6DOFModel.a6 = 0.13;
00025 motion_model_options_.mm6DOFModel.a7 = 0.03;
00026 motion_model_options_.mm6DOFModel.a8 = 0.03;
00027 motion_model_options_.mm6DOFModel.a9 = 0.03;
00028 motion_model_options_.mm6DOFModel.a10 = 0.03;
00029 motion_model_options_.mm6DOFModel.additional_std_XYZ = 0.005;
00030 motion_model_options_.mm6DOFModel.additional_std_angle = 0.0005;
00031 #endif
00032
00033
00034 SHOW_3D_LIVE = false;
00035 CAMERA_3DSCENE_FOLLOWS_ROBOT = false;
00036 }
00037
00038 EKFslam::~EKFslam()
00039 {
00040 }
00041
00042 void EKFslam::read_iniFile(std::string ini_filename)
00043 {
00044 CConfigFile iniFile(ini_filename);
00045
00046
00047
00048 mapping.loadOptions(iniFile);
00049 mapping.KF_options.dumpToConsole();
00050 mapping.options.dumpToConsole();
00051
00052 #if MRPT_VERSION >= 0x150
00053 log4cxx::LoggerPtr ros_logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME);
00054 mapping.setVerbosityLevel(mrpt_bridge::rosLoggerLvlToMRPTLoggerLvl(ros_logger->getLevel()));
00055 mapping.logging_enable_console_output = false;
00056 mapping.logRegisterCallback(static_cast<output_logger_callback_t>(&mrpt_bridge::mrptToROSLoggerCallback));
00057 #endif
00058
00059
00060 SHOW_3D_LIVE = iniFile.read_bool("MappingApplication", "SHOW_3D_LIVE", false);
00061 CAMERA_3DSCENE_FOLLOWS_ROBOT = iniFile.read_bool("MappingApplication", "CAMERA_3DSCENE_FOLLOWS_ROBOT", false);
00062 }
00063
00064 void EKFslam::observation(CSensoryFramePtr _sf, CObservationOdometryPtr _odometry)
00065 {
00066 action = CActionCollection::Create();
00067
00068 CActionRobotMovement3D odom_move;
00069
00070 odom_move.timestamp = _sf->getObservationByIndex(0)->timestamp;
00071 if (_odometry)
00072 {
00073 if (odomLastObservation_.empty())
00074 {
00075 odomLastObservation_ = mrpt::poses::CPose3D(_odometry->odometry);
00076 }
00077
00078 mrpt::poses::CPose3D incOdoPose;
00079 incOdoPose.inverseComposeFrom(mrpt::poses::CPose3D(_odometry->odometry), odomLastObservation_);
00080 odomLastObservation_ = mrpt::poses::CPose3D(_odometry->odometry);
00081 #if MRPT_VERSION >= 0x150
00082 odom_move.computeFromOdometry(incOdoPose, motion_model_options_);
00083 #else
00084 ROS_WARN("Ignoring odometry. This feature requires MRPT>=1.5.0.");
00085 #endif
00086 action->insert(odom_move);
00087 }
00088 }
00089
00090 void EKFslam::init3Dwindow()
00091 {
00092 #if MRPT_HAS_WXWIDGETS
00093 if (SHOW_3D_LIVE)
00094 {
00095 win3d = mrpt::gui::CDisplayWindow3D::Create("KF-SLAM live view", 800, 500);
00096 }
00097 #endif
00098 }
00099
00100 void EKFslam::run3Dwindow()
00101 {
00102
00103 if (SHOW_3D_LIVE && win3d.present())
00104 {
00105 mapping.getCurrentState(robotPose_, LMs_, LM_IDs_, fullState_, fullCov_);
00106
00107
00108
00109 const CPose3D robotPoseMean3D = CPose3D(robotPose_.mean);
00110
00111
00112 meanPath.push_back(TPose3D(robotPoseMean3D));
00113
00114
00115 COpenGLScenePtr scene3D = COpenGLScene::Create();
00116 opengl::CGridPlaneXYPtr grid = opengl::CGridPlaneXY::Create(-1000, 1000, -1000, 1000, 0, 5);
00117 grid->setColor(0.4, 0.4, 0.4);
00118 scene3D->insert(grid);
00119
00120
00121 opengl::CSetOfLinesPtr linesPath = opengl::CSetOfLines::Create();
00122 linesPath->setColor(1, 0, 0);
00123 TPose3D init_pose;
00124 if (!meanPath.empty())
00125 {
00126 init_pose = TPose3D(CPose3D(meanPath[0]));
00127 int path_decim = 0;
00128 for (vector<TPose3D>::iterator it = meanPath.begin(); it != meanPath.end(); ++it)
00129 {
00130 linesPath->appendLine(init_pose, *it);
00131 init_pose = *it;
00132 if (++path_decim > 10)
00133 {
00134 path_decim = 0;
00135 mrpt::opengl::CSetOfObjectsPtr xyz = mrpt::opengl::stock_objects::CornerXYZSimple(0.3f, 2.0f);
00136 xyz->setPose(CPose3D(*it));
00137 scene3D->insert(xyz);
00138 }
00139 }
00140 scene3D->insert(linesPath);
00141 }
00142
00143
00144 mrpt::opengl::CSetOfObjectsPtr xyz = mrpt::opengl::stock_objects::CornerXYZSimple(1.0, 2.5);
00145 xyz->setPose(robotPoseMean3D);
00146 scene3D->insert(xyz);
00147
00148
00149 if (CAMERA_3DSCENE_FOLLOWS_ROBOT)
00150 {
00151 win3d->setCameraPointingToPoint(robotPoseMean3D.x(), robotPoseMean3D.y(), robotPoseMean3D.z());
00152 }
00153
00154
00155 const CRangeBearingKFSLAM::TDataAssocInfo &da = mapping.getLastDataAssociation();
00156 mrpt::opengl::CSetOfLinesPtr lins = mrpt::opengl::CSetOfLines::Create();
00157 lins->setLineWidth(1.2);
00158 lins->setColor(1, 1, 1);
00159 for (std::map<observation_index_t, prediction_index_t>::const_iterator it = da.results.associations.begin();
00160 it != da.results.associations.end(); ++it)
00161 {
00162 const prediction_index_t idxPred = it->second;
00163
00164 CRangeBearingKFSLAM::KFArray_FEAT featMean;
00165 mapping.getLandmarkMean(idxPred, featMean);
00166
00167 TPoint3D featMean3D;
00168 landmark_to_3d(featMean, featMean3D);
00169
00170 lins->appendLine(robotPoseMean3D.x(), robotPoseMean3D.y(), robotPoseMean3D.z(), featMean3D.x, featMean3D.y,
00171 featMean3D.z);
00172 }
00173 scene3D->insert(lins);
00174
00175
00176 opengl::CSetOfObjectsPtr objs = opengl::CSetOfObjects::Create();
00177 mapping.getAs3DObject(objs);
00178 scene3D->insert(objs);
00179
00180 mrpt::opengl::COpenGLScenePtr &scn = win3d->get3DSceneAndLock();
00181 scn = scene3D;
00182
00183 win3d->unlockAccess3DScene();
00184 win3d->repaint();
00185 }
00186 }
00187 void EKFslam::landmark_to_3d(const CRangeBearingKFSLAM::KFArray_FEAT &lm, TPoint3D &p)
00188 {
00189 p.x = lm[0];
00190 p.y = lm[1];
00191 p.z = lm[2];
00192 }