ROS笔记
在ros操作之前,要做的是设置环境变量来定位文件
source /opt/ros/indigo/setup.bash
若在当前shell中不设置,则会出现命令找不到(commandnot found)的情况。
不要轻易关掉roscore界面(启动节点管理器),因为大多数ROS节点在启动时连接到节点管理器上,如果运行中连接中断,则不会尝试重新连接。因此,如果roscore被终止,其他的节点将无法重新建立连接,需要全部重新开启这些节点。(很麻烦)针对这个,后面有一个roslaunch的工具,可以一次性启动多个节点,如果启动多节点时没有节点管理器运行,它会自动启动节点管理器。
启动节点管理器——Roscore是核心,不能关
要是关掉了,再启动其他节点时用roslaunch
启动节点rosrun package-name executable-name
查看节点rosnode list
注:rosout 节点是一个特殊的节点,通过roscore 自动启动
查看特定节点的信息rosnode info node-name
终止节点rosnode kill node-name
注:终止和重启节点通常不会对其他节点有较大影响;即使节点间正在相互交换消息(message),这些连接也会在节点终止时断开,在节点重启时重新连接。
也可以用ctrl-c终止节点,但是终止的节点仍在rosnode列表中。可以用rosnode cleanup删除列表中无效的节点。
软件包列表和定位软件包
rospack list
每个程序包由一个清单文件(文件名为package.xml)定义
该文件定义关于包的一些细节,包括其名称、版本、维护者和依赖关系。
要找到一个软件包的目录,使用rospack find 命令
rospack find package-name
访问某软件包目录
roscd package-name
查看软件包目录下的文件:
rosls package-name
注:不用说明软件包的位置,直接由包名,ros系统能直接检索到包名所在位置。
话题和消息
ros节点之间的通信最重要的是利用消息传递。消息有组织的放在话题里。
当一个节点想要分享信息时,它就会发布(publish)消息到对应的一个或者多个话题;当一个节点想要接收信息时,它就会订阅(subscribe)它所需要的一个或者多个话题。
ROS节点管理器负责确保发布节点和订阅节点能找到对方;而且消息是直接地从发布节点传递到订阅节点,中间并不经过节点管理器转交。
查看节点之间的发布-订阅关系
rqt_graph
获取当前活跃的话题rostopic list
打印消息内容rostopic echo topic-name
测量发布频率rostopic hz topic-name
rostopic bw topic-name
查看话题rostopic info topic-name
输出的是消息类型:数据类型
理解消息的类型很重要,因为它决定了消息的内容。
查看消息类型rosmsg show message-type-name
常用的两种消息类型
geometry_msgs/Twist
turtlesim/Color
消息类型同样可以包含固定或可变长度的数组(用中括号[]表示)和常量(一般用来解析其他非常量的域)。
用命令行发布消息
rostopic pub –r rate-in-hz topic-name message-type message-content
注意:
和
这两个的区别是,上面的_ _name的意思是覆盖节点名称turtlesim_node,因为不允许节点重名。
多个发表者和多个订阅者可以共享一个话题。
问题检查roswtf
第三章:编写能够发布和订阅消息的ROS程序
1、创建工作区和功能包
mkdir workspace/src
cd ~/workspace/src
catkin_create_pkg package-name完成这一步后,src目录下有功能包,功能包中有两个配置文件package.xml清单文件;CMakeLists.txt,是一个Cmake 的脚本文件
2、编辑清单文件
gedit package.xml
ros::init函数:初始化ROS客户端库。在程序初始处调用一次该函数。Ros::NodeHandle(节点句柄)对象:是程序和ROS系统交互的主要机制。创建此对象会将你的程序注册为ROS节点管理器的节点。最简单的方法就是在整个程序中只创建一个NodeHandle对象。
ROS_INFO_STREAM 宏:将生成一条消息,且这一消息被发送到不同的位置,包括控制台窗口。
编译ros程序:(catkin系统)
1、声明依赖库:定位编译功能包所需的头文件和链接库;为了给出依赖库,编
辑包目录下的CMakeLists.txt 文件
find_package(catkin REQUIRED COMPONENTS package-names)
注:同样需要在包的清单文件中列出依赖库
2、声明可执行文件
还是在CMakeLists.txt 中添加
add_executable(executable-name source-files)
注:执行文件的文件名和源文件名
target_link_libraries(executable-name ${catkin_LIBRARIES})
注:链接可执行文件时需要哪些库(在上面的find_package 中定义)。
3、编译工作区(在工作空间目录下打开终端)
命令行:catkin_make
4、Sourcing setup.bash
最后的步骤是执行名为setup.bash 的脚本文件,它是catkin_make 在你工作区的devel 子目录下生成的。
source devel/setup.bash
注:这个自动生成的脚本文件设置了若干环境变量,从而使ROS 能够找到你创建的功能包和新生成的可执行文件。除非目录结构发生变化,否则你只需要在每个终端执行此命令一次,即使你修改了代码并且用catkin_make 执行了重编译。
执行hello程序
rosrun agitr hello
格式:rosrun 包名执行文件
2017.1.13笔记
编写ros代码来发布消息
1、包含消息类型声明
#include
每一个消息类型都对应一个头文件,如上,包名/类型名
2、创建发布者对象
Message_type消息的数据类型
Topic_name话题名
queue_size消息序列的大小,数据进入序列大于这个设定值时会丢弃最早进入队列的数据
格式:
ros::Publisher pub = node_handle.advertise
topic_name, queue_size);
一个节点发出的不同话题的消息时是需要创建不同的独立的ros::Publisher 对象。这样很耗时,所以,建议为每个话题创建一个发布者,在程序执行的
全过程中一直使用那个发布者。通过while循环外面声明发布者。
3、创建并填充消息对象
4、发布消息
pub.publish(msg);
5、定义输出格式
比方:发布和订阅相当于是牛奶厂商和定牛奶的客户,第二步消息类型和话题名称相当于牛奶种类(纯牛奶,酸奶等)和牛奶品牌,第三步的消息对象则是酸奶(或纯牛奶)的成分,如毫升数,蛋白质和水含量等等。第四步则是将制作好的酸奶装箱,第六步则是在标签上显示牛奶成分。
消息发布循环
在while循环中重复发布消息的步骤,随着时间的推移发布不同的消息。使用两个附加的构造函数。
1、节点是否停止工作的检查
循环的条件:ros::ok()
1.1,返回false的情况:
1.2对节点使用了rosnode kill 命令。
1.3给程序发送了一个终止信号(Ctrl-C)。
1.4在程序的某个位置调用了ros::shutdown()。以相同的名字启动了其他节点,
经常是因为你启动了一个相同程序的新实例。
2、控制消息发布频率
ros::Rate rate(2);控制循环运行的速度,以赫兹为单位,每秒循环次数。
邻近每次循环迭代的结尾,我们调用此对象的sleep 方法:rate.sleep();
2017.1.14
编写ros订阅者程序
上面发布者发布话题,话题中的消息要读取,这就需要订阅者来调用。
1、编写回调函数
void function_name(const package_name::type_name &msg)
{
. . .
}
其中参数package_name 和type_name 和发布消息时的相同,它们指明了我们想订阅的话题的消息类,当有消息到达时要通过这个指针找到回调函数。
你可以通过对函数名使用符号运算符(&,“取址”)来获得函数的指针。
2、创建订阅者变量
ros::Subscriber sub = node_handle.subscribe
(topic_name,queue_size, pointer_to_callback_function);
node_handle 与我们之前多次见到的节点句柄对象是相同的
topic_name 是我们想要订阅的话题的名称,以字符串的形式表示。
queue_size 是本订阅者接收消息的队列大小,是一个整数。
最后一个参数是指向回调函数的指针
ROS 清空一个发布序列的速率取决于实际上给订阅者传输消息所占用的时间,而这个时间在很大程度上是不受控制的。相反,ROS 清空订阅序列的速度取决于我们处理回调函数有多快。因此,我们可以通过如下两个方法减少订阅者队列溢出的可能性:(1)通过调用ros::spin 或者ros:spinOnce 确保允许回调发生;(2)减少每个回调函数的计算时间。
第四章
日志消息
查看日志消息
日志消息有三个不同的目的地:1、控制台输出2、rosout 话题的消息3、写入到日志文件中。
控制台可以插入时间,日志消息的源代码位置等相应的信息
格式化控制台消息$和{}是用来指出日志消息数据在何处插入
Rosout最大的特点是显示所有的日志消息,而对时间等一些信息并不显示。rostopic echo /rosout
rqt_console
日志文件
文件名类似于:~/.ros/log/run_id/rosout.log
运行标识码(run_id)是一个通用唯一识别码(UUID),它在节点管理
器开始运行时基于你计算机的MAC 地址和当前的时间生成。
查找运行标识码
通过检查roscore 生成的输出,在靠近输出末端的位置,可以
看到与下面内容类似的一行setting /run_id to run_id;
通过以下命令向节点管理器询问当前的run_id:rosparam get /run_id
检查和清除日志文件
相关命令
rosclean check查看当前账户中被ROS日志消耗的硬盘空间
rosclean purge删除所有已经存在的日志
启用和禁用日志消息
ROS 的C++程序默认只生成INFO 或者更高级别的消息,尝试生成DEBUG 级别的消息将会被忽略,所以在日志信息严重级别时不显示。这就是日志级别。
设置某个节点的日志级别
通过命令行设置日志级别:
rosservice call /node-name/set_logger_level ros.package-name level
node-name 是你期望设置日志级别的节点名称
package-name拥有这个节点的功能包的名称
level 参数是DEBUG、INFO、WARN、ERROR、FATAL中的一个字符串,即为节点设置的日志级别。
通过图形界面设置日志级别:rqt_logger_level
通过C++代码设置日志级别:调用ROS来实现日志功能的log4cxx 提供的接口
第五章计算图源命名
计算图资源(如节点、话题、参数和服务等)
全局名称和相对名称:绝对地址都写出来到是全局名称,反之。
相对名称需要设置默认命名空间,使得ros能找到
设置默认命名空间:默认的命名空间是单独地为每个节点设置的,而不是在系统范围进行。最常用的方法是在启动文件中使用命名空间(ns)属性。
_ _ns:=default-namespace
或设置环境变量(但优先是使用命名空间属性)
Export ROS_NAMESPACE=default-namespace
私有名称
私有名称,以一个波浪字符(~)开始,私有名称不是用当前默认命名空间,而是用的它们节点名称作为命名空间。每个节点内部都有这样一些资源,这些资源只与本节点有关,而不会与其他节点打交道,这些资源就可以使用私有名称。私有名称常常用于参数——roslaunch 有专门的功能用于设置私有名称可以访问的的参数;私有名称也用于管理一个节点运算的服务。
匿名名称
匿名名称的目的是使节点的命名更容易遵守唯一性的规则。其思路是,当节点调用ros::init 方法时可以请求一个自动分配的唯一名称。
ros::init(argc, argv, base_name, ros::init_options::AnonymousName);
第六章启动文件
利用启动文件一次性配置和运行多个节点。Roslaunch
roslaunch package-name launch-file-name
启动文件的存储位置:把启动文件直接存储在功能包的根目录。以.launch为后缀来命名。
启动文件的基本元素:若干节点元素和根元素。
插入根元素:
…
每个启动文件的其他元素都应该包含在这两个标签之内。 启动节点: pkg=”package-name” type=”executable-name” name=”node-name” /> 每个节点元素有如下三个必需的属性。 pkg 和type 属性定义了ROS 应该运行哪个程序来启动这个节点。给出功能包名和可执行文件的名称。 name 属性给节点指派了名称,它将覆盖任何通过调用ros::int来赋予节点的名称。 从启动文件启动节点的标准输出被重定向到一个日志文件中,而不是在控制台显示。该日志文件的名称是:~/.ros/log/run_id/node_name-number-stout.log 在控制台中输出信息对于某个单独的节点,只需在节点元素中配置output 属性就可以达到该目的:output=”screen”。 配置了该属性的节点会将标准输出显示在屏幕上而不是记录到之前讨论的日志文档。 使用--screen 命令行选项来令roslaunch 在控制台中显示所有节点的输出:roslaunch –screen package-name launch-file-name 请求复位respawn=”true”当节点停止的时候,roslaunch 会重新启动该节点。 必要节点required=”true”复位之外的另一种策略是将一个节点声明为必要节点。当一个必要节点终止的时候,roslaunch会终止所有其他活跃节点并退出。当出现(1)某个节点非常重要,此节点的故障会导致整个ROS会话的痪;(2)节点即便设置了复位属性也不能很好地重启的时候,该需求属性的作用就会体现出来。由于respawn和required二者的作用是相互矛盾的,因此,如果对一个节点同时配置了这两种属性,roslaunch会报错。 为节点维护独立的窗口Launch-prefix=“command-prefix”xterm 命令将打开一个简单终端窗口。 在命名空间内启动节点 虽然名称一样,但是加上命名空间之后实际的操作是不一样的。这很好的解释了,第6章我们用了命名空间,可以分别操作同时打开的两个乌龟;而第2章中一个键盘操作使得两个乌龟都在动,这是因为两个乌龟订阅的消息和自己的命名空间是一样的。 搞清楚这个对单独操作每一组发布和订阅消息的传递很中重要。在命名空间内启动节点可以达到节点操作独立。 roslaunch 要求启动文件中的节点名称是基名称,即不涉及任何命名空间的相对名称。如果节点元素的名称属性中出现了全局名称,roslaunch 将会报错。 名称重映射 重映射是基于替换的思想:每个重映射包含一个原始名称和一个新名称。每当节点使用重映射中的原始名称时,ROS客户端库就会将它默默地替换成其对应的新名称。 创建重映射 1、命令行时:original-name := new-name 2、启动文件时:只需在启动文件内使用重映射remap元素即可 启动文件的其他元素 1、包含其他文件 2、启动参数:args,功能有点像可执行程序中的局部变量。这样做的优点是通 过设置参数来描述节点在不同ROS会话中运行时可能需要改变的一小部分,从而避免代码重复。 声明启动参数: 参数赋值:命令行中可以roslaunch package-name launch-file-name arg-name:=arg-value 启动文件中可以 两者的唯一区别在于命令行参数可以覆盖默认值default,但是不能覆盖参数值value。 获取参数值:$(arg arg-name) 向包括的启动文件中发送参数 一种常见的情况是两个启动文件(包含文件和被包含文件)有一些共同的参数,在这种情况下,我们希望参数在传递的时候不会改变。这样的元素在两个地方使用相同的参数名: 在该例子中,第一个参数名字通常是指被包含文件中的参数,第二个参数名是指当前文件中的参数。这样做之后,给定参数在两个启动文件中有相同的值。 3、创建组group 启动文件的最后一个特征,即组(group)元素。它提供了一种在大型启动文件内管理节点的便捷方式。具体来讲,组元素可以完成如下两种任务: 1、可以把若干个节点放入同一个命名空间内 … 组内的每个节点都从给定的默认命名空间启动 2、组可以有条件地使能或禁用一个节点 如果if 属性的值为1,则组元素标签内的元素被正常包含。反之,如果if 属性的值为0,则标签内元素被忽略。还有一个unless属性的用法是相似的,只是意思相反。 … 2017.1.16 第7章参数(parameters)用于获取节点信息。其主要思想是使用集中 参数服务器(parameter server)维护一个变量集的值,包括整数、浮点数、字符串以及其他数据类型,每一个变量用一个较短的字符串标识。 1、通过命令行获取参数 查看参数列表:rosparam list 所有的参数都属于参数服务器而不是任何特定的节点。这意味着参数— —即使是由节点创建的——在节点终止时仍将继续存在。 查询参数:rosparam get parameter_name(给定参数名查询) rosparam get namespace(给定命名空间查询) 设置参数:rosparam set parameter_name parameter_value 该命令可以修改已有参数的值或者创建一个新的参数。 创建和加载参数文件: 为了以YAML 文件的形式存储命名空间中的所有参数,可以使用rosparam dump 命令:rosparam dump filename namespace 与dump 相反的命令是load,它从一个文件中读取参数,并将它们添加到参数服务器:rosparam load filename namespace 例子:更改turtlesim的背景色 1、先启动roscore和rosrun turtlesim turtlesim_node 2、获取参数列表:rosparam list 3、获取背景颜色:rosparam get /background_r rosparam get /background_g rosparam get /background_b 4、设置背景颜色:rosparam set /background_r 255 rosparam set /background_g 255 rosparam set /background_b 0 5、当turtlesim_node的/clear服务被调用时,它才会从参数服务器读取这些参 数的值。 命令行执行:rosservice call /clear 通过c++接口得到和设置ros参数: void ros::param::set(parameter_name, input_value); bool ros::param::get(parameter_name, output_value); 在启动文件中设置参数 设置参数: 设置私有参数: . . . 从文件中读取参数: 也可以写成: command="load" file="$(find package-name)/param-file" /> 与rosparam load 一样,这个功能有助于测试,因为它允许用户重现在过去的某个时间有效的参数。 2017.1.16 第8章 消息传递机制尽管是ROS 系统中节点通信的主要方法,但确实受到了一定的限制。本章介绍另一种通信方法,称为服务调用。服务调用与消息的区别在于: 1、服务调用是双向的。 2、服务调用实现的是一对一通信 2017.1.24 服务调用过程:一个客户端节点发送一些称为请求的数据到一个服务器节点,并等待回应。服务器节点接收到请求后,采取一些行动(计算、配置软件或硬件、改变自身行为等),然后发送一些称为响应的数据给客户端节点。 服务数据类型:分两部分,请求、响应。 1、命令行操作 服务通常由节点内部的代码调用。 列出所有服务: rosservice list 命令的输出是所有服务的全局名称 查看某个节点的服务类型: rosnode info node-name 查找提供服务的节点: rosservice node service-name 查找服务的数据类型: rosservice info service-name 服务数据类型有两个部分,其一声明拥有此数据类型的包,其二声明类型本身: turtlesim + Spawn ?turtlesim/Spawn 功能包名类型名服务数据类型 查看服务数据类型: rossrv show service-data-type-name 2016.2.6 从命令行调用服务 rosservice call service-name request-content 客户端程序 1、声明请求和响应的类型 #include 2、创建客户端对象 在按照节点要求初始化后(通过调用ros::init 和创建一个NodeHandle 对象),我们的程序必须创建一个类型为ros::ServiceClient 的对象,实际上是这个对象完成服务调用。 ros::ServiceClient client = node_handle.serviceClient service_name); 3、创建请求和响应对象 创建一个请求对象来容纳送往服务器的数据。 package_name::service_type::Request package_name::service_type::Response 4、调用服务 bool success = service_client.call(request,reponse); 这个方法实际上完成了定位服务器节点、传输请求数据、等待响应和存储响应等一系列工作。 服务器程序 1、编写服务的回调函数 bool function_name( package_name::service_type::Request &req), package_name::service_type::Response &resp) ) { … } 节点提供的每一个服务必须关联一个回调函数。节点每接收到一个服务请求,ROS就执行一次回调函数。参数Request中包含了来自于客户端的数据。回调函数的工作时给Response对象的数据成员赋值。 2、创建服务器对象 ros::ServiceServer server = node_handle.advertiseService( service_name,pointer_to_callback_function); 第9章消息录制与回放 包文件(bag files)是指用于存储时间戳的ROS消息的特殊格式文件。rosbag命令行工具可以录制和回放包文件。 rosbag record -O filename.bag topic-names 也可以rosbagrecord –a对当前发布的所有话题的消息进行记录。 rosbag record –j启用包文件的压缩。 回放文件包 rosbag play filename.bag 检查文件包 rosbag info filename.bag ROS入门实例 https://www.360docs.net/doc/3712808536.html,/tf/Tutorials 基础知识:tf坐标系的变换 1、绘制坐标系信息的图表:rosrun tf view_frames 2、保存并显示图:evince frames.pdf 3、可视化树的结构:rosrun rqt_tf_tree rqt_tf_tree或rqt & 4、两坐标系的交换信息:rosrun tf tf_echo [reference_frame] [target_frame] 5、Rviz可视化工具测试坐标系的关系:rosrun rviz rviz -d `rospack find turtle_tf`/rviz/turtle_rviz.rviz 编写c++程序,发布tf的信息 不懂这里的四元素。