diff --git a/svo_ros/include/svo_ros/visualizer.h b/svo_ros/include/svo_ros/visualizer.h
index 5cffa0e..aa6146a 100644
--- a/svo_ros/include/svo_ros/visualizer.h
+++ b/svo_ros/include/svo_ros/visualizer.h
@@ -42,8 +42,7 @@ class FrameHandlerMono;
typedef boost::shared_ptr FramePtr;
-/// This class bundles all functions to publish visualisation messages,
-/// trace data and output debugging information.
+/// This class bundles all functions to publish visualisation messages.
class Visualizer
{
public:
@@ -59,15 +58,30 @@ public:
ros::Publisher pub_dense_;
image_transport::Publisher pub_images_;
tf::TransformBroadcaster br_;
+ bool publish_world_in_cam_frame_;
SE3 T_world_from_vision_;
Visualizer();
+
~Visualizer() {};
- void visualizeMarkers(const FramePtr& frame, const set& core_kfs, const Map& map);
- void publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono& slam, const double timestamp);
+
+ void publishMinimal(
+ const cv::Mat& img,
+ const FramePtr& frame,
+ const FrameHandlerMono& slam,
+ const double timestamp);
+
+ void visualizeMarkers(
+ const FramePtr& frame,
+ const set& core_kfs,
+ const Map& map);
+
void publishMapRegion(set frames);
+
void removeDeletedPts(const Map& map);
+
void displayKeyframeWithMps(const FramePtr& frame, int ts);
+
void exportToDense(const FramePtr& frame);
};
diff --git a/svo_ros/src/visualizer.cpp b/svo_ros/src/visualizer.cpp
index f952fa8..32ac3e1 100644
--- a/svo_ros/src/visualizer.cpp
+++ b/svo_ros/src/visualizer.cpp
@@ -44,7 +44,8 @@ Visualizer() :
img_pub_level_(vk::getParam("svo/image_publishing_level", 0)),
img_pub_nth_(vk::getParam("svo/publish_every_nth_img", 1)),
dense_pub_nth_(vk::getParam("svo/publish_every_nth_dense_input", 1)),
- T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero())
+ T_world_from_vision_(Matrix3d::Identity(), Vector3d::Zero()),
+ publish_world_in_cam_frame_(vk::getParam("svo/publish_world_in_cam_frame", true))
{
// Init ROS Marker Publishers
pub_frames_ = pnh_.advertise("keyframes", 10);
@@ -58,25 +59,11 @@ Visualizer() :
pub_images_ = it.advertise("image", 10);
}
-void Visualizer::
-visualizeMarkers(const FramePtr& frame, const set& core_kfs, const Map& map)
-{
- if(frame != NULL)
- {
- // publish camera pose tf
- vk::output_helper::publishTfTransform(frame->T_f_w_, ros::Time(frame->timestamp_), "cam_pos", "world", br_);
- if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0)
- {
- vk::output_helper::publishHexacopterMarker(pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_), 1, 0, 0.3, Vector3d(0.,0.,1.));
- vk::output_helper::publishPointMarker(pub_points_, frame->pos(), "trajectory", ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5));
- publishMapRegion(core_kfs);
- removeDeletedPts(map);
- }
- }
-}
-
-void Visualizer::
-publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono& slam, const double timestamp)
+void Visualizer::publishMinimal(
+ const cv::Mat& img,
+ const FramePtr& frame,
+ const FrameHandlerMono& slam,
+ const double timestamp)
{
++trace_id_;
std_msgs::Header header_msg;
@@ -84,7 +71,7 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono
header_msg.seq = trace_id_;
header_msg.stamp = ros::Time(timestamp);
- // publish svo info msgs
+ // publish info msg.
if(pub_info_.getNumSubscribers() > 0)
{
svo_msgs::Info msg_info;
@@ -102,17 +89,31 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono
pub_info_.publish(msg_info);
}
- // publish pyramid-image every nth-frame
- if(frame != NULL && img_pub_nth_ > 0
- && trace_id_%img_pub_nth_ == 0 && pub_images_.getNumSubscribers() > 0)
+ if(frame == 0)
+ {
+ if(pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_PAUSED)
+ {
+ // Display image when slam is not running.
+ cv_bridge::CvImage img_msg;
+ img_msg.header.stamp = ros::Time::now();
+ img_msg.header.frame_id = "/image";
+ img_msg.image = img;
+ img_msg.encoding = sensor_msgs::image_encodings::MONO8;
+ pub_images_.publish(img_msg.toImageMsg());
+ }
+ return;
+ }
+
+ // Publish pyramid-image every nth-frame.
+ if(img_pub_nth_ > 0 && trace_id_%img_pub_nth_ == 0 && pub_images_.getNumSubscribers() > 0)
{
const int scale = (1<img_pyr_[img_pub_level_].size(), CV_8UC3);
cv::cvtColor(frame->img_pyr_[img_pub_level_], img_rgb, CV_GRAY2RGB);
- // during initialization, draw lines
if(slam.stage() == FrameHandlerBase::STAGE_SECOND_FRAME)
{
+ // During initialization, draw lines.
const vector& px_ref(slam.initFeatureTrackRefPx());
const vector& px_cur(slam.initFeatureTrackCurPx());
for(vector::const_iterator it_ref=px_ref.begin(), it_cur=px_cur.begin();
@@ -122,7 +123,6 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono
cv::Point2f(it_ref->x/scale, it_ref->y/scale), cv::Scalar(0,255,0), 2);
}
- // draw features on frame
if(img_pub_level_ == 0)
for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it)
cv::rectangle(img_rgb,
@@ -142,51 +142,74 @@ publishMinimal(const cv::Mat& img, const FramePtr& frame, const FrameHandlerMono
cv::Point2f((*it)->px[0]/scale, (*it)->px[1]/scale),
cv::Scalar(0,255,0), CV_FILLED);
- // publish image
cv_bridge::CvImage img_msg;
img_msg.header = header_msg;
img_msg.image = img_rgb;
img_msg.encoding = sensor_msgs::image_encodings::BGR8;
pub_images_.publish(img_msg.toImageMsg());
}
- else if(frame == NULL && pub_images_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_PAUSED)
- {
- // display image when slam is not running
- cv_bridge::CvImage img_msg;
- img_msg.header.stamp = ros::Time::now();
- img_msg.header.frame_id = "/image";
- img_msg.image = img;
- img_msg.encoding = sensor_msgs::image_encodings::MONO8;
- pub_images_.publish(img_msg.toImageMsg());
- }
- // publish pose (camera in world frame)
- if(pub_pose_.getNumSubscribers() > 0 && frame != NULL)
+ if(pub_pose_.getNumSubscribers() > 0)
{
- // transform from vision-frame to world-frame
- SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse());
- Quaterniond q_world_from_cam(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose());
- const Vector3d& p_cam_in_world(T_world_from_cam.translation());
- Matrix Cov_in_world = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj();
-
- // publish message
+ Quaterniond q;
+ Vector3d p;
+ Matrix Cov;
+ if(publish_world_in_cam_frame_)
+ {
+ // publish world in cam frame
+ SE3 T_cam_from_world(frame->T_f_w_* T_world_from_vision_);
+ q = Quaterniond(T_cam_from_world.rotation_matrix());
+ p = T_cam_from_world.translation();
+ Cov = frame->Cov_;
+ }
+ else
+ {
+ // publish cam in world frame
+ SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.inverse());
+ q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose());
+ p = T_world_from_cam.translation();
+ Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj();
+ }
geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped);
msg_pose->header = header_msg;
- msg_pose->pose.pose.position.x = p_cam_in_world[0];
- msg_pose->pose.pose.position.y = p_cam_in_world[1];
- msg_pose->pose.pose.position.z = p_cam_in_world[2];
- msg_pose->pose.pose.orientation.x = q_world_from_cam.x();
- msg_pose->pose.pose.orientation.y = q_world_from_cam.y();
- msg_pose->pose.pose.orientation.z = q_world_from_cam.z();
- msg_pose->pose.pose.orientation.w = q_world_from_cam.w();
+ msg_pose->pose.pose.position.x = p[0];
+ msg_pose->pose.pose.position.y = p[1];
+ msg_pose->pose.pose.position.z = p[2];
+ msg_pose->pose.pose.orientation.x = q.x();
+ msg_pose->pose.pose.orientation.y = q.y();
+ msg_pose->pose.pose.orientation.z = q.z();
+ msg_pose->pose.pose.orientation.w = q.w();
for(size_t i=0; i<36; ++i)
- msg_pose->pose.covariance[i] = Cov_in_world(i%6, i/6);
+ msg_pose->pose.covariance[i] = Cov(i%6, i/6);
pub_pose_.publish(msg_pose);
}
}
-void Visualizer::
-publishMapRegion(set frames)
+void Visualizer::visualizeMarkers(
+ const FramePtr& frame,
+ const set& core_kfs,
+ const Map& map)
+{
+ if(frame != NULL)
+ {
+ vk::output_helper::publishTfTransform(
+ frame->T_f_w_*T_world_from_vision_.inverse(),
+ ros::Time(frame->timestamp_), "cam_pos", "world", br_);
+ if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0)
+ {
+ vk::output_helper::publishHexacopterMarker(
+ pub_frames_, "cam_pos", "cams", ros::Time(frame->timestamp_),
+ 1, 0, 0.3, Vector3d(0.,0.,1.));
+ vk::output_helper::publishPointMarker(
+ pub_points_, T_world_from_vision_*frame->pos(), "trajectory",
+ ros::Time::now(), trace_id_, 0, 0.006, Vector3d(0.,0.,0.5));
+ publishMapRegion(core_kfs);
+ removeDeletedPts(map);
+ }
+ }
+}
+
+void Visualizer::publishMapRegion(set frames)
{
if(pub_points_.getNumSubscribers() > 0)
{
@@ -196,8 +219,7 @@ publishMapRegion(set frames)
}
}
-void Visualizer::
-removeDeletedPts(const Map& map)
+void Visualizer::removeDeletedPts(const Map& map)
{
if(pub_points_.getNumSubscribers() > 0)
{
@@ -206,11 +228,13 @@ removeDeletedPts(const Map& map)
}
}
-void Visualizer::
-displayKeyframeWithMps(const FramePtr& frame, int ts)
+void Visualizer::displayKeyframeWithMps(const FramePtr& frame, int ts)
{
// publish keyframe
- vk::output_helper::publishFrameMarker(pub_frames_, frame->T_f_w_.inverse().rotation_matrix(), frame->pos(), "kfs", ros::Time::now(), frame->id_*10, 0, 0.015);
+ SE3 T_world_cam(T_world_from_vision_*frame->T_f_w_.inverse());
+ vk::output_helper::publishFrameMarker(
+ pub_frames_, T_world_cam.rotation_matrix(),
+ T_world_cam.translation(), "kfs", ros::Time::now(), frame->id_*10, 0, 0.015);
// publish point cloud and links
for(Features::iterator it=frame->fts_.begin(); it!=frame->fts_.end(); ++it)
@@ -221,13 +245,14 @@ displayKeyframeWithMps(const FramePtr& frame, int ts)
if((*it)->point->last_published_ts_ == ts)
continue;
- vk::output_helper::publishPointMarker(pub_points_, (*it)->point->pos_, "pts", ros::Time::now(), (*it)->point->id_, 0, 0.005, Vector3d(1.0, 0., 1.0));
+ vk::output_helper::publishPointMarker(
+ pub_points_, T_world_from_vision_*(*it)->point->pos_, "pts",
+ ros::Time::now(), (*it)->point->id_, 0, 0.005, Vector3d(1.0, 0., 1.0));
(*it)->point->last_published_ts_ = ts;
}
}
-void Visualizer::
-exportToDense(const FramePtr& frame)
+void Visualizer::exportToDense(const FramePtr& frame)
{
// publish air_ground_msgs
if(frame != NULL && dense_pub_nth_ > 0
@@ -252,8 +277,8 @@ exportToDense(const FramePtr& frame)
if((*it)->point==NULL)
continue;
Vector3d pos = frame->T_f_w_*(*it)->point->pos_;
- min_z = min(pos[2], min_z);
- max_z = max(pos[2], max_z);
+ min_z = fmin(pos[2], min_z);
+ max_z = fmax(pos[2], max_z);
}
msg.min_depth = (float) min_z;
msg.max_depth = (float) max_z;