您的位置:首页 > 其它

初识ROS机器人操作系统

2016-08-24 01:53 513 查看

最近因工作需要,学习了一下ROS(机器人操作系统)。说是系统,其实只是一个运行在Linux下的一个框架,具有强大的分布式功能。下面是总结的一些知识点,懒得仔细整理了。

常用命令

获取所有已安装的ROS软件包列表清单   rospack list

找到一个软件包的目录   rospack find package-name

查看软件包目录下的文件   rosls package-name

将当前目录切换至此软件包目录   roscd package-name

ROS 节点管理器   roscore

启动节点   rosrun package-name executable-name

查看节点列表   rosnode list//这个不太准确,有时node崩溃或ctrl+c退出node还是会在list显示

显式设置节点的名称   rosrun package-name executable-name

查看节点   rosnode info node-name

终止节点   rosnode kill node-name ctrl-c不会立即终止

查看节点之间的连接关系   rqt_graph//这个在多机通信时查找故障非常有用,需安装QT

话题列表   rostopic list

打印消息内容   rostopic echo topic-name//可以检测消息是否发出并接收

测量发布频率   rostopic hz topic-name rostopic bw topic-name

查看话题   rostopic info topic-name

查看消息类型   rosmsg show message-type-name

用命令行发布消息   rostopic pub -r rate-in-hz topic-name

创建工作区   mkdir -p ~/catkin_ws/src

创建功能包   进入src文件夹 catkin_create_pkg package-name

 

编写程序

功能包文件夹中创建xxx.cpp文件

包含依赖库

main函数中 ros::init 最后一个参数为节点默认名

ros::NodeHandle一个程序创建一个对象

  

编译程序

声明依赖库 (package-names roscpp)

CMakeLists.txt中

find_package(catkin REQUIRED COMPONENTS package-names)


package.xml中

<build_depend>package-name</build_depend>


<run_depend>package-name</run_depend>


声明可执行文件

CMakeLists.txt 中添加两行

add_executable(executable-name source-files)


target_link_libraries(executable-name ${catkin_LIBRARIES})
<
c3d4
/li>
编译工作区

从工作区目录运行  catkin_make

source ~/catkin_ws/devel/setup.bash

每个终端需运行一次,或添加到~/.bashrc文件,这样每次开启终端就会执行

发布消息

包含消息类型声明

创建发布者对象

ros::Publisher pub = node_handle.advertise<message_type>( topic_name, queue_size);
topic_name为相对名称

同一个节点发布关于多个话题的消息,需要为每个话题创建一个独立的 ros::Publisher 对象

创建一个发布者是一个很耗时的操作

创建并填充消息对象

发布消息

pub.publish(msg);

定义输出格式

ROS_INFO_STREAM

节点是否停止工作的检查

ros::ok()

控制消息发布频率

ros::Rate对象 ros::Rate rate(hz); rate.sleep();

订阅消息:

编写回调函数

void function_name(const package_name::type_name &msg)


创建订阅者对象

创建一个ros::Subscriber对象

ros::Subscriber sub = node_handle.subscribe (topic_name,queue_size, pointer_to_callback_function)


给ROS控制权

ros::spin() 这个方法要求 ROS 等待并且执行回调函数,相当于
while(1){ros::spinOnce();}


ros::spinOnce()这个代码要求 ROS 去执行所有挂起的回调函数,然后将控制权限返回给我们

日志

每一个日志消息都被发布到话题/rosout 上。该话题的消息类型是rosgraph_msgs/Log

查看/rosout消息:rostopic echo /rosout rqt_console

设置某个节点的日志级别:

1.通过命令行设置日志级别 rosservice call /node-name/set_logger_level ros.package-name level

2.通过图形界面设置日志级别 rqt_logger_level

3.通过 C++代码设置日志级别

名称

全局名称 前斜杠”/”

默认命名空间+相对名称=全局名称

为每个节点设置默认命名空间(不设则使用”/”)

1.ROS 程序 _ _ns:=default-namespace

2.环境变量为在 shell 内执行的 ROS 程序设置默认命名空间 Export ROS_NAMESPACE=default-namespace

3.启动文件 ns=”namespace(最常用)

私有名称 以一个波浪字符(~)开始

节点名+私有名称=全局名称

匿名名称 一般用于为节点命名 ros::init_options::Anonymous-Name 作为第四个参数传递给ros::init 方法

启动文件

.launch 由一个包含若干节点元素(node elements)的根元素(root element)组成

执行启动文件

roslaunch package-name launch-file-name

每个节点元素有如下三个必需的属性

pkg type name

在启动文件内使用一个匿名名称

name=”$(anon base_name)

在控制台中输出信息

output=”screen“

令 roslaunch 在控制台中显示所有节点的输出

