How to compile a node file?如何编译一个节点文件?
Posted williamc17
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了How to compile a node file?如何编译一个节点文件?相关的知识,希望对你有一定的参考价值。
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 = 1; // 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[100]; char file_depth[100]; 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( 9 ); 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" , 1 ); message_filters::Subscriber<sensor_msgs::Image> subscriber_rgb( nh , "/camera/rgb/image_rect_color" , 1 ); #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(10), 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 < 300 ) { ros::spinOnce(); } } else break; } ROS_INFO_STREAM("Cerrando nodo\nClosing node\n"); return 0; }
——————现在开始我们的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 from rosbags(contains depth and RGB data) as picture frames
Installing and Configuring Your ROS Environment
以上是关于How to compile a node file?如何编译一个节点文件?的主要内容,如果未能解决你的问题,请参考以下文章
How to modify a compiled Android application (.apk file)
How to cross-compile and use Mainline Kernel
[译]How to Install Node.js on Ubuntu 14.04 如何在ubuntu14.04上安装node.js
How to download and compile Android kernel goldfish ?
[An Introduction to GCC 学习笔记] 15 How the compiler works, Identifying files
[An Introduction to GCC 学习笔记] 15 How the compiler works, Identifying files