ROS学习小笔记
(注:自己整合的小笔记,只是为了方便我这个小菜鸡学习嘻嘻,各博主的链接已经挂上,不小心来到我这边的朋友记得去其他博主学习,谢谢)
在ROS系统中,要编译ROS功能包里面的内容,就要要包含 CMakeLists.txt 与 package.xml 文件。
1、CMakeLists.txt文件
原文链接:https://blog.csdn.net/qq_32761549/article/details/104535989原文链接:https://blog.csdn.net/weixin_45590473/article/details/121208270
1-1、CMakeLists.txt文件的作用:
Linux 平台编译 C++ 文件,需要编译器和链接器,其中编译器是将源代码编译成目标代码,链接器是将目标代码链接到可执行文件。
通过编写简单的 CMakeLists.txt 规则文件,就能自动生成 makefile 文件,并且 CMake 是跨平台的,十分强大。ROS 的编译器便是 CMake,为了更加人性化,ROS 在 CMake 基础上封装了 catkin 命令,用 cmake 命令创建功能包时,会自动生成 CMakeList.txt 文件,已配置了多数编译选项,且包含详细的注释,只需稍作修改便可编译自己的文件。
这个文件直接规定了这个package要依赖哪些package,要编译生成哪些目标,如何编译等等 流程。所以 CMakeLists.txt 非常重要,它指定了由源码到目标文件的规则,catkin编译系统在 工作时首先会找到每个package下的 CMakeLists.txt ,然后按照规则来编译构建。
发现有两种CMakelist.txt文件,一个是针对所有package的,一个是针对于某一个特性的package的。这两种不同使用范围的CMake文件回答了:“如何将所有package功能包生成的可执行文件组成我们想要的目标文件——宏观把握“‘以及”如何将某一个特定的package功能包中的源代码生成可执行目标文件——细节掌控“。
1-2、CMakeLists.txt文件的总体结构:
cmake_minimum_required() #CMake的版本号
project() #项目名称
find_package() #找到编译需要的其他CMake/Catkin package
catkin_python_setup() #catkin新加宏,打开catkin的Python Module的支持
add_message_files() #catkin新加宏,添加自定义Message文件
add_service_files() #catkin新加宏,添加自定义Service文件
add_action_files() #catkin新加宏,添加自定义Action文件
generate_message() #catkin新加宏,生成不同语言版本的msg/srv/action接口
catkin_package() #catkin新加宏,生成当前package的cmake配置,供依赖本包的其他软件包调用
add_library() #生成库
add_executable() #生成可执行二进制文件
add_dependencies() #定义目标文件依赖于其他目标文件,确保其他目标已被构建
target_link_libraries() #链接
catkin_add_gtest() #catkin新加宏,生成测试
install() #安装至本机
1-3、例子:camera_umd(相机图元)的CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(camera_umd)
find_package(catkin REQUIRED)
catkin_metapackage()
#定义cmake的最低版本时2.8
#声明 cmake 工程名字
#find_package 是 cmake 中常见的宏,用于加载 catkin 宏和指定对其他 ROS 功能包的依赖关系。
#find_package的作用就是去寻找该库的头文件位置、库文件位置以及库文件名称,并将其设为变量,返回提供给CMakeLists.txt其他部分使用。
#添加依赖find_package( catkin REQUIRED )
#catkin_package 宏是 catkin 的宏之一,声明要传递给依赖项目的内容,生成 cmake 配置文件。也就是说它对依赖于此功能包的其他功能包来说具有重要作用
1-4、例子:uvc_camera的cmakelists.txt
cmake_minimum_required(VERSION 2.8.3)
project(uvc_camera)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
##如果使用了像find_Package这样的组件列表(catkin必需组件xyz),也可以找到其他catkin包。
find_package(catkin REQUIRED COMPONENTS camera_info_manager image_transport nodelet roscpp sensor_msgs)
## System dependencies are found with CMake's conventions
##系统依赖关系是用cmake的约定发现的。
find_package(Boost REQUIRED COMPONENTS thread system)
#find_package(V4L2 REQUIRED)
set(V4L2_LIBRARIES v4l2)
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
##如果包有setup.py,则取消此操作。这个宏确保
##模块和在其中声明的全局脚本得到安装
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()
#######################################
## Declare ROS messages and services ##
#######################################
## Generate messages in the 'msg' folder
##在“msg”文件夹中生成
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
## Generate services in the 'srv' folder
##在“srv”文件夹中生成
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
## Generate added messages and services with any dependencies listed here
###使用此处列出的任何依赖项生成添加的nessage和服务
# generate_messages(
# DEPENDENCIES
# sensor_msgs
# )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
##catkin_Package Nacro为您的包生成cnake配置文件
##声明要传递给依赖项目的东西
##include_Dirs:如果包包含头文件,请取消此连接
##库:您在这个项目中创建的依赖项目还需要
##catkin_依赖性的库:catkin_Packages依赖的项目也需要
##依赖:此项目的系统依赖关系,而依赖项目也需要
catkin_package(
# INCLUDE_DIRS include
LIBRARIES nodelet_uvc_camera
CATKIN_DEPENDS roscpp nodelet sensor_msgs
# DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
##指定头文件的其他位置
##您的包位置应该列在其他位置之前
include_directories(include)
include_directories(
${catkin_INCLUDE_DIRS}
)
## Declare a cpp library
##声明一个CPP库
# add_library(uvc_camera
# src/${PROJECT_NAME}/uvc_camera.cpp
# )
## Declare a cpp executable
##声明CPP可执行文件
# add_executable(uvc_camera_node src/uvc_camera_node.cpp)
## Add cmake target dependencies of the executable/library
## as an example, message headers may need to be generated before nodes
##添加可执行文件/库的cnake目标依赖项
##作为一个例子,可能需要在节点依赖项之前生成nessage报头。
# add_dependencies(uvc_camera_node uvc_camera_generate_messages_cpp)
## Specify libraries to link a library or executable target against
##指定库链接库或可执行目标
# target_link_libraries(uvc_camera_node
# ${catkin_LIBRARIES}
# )
add_library(nodelet_uvc_camera src/nodelets.cpp src/camera.cpp src/stereo.cpp src/uvc_cam.cpp)
target_link_libraries(nodelet_uvc_camera ${Boost_LIBRARIES} ${V4L2_LIBRARIES} ${catkin_LIBRARIES})
add_executable(uvc_camera_node src/camera_node.cpp src/camera.cpp src/uvc_cam.cpp)
target_link_libraries(uvc_camera_node ${Boost_LIBRARIES} ${V4L2_LIBRARIES} ${catkin_LIBRARIES})
add_executable(uvc_stereo_node src/stereo_node.cpp src/stereo.cpp src/uvc_cam.cpp)
target_link_libraries(uvc_stereo_node ${Boost_LIBRARIES} ${V4L2_LIBRARIES} ${catkin_LIBRARIES})
#############
## Install ##
#############
# all install targets should use catkin DESTINATION variables
#所有安装目标都应该使用catkin目标变量
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
##标记可执行脚本(Python等)用于安装
##与setup.py相比,您可以选择目的地
# install(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables and/or libraries for installation
##标记可执行文件和/或安装库
install(TARGETS nodelet_uvc_camera uvc_camera_node uvc_stereo_node
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
install(FILES
nodelet_uvc_camera.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
## Mark cpp header files for installation
##标记用于安装的cpp头文件
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )
## Mark other files for installation (e.g. launch and bag files, etc.)
##标记其他安装文件(例如启动和打包文件等)安装(目录启动)
install(DIRECTORY launch
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)
#############
## Testing ##
#############
## Add gtest based cpp test target and link libraries
##添加基于gtest的CPP测试目标和链接库
# catkin_add_gtest(${PROJECT_NAME}-test test/test_uvc_camera.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
## Add folders to be run by python nosetests
##添加由python nosetest运行的文件夹
# catkin_add_nosetests(test)
2、package.xml文件
原文链接:https://blog.csdn.net/wangxiao7474/article/details/109840779
2-1、pacakge.xml 格式的作用:
Package功能包的身份证——package.xml文件。
ROS本质上就是由一个又一个的package组成的,package可以说是ROS的细胞。在catkin_make的时候它会一个一个的去找package然后生成目标文件。一个package可以有多个节点。
判断是否为Package :一个文件夹要被ROS认为是package的话,必须包含以下两个文件:CMakeList.txt和package.xml。
2-2、pacakge.xml 的写法:
pacakge.xml 遵循xml标签文本的写法, 由于版本更迭原因, 现在有两种格式并存( format1与format2) , 不过区别不大。
2-2.1、 pacakge.xml 的格式(旧版本format1)
<package> <!--1. 根标签-->
<name> <!--2. 包名-->
<version> <!--3. 版本号-->
<description> <!--4. 包描述-->
<maintainer> <!--5. 维护者-->
<license> <!--6. 软件许可-->
<buildtool_depend> <!--7. 编译工具-->
<build_depend> <!--8. 编译时的依赖-->
<run_depend> <!--9. 运行时的依赖-->
</package> <!--根标签-->
PS:其中1-6为必备标签,1是根标签嵌套了其余所有标签,2-6是包的各种属性,7-9是编译相关信息。
2-2.2 、pacakge.xml 的格式(新版本format2)
<package> <!--1. 根标签-->
<name> <!--2. 包名-->
<version> <!--3. 版本号-->
<description> <!--4. 包描述-->
<maintainer> <!--5. 维护者-->
<license> <!--6. 软件许可-->
<buildtool_depend> <!--7. 编译构建工具,通常为catkin-->
<depend> <!--8. 指定依赖项为编译、 导出、 运行需要的依赖,最常用的依赖标记。-->
<build_depend> <!--9. 编译依赖项-->
<build_export_depend><!--10. 导出依赖项-->
<exec_depend> <!--11. 运行依赖项-->
<test_depend> <!--12. 测试用例依赖项-->
<doc_depend> <!--13. 文档依赖项-->
</package> <!--根标签-->
2-2.3、 pacakge.xml 的格式新旧版本的区别
新增的标签:
<depend> <!--8. 指定依赖项为编译、 导出、 运行需要的依赖,最常用的依赖标记。-->
<build_export_depend> <!--10. 导出依赖项-->
<test_depend> <!--12. 测试用例依赖项-->
<doc_depend> <!--13. 文档依赖项-->
更改的标签:
运行依赖项由<run_depend> 改为<exec_depend>
2-3、例子:camera_umd(相机图元)的pacakge.xml
<?xml version="1.0"?>
<!-- 1.根标签 2. 包名 3. 版本号 4. 包描述-->
<package>
<name>camera_umd</name>
<version>0.2.7</version>
<description>UMD camera metapackage</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<!--需要一个保持器标记,多个许可,每个标签一人-->
<maintainer email="ken@tossell.net">Ken Tossell</maintainer>
<maintainer email="ros-orphaned-packages@googlegroups.com">ROS Orphaned Package Maintainers</maintainer>
<!-- One license tag required, multiple allowed, one license per tag -->
<!--Commonly used license strings: -->
<!--需要一个许可证标记,多个许可,每个标签一个许可证-->
<!--常用的许可字符串-->
<license>GPLv2</license>
<!-- Url tags are optional, but mutiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://ros.org/wiki/camera_umd</url> -->
<!--url标记是可选的,但允许使用数字,每个标记一个-->
<!--可选属性类型可以是:网站、bug跟踪器或存储库-->
<!-- Author tags are optional, mutiple are allowed, one per tag -->
<!-- Authors do not have to be maintianers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!--作者标记是可选的,允许使用数字,每个标记有一个-->
<!--作者不必是维护者,但可以是-->
<!-- The *_depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use run_depend for packages you need at runtime: -->
<!-- <run_depend>message_runtime</run_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<run_depend>uvc_camera</run_depend>
<run_depend>jpeg_streamer</run_depend>
<!-- The export tag contains other, unspecified, tags -->
<!--导出标记包含其他未指定的标记-->
<export>
<!-- You can specify that this package is a metapackage here: -->
<!--您可以在这里指定此包是netapackage:-->
<metapackage/>
<!-- Other tools can request additional information be placed here -->
<!--其他工具可以要求更多的信息放在这里-->
</export>
</package>
3、launch文件
原文链接:https://blog.csdn.net/ben_xiao_hai_123/article/details/119250218
原文链接:https://blog.csdn.net/u011017694/article/details/117254391
launch英文翻译过来的意思是“启动”,说明它与启动有关
3-1、launch文件作用:
rosrun命令用于运行一个ROS节点,这个在简单程序中使用比较方便。但是在规模比较大的程序中,常常有几个或者几十个节点,这些节点之间彼此互有联系,协同达到软件正确执行的目的。这时候再使用rosrun命令的话,就会比较麻烦。此时,roslaunch命令闪亮登场了,它可以运行多个节点。
就相当于一个包,包里啥节点node都有,运行的时候不管三七二十一直接跑整个包。
3-2、launch文件的构成:
指令格式:roslaunch package_name file.launch
扩展名为.launch
文件包括了指定执行哪个包,哪个节点node 、以及他们的参数param
launch文件由<launch>、</launch>
开始与结束,其他参数均为子元素。
其子元素有:
<node>:节点
<machine>:机器名
<include>:嵌套,包含其他launch文件
<remap>:重映射
<env>:
<param>:设置ROS系统运行中的参数,储存再参数服务器中,name:参数名,value:参数值
<rosparam>:加载参数文件中的多个参数
<group>:
<test>:
<arg>:launch文件内部的局部变量,仅限launch使用
1、注释:<!-- 注释长这样 -->
2、xml说明了launch文件的本质是一个xml文件
3、每个xml文件都必须要包含一个根元素。根元素由一对launch标签定义:<launch> … </launch>
,元素都应该包含在这两个标签之内。
4、启动节点<node>...</node>
5、pkg:工作空间中,节点所在功能包的名称
6、type:是包中需要运行的具体节点,其指向的文件必须有对应的可执行文件 ,是节点的可执行文件名称
7、name:是给这个节点运行时候的名字(取代源文件的名称)
8、output:是否打印日志信息,某个单独的节点在控制台中输出信息,output="screen"配置了该属性的节点会将标准输出显示在屏幕上而不是 记录到日志文档。
8、param参数服务器:<param …/> 设置ROS系统运行中的参数,存储在参数服务器中。
<launch>
<!-- pkg包名 type节点可执行文件名 name自定义名 output输出方式 respawn起死回生 respawn_delay起死回生所需要的时间,默认0 -->
<!--ns表示在指定命名空间运行节点(可以理解为改rostopic list中的节点名称),交互的节点间要在同一ns下,下面这俩必须在同ns下-->
<node pkg="turtlesim" type="turtlesim_node" name="turtletest" output="screen" respawn="true" respawn_delay="3" ns="turtle"/>
<!--required是必需的,死后全死-->
<node pkg="turtlesim" type="turtle_teleop_key" name="mycontrol" required="true" output="screen" ns="turtle"/>
</launch>
<node>
里可以添加以下常见的参数
pkg=“mypackage”, 包名
type=“nodetype” , 执行文件的名称如果是用Python编写的就填写xxx.py,如果是cpp就写编译生成的可执行文件名
name=“nodename”, 这将会覆盖掉ros::init()定义的node_name
args=“arg1 arg2 arg3”, 所带的参数
respawn=“true”, 默认为false,节点挂掉/退出后是否重新启动。
required=“true”, 如果该节点退出/挂掉,会杀死roslaunch的所有进程。
clear_params=“true|false” 在启动之前,删除节点的私有名称空间中的所有参数。
output=“log|screen” 若为screen,stdout/stderr 会显示在屏幕上,若为log,stdout/stderr 会被记录到$ROS_HOME/log(日志文件),仅显示stderr。注stderr是那个红色的错误字体。
3-3、例子:camera_node的.launch(在uvc_camera包中)
<launch>
<node pkg="uvc_camera" type="uvc_camera_node" name="uvc_camera" output="screen">
<param name="width" type="int" value="320" />
<param name="height" type="int" value="240" />
<param name="fps" type="int" value="30" />
<param name="frame" type="string" value="wide_stereo" />
<param name="auto_focus" type="bool" value="False" />
<param name="focus_absolute" type="int" value="0" />
<!-- other supported params: auto_exposure, exposure_absolute, brightness, power_line_frequency -->
<param name="device" type="string" value="/dev/video0" />
<param name="camera_info_url" type="string" value="file://$(find uvc_camera)/example.yaml" />
</node>
</launch>
顺带提一个camera_node的底层文件:camera_node.cpp
camera_node.cpp
#include <ros/ros.h>
#include <nodelet/loader.h>
#include "uvc_camera/camera.h"
int main (int argc, char **argv) {
ros::init(argc, argv, "uvc_camera");
uvc_camera::Camera camera(ros::NodeHandle(), ros::NodeHandle("~"));
ros::spin();
return 0;
}
4、msg文件
原文链接:http://www.cnblogs.com/LiuQiang921202/articles/7681213.html
msg:msg文件是描述ROS消息的字段的文件,其本质上是简单的.txt格式的文件,其目的是用来生成基于不同编程语言的承载消息的源代码。
.msg格式的文件是存储在名为msg的目录下
4-1、字段类型+字段名
消息文件中的每一行包含两个字段,分别是字段类型和字段名。
可用的字段类型有:
int8
int16
int32
int64
float32
float64
string
time
duration
other msg files
可变长度的数组array[]
固定长度的数组array[C]
ROS中的特殊类型:Header,头包含了ROS中常用的时间戳和坐标系信息,所以经常看到一个.msg文件的第一行有Header header。
具体的.msg文件的例子:
Header header
string child_frame_id
geometry_msgs/PoseWithCovariance pose
geometry_msgs/TwistWithCovariance twist
5、srv文件
原文链接:http://www.cnblogs.com/LiuQiang921202/articles/7681213.html
srv:一个srv文件描述一项服务。它包含两个部分:请求和响应。所以srv文件具体描述的就是一个服务中请求和响应分别要求的消息格式
.srv格式的文件存储在名为srv的目录下
5-1、请求部分和响应部分
这两部分之间由’—'三条破折线隔开:
上:请求
下:响应
int64 A
int64 B
---
int64 Sum