在编写第一个ROS节点程序之前需要创建工作空间(workspace)和功能包(package)。

一、创建工作空间(workspace)

创建一个catkin_ws:

#注意:如果使用sudo一次性创建多个目录,则这多个目录属主都为root,若是非root用户创建的ROS,则无法在root目录创建工作空间
sudo mkdir -p ~/dev/catkin_ws/src
cd ~/dev/catkin_ws/src
catkin_init_workspace

当我们创建工作空间文件夹后,里面并没有功能包,只有CMakeList.txt。下一步是编译工作空间,使用下面命令:

cd ~/dev/catkin_ws
catkin_make

现在,如果你输入ls -l命令,可以看到上面命令创建的新文件夹,分别是“build”和一个“devel”文件夹:

zlkj@ubuntu:~/dev/catkin_ws$ ls -l
total 12
drwxrwxr-x 7 zlkj zlkj 4096 Mar 19 12:10 build
drwxrwxr-x 3 zlkj zlkj 4096 Mar 19 12:10 devel
drwxrwxr-x 2 zlkj zlkj 4096 Mar 19 11:23 srczlkj@ubuntu:~/dev/catkin_ws/build$ ls -l
total 64
drwxrwxr-x 3 zlkj zlkj  4096 Mar 19 12:10 catkin
drwxrwxr-x 4 zlkj zlkj  4096 Mar 19 12:10 catkin_generated
-rw-rw-r-- 1 zlkj zlkj     0 Mar 19 12:10 CATKIN_IGNORE
-rw-rw-r-- 1 zlkj zlkj   125 Mar 19 12:10 catkin_make.cache
-rw-rw-r-- 1 zlkj zlkj 16071 Mar 19 12:10 CMakeCache.txt
drwxrwxr-x 9 zlkj zlkj  4096 Mar 19 12:10 CMakeFiles
-rw-rw-r-- 1 zlkj zlkj  7365 Mar 19 12:10 cmake_install.cmake
-rw-rw-r-- 1 zlkj zlkj   284 Mar 19 12:10 CTestTestfile.cmake
drwxrwxr-x 3 zlkj zlkj  4096 Mar 19 12:10 gtest
-rw-rw-r-- 1 zlkj zlkj  8578 Mar 19 12:10 Makefile
drwxrwxr-x 2 zlkj zlkj  4096 Mar 19 12:10 test_resultszlkj@ubuntu:~/dev/catkin_ws/devel$ ls -l
total 36
-rwxr-xr-x 1 zlkj zlkj   506 Mar 19 12:10 env.sh
drwxrwxr-x 2 zlkj zlkj  4096 Mar 19 12:10 lib
-rw-r--r-- 1 zlkj zlkj   260 Mar 19 12:10 setup.bash
-rw-r--r-- 1 zlkj zlkj  2542 Mar 19 12:10 setup.sh
-rwxr-xr-x 1 zlkj zlkj 12378 Mar 19 12:10 _setup_util.py
-rw-r--r-- 1 zlkj zlkj   270 Mar 19 12:10 setup.zsh

可以看到在devel目录下,有很多setup.*sh文件,读取这些文件中的任何一个都会将当前工作空间的环境变量置于所有环境变量的最上层。如果我们打开这些文件会发现,最终都是要读取setup.bash文件,这个文件中定义了catkin_ws空间所需要的环境变量。

读取setup.bash文件:

source devel/setup.bash

确认已经加载好catkin工作空间环境变量:

echo $ROS_PACKAGE_PATH//显示出:
/home/zlkj/catkin_ws/src:/opt/ros/indigo/share:/opt/ros/indigo/stacks

这时ROS的工作空间已经创建好了。

总结:

初始化ROS的catkin工作空间:catkin_init_workspace

编译ROS的catkin工作空间:catkin_make

读取当前catkin工作空间的环境变量:source devel/setup.bash

验证ROS工作空间的环境变量加载成功:echo $ROS_PACKAGE_PATH

二、创建功能包(package)

使用catkin_create_pkg命令行工具在之前创建的工作空间创建新的功能包:

cd ~/dev/catkin_ws/src
catkin_create_pkg amin std_msgs roscpp

其实,这个功能包创建命令没有做太多工作,它只不过创建了一个存放这个功能包的目录(也就是我所创建的功能包amin),并在amin那个目录下生成了两个配置文件。

  • 第一个配置文件,叫做 package.xml,称为清单文件。
  • 第二个文件,叫做 CMakeLists.txt,是一个 Cmake 的脚本文件,Cmake 是一个符合工业标准的跨平台编译系统。这个文件包含了一系列的编译指令,包括应该生成哪种可执行文件,需要哪些源文件,以及在哪里可以找到所需的头文件和链接库。当然,这个文件表明 catkin 在内部使用了 Cmake。

