ROS入门讲义学习笔记1-topic_demo

ROS入门讲义笔记1 - topic_demo

最近开始在学习ROS,几经辗转找到了这个教程。这个教程比较简单,能快速上手,而且视频节奏比较好,不是很墨迹。缺点就是比较面向初学者,不够深入,但是默认你有一些Linux系统操作的基本常识。前面经历的安装环境的坑后面会补上,今天首先记录一下对自己比较有用的第一个package,以便日后复习,同时分享给同样需要的同学们。

资源下载:

  1. 机器人操作系统入门讲义:百度网盘(提取码:mziy)
  2. 视频教程:B站
  3. 教学代码包:GitHub

Topic简介

topic是常用的一种ROS中的通信方式。对于实时性、周期性的消息,使用topic来传输是最佳的选择。topic是一种点对点的单向通信方式,这里的“点”指的是node,也就是说node之间可以通过topic方式来传递信息。

topic是一种异步通信方式,publisher不断发送topic,subscriber可以在需要的时候进行订阅并处理。
topic是N对N的,一个topic可以由多个publisher发布。同时多个subscriber可以订阅同一个topic。
topic使用message进行通信,message通常是自定义的数据结构。
ROS中使用的激光雷达、IMU、相机、里程计等不断发布消息并接收处理的单元,通常都是使用topic来进行通信的。

topic要经历下面几步的初始化过程:首先,publisher节点和subscriber节点都要到节点管理器进行注册,然后publisher会发布topic,subscriber在master的指挥下会订阅该topic,从而建立起sub-pub之间的通信。注意整个过程是单向的。其结构示意图如下:
在这里插入图片描述

topic_demo Package功能描述

两个node,通过message进行通信

  1. talker 节点发布模拟GPS消息(假想出来的,可能是传感器串口/USB读出数据,经过ROS封装发布message)
  2. listener 节点接受并处理该消息
  3. msg 格式自定义,包括坐标和工作状态

步骤

  1. 创建工作空间并初始化
  2. 创建package
  3. 定义msg
  4. 编写cpp文件
  5. 修改CMakeLists.txt & package.xml文件
  6. catkin_make & source setup.bash文件

创建工作空间并初始化

//创建工作空间
$ mkdir -p ~/test_ws/src
$ cd ~/test_ws
//初始化工作空间
$ catkin_make

工作空间名字可以任意取,但是里面必须包含/src。
执行catkin_make后可以看到多出来了build 和 devel 文件夹,build文件夹放的是CMake和catkin的缓存信息和中间文件,devel中存放目标文件,日常只与src打交道。

创建package

//创建package
$ cd ~/test_ws/src
$ catkin_create_pkg topic_demo roscpp std_msgs

使用 [catkin_create_pkg 包名 依赖项] 命令,创建package。

定义msg

//创建msg文件
$ cd ~/test_ws/src/topic_demo
//$ roscd topic_demo  //也可以使用这条命令
$ mkdir msg
$ cd msg
$vi gps.msg//自定义gps.msg文件

gps.msg中需要定义工作状态和坐标

//定义msg
string state
float32 x
float32 y

gps.msg文件编译后会在~/test_ws/devel/include/topic_demo中生成一个gps.h文件,供cpp文件#include使用。

编写cpp

代码放在包的src文件当中。

//创建msg文件
$ cd ~/test_ws/src/topic_demo
$ cd src
$vi talker.cpp//自定义gps.msg文件
  1. talker.cpp
//ROS头文件
#include <ros/ros.h>
//自定义msg产生的头文件
#include <topic_demo/gps.h>

int main(int argc, char **argv)
{
//用于解析ROS参数,第三个参数为本节点名
ros::init(argc, argv, "talker");

//实例化句柄,初始化node
ros::NodeHandle nh;

//自定义gps msg
topic_demo::gps msg;
msg.x = 1.0;
msg.y = 1.0;
msg.state = "working";

//创建publisher。gps_info是topic名称,1是buffer的长度,因为是时发时收的
ros::Publisher pub = nh.advertise<topic_demo::gps>("gps_info", 1);
//定义发布的频率 1Hz
ros::Rate loop_rate(1.0);
//循环发布msg
while (ros::ok())
{
  //以指数增长,每隔1秒更新一次
  msg.x = 1.03 * msg.x ;
  msg.y = 1.01 * msg.y;
  //相当于printf,打印到控制台
  ROS_INFO("Talker: GPS: x = %f, y = %f ",  msg.x ,msg.y);
  //以1Hz的频率发布msg
  pub.publish(msg);
  //根据前面定义的频率, sleep 1s
  loop_rate.sleep();//根据前面的定义的loop_rate,设置1s的暂停
}

return 0;
} 
  1. listener.cpp
