Ubuntu16.04,ros Kinetic

最近几次遇到的问题都是,给你一个写好的ros node文件,没有给你其他的东西,你如何编译它?

以从ros中提取rgb图像和深度图像为例,示例源代码extract_images.cpp如下:

/* Este es un nodo de ROS Indigo para guardar imagenes de /camera/depth_registered/image_rect_raw
* y de /camera/rgb/color/image_rect_raw de un Turtlebot1 para luego procesarlas con otro programa.
* Las de profundidad se guardan como unsigned int de 16 bits
* y 1 canal, las de color se guardan como unsigned int de 8 bits en 3 canales.
* Se utiliza un suscriptor sincronizado para guardar el par de imagenes que estén más
* cercanas en el tiempo.
* LAS IMAGENES SE GUARDAN ADONDE SE EJECUTE EL NODO.
* ---------------------------------------------------------
* Creado por Fabricio Emder y Pablo Aguado en el 2016 */ /* This is a ROS Indigo node for saving Turtlebot images from the /camera/depth_registered/image_rect_raw
* and /camera/rgb/color/image_rect_raw topics, for further processing outside of the program.
* Depth images are saved as 1 channel 16 bit unsigned int PNGs (CV_16UC1), and
* RGB images are saved as 3 channel 8 bit unsigned int PNGs (CV_8UC3).
* A synchronized subscriber is used, for saving the pair of images that are most closer in time.
* THE IMAGES ARE SAVED WHEREVER THE NODE IS RUN.
* Created by Fabricio Emder and Pablo Aguado - 2016
* */ #include <ros/ros.h>
#include <cv_bridge/cv_bridge.h> // OpenCV
#include <sensor_msgs/Image.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp> #include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h> /* La política de sincronización exacta NO FUNCIONA para los topics seleccionados, ya
* que la Kinect o sus drivers no los están publicando con la misma marca temporal.
* Ver más en http://wiki.ros.org/message_filters
*
* Exact sychronization policy IS NOT WORKING for the topics used, because the kinect
* is not publishing them with the same timestamp.
* See more in http://wiki.ros.org/message_filters */ //#define EXACT
#define APPROXIMATE #ifdef EXACT
#include <message_filters/sync_policies/exact_time.h>
#endif
#ifdef APPROXIMATE
#include <message_filters/sync_policies/approximate_time.h>
#endif using namespace std;
//using namespace sensor_msgs;
using namespace message_filters; // Contador para la numeración de los archivos.
// Counter for filenames.
unsigned int cnt = ; // Handler / callback
void callback( const sensor_msgs::ImageConstPtr& msg_rgb , const sensor_msgs::ImageConstPtr& msg_depth )
{
//ROS_INFO_STREAM("Adentro del callback\n");
cv_bridge::CvImagePtr img_ptr_rgb;
cv_bridge::CvImagePtr img_ptr_depth;
try{
img_ptr_depth = cv_bridge::toCvCopy(*msg_depth, sensor_msgs::image_encodings::TYPE_16UC1);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
try{
img_ptr_rgb = cv_bridge::toCvCopy(*msg_rgb, sensor_msgs::image_encodings::TYPE_8UC3);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
} cv::Mat& mat_depth = img_ptr_depth->image;
cv::Mat& mat_rgb = img_ptr_rgb->image; char file_rgb[];
char file_depth[]; sprintf( file_rgb, "%04d_rgb.png", cnt );
sprintf( file_depth, "%04d_depth.png", cnt ); vector<int> png_parameters;
png_parameters.push_back( CV_IMWRITE_PNG_COMPRESSION );
/* We save with no compression for faster processing.
* Guardamos PNG sin compresión para menor retardo. */
png_parameters.push_back( ); cv::imwrite( file_rgb , mat_rgb, png_parameters );
cv::imwrite( file_depth, mat_depth, png_parameters ); ROS_INFO_STREAM(cnt << "\n");
ROS_INFO_STREAM("Imágenes guardadas - "
"Images saved\n"); cnt++; } int main(int argc, char** argv)
{
// Initialize the ROS system and become a node.
ros::init(argc, argv, "guardar_imagenes");
ros::NodeHandle nh; message_filters::Subscriber<sensor_msgs::Image> subscriber_depth( nh , "/camera/depth_registered/hw_registered/image_rect_raw" , );
message_filters::Subscriber<sensor_msgs::Image> subscriber_rgb( nh , "/camera/rgb/image_rect_color" , ); #ifdef EXACT
typedef sync_policies::ExactTime<sensor_msgs::Image, sensor_msgs::Image> MySyncPolicy;
#endif
#ifdef APPROXIMATE
typedef sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image> MySyncPolicy;
#endif // ExactTime or ApproximateTime take a queue size as its constructor argument, hence MySyncPolicy(10)
Synchronizer<MySyncPolicy> sync(MySyncPolicy(), subscriber_rgb, subscriber_depth );
sync.registerCallback(boost::bind(&callback, _1, _2)); while(ros::ok())
{
char c; ROS_INFO_STREAM("\nIngrese 'a' para guardar un par de imágenes o 'b' para guardar 300 imágenes\n"
"Enter 'a' to save a pair of images or 'b' to automatically save 300 images\n");
cin.get(c);
cin.ignore();
c = tolower(c);
ROS_INFO_STREAM("You entered " << c << "\n"); if( c == 'a' )
{
/* Le damos el control a la función callback cuando haya imágenes.
* We give control to the callback function.*/
ros::spinOnce();
} else if( c == 'b' )
{
unsigned int cnt_init = cnt;
while( cnt - cnt_init < )
{
ros::spinOnce();
}
} else break; }
ROS_INFO_STREAM("Cerrando nodo\nClosing node\n"); return ;
}

——————现在开始我们的ros编译之旅——————

主要分为几大步:

1. 确认头文件,观察.cpp文件中,哪些属于ros内部库,哪些是外部库。示例中,除了opencv2的库是外部库,其余是内部库

2. 在工作空间中(如果没有,请按照ros tutorial新建)test_ws/src并source后,新建package,将所有内部库添加到依赖中(若此时遗漏,仍可通过修改package.xml来添加。实际效果是一样的)

$ cd ~/test/ws/src
$ catkin_create_pkg extract_images roscpp cv_bridge sensor_msgs message_filters
$ catkin_make
$ . ~/test_ws/devel/setup.bash

可查看依赖项

$ rospack depend1 extrac_images

此时只有OpenCV2的库文件没有链接

修改CMakeLists.txt

加入搜索库文件

find_package( OpenCV REQUIRED )
include_directoties( ${OpenCV_INCLUDE_DIRS} )

添加可执行文件,链接cpp文件和库,以及最重要的一点是,将可执行文件与ROS库链接,不然会出现一大堆ROS的报错

add_executable( extract_images src/extrac_iamges.cpp )

target_link_libraries( extract_images ${OpenCV_DIRS} ${catkin_LIBRARIES} )

最后再回到工作空间test_ws,catkin_make即可。

课后作业——根据这个方法,推广为将node文件加入已有的项目中,应该怎么写呢?请读者自行解决!

参考文献:

How to extract depth data fromrosbags(contains depth and RGB data) as picture frames

Installing and Configuring Your ROS Environment

Creating a ROS Package

How to compile a node file?如何编译一个节点文件?的更多相关文章

  1. Java-Runoob-高级教程-实例-环境设置实例:1.Java 实例 – 如何编译一个Java 文件?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:1.Java 实例 – 如何编译一个Java 文件? 1.返回顶部 1. Java 实例 - 如何编译 Java 文件  Java ...

  2. LeetCode OJ:Populating Next Right Pointers in Each Node(指出每一个节点的下一个右侧节点)

    Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...

  3. 手动编译一个c文件(Win7下如何使用GCC编译器)

    主要参考这篇http://jingyan.baidu.com/article/c275f6bacc0126e33c756771.html 我没找到minGW的下载地址,而是直接用codeblocks自 ...

  4. 使用javac,手动编译一个java文件的方法

    参考<Tomcat与Java Web开发技术详解>中的命令: javac -classpath c:\tomcat\lib\servlet-api.jar                  ...

  5. Linux c codeblock的使用(二):在工程中编译多个文件

    (一)前言 我们刚开始学习linux c的时候,一般都是在一个c文件里面写完所有程序,然后用gcc编译这个c文件就好了,十分简单. 但是你有没有想过,如果我们希望将不同模块的代码放到不同的c文件,然后 ...

  6. org.w3c.dom.Node.getTextContent()方法编译错误-已解决

    org.w3c.dom.Node.getTextContent()方法编译错误. 在项目的Java Build Path | Order and Export选项卡中,将JRE System Libr ...

  7. Node Server零基础——开发环境文件自动重载

    收录待用,修改转载已取得腾讯云授权 前言 在 web 前端开发中,我们会借助 Grunt.Gulp 和 Webpack 等工具的 Watch 模块去监听文件变化,那服务端应该怎么做?其实文件变化的监听 ...

  8. 第48章 MDK的编译过程及文件类型全解—零死角玩转STM32-F429系列

    第48章     MDK的编译过程及文件类型全解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.co ...

  9. 第48章 MDK的编译过程及文件类型全解

    Frm: http://www.cnblogs.com/firege/p/5806134.html 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教 ...

随机推荐

  1. [C++] 分治法之棋盘覆盖、循环赛日程表

    一.分治的基本思想 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 对于一个规模为 n 的问题,若问题可以容易地解决,则直接解决,否则将其分解为 k 个规模较小的子 ...

  2. 摘之知乎网友...PHYTIN学习

    作者:东瓜王链接:https://www.zhihu.com/question/19593179/answer/23746083来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  3. POJ 3624 Charm Bracelet(01背包模板)

    Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45191   Accepted: 19318 ...

  4. [Codeforces]#179 div1-----295ABCDE

    摘自我的github:https://github.com/Anoxxx The Solution Source: Codeforces Round #179 (Div. 1) VJudge链接: h ...

  5. delphi 10.2.2.2004 Tokyo 安装步骤

    delphi 各版本的安装,其XX工具都附有详细说明.遵守其安装步骤,很容易成功. 本教就以 delphi 10.2.2.2004 为例,演示一下整个安装过程.其它各版本就自行尝试. 附: delph ...

  6. FireMoneky 菜单

    FireMoneky 菜单 TPopup是容器,里边摆放一排button也可. TPopup + ListBox 也可以用弹出窗体实现,form上放一排按钮,功效类似,但是form在fmx下不能半屏显 ...

  7. 部署和调优 1.5 vsftp部署和优化-1

    系统自带的ftp服务软件.vsftpd 安装vsftpd yum install -y vsftpd 启动vsftpd /etc/init.d/vsftpd start 如果启动失败,可能是端口被占用 ...

  8. hbase.client.RetriesExhaustedException: Can't get the locations hive关联Hbase查询报错

    特征1: hbase.client.RetriesExhaustedException: Can't get the locations 特征2: hbase日志报错如下:org.apache.zoo ...

  9. with上下文管理基础

    import queue import contextlib import time @contextlib.contextmanager def worker_state(xxx,val): xxx ...

  10. oracle 之sys 、system区别

    角色 1)最重要的区别,存储的数据的重要性不同sys--所有oracle的数据字典的基表和视图都存放在sys用户中,这些基表和视图对于oracle的运行是至关重要的,由数据库自己维护,任何用户都不能手 ...