初识ROS机器人操作系统

最近因工作需要,学习了一下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
     

编写程序

  1. 功能包文件夹中创建xxx.cpp文件
  2. 包含依赖库
  3. main函数中 ros::init 最后一个参数为节点默认名
  4. ros::NodeHandle一个程序创建一个对象
      

编译程序

  1. 声明依赖库 (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>
  2. 声明可执行文件
    CMakeLists.txt 中添加两行
    add_executable(executable-name source-files)
    target_link_libraries(executable-name ${catkin_LIBRARIES})
  3. 编译工作区
    从工作区目录运行  catkin_make
  4. source ~/catkin_ws/devel/setup.bash
    每个终端需运行一次,或添加到~/.bashrc文件,这样每次开启终端就会执行

发布消息

  1. 包含消息类型声明
  2. 创建发布者对象
    ros::Publisher pub = node_handle.advertise<message_type>( topic_name, queue_size);topic_name为相对名称
    同一个节点发布关于多个话题的消息,需要为每个话题创建一个独立的 ros::Publisher 对象
    创建一个发布者是一个很耗时的操作
  3. 创建并填充消息对象
  4. 发布消息
    pub.publish(msg);
  5. 定义输出格式
    ROS_INFO_STREAM

节点是否停止工作的检查
ros::ok()
控制消息发布频率
ros::Rate对象 ros::Rate rate(hz); rate.sleep();

订阅消息:

  1. 编写回调函数
    void function_name(const package_name::type_name &msg)
  2. 创建订阅者对象
    创建一个ros::Subscriber对象
    ros::Subscriber sub = node_handle.subscribe (topic_name,queue_size, pointer_to_callback_function)
  3. 给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

  • 一个服务的客户端程序:

    1. 声明请求和响应的类型
    2. 创建客户端对象
      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);
    5. 声明对定义服务类型的功能包的依赖
      编辑CMakeLists.txt的find_package行和清单文件 packag.xml的build_depend、run_depend
  • 服务器程序:

    1. 编写服务的回调函数,给 Response 对象的数据成员赋值
      bool function_name(
      package_name::service_type::Request &req),
      package_name::service_type::Response &resp) ) { }
    2. 创建服务器对象 (service_name局部名称)
      ros::ServiceServer server = node_handle.advertiseService( service_name,pointer_to_callback_function);

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

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

  1. 变量类型与名称之间只能用空格,不能用tab
  2. 数组可以不指定大小。发布端数组不能直接用{}赋值,用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)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值