//ROS头文件
#include <ros/ros.h>
//包含自定义msg产生的头文件
#include <topic_demo/gps.h>
//ROS标准msg头文件
#include <std_msgs/Float32.h>

void gpsCallback(const topic_demo::gps::ConstPtr &msg)//常指针作为参数,是从gps.h文件中来
{  
   //计算离原点(0,0)的距离
   std_msgs::Float32 distance;//ROS原生Float32结构,只有一个成员,data。
   distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2));
   //float distance = sqrt(pow(msg->x,2)+pow(msg->y,2));
   ROS_INFO("Listener: Distance to origin = %f, state: %s",distance.data,msg->state.c_str());
}

int main(int argc, char **argv)
{
 ros::init(argc, argv, "listener");
 ros::NodeHandle n;
 ros::Subscriber sub = n.subscribe("gps_info", 1, gpsCallback);
 //ros::spin()用于调用所有可触发的回调函数。将进入循环,不会返回,用于阻塞,类似于在循环里反复调用ros::spinOnce()。
 ros::spin(); 
 return 0;
}

修改CMakeLists.txt & package.xml文件

CMakeList.txt 和 package.xml文件都是已经生成的模板,需要在几个地方做一下修改
1.CMakeLists.txt
最前面find_package处,指定依赖项

find_package(catkin REQUIRED COMPONENTS
 message_generation
 roscpp
 std_msgs
)

添加自定义的msg,以及依赖项

## Generate messages in the 'msg' folder
 add_message_files(
   FILES
   gps.msg
 )
//...
## Generate added messages and services with any dependencies listed here
 generate_messages(
   DEPENDENCIES
   std_msgs
 )

catkin配置

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES topic_demo
  CATKIN_DEPENDS  roscpp std_msgs message_runtime
#  DEPENDS system_lib
)

Build中引用头文件,指定头文件路径

include_directories(
 include
  ${catkin_INCLUDE_DIRS}
)

Build最后,Install前,要加上执行文件以及其所需依赖项

add_executable(talker src/talker.cpp )
add_dependencies(talker test1_generate_messages_cpp)
target_link_libraries(talker ${catkin_LIBRARIES})

add_executable(listener src/listener.cpp )
add_dependencies(listener test1_generate_messages_cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
  1. package.xml

需要将原本的< package format=“2” > 中的 format="2"去掉,教程中给出的都是< run depend >, fomat="2"的话给出的都是 < exec_depend >,这个在后文中也需要修改。
在原有代码的基础上添加

  <build_depend>message_generation</build_depend>
  <run_depend>message_runtime</run_depend>

修改之后的文件如下

<?xml version="1.0"?>
<package>
 <name>topic_demo</name>
 <version>0.0.0</version>
 <description>The topic_demo package</description>

 <! ....... -->
 <buildtool_depend>catkin</buildtool_depend>
 <build_depend>message_generation</build_depend>
 <build_depend>roscpp</build_depend>
 <build_depend>rospy</build_depend>
 <build_depend>std_msgs</build_depend>
 <run_depend>roscpp</run_depend>
 <run_depend>rospy</run_depend>
 <run_depend>std_msgs</run_depend>
 <run_depend>message_runtime</run_depend>
 
 <!-- The export tag contains other, unspecified, tags -->
 <export>
   <!-- Other tools can request additional information be placed here -->
 </export>
</package>

catkin_make & source setup.bash文件

这一步就是进行编译。
首先回到工作空间,catkin_make需要在工作空间内执行

$ cd ~/test_ws //回到工作空间
$ catkin_make

注意!!!编译之后需要刷新环境,指定包在哪里,要不然生成的可执行文件可能无法运行。

$ source ~/test_ws/devel/setup.bash

source指令的生命周期只在terminal打开期间,如果常用该工作空间的话,可以将setup.bash文件写入~/.bashrc,这样就不用每次开一个terminal的时候都执行一遍source命令

$ echo "source ~/test_ws/devel/setup.bash" >> ~/.bashrc

以上就是编写的全部工作,下面来进行一下测试

测试

  1. 开启master节点
    打开一个终端,输入
$ roscore

运行master节点,因为所有的publisher和subscriber都需要在master上进行注册才能通信。
在这里插入图片描述
2. 运行talker
开启另一个终端,输入

$ rosrun topic_demo talker

可以看到之前编写的模拟GPS程序发布情况
在这里插入图片描述
3. 运行listener
再开启一个终端,输入

$ rosrun topic_demo listener

即可看到模拟接收的结果
在这里插入图片描述

以上就是对topic这种通信方式的学习和总结,希望对你也有帮助。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值