zoukankan      html  css  js  c++  java
  • catkin编译系统

    引言

    最近项目中遇到一个需求:将 C++ 程序 (不是 ROS node,只是普通的 C++ 程序)中的变量发布到 ROS topic 上,以便 ROS 中的其他 node 进行后续处理。

    原 C++ 程序比较复杂,我们希望尽量少修改原程序,只要输出其中某些变量的值即可,不要大规模改写成 ROS node 的形式,不要新建 ROS package。

    在以往使用 ROS 的过程中,我们一般是借助 catkin 来编译 ROS node C++ 程序。这可以看成是将 C++ 程序放入 ROS 框架中,以 ROS 的标准形式来编译。现在这个项目需求正好相反,我们要将 ROS 的相关库(library)嵌入到普通 C++ 程序中,采用 C++ 标准的 cmake 方式来编译。这就要求我们对 cmake 和 catkin 的关系有比较深入的了解。

    在查找资料的过程中,我们发现了一篇讲解 catkin 编译系统的文章,从最基本的命令行编译方式,到 makefile 文件编译,再到 catkin 编译,每一步发展的必要性都讲解的很清楚,看完之后,我们对 catkin 有了更深入的认识。

    本文是一篇学习笔记,也可以看成是对原文的意译。

    对原文感兴趣的读者可以移步这里 http://jbohren.com/tutorials/2014-02-12-gentle-catkin-intro/

    预安装

    原文例子中使用了 hydro 版本的 ROS,现在看来比较古老了,这里替换为 kinetic 版本。

    • Ubuntu 16.04
    • ROS kinetic (base 即可)

    从最简单的例子开始

    首先创建一个文件夹 hello_world_tutorial,存放我们的程序

    mkdir hello_world_tutorial
    cd hello_world_tutorial

     创建 C++ 源文件,名为 hello_world_node.cpp

    // 为了与 ROS 交互,需要调用 ROS C++ APIs
    #include <ros/ros.h>
    
    // 标准的 C++ main 函数
    int main(int argc, char** argv) {
    
      // 该命令告诉 ROS 初始化了一个 node,名为 hello_world_node 
      ros::init(argc, argv, "hello_world_node");
    
      // 在一般的 ROS node 程序中,我们会用 ros::NodeHandle nh 来启动 node 程序,
      // ros::NodeHandle nh 默认会调用 ros::start() 函数,程序关闭时也会自动调用 ros::shutdown() 函数。
      // 我们也可以直接通过 ros::start() 和 ros::shutdown() 来手动控制 node 的开启和关闭
      ros::start();
    
      // 显示 hello, world! 信息
      ROS_INFO_STREAM("Hello, world!");
    
      // 用 ros::spin() 保持该程序运行,一直等待处理 subscribe 的数据
      // 由于该程序并没有 sub,所以就是简单的保持程序不退出而已, 直到接受到终止信号 SIGINT (ctrl-c)
      ros::spin();
    
      // 关闭 node 程序
      ros::shutdown();
    
      // 结束主程序
      return 0;
    }

     下边将 C++ 源文件编译成可执行文件

    g++ hello_world_node.cpp -o hello_world_node -I/opt/ros/kinetic/include -L/opt/ros/kinetic/lib -Wl,-rpath,/opt/ros/kinetic/lib -lroscpp -lrosconsole

    各参数含义

    • -I<dir> 指定头文件的搜索路径
    • -L<dir> 指定静态库的搜索路径
    • -Wl,-rpath,/opt/ros/kinetic/lib 指定共享库的搜索路径
    • -lroscpp -lrosconsole 指定需要链接的具体的库文件

    编译之后,生成 hello_world_node 可执行文件。由于程序中生成了 ROS node,而 ROS node 需要与 ROS master 进行通讯注册,否则会报错。因此为了正常运行程序,需要先开启 ROS master

    roscore

    然后运行 hello_world_node

    ./hello_world_node

    如果一切顺利,应该显示类似如下信息:

    [ INFO] [1561908777.116073864]: Hello, world!

    上述编译方式扩展性很差,对于如此简单的 hello_world 程序,需要设置的参数已经这么多了。而且在 terminal 中书写比较麻烦,修改也不方便。

    上面是使用g++编译器直接在终端中对源文件进行编译,通过上面的过程了解到,当编译的源文件需要链接其他库文件、头文件时需要额外添加命令以及文件路径,这样当需要链接的文件比较多时或者编译文件进行修改重新编译时,非常不方便,如果能在脚本文件中将编译命令以及链接文件的路径全部链接到,然后在终端直接执行这个脚本文件岂不是更加方便。因此前人进行了改进

    改进:使用 Makefile 文件进行编译

    我们向往远方,却忽略了此刻的美丽
  • 相关阅读:
    csu 1503: 点弧之间的距离-湖南省第十届大学生计算机程序设计大赛
    Android MediaPlayer 和 NativePlayer 播放格式控制
    国内互联网企业奇妙招数
    [Oracle] Insert All神奇
    代码杂记
    R.layout.main connot be resolved 和R.java消失
    计算机安全篇(1)
    深入浅出谈开窗函数(一)
    PHP JSON_ENCODE 不转义中文汉字的方法
    c#indexof使用方法
  • 原文地址:https://www.cnblogs.com/zhjblogs/p/15674149.html
Copyright © 2011-2022 走看看