00001
00002
00003
00004
00005
00006
00007 #include <mrpt_rbpf_slam/mrpt_rbpf_slam.h>
00008 #include <mrpt/version.h>
00009 #if MRPT_VERSION >= 0x150
00010 #include <mrpt_bridge/utils.h>
00011 #endif
00012
00013 PFslam::PFslam()
00014 {
00015 #if MRPT_VERSION>=0x150
00016 #define gausianModel gaussianModel // a typo was fixed in 1.5.0
00017 #endif
00018
00019 use_motion_model_default_options_ = false;
00020 motion_model_default_options_.modelSelection = CActionRobotMovement2D::mmGaussian;
00021 motion_model_default_options_.gausianModel.minStdXY = 0.10;
00022 motion_model_default_options_.gausianModel.minStdPHI = 2.0;
00023
00024 motion_model_options_.modelSelection = CActionRobotMovement2D::mmGaussian;
00025 motion_model_options_.gausianModel.a1 = 0.034;
00026 motion_model_options_.gausianModel.a2 = 0.057;
00027 motion_model_options_.gausianModel.a3 = 0.014;
00028 motion_model_options_.gausianModel.a4 = 0.097;
00029 motion_model_options_.gausianModel.minStdXY = 0.005;
00030 motion_model_options_.gausianModel.minStdPHI = 0.05;
00031
00032 PROGRESS_WINDOW_WIDTH = 600;
00033 PROGRESS_WINDOW_HEIGHT = 500;
00034 SHOW_PROGRESS_IN_WINDOW = false;
00035 SHOW_PROGRESS_IN_WINDOW_DELAY_MS = 0;
00036 CAMERA_3DSCENE_FOLLOWS_ROBOT = false;
00037 }
00038
00039 PFslam::~PFslam()
00040 {
00041 try {
00042 std::string sOutMap = "mrpt_rbpfslam_";
00043 mrpt::system::TTimeParts parts;
00044 mrpt::system::timestampToParts(now(), parts, true);
00045 sOutMap += format("%04u-%02u-%02u_%02uh%02um%02us",
00046 (unsigned int)parts.year,
00047 (unsigned int)parts.month,
00048 (unsigned int)parts.day,
00049 (unsigned int)parts.hour,
00050 (unsigned int)parts.minute,
00051 (unsigned int)parts.second );
00052 sOutMap += ".simplemap";
00053
00054 sOutMap = mrpt::system::fileNameStripInvalidChars( sOutMap );
00055 ROS_INFO("Saving built map to `%s`", sOutMap.c_str());
00056 mapBuilder->saveCurrentMapToFile(sOutMap);
00057 } catch (std::exception &e) {
00058 ROS_ERROR("Exception: %s",e.what());
00059 }
00060 }
00061
00062 void PFslam::read_iniFile(std::string ini_filename)
00063 {
00064 CConfigFile iniFile(ini_filename);
00065 rbpfMappingOptions.loadFromConfigFile(iniFile, "MappingApplication");
00066 rbpfMappingOptions.dumpToConsole();
00067
00068
00069 CAMERA_3DSCENE_FOLLOWS_ROBOT = iniFile.read_bool("MappingApplication", "CAMERA_3DSCENE_FOLLOWS_ROBOT", true);
00070 SHOW_PROGRESS_IN_WINDOW = iniFile.read_bool("MappingApplication", "SHOW_PROGRESS_IN_WINDOW", false);
00071 SHOW_PROGRESS_IN_WINDOW_DELAY_MS = iniFile.read_int("MappingApplication", "SHOW_PROGRESS_IN_WINDOW_DELAY_MS", 1);
00072
00073 MRPT_LOAD_CONFIG_VAR(PROGRESS_WINDOW_WIDTH, int, iniFile, "MappingApplication");
00074 MRPT_LOAD_CONFIG_VAR(PROGRESS_WINDOW_HEIGHT, int, iniFile, "MappingApplication");
00075 }
00076
00077 void PFslam::read_rawlog(std::vector<std::pair<CActionCollection, CSensoryFrame>> &data, std::string rawlog_filename)
00078 {
00079 size_t rawlogEntry = 0;
00080 CFileGZInputStream rawlogFile(rawlog_filename);
00081 CActionCollectionPtr action;
00082 CSensoryFramePtr observations;
00083
00084 for (;;)
00085 {
00086 if (os::kbhit())
00087 {
00088 char c = os::getch();
00089 if (c == 27)
00090 break;
00091 }
00092
00093
00094
00095 if (!CRawlog::readActionObservationPair(rawlogFile, action, observations, rawlogEntry))
00096 {
00097 break;
00098 }
00099 data.push_back(std::make_pair(*action, *observations));
00100 }
00101 }
00102
00103 void PFslam::observation(CSensoryFramePtr _sf, CObservationOdometryPtr _odometry)
00104 {
00105 action = CActionCollection::Create();
00106 CActionRobotMovement2D odom_move;
00107 odom_move.timestamp = _sf->getObservationByIndex(0)->timestamp;
00108
00109 if (_odometry)
00110 {
00111 if (odomLastObservation_.empty())
00112 {
00113 odomLastObservation_ = _odometry->odometry;
00114 }
00115
00116 mrpt::poses::CPose2D incOdoPose = _odometry->odometry - odomLastObservation_;
00117 odomLastObservation_ = _odometry->odometry;
00118 odom_move.computeFromOdometry(incOdoPose, motion_model_options_);
00119 action->insert(odom_move);
00120 }
00121 else if (use_motion_model_default_options_)
00122 {
00123 odom_move.computeFromOdometry(mrpt::poses::CPose2D(0, 0, 0), motion_model_default_options_);
00124 action->insert(odom_move);
00125 }
00126 }
00127
00128 void PFslam::init_slam()
00129 {
00130 #if MRPT_VERSION < 0x150
00131 mapBuilder->options.verbose = true;
00132 #else
00133 log4cxx::LoggerPtr ros_logger = log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME);
00134 mapBuilder->setVerbosityLevel(mrpt_bridge::rosLoggerLvlToMRPTLoggerLvl(ros_logger->getLevel()));
00135 mapBuilder->logging_enable_console_output = false;
00136 mapBuilder->logRegisterCallback(static_cast<output_logger_callback_t>(&mrpt_bridge::mrptToROSLoggerCallback));
00137 #endif
00138
00139 mapBuilder->options.enableMapUpdating = true;
00140 mapBuilder->options.debugForceInsertion = false;
00141
00142 randomGenerator.randomize();
00143 }
00144
00145 void PFslam::init3Dwindow()
00146 {
00147 #if MRPT_HAS_WXWIDGETS
00148
00149 if (SHOW_PROGRESS_IN_WINDOW)
00150 {
00151 win3D = mrpt::gui::CDisplayWindow3D::Create("RBPF-SLAM @ MRPT C++ Library", PROGRESS_WINDOW_WIDTH,
00152 PROGRESS_WINDOW_HEIGHT);
00153 win3D->setCameraZoom(40);
00154 win3D->setCameraAzimuthDeg(-50);
00155 win3D->setCameraElevationDeg(70);
00156 }
00157
00158 #endif
00159 }
00160 void PFslam::run3Dwindow()
00161 {
00162
00163 if (SHOW_PROGRESS_IN_WINDOW && win3D.present())
00164 {
00165
00166 metric_map_ = mapBuilder->mapPDF.getCurrentMostLikelyMetricMap();
00167 mapBuilder->mapPDF.getEstimatedPosePDF(curPDF);
00168 COpenGLScenePtr scene;
00169 scene = COpenGLScene::Create();
00170
00171
00172 mrpt::opengl::CGridPlaneXYPtr groundPlane = mrpt::opengl::CGridPlaneXY::Create(-200, 200, -200, 200, 0, 5);
00173 groundPlane->setColor(0.4, 0.4, 0.4);
00174 scene->insert(groundPlane);
00175
00176
00177 if (CAMERA_3DSCENE_FOLLOWS_ROBOT)
00178 {
00179 mrpt::opengl::CCameraPtr objCam = mrpt::opengl::CCamera::Create();
00180 CPose3D robotPose;
00181 curPDF.getMean(robotPose);
00182
00183 objCam->setPointingAt(robotPose);
00184 objCam->setAzimuthDegrees(-30);
00185 objCam->setElevationDegrees(30);
00186 scene->insert(objCam);
00187 }
00188
00189 mrpt::opengl::CSetOfObjectsPtr objs = mrpt::opengl::CSetOfObjects::Create();
00190 metric_map_->getAs3DObject(objs);
00191 scene->insert(objs);
00192
00193
00194 size_t M = mapBuilder->mapPDF.particlesCount();
00195 mrpt::opengl::CSetOfLinesPtr objLines = mrpt::opengl::CSetOfLines::Create();
00196 objLines->setColor(0, 1, 1);
00197 for (size_t i = 0; i < M; i++)
00198 {
00199 std::deque<TPose3D> path;
00200 mapBuilder->mapPDF.getPath(i, path);
00201
00202 float x0 = 0, y0 = 0, z0 = 0;
00203 for (size_t k = 0; k < path.size(); k++)
00204 {
00205 objLines->appendLine(x0, y0, z0 + 0.001, path[k].x, path[k].y, path[k].z + 0.001);
00206 x0 = path[k].x;
00207 y0 = path[k].y;
00208 z0 = path[k].z;
00209 }
00210 }
00211 scene->insert(objLines);
00212
00213
00214 CPose3D lastMeanPose;
00215 float minDistBtwPoses = -1;
00216 std::deque<TPose3D> dummyPath;
00217 mapBuilder->mapPDF.getPath(0, dummyPath);
00218 for (int k = (int)dummyPath.size() - 1; k >= 0; k--)
00219 {
00220 CPose3DPDFParticles poseParts;
00221 mapBuilder->mapPDF.getEstimatedPosePDFAtTime(k, poseParts);
00222 CPose3D meanPose;
00223 CMatrixDouble66 COV;
00224 poseParts.getCovarianceAndMean(COV, meanPose);
00225
00226 if (meanPose.distanceTo(lastMeanPose) > minDistBtwPoses)
00227 {
00228 CMatrixDouble33 COV3 = COV.block(0, 0, 3, 3);
00229
00230 minDistBtwPoses = 6 * sqrt(COV3(0, 0) + COV3(1, 1));
00231
00232 opengl::CEllipsoidPtr objEllip = opengl::CEllipsoid::Create();
00233 objEllip->setLocation(meanPose.x(), meanPose.y(), meanPose.z() + 0.001);
00234 objEllip->setCovMatrix(COV3, COV3(2, 2) == 0 ? 2 : 3);
00235
00236 objEllip->setColor(0, 0, 1);
00237 objEllip->enableDrawSolid3D(false);
00238 scene->insert(objEllip);
00239
00240 lastMeanPose = meanPose;
00241 }
00242 }
00243
00244 COpenGLScenePtr &scenePtr = win3D->get3DSceneAndLock();
00245 scenePtr = scene;
00246 win3D->unlockAccess3DScene();
00247 win3D->forceRepaint();
00248 }
00249 }