pl-svo在ROS下运行笔记
一、程序更改的思路(参考svo_ros的做法):
1.在ROS下将pl-svo链接成库需要更改相应的CMakeLists.txt文件,添加package.xml文件;
2.注册一个ROS节点使用svo那个ATAN的数据集测试pl-svo;
3.显示部分也是参考svo_ros(visualizer.cpp)并进行相应简化(不必链接成库);
4.程序运行时参数要改(亲测svo的两个参数文件(vo_accurate.yaml,vo_fast.yaml)并不适用于pl-svo,不知道如何选择参数,使用的默认值);
二、具体代码和遇到的问题
1.将pl-svo链接成ROS下的库(change in CMakeLists.txt)
SET(USE_ROS true)
...
...
IF(USE_ROS)
FIND_PACKAGE(catkin REQUIRED COMPONENTS roscpp roslib cmake_modules vikit_common vikit_ros)
catkin_package(
DEPENDS Eigen OpenCV Sophus Boost fast linedesc
CATKIN_DEPENDS roscpp roslib vikit_common vikit_ros
INCLUDE_DIRS include
LIBRARIES plsvo
)
ELSE()
FIND_PACKAGE(vikit_common REQUIRED)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
ENDIF()
...
之后,我遇到一个问题,pl-svo找不到Line_Descript了
终端提示如下(大概是这样,记不清楚了):cannot find file named Findlinedesc.cmake or linedescConfig.cmake ...
解决:
(1)将line_descript链接成SHARED LIBRARIES,重新编译
add_library( linedesc SHARED ${all_source_files} )
(2)做法1没有用的话,可以尝试生成.cmake文件,参考fast的做法在line_descript里的CMakeLists.txt文件添加如下指令
GET_TARGET_PROPERTY( FULL_LIBRARY_NAME ${PROJECT_NAME} LOCATION )
SET(linedesc_LIBRARIES ${FULL_LIBRARY_NAME} )
SET(linedesc_LIBRARY_DIR ${PROJECT_BINARY_DIR} )
SET(linedesc_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include")
#生成linedescConfig.cmake文件的指令
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/linedescConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/linedescConfig.cmake @ONLY IMMEDIATE )
export( PACKAGE linedesc )
并创建文件linedescConfig.cmake.in,文件内容如下:
#######################################################
# linedesc source dir
set( linedesc_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@") #######################################################
# linedesc build dir
set( linedesc_DIR "@CMAKE_CURRENT_BINARY_DIR@") #######################################################
set( linedesc_INCLUDE_DIR "@linedesc_INCLUDE_DIR@" )
set( linedesc_INCLUDE_DIRS "@linedesc_INCLUDE_DIR@" ) set( linedesc_LIBRARIES "@linedesc_LIBRARIES@" )
set( linedesc_LIBRARY "@linedesc_LIBRARIES@" ) set( linedesc_LIBRARY_DIR "@linedesc_LIBRARY_DIR@" )
set( linedesc_LIBRARY_DIRS "@linedesc_LIBRARY_DIR@" )
最后重新编译一下line_descript,在build文件夹中就生成了linedescConfig.cmake文件。
然后在pl-svo的CMakeLists.txt中作相应更改:
#add:
FIND_PACKAGE(linedesc REQUIRED)
...
...
INCLUDE_DIRECTORIES(
...
...
# delete:
#${PROJECT_SOURCE_DIR}/3rdparty/line_descriptor/include/
#add:
${linedesc_INCLUDE_DIRS}
)
添加相应的package.xml文件,在ROS的worksapce下使用catkin_make即可编译成功,生成pl-svo的共享库。
心得: packagenameConfig.cmake文件存储的是已安装的程序包的绝对安装路径。
2.创建一个ROS下的程序包测试上一步生成的pl-svo的库
catkin_create_pkg plsvo_ros ...
下面写程序
先说思路:
(1)照例先注册好ROS的node,定义nodehandle;
(2)然后读取ATAN的yaml文件加载相机的参数使用vikit工具定义相机;
(3)定义一个VoNode类作为pl-svo算法部分的接口,它的属性和子函数大致有plsvo::FrameHandlerMono*,vk::AbstractCamera*,void imgcb(const sensor_msgs::ImageConstPtr&);
(4)订阅rosbag发布的图像,在回调函数中调用plsvo::FrameHandleMono::addImage()进行解算;
先上部分代码:
//plsvo interface
class VoNode
{
public:
//Frame handle
FrameHandlerMono* vo_;
//camera
vk::AbstractCamera* cam_;
//show in rviz
plsvo::Visualizer visualizer_; VoNode();
//initialize by camera
VoNode(vk::AbstractCamera *cam_);
~VoNode();
//function for image callback
void imgCb(const sensor_msgs::ImageConstPtr& msg);
}; ...
//The body of VoNode::imgCb()
void VoNode::imgCb(const sensor_msgs::ImageConstPtr& msg)
{
//read image
cv::Mat img;
try {
img = cv_bridge::toCvShare(msg, "mono8")->image;
} catch (cv_bridge::Exception& e) {
ROS_ERROR("cv_bridge exception: %s", e.what());
} //Compute
vo_->addImage(img, msg->header.stamp.toSec());
//Show
visualizer_.publishMinimal(img,vo_,msg->header.stamp.toSec());
//print in terminal when run vo
if (vo_->lastFrame() != NULL){
std::cout << "Frame-Id: "<< vo_->lastFrame()->id_ << " \t"
<<"#PointFeatures: "<<vo_->lastNumPtObservations()<<" \t"
<<"#LineFeatures: "<<vo_->lastNumLsObservations()<< " \t"
<<"Proc. Time: "<<vo_->lastProcessingTime()* << "ms" << std::endl << std::endl;
}
} ...
int main(int argc, char **argv)
{
//ROS initialize
ros::init(argc, argv, "plsvo");
ros::NodeHandle nh; YAML::Node dset_config = YAML::LoadFile("The path to parameter.");
...
//create VoNode
plsvo::VoNode vo_node(cam_atan_und);
//subscribe the topic publish image.
image_transport::ImageTransport it(nh);
image_transport::Subscriber it_sub = it.subscribe("camera/image_raw",, &plsvo::VoNode::imgCb, &vo_node);
... }
plsvo_node.cpp
3.显示部分(visualization.h,visualization.cpp)
功能:
把pl-svo每一帧跟踪的特征点显示在图片上;
在rviz里用tf表示pl-svo解算的位姿;
Path的话还没加进去(应该可以),下一步可以加进去跟GroundTruth对比一下;
相应代码:
...
...
// Publish features in image.
if(pub_images_.getNumSubscribers()>){
const int scale=(>>img_pub_level_);
cv::Mat img_rgb(vo->lastFrame()->img_pyr_[img_pub_level_].size(), CV_8UC3);
cv::cvtColor(vo->lastFrame()->img_pyr_[img_pub_level_], img_rgb, CV_GRAY2RGB);
if(img_pub_level_ == )
{
std::vector<cv::Point2f> points2d;
for(std::list<PointFeat*>::iterator it=vo->lastFrame()->pt_fts_.begin();it!=vo->lastFrame()->pt_fts_.end();++it){
//if((*it)->type == Feature::EDGELET)
cv::rectangle(img_rgb,
cv::Point2f((*it)->px[]-,
(*it)->px[]-),
cv::Point2f((*it)->px[]+,
(*it)->px[]+),
cv::Scalar(,,),
CV_FILLED);
}
}
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());
} ...
//Publish tansform tf and rotation.
if(vo->stage() ==FrameHandlerBase::STAGE_DEFAULT_FRAME)
{
Quaterniond q;
Vector3d p;
Matrix<double,,> Cov;
// publish world in cam frame
SE3 T_cam_from_world(vo->lastFrame()->T_f_w_* T_world_from_vision_.inverse());
q = Quaterniond(T_cam_from_world.rotation_matrix());
p = T_cam_from_world.translation();
Cov = vo->lastFrame()->Cov_;
geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped);
msg_pose->header=header_msg;
msg_pose->pose.pose.position.x=p[];
msg_pose->pose.pose.position.y=p[];
msg_pose->pose.pose.position.z=p[]; 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=;i<;++i)
msg_pose->pose.covariance[i]=Cov(i%,i/);
pub_pose_.publish(msg_pose);
br_.sendTransform(tf::StampedTransform(tf::Transform(tf::Quaternion(q.x(),q.y(),q.z(),q.w()),
tf::Vector3(p[],p[],p[])),
ros::Time(timestamp),
"world",
"cam"));
}
...
...
visualization.cpp
只要在上一步的imgCb()中调用发布带有特征的图像,tf,位姿的函数,就可以在rviz中显示pl-svo跟踪和解算的结果。
没遇到过的bug:

这是因为形参对象plsvo::FrameHandlerMono是const的,而它的属性是非const的,当使用'vo->lastFrame()'时,gcc就会报错
两种解决方法: (1)形参改为非const的; (2)添加形参;
4.程序运行时参数
最后一个问题,也是还没有解决的问题,由于还没有认真阅读pl-svo的代码,github上也只提供了相机的参数,所以很多参数没有自己设置,使用了
config.cpp中的默认值。
下一步,先想办法在rviz里画下path跟GroundTruth对比一下;然后读读程序,看参数还能不能改。
最后,目前的运行效果图:

pl-svo在ROS下运行笔记的更多相关文章
- SVO在ROS下的配置与运行
最近在做实验的时候,需要配置SVO,下面讲讲其中的过程以及遇到的问题: 首先说明配置环境:Ubuntu 14.04 + ROS indigo,ROS的安装我参考了ROS的官网上给出的教程:http:/ ...
- ubuntu16.04下用笔记本摄像头和ROS编译运行ORB_SLAM2的单目AR例程
要编译ORB_SLAM2的ROS例程首先需要安装ROS,以及在ROS下安装usb_cam驱动并调用,最后搭建ORB_SLAM2. 1.ROS的安装 我的电脑安装的是ubuntu16.04系统,所以我安 ...
- .NET Core学习笔记(1)——在Linux下运行Console APP
都说.NET Core可以跨平台,说实话Linux咱也不太懂,咱也不敢问.怎样把一个简单的Console App在Linux下跑起来,真是费了我一番功夫.特做此篇以供指北. .NET Core的大饼我 ...
- LSD-SLAM深入学习(1)-基本介绍与ros下的安装
前言 借鉴来自RGB-D数据处理的两种方法-基于特征与基于整体的,同样可以考虑整个图片的匹配,而不是只考虑特征点的…… 一般这种稠密的方法需要很大的计算量,DTAM: Dense tracking a ...
- ros下多机器人系统(1)
multi-robot system 经过两个多月的ros学习,对ros的认识有了比较深入的了解,本篇博客主要记录在ros下开发多机器人系统以及对ros更深入的开发.本篇博客是假定读者已经学习完了全部 ...
- ZED 相机 && ORB-SLAM2安装环境配置与ROS下的调试
注:1. 对某些地方进行了更新(红色标注),以方便进行配置. 2. ZED ROS Wrapper官方github已经更新,根据描述新的Wrapper可能已经不适用与Ros Indigo了,如果大家想 ...
- Rplidar学习(四)—— ROS下进行rplidar雷达数据采集源码分析
一.子函数分析 1.发布数据子函数 (1)雷达数据数据类型 Header header # timestamp in the header is the acquisition time of # t ...
- ros下基于百度语音的,语音识别和语音合成
代码地址如下:http://www.demodashi.com/demo/13153.html 概述: 本demo是ros下基于百度语音的,语音识别和语音合成,能够实现文字转语音,语音转文字的功能. ...
- Faster_Rcnn在windows下运行踩坑总结
Faster_Rcnn在windows下运行踩坑总结 20190524 今天又是元气满满的一天! 1.代码下载 2.编译 3.下载数据集 4.下载pre-train Model 5.运行train ...
随机推荐
- css animate
AniX https://a-jie.github.io/AniX/
- 1. cocos creator 连接服务端
客户端向服务端发送 请求: this.network.send("/////",) 上面这段代码要写在logic.js中,(关于服务端的东西全部扔到logic中): ////中写 ...
- zoj 1649 bfs
Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M ...
- face_recognition
人脸定位import face_recognition image = face_recognition.load_image_file("your_file.jpg") face ...
- magento 1.9 上传后图片前后台无法正常显示
1.上传后图片不显示,设置 允许 flash 2.保证php 执行是内存大小至少为为128M,多种方式设置,这里以init_set为例子,在index.php 加入下面一行代码,根据情况而定 ini_ ...
- .Net 一开始就不应该搞 .Net Core
.Net 一开始就不应该搞 .Net Core, java 跨平台 是 java 选择的道路, .Net 应该发挥 和 平台 紧密结合 的 优势 . 如 控件哥 所说, 微软 应该把 IIS ...
- [转载]使用QTP测试Windows对象
Desktop对象的使用: 通过Desktop对象,可以访问Windows的桌面顶层对象.Desktop对象包括CaptureBitmap.ChildObjects.RunAnalog方法. (1) ...
- [ZZ] MATLAB曲线拟合
MATLAB曲线拟合 http://blog.sina.com.cn/s/blog_5db2286f0100enlo.html MATLAB软件提供了基本的曲线拟合函数的命令: 多项式函数拟合: a ...
- mysql 8.0 主从复制的优化
mysql 8.0复制改进一简介: 基于GTID下的并行复制,本文不考虑MGR架构二 主要特性 1 基于writeset的下的改进型并行复制 我在之前的一篇文章关于并行复制中详细的介绍了关 ...
- 如何一步一步新建一个Owin项目
打开VS2015,新建Web应用程序,命名为OwinWeb(名字随意). 在弹出的“新建ASP.NET项目”窗口中选择“Empty”模板,“为以下项添加文件夹和核心引用”处全不选.点击确定. 创建完后 ...