catkin_create_pkg命令的格式包括功能包的名称和依赖项。在上面示例中,依赖项为std_msgs和roscpp。如以下命令行所示:

catkin_create_pkg [package_name] [depend1] [depend2] [depend3]

这些依赖项包括:

  • std_msgs 包含了常见消息类型,表示基本数据类型和其他基本的消息构造,如多维数组。
  • roscpp 使用C++实现ROS的各种功能。它提供了一个客户端库,让C++程序员能够调用这些接口快速完成与ROS的主题、服务和参数相关的开发工作。

注意:ROS 功能包的命名遵循一个命名规范,只允许使用小写字母、数字和下划线,而且首字符必须是一个小写字母。一些 ROS工具,包括 catkin,不支持那些不遵循此命名规范的功能包。

三、编写ROS节点程序

编写一个简单的ros节点程序,命名为hello.cpp。这个名为 hello.cpp 的源文件也存放在你的功能包 amin文件夹中 , 挨着 package.xml 和 CMakeLists.txt。

注意:一些在线教程建议在你的功能包目录中创建 src 目录来存放 C ++源文件。这个附加的组织结构可能是有益的,特别是对于那些含有多种类型文件的较大的功能包,但它不是严格必要的。

ROS节点程序如下:

#include <ros/ros.h>int main (int argc, char **argv)
{ros::init(argc, argv, "hello") ;ros::NodeHandle nh;ROS_INFO_STREAM("Hello, ROS!") ;
}

四、编译Hello.cpp程序

我们该如何编译和运行这个程序呢?这些交给ROS的catkin编译系统来处理。

第一步:声明依赖库

首先,我们需要声明程序所依赖的其他功能包。对于 c++程序而言,此步骤是必要的,以确保 catkin 能够向 c++编译器提供合适的标记来定位编译功能包所需的头文件和链接库。

为了给出依赖库,需要编辑功能目录下的 CMakeLists.txt 与 package.xml 文件,通过使用build_depend (编译依赖)和 run_depend(运行依赖)两个关键字实现,格式如下:

<build_depend>package-name</build_depend>
<run_depend>package-name</run_depend>

不过这一步可以省略,因为在创建功能包说明依赖项的同时,系统自动声明了依赖库,除非创建时未说明依赖项。

使用rospack depend1 amin可以查看直接功能包的直接依赖。在很多情况下,我们会遇到依赖的依赖,即间接依赖。例如amin的依赖文件roscpp也有其他依赖。如果我们使用rospack depends amin,则会列出amin功能包的所有依赖文件。

第二步:声明可执行文件

接下来,我们需要在 CMakeLists.txt 中添加两行,来声明我们需要创建的可执行文件。其一般形式是:

add_executable(executable-name source-files)
target_link_libraries(executable-name ${catkin_LIBRARIES})
  • 第一行声明了我们想要的可执行文件的文件名,以及生成此可执行文件所需的源文件列表。如果你有多个源文件,把它们列在此处,并用空格将其区分开。
  • 第二行告诉 Cmake 当链接此可执行文件时需要链接哪些库(在上面的 find_package 中定义)。如果你的包中包括多个可执行文件,为每一个可执行文件复制和修改上述两行代码。

在本例程中,我们需要一个名为 hello 的可执行文件,它通过名为 hello.cpp 的源文件编译而来。所以我们需要添加如下两行代码到 CMakeLists.txt 文件中 include_directories(include ${catkin_INCLUDE_DIRS}) 之后:

add_executable(hello hello.cpp)
target_link_libraries(hello ${catkin_LIBRARIES})

第三步:编译工作区

利用catkin_make这个命令进行编译,注意必须在你的工作空间目录运行。

cd ~/dev/catkin_ws
catkin_make

运行完后会在 ~/dev/catkin_ws/devel/amin 目录下生产 hello 这个可执行文件。下图为运行的结果。

五、执行hello程序

首先要启动 roscore:这个程序是一个节点,节点需要一个节点管理器才可以正常运行。启动节点管理器的命令:

roscore

启动完节点管理器后,执行名为 setup.bash 的脚本文件,它是 catkin_make 在你工作区的 devel 子目录下生成的。这个自动生成的脚本文件设置了若干环境变量,从而使 ROS 能够找到你创建的功能包和新生成的可执行文件。(也就是将程序注册)

source devel/setup.bash