roslaunch -screen package-name launch-file-name

请求复位

respawn=”true “这样当节点停止的时候, roslaunch 会重新启动该节点

必要节点

required=”true “当一个必要节点终止的时候,roslaunch 会终止所有其他活跃节点并退出

为节点维护独立的窗口

launch-prefix=”xterm-e”

在启动文件中包含其他文件

include file=”$(find packag-name)/launch-file-name”

名称重映射

创建重映射

1.当使用命令行启动节点时 original-name := new-name

2.通过启动文件的方式

怎样理解重映射??

参数

查看参数列表 rosparam list

查询参数 rosparam get parameter_name

检索给定命名空间中的每一个参数的值 rosparam get namespace

设置参数 rosparam set parameter_name parameter_value

只有当节点的/clear服务被调用时,它才会从参数服务器读取这些参数的值 rosservice call /clear

使用c++获取参数 void ros::param::set(parameter_name, input_value);

bool ros::param::get(parameter_name, output_value);

在启动文件中设置参数
<param name="param-name" value="param-value" />


设置私有参数 在节点元素中包含param元素

服务

服务调用是双向的,一个节点给另一个节点发送信息并等待响应

服务调用实现的是一对一通信

服务数据类型分为两部分,分别表示请求和响应

列出所有服务 rosservice list

查看某个节点的服务类型 rosnode info node-name

查找提供服务的节点 rosservice node service-name

查找服务的数据类型 rosservice info service-name

功能包名+类型名=服务数据类型

查看服务数据类型 rossrv show service-data-type-name

从命令行调用服务 rosservice call service-name request-content

一个服务的客户端程序:

声明请求和响应的类型

创建客户端对象

ros::ServiceClient client = node_handle.serviceClient( service_name);

创建请求和响应对象

package_name::service_type::Request

package_name::service_type::Response

调用服务

bool success = service_client.call(request,reponse);

声明对定义服务类型的功能包的依赖

编辑CMakeLists.txt的find_package行和清单文件 packag.xml的build_depend、run_depend

服务器程序:

编写服务的回调函数,给 Response 对象的数据成员赋值

bool function_name(

package_name::service_type::Request &req),

package_name::service_type::Response &resp) ) { }

创建服务器对象 (service_name局部名称)

ros::ServiceServer server = node_handle.advertiseService( service_name,pointer_to_callback_function);

编译单个或多个package
catkin_make --pkg <package A> <package B>


创建自定义消息msg\srv文件

变量类型与名称之间只能用空格,不能用tab

数组可以不指定大小。发布端数组不能直接用{}赋值,用pushback赋值或resize()指定大小,或逐个赋值。接收端可用size()获取消息变量大小

ros多机通信:

gedit ~/.bashrc

在最下端添加:

export ROS_IP=本机IP

export ROS_MASTER_URI=http://roscore机器IP:11311

最后别忘了source .bashrc一下

我们看到网上绝大多数教程都是循环中按一定频率发布消息,那么如何只发布一条消息呢?

我们启动消息发布节点后,并不能立即连接到订阅节点,即使两个节点在同一台机器上,也会有少许延迟。

所以如果第一次while循环就发布消息,然后结束循环,订阅节点将接收不到。使用发布对象的getNumSubscribers()函数得知已连接到订阅节点时,即可成功发布消息。

ros::Rate loop_rate(1);
static bool first_time = true ;
while(ros::ok()&&first_time)
{
if(pub.getNumSubscribers()>0)
{
pub.publish(base_msg);
ROS_INFO("sending message");
ros::spinOnce();
loop_rate.sleep();
first_time = false;
}
}


ros 节点开机自启

首先尝试了robot_upstart工具,参考http://blog.csdn.net/w383117613/article/details/50254711,发现不存在service robot,原因未知。

然后使用脚本,成功。参考http://ros-users.122217.n3.nabble.com/auto-start-ROS-launch-script-on-boot-up-td1687093.html

1.编写.sh脚本文件

#! /bin/sh
sleep 1m    #开机后等待一分钟再启动
source /opt/ros/indigo/setup.sh
source /catkin_ws/devel/setup.sh
roslaunch hokuyo_node hokuyo_test.launch


2.sudo chmod +x /path/to/script.sh

3.Ubuntu系统Startup Application中,添加启动程序,名称 “rosnome” ,命令gnome-terminal -x /path/to/script.sh

4.设置终端窗口属性为保持打开

程序使用第三方库,需在CMakeList最下面添加link_directories等

include_directories(/usr/include/opencv)

link_directories(/usr/lib/x86_64-linux-gnu)

add_definitions(-D_UNIX_ -D_LINUX_ )

target_link_libraries(执行程序名 ${catkin_LIBRARIES} pthread dl opencv_core opencv_highgui)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息