mrpt_rbpf_slam.cpp
Go to the documentation of this file.
1 /*
2  * File: mrpt_slam.cpp
3  * Author: Vladislav Tananaev
4  *
5  *
6  */
7 #include <mrpt/version.h>
8 #include <mrpt_bridge/utils.h>
10 
11 #if MRPT_VERSION >= 0x199
12 #include <mrpt/serialization/CArchive.h>
13 #endif
14 
15 namespace mrpt_rbpf_slam {
17  try {
18  std::string sOutMap = "mrpt_rbpfslam_";
19  mrpt::system::TTimeParts parts;
20  mrpt::system::timestampToParts(mrpt::system::now(), parts, true);
21  sOutMap +=
22  mrpt::format("%04u-%02u-%02u_%02uh%02um%02us", (unsigned int)parts.year,
23  (unsigned int)parts.month, (unsigned int)parts.day,
24  (unsigned int)parts.hour, (unsigned int)parts.minute,
25  (unsigned int)parts.second);
26  sOutMap += ".simplemap";
27 
28  sOutMap = mrpt::system::fileNameStripInvalidChars(sOutMap);
29  if (mrpt::system::directoryExists(options_.simplemap_path_prefix)) {
30  sOutMap = options_.simplemap_path_prefix + sOutMap;
31  } else {
32  std::cerr << "Folder " << options_.simplemap_path_prefix
33  << " doesn't exist, cannot save simplemap there! Default "
34  "'~/.ros/' path will be used.\n";
35  }
36  std::cout << "Saving built map " << sOutMap << "\n";
37  mapBuilder_.saveCurrentMapToFile(sOutMap);
38  } catch (const std::exception &e) {
39  std::cerr << "Exception: " << e.what() << "\n";
40  }
41 }
42 
43 void PFslam::readIniFile(const std::string &ini_filename) {
44 #if MRPT_VERSION >= 0x199
45  mrpt::config::CConfigFile iniFile(ini_filename);
46 #else
47  mrpt::utils::CConfigFile iniFile(ini_filename);
48 #endif
49  options_.rbpfMappingOptions_.loadFromConfigFile(iniFile,
50  "MappingApplication");
51  options_.rbpfMappingOptions_.dumpToConsole();
52 }
53 
55  const std::string &rawlog_filename,
56  std::vector<std::pair<mrpt::obs::CActionCollection,
57  mrpt::obs::CSensoryFrame>> &data) {
58  size_t rawlogEntry = 0;
59 #if MRPT_VERSION >= 0x199
60  mrpt::io::CFileGZInputStream rawlog_stream(rawlog_filename);
61  auto rawlogFile = mrpt::serialization::archiveFrom(rawlog_stream);
62 #else
63  mrpt::utils::CFileGZInputStream rawlogFile(rawlog_filename);
64 #endif
65  mrpt::obs::CActionCollection::Ptr action;
66  mrpt::obs::CSensoryFrame::Ptr observations;
67 
68  for (;;) {
69  if (mrpt::system::os::kbhit()) {
70  char c = mrpt::system::os::getch();
71  if (c == 27)
72  break;
73  }
74 
75  // Load action/observation pair from the rawlog:
76  // --------------------------------------------------
77  if (!mrpt::obs::CRawlog::readActionObservationPair(
78  rawlogFile, action, observations, rawlogEntry)) {
79  break; // file EOF
80  }
81  data.emplace_back(*action, *observations);
82  }
83 }
84 
86  const mrpt::obs::CSensoryFrame::ConstPtr sensory_frame,
87  const mrpt::obs::CObservationOdometry::ConstPtr odometry) {
88  action_ = mrpt::obs::CActionCollection::Create();
89  mrpt::obs::CActionRobotMovement2D odom_move;
90  odom_move.timestamp = sensory_frame->getObservationByIndex(0)->timestamp;
91 
92  if (odometry) {
93  if (odomLastObservation_.empty()) {
94  odomLastObservation_ = odometry->odometry;
95  }
96 
97  mrpt::poses::CPose2D incOdoPose = odometry->odometry - odomLastObservation_;
98  odomLastObservation_ = odometry->odometry;
99  odom_move.computeFromOdometry(incOdoPose, options_.motion_model_options_);
100  action_->insert(odom_move);
101  }
102 }
103 
105  log4cxx::LoggerPtr ros_logger =
106  log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME);
107  mapBuilder_.setVerbosityLevel(
108  mrpt_bridge::rosLoggerLvlToMRPTLoggerLvl(ros_logger->getLevel()));
109  mapBuilder_.logging_enable_console_output = false;
110 #if MRPT_VERSION < 0x199
111  mapBuilder_.logRegisterCallback(static_cast<output_logger_callback_t>(
112  &mrpt_bridge::mrptToROSLoggerCallback_mrpt_15));
113 #else
114  mapBuilder_.logRegisterCallback(static_cast<output_logger_callback_t>(
115  &mrpt_bridge::mrptToROSLoggerCallback));
116 #endif
117  mapBuilder_.options.enableMapUpdating = true;
118  mapBuilder_.options.debugForceInsertion = false;
119 
120 #if MRPT_VERSION >= 0x199
121  mrpt::random::getRandomGenerator().randomize();
122 #else
123  mrpt::random::randomGenerator.randomize();
124 #endif
125 
126  options_ = std::move(options);
127 
128  // use_motion_model_default_options_ = false;
129  // // motion_model_default_options_.modelSelection =
130  // mrpt::obs::CActionRobotMovement2D::mmGaussian;
131  // // motion_model_default_options_.gaussianModel.minStdXY = 0.10;
132  // // motion_model_default_options_.gaussianModel.minStdPHI = 2.0;
133 
134  // motion_model_options_.modelSelection =
135  // mrpt::obs::CActionRobotMovement2D::mmGaussian;
136  // motion_model_options_.gaussianModel.a1 = 0.034f;
137  // motion_model_options_.gaussianModel.a2 = 0.057f;
138  // motion_model_options_.gaussianModel.a3 = 0.014f;
139  // motion_model_options_.gaussianModel.a4 = 0.097f;
140  // motion_model_options_.gaussianModel.minStdXY = 0.005f;
141  // motion_model_options_.gaussianModel.minStdPHI = 0.05f;
142 
143  // PROGRESS_WINDOW_WIDTH_ = 600;
144  // PROGRESS_WINDOW_HEIGHT_ = 500;
145  // SHOW_PROGRESS_IN_WINDOW_ = false;
146  // SHOW_PROGRESS_IN_WINDOW_DELAY_MS_ = 0;
147  // CAMERA_3DSCENE_FOLLOWS_ROBOT_ = false;
148 }
149 
151 #if MRPT_HAS_WXWIDGETS
153  win3D_ = mrpt::gui::CDisplayWindow3D::Create(
154  "RBPF-SLAM @ MRPT C++ Library", options_.PROGRESS_WINDOW_WIDTH_,
156  win3D_->setCameraZoom(40);
157  win3D_->setCameraAzimuthDeg(-50);
158  win3D_->setCameraElevationDeg(70);
159  }
160 #endif
161 }
163  // Save a 3D scene view of the mapping process:
165  // get the current map and pose
166  metric_map_ = mapBuilder_.mapPDF.getCurrentMostLikelyMetricMap();
167  mapBuilder_.mapPDF.getEstimatedPosePDF(curPDF);
168  mrpt::opengl::COpenGLScene::Ptr scene;
169  scene = mrpt::opengl::COpenGLScene::Create();
170 
171  // The ground:
172  mrpt::opengl::CGridPlaneXY::Ptr groundPlane =
173  mrpt::opengl::CGridPlaneXY::Create(-200, 200, -200, 200, 0, 5);
174  groundPlane->setColor(0.4, 0.4, 0.4);
175  scene->insert(groundPlane);
176 
177  // The camera pointing to the current robot pose:
179  mrpt::opengl::CCamera::Ptr objCam = mrpt::opengl::CCamera::Create();
180  mrpt::poses::CPose3D robotPose;
181  curPDF.getMean(robotPose);
182 
183  objCam->setPointingAt(robotPose);
184  objCam->setAzimuthDegrees(-30);
185  objCam->setElevationDegrees(30);
186  scene->insert(objCam);
187  }
188  // Draw the map(s):
189  mrpt::opengl::CSetOfObjects::Ptr objs =
190  mrpt::opengl::CSetOfObjects::Create();
191  metric_map_->getAs3DObject(objs);
192  scene->insert(objs);
193 
194  // Draw the robot particles:
195  size_t M = mapBuilder_.mapPDF.particlesCount();
196  mrpt::opengl::CSetOfLines::Ptr objLines =
197  mrpt::opengl::CSetOfLines::Create();
198  objLines->setColor(0, 1, 1);
199  for (size_t i = 0; i < M; i++) {
200  std::deque<mrpt::math::TPose3D> path;
201  mapBuilder_.mapPDF.getPath(i, path);
202 
203  float x0 = 0, y0 = 0, z0 = 0;
204  for (size_t k = 0; k < path.size(); k++) {
205  objLines->appendLine(x0, y0, z0 + 0.001, path[k].x, path[k].y,
206  path[k].z + 0.001);
207  x0 = path[k].x;
208  y0 = path[k].y;
209  z0 = path[k].z;
210  }
211  }
212  scene->insert(objLines);
213 
214  // An ellipsoid:
215  mrpt::poses::CPose3D lastMeanPose;
216  float minDistBtwPoses = -1;
217  std::deque<mrpt::math::TPose3D> dummyPath;
218  mapBuilder_.mapPDF.getPath(0, dummyPath);
219  for (int k = (int)dummyPath.size() - 1; k >= 0; k--) {
220  mrpt::poses::CPose3DPDFParticles poseParts;
221  mapBuilder_.mapPDF.getEstimatedPosePDFAtTime(k, poseParts);
222 
223 #if MRPT_VERSION >= 0x199
224  const auto [COV, meanPose] = poseParts.getCovarianceAndMean();
225 #else
226  mrpt::poses::CPose3D meanPose;
227  mrpt::math::CMatrixDouble66 COV;
228  poseParts.getCovarianceAndMean(COV, meanPose);
229 #endif
230 
231  if (meanPose.distanceTo(lastMeanPose) > minDistBtwPoses) {
232  mrpt::math::CMatrixDouble33 COV3 =
233 #if MRPT_VERSION >= 0x199
234  COV.blockCopy<3, 3>(0, 0);
235 #else
236  COV.block(0, 0, 3, 3);
237 #endif
238 
239  minDistBtwPoses = 6 * sqrt(COV3(0, 0) + COV3(1, 1));
240 
241  mrpt::opengl::CEllipsoid::Ptr objEllip =
242  mrpt::opengl::CEllipsoid::Create();
243  objEllip->setLocation(meanPose.x(), meanPose.y(), meanPose.z() + 0.001);
244  objEllip->setCovMatrix(COV3, COV3(2, 2) == 0 ? 2 : 3);
245 
246  objEllip->setColor(0, 0, 1);
247  objEllip->enableDrawSolid3D(false);
248  scene->insert(objEllip);
249 
250  lastMeanPose = meanPose;
251  }
252  }
253 
254  mrpt::opengl::COpenGLScene::Ptr &scenePtr = win3D_->get3DSceneAndLock();
255  scenePtr = scene;
256  win3D_->unlockAccess3DScene();
257  win3D_->forceRepaint();
258  }
259 }
260 } // namespace mrpt_rbpf_slam
mrpt::slam::CMetricMapBuilderRBPF::TConstructionOptions rbpfMappingOptions_
options for SLAM from ini file
void observation(const mrpt::obs::CSensoryFrame::ConstPtr sensory_frame, const mrpt::obs::CObservationOdometry::ConstPtr odometry)
Calculate the actions from odometry model for current observation.
mrpt::poses::CPose3DPDFParticles curPDF
current robot pose
TFSIMD_FORCE_INLINE const tfScalar & y() const
mrpt::gui::CDisplayWindow3D::Ptr win3D_
MRPT window.
struct mrpt_rbpf_slam::PFslam::Options options_
void readIniFile(const std::string &ini_filename)
Read ini file.
mrpt::slam::CMetricMapBuilderRBPF mapBuilder_
map builder
void initSlam(Options options)
initialize the SLAM
mrpt::obs::CActionCollection::Ptr action_
actions
TFSIMD_FORCE_INLINE const tfScalar & x() const
void readRawlog(const std::string &rawlog_filename, std::vector< std::pair< mrpt::obs::CActionCollection, mrpt::obs::CSensoryFrame >> &data)
Read pairs of actions and observations from rawlog file.
const mrpt::maps::CMultiMetricMap * metric_map_
receive map after iteration of SLAM to metric map
action
TFSIMD_FORCE_INLINE const tfScalar & z() const
mrpt::poses::CPose2D odomLastObservation_
last observation of odometry
#define ROSCONSOLE_DEFAULT_NAME
mrpt::obs::CActionRobotMovement2D::TMotionModelOptions motion_model_options_


mrpt_rbpf_slam
Author(s): Vladislav Tananaev
autogenerated on Thu Jun 6 2019 19:37:56