最后一步,运行节点,用命令:使用格式为"rosrun package-name executable-name" ,package-name 为功能包名称, executable-name为可执行文件名称。

rosrun amin hello

运行结果如图:

这样一个简单的ROS程序就完成了。

转载于:https://www.cnblogs.com/linuxAndMcu/p/10571643.html

ROS学习笔记三:编写第一个ROS节点程序相关推荐

  1. ROS学习笔记10(创建一个ROS消息和服务)

    这篇教程主要介绍怎样创建和编译一个msg消息和srv服务文件,同时介绍rosmsg,rossrv,roscp等命令工具. 文章目录 1 msg和srv文件长什么样 2 msg使用 2.1 创建一个ms ...

  2. ROS学习笔记4(编译一个ROS Package)

    文章目录 1 准备工作 2 使用catkin_make 3 编译一个package 1 准备工作 在所有的系统依赖项都安装好之后,就可以编译一个新的package了. 注意:如果是使用apt方式安装的 ...

  3. ROS学习笔记3(创建一个ROS Package)

    文章目录 1 catkin Package由什么组成? 2 catkin工作空间下的packages 3 创建一个catkin package 4 编译并且刷新setup文件 5 package依赖 ...

  4. ROS学习笔记三:创建ROS软件包

    ,# ROS学习笔记三:创建ROS软件包 catkin软件包的组成 一个软件包必须满足如下条件才能被称之为catkin软件包: 这个软件包必须包含一个catkin编译文件package.xml(man ...

  5. ROS学习笔记(八): ROS通信架构

    ROS学习笔记(八): ROS通信架构 文章目录 01 Node & Master 1.1 Node 1.2 Master 1.3 启动master和node 1.4 rosrun和rosno ...

  6. ROS学习笔记一:安装配置ROS环境

    ROS学习笔记一:安装配置ROS环境 在安装完成ROS indigo之后,需要查看环境变量是否设置正确,并通过创建一个简单的实例来验证ROS能否正常运行. 1 查看环境变量 在ROS的安装过程中,我们 ...

  7. IOS学习笔记04---编写第一个C语言程序-Hello World

    IOS学习笔记04---编写第一个C语言程序-Hello World --------------------------------------------------------         ...

  8. ROS学习笔记(一):ROS noetic的安装

    前言 ROS是一个机器人操作系统,机器人的不同模块之间的数据传输都在ROS上进行,下面记录一下ROS noetic的安装和基本使用 一.预备 ROS的不同版本和Ubuntu的不同版本向适配,这里与RO ...

  9. c语言 方程改main的值_C语言编程笔记丨编写第一个C语言程序hello world,我教你哇...

    如果用C语言输出:Hello,world!,该如何编写程序? **代码如下:** #include//包含标准库的信息 main()//定义名为main的函数,不接受参数值 {//main函数的语句都 ...

最新文章

  1. 图像边缘检测--OpenCV之cvCanny函数
  2. crontab定时任务运行
  3. 使用SAP iRPA Studio创建的本地项目,如何部署到SAP云平台上?
  4. 8080:The Tomcat connector configured to listen on port 8080 failed to start 的解决办法
  5. Arduino笔记-数字输入(开关的正确使用)
  6. 自己动手「焊」键盘,使用Python编写,一键放连招不在话下
  7. 辽宁省计算机辅助普通话水平测试应试指南,计算机辅助普通话水平测试 应 试 指 南...
  8. 使用post访问不到接口_Postman调试依赖登录接口的3种方法
  9. Node.js 学习笔记 - 学习《深入浅出Node.js》-朴灵
  10. HTML5期末大作业:网站——餐饮网页设计(HTML+CSS+JS)
  11. python绘图画猫咪_使用Python的turtle画小猫咪
  12. 树莓派Python编程手册
  13. 将assets文件转为byte[]
  14. Excel不同列多条件计数
  15. 阿里云linux服务器安装ssh(从登录的坑开始,心酸)
  16. 签约新闻 | 出版发行行业又一位老牌企业的数字化转型,扬帆起航!
  17. Pandas数据分析——Task2
  18. cesium图层管理
  19. zonecreate
  20. 蓝牙4.0 BLE协议结构图详解

热门文章

  1. java 多态判断非空_跳槽涨薪季面试题之java基础(一)
  2. Javascript 进阶 作用域 作用域链
  3. Linux程序移植到Android上
  4. iOS内存优化及排查方法
  5. Android 通过 annotation ViewInject
  6. golang中的goto
  7. golang中的strings.Trim
  8. c++中new和delete的使用方法
  9. 数据结构:O(nlogn)算法
  10. 通过实例理解 RabbitMQ 的基本概念