Skip to content

Instantly share code, notes, and snippets.

@xaxxontech
Last active June 25, 2018 03:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xaxxontech/073ed0bde34fd91638007d2e9869a839 to your computer and use it in GitHub Desktop.
Save xaxxontech/073ed0bde34fd91638007d2e9869a839 to your computer and use it in GitHub Desktop.
ros_rgbd.cc modified to publish ROS pose msg (revised form joshnroy pull request #443)
/**
* This file is part of ORB-SLAM2.
*
* Copyright (C) 2014-2016 Raúl Mur-Artal <raulmur at unizar dot es> (University of Zaragoza)
* For more information see <https://github.com/raulmur/ORB_SLAM2>
*
* ORB-SLAM2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ORB-SLAM2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ORB-SLAM2. If not, see <http://www.gnu.org/licenses/>.
*/
#include<iostream>
#include<algorithm>
#include<fstream>
#include<chrono>
#include<ros/ros.h>
#include <cv_bridge/cv_bridge.h>
#include <message_filters/subscriber.h>
#include <message_filters/time_synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>
#include<opencv2/core/core.hpp>
#include"../../../include/System.h"
#include"../../../include/MapPoint.h"
//#include "sensor_msgs/PointCloud.h"
#include "geometry_msgs/PoseStamped.h"
//#include "geometry_msgs/Point32.h"
#include "tf/transform_datatypes.h"
#include <tf/transform_broadcaster.h>
using namespace std;
using namespace tf;
class ImageGrabber
{
public:
ImageGrabber(ORB_SLAM2::System* pSLAM):mpSLAM(pSLAM){}
void GrabRGBD(const sensor_msgs::ImageConstPtr& msgRGB,const sensor_msgs::ImageConstPtr& msgD, ros::Publisher pos_pub);
ORB_SLAM2::System* mpSLAM;
};
int main(int argc, char **argv)
{
ros::init(argc, argv, "RGBD");
ros::start();
if(argc != 3)
{
cerr << endl << "Usage: rosrun ORB_SLAM2 RGBD path_to_vocabulary path_to_settings" << endl;
ros::shutdown();
return 1;
}
// Create SLAM system. It initializes all system threads and gets ready to process frames.
ORB_SLAM2::System SLAM(argv[1],argv[2],ORB_SLAM2::System::RGBD,true);
ImageGrabber igb(&SLAM);
ros::NodeHandle nh;
ros::Rate loop_rate(30);
message_filters::Subscriber<sensor_msgs::Image> rgb_sub(nh, "/camera/rgb/image_raw", 1);
message_filters::Subscriber<sensor_msgs::Image> depth_sub(nh, "camera/depth_registered/image_raw", 1);
//ros::Publisher cloud_pub = nh.advertise<sensor_msgs::PointCloud>("/slam/pointcloud", 1);
ros::Publisher pos_pub = nh.advertise<geometry_msgs::PoseStamped>("/slam/pos", 1);
typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image> sync_pol;
message_filters::Synchronizer<sync_pol> sync(sync_pol(10), rgb_sub,depth_sub);
sync.registerCallback(boost::bind(&ImageGrabber::GrabRGBD,&igb,_1,_2, pos_pub));
while (ros::ok()) {
// Spin
ros::spinOnce();
// Sleep
loop_rate.sleep();
}
// Stop all threads
SLAM.Shutdown();
// Save camera trajectory
SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");
ros::shutdown();
return 0;
}
void ImageGrabber::GrabRGBD(const sensor_msgs::ImageConstPtr& msgRGB,const sensor_msgs::ImageConstPtr& msgD, ros::Publisher pos_pub)
{
// Copy the ros image message to cv::Mat.
cv_bridge::CvImageConstPtr cv_ptrRGB;
try
{
cv_ptrRGB = cv_bridge::toCvShare(msgRGB);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
cv_bridge::CvImageConstPtr cv_ptrD;
try
{
cv_ptrD = cv_bridge::toCvShare(msgD);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
cv::Mat pose = mpSLAM->TrackRGBD(cv_ptrRGB->image,cv_ptrD->image,cv_ptrRGB->header.stamp.toSec());
// CAMERA POSE
if (pose.empty()) {
return;
}
// transform into right handed camera frame
tf::Matrix3x3 rh_cameraPose( - pose.at<float>(0,0), pose.at<float>(0,1), pose.at<float>(0,2),
- pose.at<float>(1,0), pose.at<float>(1,1), pose.at<float>(1,2),
pose.at<float>(2,0), - pose.at<float>(2,1), - pose.at<float>(2,2));
tf::Vector3 rh_cameraTranslation( pose.at<float>(0,3),pose.at<float>(1,3), - pose.at<float>(2,3) );
//rotate 270deg about z and 270deg about x
// tf::Matrix3x3 rotation270degZX( 0, 0, 1,
// -1, 0, 0,
// 0,-1, 0);
//publish right handed, x forward, y right, z down (NED)
tf::Quaternion q;
rh_cameraPose.getRotation(q);
geometry_msgs::PoseStamped p;
p.header.frame_id = "world";
p.pose.position.x = rh_cameraTranslation[0];
p.pose.position.y = rh_cameraTranslation[1];
p.pose.position.z = rh_cameraTranslation[2];
p.pose.orientation.x = q[0];
p.pose.orientation.y = q[1];
p.pose.orientation.z = q[2];
p.pose.orientation.w = q[3];
pos_pub.publish(p);
// POINT CLOUD
//sensor_msgs::PointCloud cloud;
//cloud.header.frame_id = "world";
//std::vector<geometry_msgs::Point32> geo_points;
//std::vector<ORB_SLAM2::MapPoint*> points = mpSLAM->GetTrackedMapPoints();
//cout << points.size() << endl;
//for (std::vector<int>::size_type i = 0; i != points.size(); i++) {
//if (points[i]) {
//cv::Mat coords = points[i]->GetWorldPos();
//geometry_msgs::Point32 pt;
//pt.x = coords.at<float>(0);
//pt.y = coords.at<float>(1);
//pt.z = coords.at<float>(2);
//geo_points.push_back(pt);
//} else {
//}
//}
//cout << geo_points.size() << endl;
//cloud.points = geo_points;
//cloud_pub.publish(cloud);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment