00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "rtabmap_ros/MsgConversion.h"
00029
00030 #include <opencv2/highgui/highgui.hpp>
00031 #include <zlib.h>
00032 #include <ros/ros.h>
00033 #include <rtabmap/core/util3d.h>
00034 #include <rtabmap/utilite/UStl.h>
00035 #include <rtabmap/utilite/ULogger.h>
00036 #include <pcl_conversions/pcl_conversions.h>
00037 #include <eigen_conversions/eigen_msg.h>
00038 #include <tf_conversions/tf_eigen.h>
00039 #include <image_geometry/pinhole_camera_model.h>
00040 #include <image_geometry/stereo_camera_model.h>
00041
00042 namespace rtabmap_ros {
00043
00044 void transformToTF(const rtabmap::Transform & transform, tf::Transform & tfTransform)
00045 {
00046 if(!transform.isNull())
00047 {
00048 tf::transformEigenToTF(transform.toEigen3d(), tfTransform);
00049 }
00050 else
00051 {
00052 tfTransform = tf::Transform();
00053 }
00054 }
00055
00056 rtabmap::Transform transformFromTF(const tf::Transform & transform)
00057 {
00058 Eigen::Affine3d eigenTf;
00059 tf::transformTFToEigen(transform, eigenTf);
00060 return rtabmap::Transform::fromEigen3d(eigenTf);
00061 }
00062
00063 void transformToGeometryMsg(const rtabmap::Transform & transform, geometry_msgs::Transform & msg)
00064 {
00065 if(!transform.isNull())
00066 {
00067 tf::transformEigenToMsg(transform.toEigen3d(), msg);
00068 }
00069 else
00070 {
00071 msg = geometry_msgs::Transform();
00072 }
00073 }
00074
00075
00076 rtabmap::Transform transformFromGeometryMsg(const geometry_msgs::Transform & msg)
00077 {
00078 if(msg.rotation.w == 0 &&
00079 msg.rotation.x == 0 &&
00080 msg.rotation.y == 0 &&
00081 msg.rotation.z ==0)
00082 {
00083 return rtabmap::Transform();
00084 }
00085
00086 Eigen::Affine3d tfTransform;
00087 tf::transformMsgToEigen(msg, tfTransform);
00088 return rtabmap::Transform::fromEigen3d(tfTransform);
00089 }
00090
00091 void transformToPoseMsg(const rtabmap::Transform & transform, geometry_msgs::Pose & msg)
00092 {
00093 if(!transform.isNull())
00094 {
00095 tf::poseEigenToMsg(transform.toEigen3d(), msg);
00096 }
00097 else
00098 {
00099 msg = geometry_msgs::Pose();
00100 }
00101 }
00102
00103 rtabmap::Transform transformFromPoseMsg(const geometry_msgs::Pose & msg)
00104 {
00105 if(msg.orientation.w == 0 &&
00106 msg.orientation.x == 0 &&
00107 msg.orientation.y == 0 &&
00108 msg.orientation.z ==0)
00109 {
00110 return rtabmap::Transform();
00111 }
00112 Eigen::Affine3d tfPose;
00113 tf::poseMsgToEigen(msg, tfPose);
00114 return rtabmap::Transform::fromEigen3d(tfPose);
00115 }
00116
00117 void compressedMatToBytes(const cv::Mat & compressed, std::vector<unsigned char> & bytes)
00118 {
00119 UASSERT(compressed.empty() || compressed.type() == CV_8UC1);
00120 bytes.clear();
00121 if(!compressed.empty())
00122 {
00123 bytes.resize(compressed.cols * compressed.rows);
00124 memcpy(bytes.data(), compressed.data, bytes.size());
00125 }
00126 }
00127
00128 cv::Mat compressedMatFromBytes(const std::vector<unsigned char> & bytes, bool copy)
00129 {
00130 cv::Mat out;
00131 if(bytes.size())
00132 {
00133 out = cv::Mat(1, bytes.size(), CV_8UC1, (void*)bytes.data());
00134 if(copy)
00135 {
00136 out = out.clone();
00137 }
00138 }
00139 return out;
00140 }
00141
00142 void infoFromROS(const rtabmap_ros::Info & info, rtabmap::Statistics & stat)
00143 {
00144 stat.setExtended(true);
00145
00146
00147 stat.setRefImageId(info.refId);
00148 stat.setLoopClosureId(info.loopClosureId);
00149 stat.setProximityDetectionId(info.proximityDetectionId);
00150 stat.setStamp(info.header.stamp.toSec());
00151
00152 stat.setLoopClosureTransform(rtabmap_ros::transformFromGeometryMsg(info.loopClosureTransform));
00153
00154
00155 std::map<int, float> mapIntFloat;
00156 for(unsigned int i=0; i<info.posteriorKeys.size() && i<info.posteriorValues.size(); ++i)
00157 {
00158 mapIntFloat.insert(std::pair<int, float>(info.posteriorKeys.at(i), info.posteriorValues.at(i)));
00159 }
00160 stat.setPosterior(mapIntFloat);
00161 mapIntFloat.clear();
00162 for(unsigned int i=0; i<info.likelihoodKeys.size() && i<info.likelihoodValues.size(); ++i)
00163 {
00164 mapIntFloat.insert(std::pair<int, float>(info.likelihoodKeys.at(i), info.likelihoodValues.at(i)));
00165 }
00166 stat.setLikelihood(mapIntFloat);
00167 mapIntFloat.clear();
00168 for(unsigned int i=0; i<info.rawLikelihoodKeys.size() && i<info.rawLikelihoodValues.size(); ++i)
00169 {
00170 mapIntFloat.insert(std::pair<int, float>(info.rawLikelihoodKeys.at(i), info.rawLikelihoodValues.at(i)));
00171 }
00172 stat.setRawLikelihood(mapIntFloat);
00173 std::map<int, int> mapIntInt;
00174 for(unsigned int i=0; i<info.weightsKeys.size() && i<info.weightsValues.size(); ++i)
00175 {
00176 mapIntInt.insert(std::pair<int, int>(info.weightsKeys.at(i), info.weightsValues.at(i)));
00177 }
00178 stat.setWeights(mapIntInt);
00179
00180 stat.setLocalPath(info.localPath);
00181 stat.setCurrentGoalId(info.currentGoalId);
00182
00183
00184 for(unsigned int i=0; i<info.statsKeys.size() && i<info.statsValues.size(); i++)
00185 {
00186 stat.addStatistic(info.statsKeys.at(i), info.statsValues.at(i));
00187 }
00188 }
00189
00190 void infoToROS(const rtabmap::Statistics & stats, rtabmap_ros::Info & info)
00191 {
00192 info.refId = stats.refImageId();
00193 info.loopClosureId = stats.loopClosureId();
00194 info.proximityDetectionId = stats.proximityDetectionId();
00195
00196 rtabmap_ros::transformToGeometryMsg(stats.loopClosureTransform(), info.loopClosureTransform);
00197
00198
00199 if(stats.extended())
00200 {
00201
00202 info.posteriorKeys = uKeys(stats.posterior());
00203 info.posteriorValues = uValues(stats.posterior());
00204 info.likelihoodKeys = uKeys(stats.likelihood());
00205 info.likelihoodValues = uValues(stats.likelihood());
00206 info.rawLikelihoodKeys = uKeys(stats.rawLikelihood());
00207 info.rawLikelihoodValues = uValues(stats.rawLikelihood());
00208 info.weightsKeys = uKeys(stats.weights());
00209 info.weightsValues = uValues(stats.weights());
00210 info.localPath = stats.localPath();
00211 info.currentGoalId = stats.currentGoalId();
00212
00213
00214 info.statsKeys = uKeys(stats.data());
00215 info.statsValues = uValues(stats.data());
00216 }
00217 }
00218
00219 rtabmap::Link linkFromROS(const rtabmap_ros::Link & msg)
00220 {
00221 return rtabmap::Link(msg.fromId, msg.toId, (rtabmap::Link::Type)msg.type, transformFromGeometryMsg(msg.transform), msg.rotVariance, msg.transVariance);
00222 }
00223
00224 void linkToROS(const rtabmap::Link & link, rtabmap_ros::Link & msg)
00225 {
00226 msg.fromId = link.from();
00227 msg.toId = link.to();
00228 msg.type = link.type();
00229 msg.rotVariance = link.rotVariance();
00230 msg.transVariance = link.transVariance();
00231 transformToGeometryMsg(link.transform(), msg.transform);
00232 }
00233
00234 cv::KeyPoint keypointFromROS(const rtabmap_ros::KeyPoint & msg)
00235 {
00236 return cv::KeyPoint(msg.pt.x, msg.pt.y, msg.size, msg.angle, msg.response, msg.octave, msg.class_id);
00237 }
00238
00239 void keypointToROS(const cv::KeyPoint & kpt, rtabmap_ros::KeyPoint & msg)
00240 {
00241 msg.angle = kpt.angle;
00242 msg.class_id = kpt.class_id;
00243 msg.octave = kpt.octave;
00244 msg.pt.x = kpt.pt.x;
00245 msg.pt.y = kpt.pt.y;
00246 msg.response = kpt.response;
00247 msg.size = kpt.size;
00248 }
00249
00250 std::vector<cv::KeyPoint> keypointsFromROS(const std::vector<rtabmap_ros::KeyPoint> & msg)
00251 {
00252 std::vector<cv::KeyPoint> v(msg.size());
00253 for(unsigned int i=0; i<msg.size(); ++i)
00254 {
00255 v[i] = keypointFromROS(msg[i]);
00256 }
00257 return v;
00258 }
00259
00260 void keypointsToROS(const std::vector<cv::KeyPoint> & kpts, std::vector<rtabmap_ros::KeyPoint> & msg)
00261 {
00262 msg.resize(kpts.size());
00263 for(unsigned int i=0; i<msg.size(); ++i)
00264 {
00265 keypointToROS(kpts[i], msg[i]);
00266 }
00267 }
00268
00269 cv::Point2f point2fFromROS(const rtabmap_ros::Point2f & msg)
00270 {
00271 return cv::Point2f(msg.x, msg.y);
00272 }
00273
00274 void point2fToROS(const cv::Point2f & kpt, rtabmap_ros::Point2f & msg)
00275 {
00276 msg.x = kpt.x;
00277 msg.y = kpt.y;
00278 }
00279
00280 std::vector<cv::Point2f> points2fFromROS(const std::vector<rtabmap_ros::Point2f> & msg)
00281 {
00282 std::vector<cv::Point2f> v(msg.size());
00283 for(unsigned int i=0; i<msg.size(); ++i)
00284 {
00285 v[i] = point2fFromROS(msg[i]);
00286 }
00287 return v;
00288 }
00289
00290 void points2fToROS(const std::vector<cv::Point2f> & kpts, std::vector<rtabmap_ros::Point2f> & msg)
00291 {
00292 msg.resize(kpts.size());
00293 for(unsigned int i=0; i<msg.size(); ++i)
00294 {
00295 point2fToROS(kpts[i], msg[i]);
00296 }
00297 }
00298
00299 cv::Point3f point3fFromROS(const rtabmap_ros::Point3f & msg)
00300 {
00301 return cv::Point3f(msg.x, msg.y, msg.z);
00302 }
00303
00304 void point3fToROS(const cv::Point3f & kpt, rtabmap_ros::Point3f & msg)
00305 {
00306 msg.x = kpt.x;
00307 msg.y = kpt.y;
00308 msg.z = kpt.z;
00309 }
00310
00311 std::vector<cv::Point3f> points3fFromROS(const std::vector<rtabmap_ros::Point3f> & msg)
00312 {
00313 std::vector<cv::Point3f> v(msg.size());
00314 for(unsigned int i=0; i<msg.size(); ++i)
00315 {
00316 v[i] = point3fFromROS(msg[i]);
00317 }
00318 return v;
00319 }
00320
00321 void points3fToROS(const std::vector<cv::Point3f> & kpts, std::vector<rtabmap_ros::Point3f> & msg)
00322 {
00323 msg.resize(kpts.size());
00324 for(unsigned int i=0; i<msg.size(); ++i)
00325 {
00326 point3fToROS(kpts[i], msg[i]);
00327 }
00328 }
00329
00330 rtabmap::CameraModel cameraModelFromROS(
00331 const sensor_msgs::CameraInfo & camInfo,
00332 const rtabmap::Transform & localTransform)
00333 {
00334 image_geometry::PinholeCameraModel model;
00335 model.fromCameraInfo(camInfo);
00336 return rtabmap::CameraModel(
00337 model.fx(),
00338 model.fy(),
00339 model.cx(),
00340 model.cy(),
00341 localTransform,
00342 0.0,
00343 cv::Size(model.fullResolution().width, model.fullResolution().height));
00344 }
00345 void cameraModelToROS(
00346 const rtabmap::CameraModel & model,
00347 sensor_msgs::CameraInfo & camInfo)
00348 {
00349 camInfo.D = std::vector<double>(model.D_raw().cols);
00350 memcpy(camInfo.D.data(), model.D_raw().data, model.D_raw().cols*sizeof(double));
00351
00352 UASSERT(model.K_raw().empty() || model.K_raw().total() == 9);
00353 if(model.K_raw().empty())
00354 {
00355 memset(camInfo.K.elems, 0.0, 9*sizeof(double));
00356 }
00357 else
00358 {
00359 memcpy(camInfo.K.elems, model.K_raw().data, 9*sizeof(double));
00360 }
00361
00362 UASSERT(model.R().empty() || model.R().total() == 9);
00363 if(model.R().empty())
00364 {
00365 memset(camInfo.R.elems, 0.0, 9*sizeof(double));
00366 }
00367 else
00368 {
00369 memcpy(camInfo.R.elems, model.R().data, 9*sizeof(double));
00370 }
00371
00372 UASSERT(model.P().empty() || model.P().total() == 12);
00373 if(model.P().empty())
00374 {
00375 memset(camInfo.P.elems, 0.0, 12*sizeof(double));
00376 }
00377 else
00378 {
00379 memcpy(camInfo.P.elems, model.P().data, 12*sizeof(double));
00380 }
00381
00382 if(camInfo.D.size() > 5)
00383 {
00384 camInfo.distortion_model = "rational_polynomial";
00385 }
00386 else
00387 {
00388 camInfo.distortion_model = "plumb_bob";
00389 }
00390 camInfo.binning_x = 1;
00391 camInfo.binning_y = 1;
00392 camInfo.roi.width = model.imageWidth();
00393 camInfo.roi.height = model.imageHeight();
00394
00395 camInfo.width = model.imageWidth();
00396 camInfo.height = model.imageHeight();
00397 }
00398 rtabmap::StereoCameraModel stereoCameraModelFromROS(
00399 const sensor_msgs::CameraInfo & leftCamInfo,
00400 const sensor_msgs::CameraInfo & rightCamInfo,
00401 const rtabmap::Transform & localTransform)
00402 {
00403 image_geometry::StereoCameraModel model;
00404 model.fromCameraInfo(leftCamInfo, rightCamInfo);
00405 return rtabmap::StereoCameraModel(
00406 model.left().fx(),
00407 model.left().fy(),
00408 model.left().cx(),
00409 model.left().cy(),
00410 model.baseline(),
00411 localTransform,
00412 cv::Size(model.left().fullResolution().width, model.left().fullResolution().height));
00413 }
00414
00415 void mapDataFromROS(
00416 const rtabmap_ros::MapData & msg,
00417 std::map<int, rtabmap::Transform> & poses,
00418 std::multimap<int, rtabmap::Link> & links,
00419 std::map<int, rtabmap::Signature> & signatures,
00420 rtabmap::Transform & mapToOdom)
00421 {
00422
00423 mapGraphFromROS(msg.graph, poses, links, mapToOdom);
00424
00425
00426 for(unsigned int i=0; i<msg.nodes.size(); ++i)
00427 {
00428 signatures.insert(std::make_pair(msg.nodes[i].id, nodeDataFromROS(msg.nodes[i])));
00429 }
00430 }
00431 void mapDataToROS(
00432 const std::map<int, rtabmap::Transform> & poses,
00433 const std::multimap<int, rtabmap::Link> & links,
00434 const std::map<int, rtabmap::Signature> & signatures,
00435 const rtabmap::Transform & mapToOdom,
00436 rtabmap_ros::MapData & msg)
00437 {
00438
00439 mapGraphToROS(poses, links, mapToOdom, msg.graph);
00440
00441
00442 msg.nodes.resize(signatures.size());
00443 int index=0;
00444 for(std::multimap<int, rtabmap::Signature>::const_iterator iter = signatures.begin();
00445 iter!=signatures.end();
00446 ++iter)
00447 {
00448 nodeDataToROS(iter->second, msg.nodes[index++]);
00449 }
00450 }
00451
00452 void mapGraphFromROS(
00453 const rtabmap_ros::MapGraph & msg,
00454 std::map<int, rtabmap::Transform> & poses,
00455 std::multimap<int, rtabmap::Link> & links,
00456 rtabmap::Transform & mapToOdom)
00457 {
00458
00459 UASSERT(msg.posesId.size() == msg.poses.size());
00460 for(unsigned int i=0; i<msg.posesId.size(); ++i)
00461 {
00462 poses.insert(std::make_pair(msg.posesId[i], rtabmap_ros::transformFromPoseMsg(msg.poses[i])));
00463 }
00464 for(unsigned int i=0; i<msg.links.size(); ++i)
00465 {
00466 rtabmap::Transform t = rtabmap_ros::transformFromGeometryMsg(msg.links[i].transform);
00467 links.insert(std::make_pair(msg.links[i].fromId, linkFromROS(msg.links[i])));
00468 }
00469 mapToOdom = transformFromGeometryMsg(msg.mapToOdom);
00470 }
00471 void mapGraphToROS(
00472 const std::map<int, rtabmap::Transform> & poses,
00473 const std::multimap<int, rtabmap::Link> & links,
00474 const rtabmap::Transform & mapToOdom,
00475 rtabmap_ros::MapGraph & msg)
00476 {
00477
00478 msg.posesId.resize(poses.size());
00479 msg.poses.resize(poses.size());
00480 int index = 0;
00481 for(std::map<int, rtabmap::Transform>::const_iterator iter = poses.begin();
00482 iter != poses.end();
00483 ++iter)
00484 {
00485 msg.posesId[index] = iter->first;
00486 transformToPoseMsg(iter->second, msg.poses[index]);
00487 ++index;
00488 }
00489
00490 msg.links.resize(links.size());
00491 index=0;
00492 for(std::multimap<int, rtabmap::Link>::const_iterator iter = links.begin();
00493 iter!=links.end();
00494 ++iter)
00495 {
00496 linkToROS(iter->second, msg.links[index++]);
00497 }
00498
00499 transformToGeometryMsg(mapToOdom, msg.mapToOdom);
00500 }
00501
00502 rtabmap::Signature nodeDataFromROS(const rtabmap_ros::NodeData & msg)
00503 {
00504
00505 std::multimap<int, cv::KeyPoint> words;
00506 std::multimap<int, cv::Point3f> words3D;
00507 pcl::PointCloud<pcl::PointXYZ> cloud;
00508 if(msg.wordPts.data.size() &&
00509 msg.wordPts.height*msg.wordPts.width == msg.wordIds.size())
00510 {
00511 pcl::fromROSMsg(msg.wordPts, cloud);
00512 }
00513
00514 for(unsigned int i=0; i<msg.wordIds.size() && i<msg.wordKpts.size(); ++i)
00515 {
00516 cv::KeyPoint pt = keypointFromROS(msg.wordKpts.at(i));
00517 int wordId = msg.wordIds.at(i);
00518 words.insert(std::make_pair(wordId, pt));
00519 if(i< cloud.size())
00520 {
00521 words3D.insert(std::make_pair(wordId, cv::Point3f(cloud[i].x, cloud[i].y, cloud[i].z)));
00522 }
00523 }
00524
00525 if(words3D.size() && words3D.size() != words.size())
00526 {
00527 ROS_ERROR("Words 2D and 3D should be the same size (%d, %d)!", (int)words.size(), (int)words3D.size());
00528 }
00529
00530 rtabmap::StereoCameraModel stereoModel;
00531 std::vector<rtabmap::CameraModel> models;
00532 if(msg.baseline > 0.0f)
00533 {
00534
00535 if(msg.fx.size() == 1 &&
00536 msg.fy.size() == 1,
00537 msg.cx.size() == 1,
00538 msg.cy.size() == 1,
00539 msg.localTransform.size() == 1)
00540 {
00541 stereoModel = rtabmap::StereoCameraModel(
00542 msg.fx[0],
00543 msg.fy[0],
00544 msg.cx[0],
00545 msg.cy[0],
00546 msg.baseline,
00547 transformFromGeometryMsg(msg.localTransform[0]));
00548 }
00549 }
00550 else
00551 {
00552
00553 if(msg.fx.size() &&
00554 msg.fx.size() == msg.fy.size(),
00555 msg.fx.size() == msg.cx.size(),
00556 msg.fx.size() == msg.cy.size(),
00557 msg.fx.size() == msg.localTransform.size())
00558 {
00559 for(unsigned int i=0; i<msg.fx.size(); ++i)
00560 {
00561 models.push_back(rtabmap::CameraModel(
00562 msg.fx[i],
00563 msg.fy[i],
00564 msg.cx[i],
00565 msg.cy[i],
00566 transformFromGeometryMsg(msg.localTransform[i])));
00567 }
00568 }
00569 }
00570
00571 rtabmap::Signature s(
00572 msg.id,
00573 msg.mapId,
00574 msg.weight,
00575 msg.stamp,
00576 msg.label,
00577 transformFromPoseMsg(msg.pose),
00578 transformFromPoseMsg(msg.groundTruthPose),
00579 stereoModel.isValidForProjection()?
00580 rtabmap::SensorData(
00581 compressedMatFromBytes(msg.laserScan),
00582 msg.laserScanMaxPts,
00583 msg.laserScanMaxRange,
00584 compressedMatFromBytes(msg.image),
00585 compressedMatFromBytes(msg.depth),
00586 stereoModel,
00587 msg.id,
00588 msg.stamp,
00589 compressedMatFromBytes(msg.userData)):
00590 rtabmap::SensorData(
00591 compressedMatFromBytes(msg.laserScan),
00592 msg.laserScanMaxPts,
00593 msg.laserScanMaxRange,
00594 compressedMatFromBytes(msg.image),
00595 compressedMatFromBytes(msg.depth),
00596 models,
00597 msg.id,
00598 msg.stamp,
00599 compressedMatFromBytes(msg.userData)));
00600 s.setWords(words);
00601 s.setWords3(words3D);
00602 return s;
00603 }
00604 void nodeDataToROS(const rtabmap::Signature & signature, rtabmap_ros::NodeData & msg)
00605 {
00606
00607 msg.id = signature.id();
00608 msg.mapId = signature.mapId();
00609 msg.weight = signature.getWeight();
00610 msg.stamp = signature.getStamp();
00611 msg.label = signature.getLabel();
00612 transformToPoseMsg(signature.getPose(), msg.pose);
00613 transformToPoseMsg(signature.getGroundTruthPose(), msg.groundTruthPose);
00614 compressedMatToBytes(signature.sensorData().imageCompressed(), msg.image);
00615 compressedMatToBytes(signature.sensorData().depthOrRightCompressed(), msg.depth);
00616 compressedMatToBytes(signature.sensorData().laserScanCompressed(), msg.laserScan);
00617 compressedMatToBytes(signature.sensorData().userDataCompressed(), msg.userData);
00618 msg.laserScanMaxPts = signature.sensorData().laserScanMaxPts();
00619 msg.laserScanMaxRange = signature.sensorData().laserScanMaxRange();
00620 msg.baseline = 0;
00621 if(signature.sensorData().cameraModels().size())
00622 {
00623 msg.fx.resize(signature.sensorData().cameraModels().size());
00624 msg.fy.resize(signature.sensorData().cameraModels().size());
00625 msg.cx.resize(signature.sensorData().cameraModels().size());
00626 msg.cy.resize(signature.sensorData().cameraModels().size());
00627 msg.localTransform.resize(signature.sensorData().cameraModels().size());
00628 for(unsigned int i=0; i<signature.sensorData().cameraModels().size(); ++i)
00629 {
00630 msg.fx[i] = signature.sensorData().cameraModels()[i].fx();
00631 msg.fy[i] = signature.sensorData().cameraModels()[i].fy();
00632 msg.cx[i] = signature.sensorData().cameraModels()[i].cx();
00633 msg.cy[i] = signature.sensorData().cameraModels()[i].cy();
00634 transformToGeometryMsg(signature.sensorData().cameraModels()[i].localTransform(), msg.localTransform[i]);
00635 }
00636 }
00637 else if(signature.sensorData().stereoCameraModel().isValidForProjection())
00638 {
00639 msg.fx.push_back(signature.sensorData().stereoCameraModel().left().fx());
00640 msg.fy.push_back(signature.sensorData().stereoCameraModel().left().fy());
00641 msg.cx.push_back(signature.sensorData().stereoCameraModel().left().cx());
00642 msg.cy.push_back(signature.sensorData().stereoCameraModel().left().cy());
00643 msg.baseline = signature.sensorData().stereoCameraModel().baseline();
00644 msg.localTransform.resize(1);
00645 transformToGeometryMsg(signature.sensorData().stereoCameraModel().left().localTransform(), msg.localTransform[0]);
00646 }
00647
00648
00649 msg.wordIds = uKeys(signature.getWords());
00650 msg.wordKpts.resize(signature.getWords().size());
00651 int index = 0;
00652 for(std::multimap<int, cv::KeyPoint>::const_iterator jter=signature.getWords().begin();
00653 jter!=signature.getWords().end();
00654 ++jter)
00655 {
00656 keypointToROS(jter->second, msg.wordKpts.at(index++));
00657 }
00658
00659 if(signature.getWords3().size() && signature.getWords3().size() == signature.getWords().size())
00660 {
00661 pcl::PointCloud<pcl::PointXYZ> cloud;
00662 cloud.resize(signature.getWords3().size());
00663 index = 0;
00664 for(std::multimap<int, cv::Point3f>::const_iterator jter=signature.getWords3().begin();
00665 jter!=signature.getWords3().end();
00666 ++jter)
00667 {
00668 cloud[index].x = jter->second.x;
00669 cloud[index].y = jter->second.y;
00670 cloud[index++].z = jter->second.z;
00671 }
00672 pcl::toROSMsg(cloud, msg.wordPts);
00673 }
00674 else if(signature.getWords3().size())
00675 {
00676 ROS_ERROR("Words 2D and words 3D must have the same size (%d vs %d)!",
00677 (int)signature.getWords().size(),
00678 (int)signature.getWords3().size());
00679 }
00680 }
00681
00682 rtabmap::Signature nodeInfoFromROS(const rtabmap_ros::NodeData & msg)
00683 {
00684 rtabmap::Signature s(
00685 msg.id,
00686 msg.mapId,
00687 msg.weight,
00688 msg.stamp,
00689 msg.label,
00690 transformFromPoseMsg(msg.pose),
00691 transformFromPoseMsg(msg.groundTruthPose));
00692 return s;
00693 }
00694 void nodeInfoToROS(const rtabmap::Signature & signature, rtabmap_ros::NodeData & msg)
00695 {
00696
00697 msg.id = signature.id();
00698 msg.mapId = signature.mapId();
00699 msg.weight = signature.getWeight();
00700 msg.stamp = signature.getStamp();
00701 msg.label = signature.getLabel();
00702 transformToPoseMsg(signature.getPose(), msg.pose);
00703 transformToPoseMsg(signature.getGroundTruthPose(), msg.groundTruthPose);
00704 }
00705
00706 rtabmap::OdometryInfo odomInfoFromROS(const rtabmap_ros::OdomInfo & msg)
00707 {
00708 rtabmap::OdometryInfo info;
00709 info.lost = msg.lost;
00710 info.matches = msg.matches;
00711 info.features = msg.features;
00712 info.inliers = msg.inliers;
00713 info.localMapSize = msg.localMapSize;
00714 info.timeEstimation = msg.timeEstimation;
00715 info.variance = msg.variance;
00716 info.timeParticleFiltering = msg.timeParticleFiltering;
00717 info.stamp = msg.stamp;
00718 info.interval = msg.interval;
00719 info.distanceTravelled = msg.distanceTravelled;
00720
00721 info.type = msg.type;
00722
00723 UASSERT(msg.wordsKeys.size() == msg.wordsValues.size());
00724 for(unsigned int i=0; i<msg.wordsKeys.size(); ++i)
00725 {
00726 info.words.insert(std::make_pair(msg.wordsKeys[i], keypointFromROS(msg.wordsValues[i])));
00727 }
00728
00729 info.wordMatches = msg.wordMatches;
00730 info.wordInliers = msg.wordInliers;
00731
00732 info.refCorners = points2fFromROS(msg.refCorners);
00733 info.newCorners = points2fFromROS(msg.newCorners);
00734 info.cornerInliers = msg.cornerInliers;
00735
00736 info.transform = transformFromGeometryMsg(msg.transform);
00737 info.transformFiltered = transformFromGeometryMsg(msg.transformFiltered);
00738
00739 UASSERT(msg.localMapKeys.size() == msg.localMapValues.size());
00740 for(unsigned int i=0; i<msg.localMapKeys.size(); ++i)
00741 {
00742 info.localMap.insert(std::make_pair(msg.localMapKeys[i], point3fFromROS(msg.localMapValues[i])));
00743 }
00744
00745 return info;
00746 }
00747
00748 void odomInfoToROS(const rtabmap::OdometryInfo & info, rtabmap_ros::OdomInfo & msg)
00749 {
00750 msg.lost = info.lost;
00751 msg.matches = info.matches;
00752 msg.features = info.features;
00753 msg.inliers = info.inliers;
00754 msg.localMapSize = info.localMapSize;
00755 msg.timeEstimation = info.timeEstimation;
00756 msg.variance = info.variance;
00757 msg.timeParticleFiltering = info.timeParticleFiltering;
00758 msg.stamp = info.stamp;
00759 msg.interval = info.interval;
00760 msg.distanceTravelled = info.distanceTravelled;
00761
00762 msg.type = info.type;
00763
00764 msg.wordsKeys = uKeys(info.words);
00765 keypointsToROS(uValues(info.words), msg.wordsValues);
00766
00767 msg.wordMatches = info.wordMatches;
00768 msg.wordInliers = info.wordInliers;
00769
00770 points2fToROS(info.refCorners, msg.refCorners);
00771 points2fToROS(info.newCorners, msg.newCorners);
00772 msg.cornerInliers = info.cornerInliers;
00773
00774 transformToGeometryMsg(info.transform, msg.transform);
00775 transformToGeometryMsg(info.transformFiltered, msg.transformFiltered);
00776
00777 msg.localMapKeys = uKeys(info.localMap);
00778 points3fToROS(uValues(info.localMap), msg.localMapValues);
00779
00780 }
00781
00782 }