ROS学习笔记(二):ROS话题的发布与订阅

这篇具有很好参考价值的文章主要介绍了ROS学习笔记(二):ROS话题的发布与订阅。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第十讲  发布者Publisher的编程
1. 创建功能包 learning_topic 
$ cd ~/test1/src 
$ catkin_create_pkg learning_topic std_msgs rospy roscpp geometry_msgs turtlesim

2.执行C++文件程序如下:放在创建的功能包的/learning_topic/src里 程序名为velocity_publisher.cpp

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

int main(int argc, char **argv)
{
    // ROS节点初始化
    ros::init(argc, argv, "velocity_publisher");  //velocity_publisher 节点名称,不能和其他节点名称相同

    // 创建节点句柄
    ros::NodeHandle n; //用于管理API资源,发布者

    // 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型(数据结构)为geometry_msgs::Twist,"/turtle1/cmd_vel":发布的话题名,队列长度10
    ros::Publisher turtle_vel_pub = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 10);

    // 设置循环的频率
    ros::Rate loop_rate(10);

    int count = 0;
    while (ros::ok())
    {
        // 初始化geometry_msgs::Twist类型的消息(内容)
        geometry_msgs::Twist vel_msg; //创建Twist消息类对象
        vel_msg.linear.x = 0.5;
        vel_msg.angular.z = 0.2;

        // 发布消息
        turtle_vel_pub.publish(vel_msg);
        ROS_INFO("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]", 
                vel_msg.linear.x, vel_msg.angular.z);

        // 按照循环频率延时
        loop_rate.sleep();
    }

    return 0;
}

2.如何实现一个发布者(发布到ros自带节点 )
(1)初始化ROS节点
(2)向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型
(3)创建消息数据
(4)按照一定频率循环发送消息
(5)如何配置CMakeList.txt中的编译规则
     设置需要编译的代码和生成的可执行文件
     设置链接库
     将下面两句话复制到功能包learning_topic里面的CMakeList.txt,放在文件中## Build ##的下面,## Install ##的上面   中间需要空一行
     add_executable(velocity_publisher src/velocity_publisher.cpp) #把哪一个cpp文件编译成那一个可执行文件

     target_link_libraries(velocity_publisher ${catkin_LIBRARIES}) #把可执行文件和ROS相关库作链接


 (6)编译 $ cd ~/test1  (回到工作空间的根目录)
          $ catkin_make (出现100%说明编译成功)
  (7)设置环境变量 (在主文件夹下(带下载,图片的那个)按ctrl + H,显示隐藏文件.bashrc)
                  终端输入:gedit ~/.bashrc
          - 文件打开后直接翻到最后面
          - 在底部添加source ~/test1/devel/setup.bash  (test1替换掉)路径写错在下一步打开终端时会报错
          - 保存退出即可(通过该方法设置的环境变量以后执行该工作空间的程序时都不用再添加了)
  (8)运行节点(重新打开三个终端,依次运行三个节点) $ roscore    $ rosrun turtlesim turtlesim_node $ rosrun  learning_topic velocity_publisher
  (9)编译生成的 velocity_publisher 在~/test1/devel/lib/learning_topic下  

3.执行Python文件
在learning_topic文件夹下创建一个文件夹scripts来存储.py程序 程序名为velocity_publisher.py,然后到scripts文件夹内将.py文件右键->属性->权限->允许作为程序执行文件 打钩

程序如下:

import rospy
from geometry_msgs.msg import Twist

def velocity_publisher():
    # ROS节点初始化
    rospy.init_node('velocity_publisher', anonymous=True)

    # 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
    turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)

    #设置循环的频率
    rate = rospy.Rate(10) 

    while not rospy.is_shutdown():
        # 初始化geometry_msgs::Twist类型的消息
        vel_msg = Twist()
        vel_msg.linear.x = 0.5
        vel_msg.angular.z = 0.2

        # 发布消息
        turtle_vel_pub.publish(vel_msg)
        rospy.loginfo("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]", 
                vel_msg.linear.x, vel_msg.angular.z)

        # 按照循环频率延时
        rate.sleep()

if __name__ == '__main__':
    try:
        velocity_publisher()
    except rospy.ROSInterruptException:
        pass


        
运行节点(重新打开三个终端,依次运行三个节点) $ roscore    $ rosrun turtlesim turtlesim_node  $rosrun learning_topic 双击Tab键会出现.py文件, $ rosrun learning_topic elocity_publisher.py 直接运行节点
 
第十一讲  订阅者Subscrier的编程1. 将下面程序放在创建的功能包的/learning_topic/src里 命名为:pose_subscriber.cpp
/**
 * 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose
 */
 

#include <ros/ros.h>
#include "turtlesim/Pose.h"

// 接收到订阅的消息后,会进入消息回调函数
void poseCallback(const turtlesim::Pose::ConstPtr& msg)
{
    // 将接收到的消息打印出来
    ROS_INFO("Turtle pose: x:%0.6f, y:%0.6f", msg->x, msg->y);
}

int main(int argc, char **argv)
{
    // 初始化ROS节点
    ros::init(argc, argv, "pose_subscriber");

    // 创建节点句柄
    ros::NodeHandle n;

    // 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
    ros::Subscriber pose_sub = n.subscribe("/turtle1/pose", 10, poseCallback);

    // 循环等待回调函数
    ros::spin();

    return 0;
}

2.如何实现一个订阅者
(1)初始化ROS节点
(2)订阅需要的话题
(3)循环等待话题消息,接收到消息后进入回调函数(类似中断)
(4)在回调函数中完成消息处理
(5)配置CMakeList.txt中的编译规则
     设置需要编译的代码和生成的可执行文件
     设置链接库
     将下面两句话复制到功能包learning_topic里面的CMakeList.txt,放在文件中## Build ##的下面,## Install ##的上面
     add_executable(pose_subscriber src/pose_subscriber.cpp) #把哪一个cpp文件编译成那一个可执行文件
     target_link_libraries(pose_subscriber ${catkin_LIBRARIES}) #把可执行文件和ROS相关库作链接
 (6)编译 $ cd ~/test1  (回到工作空间的根目录)
          $ catkin_make (出现100%说明编译成功)
  (7)设置环境变量 (在主文件夹下(带下载,图片的那个)按ctrl + H,显示隐藏文件.bashrc)
                  终端输入:gedit ~/.bashrc
          - 文件打开后直接翻到最后面
          - 在底部添加source ~/test1/devel/setup.bash  (test1替换掉)路径写错在下一步打开终端时会报错
          - 保存退出即可(通过该方法设置的环境变量以后执行该工作空间的程序时都不用再添加了)
  (8)运行节点(重新打开三个终端,依次运行三个节点) $ roscore    $ rosrun turtlesim turtlesim_node $ rosrun  learning_topic velocity_publisher
  (9)编译生成的 velocity_publisher 在~/test1/devel/lib/learning_topic下 

# 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose

import rospy
from turtlesim.msg import Pose

def poseCallback(msg):
    rospy.loginfo("Turtle pose: x:%0.6f, y:%0.6f", msg.x, msg.y)

def pose_subscriber():
    # ROS节点初始化
    rospy.init_node('pose_subscriber', anonymous=True)

    # 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
    rospy.Subscriber("/turtle1/pose", Pose, poseCallback)

    # 循环等待回调函数
    rospy.spin()

if __name__ == '__main__':
    pose_subscriber()

运行节点(重新打开四个终端,依次运行四个节点) $ roscore    $ rosrun turtlesim turtlesim_node  $rosrun learning_topic 双击Tab键会出现.py文件, 
                                          $ rosrun learning_topic elocity_publisher.py   $ rosrun learning_topic pose_subscriber.py 直接运行节点  

第十二讲  话题消息的自定义与使用(!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)

1. 如何自定义话题消息
Person.msg 文件内容如下需要根据不同的语言配置数据类型,下面是C++ 

string name
uint8 sex
uint8 age

uint8 unknown = 0  相当于宏定义,可以利用这些宏来表达性别
uint8 male = 1
uint8 female = 2

(1)定义msg文件
    在learning_topic文件夹内自定义文件夹msg,存放与消息相关的定义
    终端在msg文件夹内打开,利用 $ touch Person.msg 创建消息文件,然后将自定义数据粘贴进去
    string name
    uint8 sex
    uint8 age

    uint8 unknown = 0  
    uint8 male = 1
    uint8 female = 2
    
(2)在learning_topic中的package.xml中添加功能包依赖,动态生成程序,放到最下面有一对类似的放一起 (<export>的上面)
    <build_depend>message_generation</build_depend>
    <exec_depend>message_runtime</exec_depend>
    
(3)在learning_topic中的CMakeList.txt添加编译选项 
      1.在find_package(最上面)中加入message_generation功能包
     find_package(...... message_generation)
    
      2.添加编译FILES Person.msg的依赖,将下面添加到generate_messages的下面(## Declare ROS dynamic reconfigure parameters ##的上面)
    add_message_files(FILES Person.msg)
    generate_messages(DEPENDENCIES std_msgs)
    
      3.创建message运行的依赖,将catkin_package中的CATKIN_DEPENDS那一行取消注释,然后添加到后面    
    catkin_package(...... message_runtime)
(4)编译生成语言相关文件 回到工作空间目录,利用$ catkin_make 编译,生成的文件在devel/include/learning_topic/Person.h

(5)创建发布者/订阅者代码C++  /**
 * 该例程将发布/person_info话题,自定义消息类型learning_topic::Person   代码名称:person_publisher.cpp
 */
 

#include <ros/ros.h>
#include "learning_topic/Person.h"

int main(int argc, char **argv)
{
    // ROS节点初始化
    ros::init(argc, argv, "person_publisher");

    // 创建节点句柄
    ros::NodeHandle n;

    // 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10
    ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info", 10);

    // 设置循环的频率
    ros::Rate loop_rate(1);

    int count = 0;
    while (ros::ok())
    {
        // 初始化learning_topic::Person类型的消息
        learning_topic::Person person_msg;
        person_msg.name = "Tom";
        person_msg.age  = 18;
        person_msg.sex  = learning_topic::Person::male;

        // 发布消息
        person_info_pub.publish(person_msg);

           ROS_INFO("Publish Person Info: name:%s  age:%d  sex:%d", 
                  person_msg.name.c_str(), person_msg.age, person_msg.sex);

        // 按照循环频率延时
        loop_rate.sleep();
    }

    return 0;
}

/**
 * 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person  代码名称:person_subscriber.cpp
 */
 

#include <ros/ros.h>
#include "learning_topic/Person.h"

// 接收到订阅的消息后,会进入消息回调函数
void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{
    // 将接收到的消息打印出来
    ROS_INFO("Subcribe Person Info: name:%s  age:%d  sex:%d", 
             msg->name.c_str(), msg->age, msg->sex);
}

int main(int argc, char **argv)
{
    // 初始化ROS节点
    ros::init(argc, argv, "person_subscriber");

    // 创建节点句柄
    ros::NodeHandle n;

    // 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallback
    ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);

    // 循环等待回调函数
    ros::spin();

    return 0;
}

(6)编译上面的两个C++文件,将下面6句添加到learning_topic中的CMakeList.txt, 放在文件中## Build ##的下面,## Install ##的上面


     add_executable(person_publisher src/person_publisher.cpp) 
     target_link_libraries(person_publisher ${catkin_LIBRARIES}) 
     add_dependencies(person_publisher ${PROJECT_NAME}_generate_messages_cpp)
     
     add_executable(person_subscriber src/person_subscriber.cpp) 
     target_link_libraries(person_subscriber ${catkin_LIBRARIES}) 
     add_dependencies(person_subscriber ${PROJECT_NAME}_generate_messages_cpp)
     
 (7)依次打开三个终端运行三个节点,$ roscore  $ rosrun learning_topic person_subscriber  $ rosrun learning_topic person_publisher    (PS:先运行person_subscriber节点让它等待)
     文章来源地址https://www.toymoban.com/news/detail-444747.html

到了这里,关于ROS学习笔记(二):ROS话题的发布与订阅的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 随手笔记——将ROS图像话题转为OpenCV图像格式处理后再转为ROS图像话题发布(C++版)

    将ROS图像话题转为OpenCV图像格式处理后再转为ROS图像话题发布,主要通过cv_bridge的toImageMsg()和toCvCopy()函数(C++版)。 ​ 代码来自wiki

    2024年02月12日
    浏览(32)
  • 随手笔记——通过OpenCV获取图像转为ROS图像话题发布(C++版)

    通过OpenCV获取图像转为ROS图像话题发布 注:sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), “bgr8”, image).toImageMsg(); //核心代码

    2024年02月12日
    浏览(25)
  • Fast DDS(1)编写一个简单的C++发布者和订阅者应用程序

            本次我们详细介绍如何使用C++API逐步创建一个简单的Fast DDS应用程序,其中包含发布者和订阅者。也可以使用eProsima Fast DDS-Gen工具自行生成与本节中实现的示例相类似的示例。在构建发布/订阅应用程序中解释了这种附加方法。 ​​​​​​​1.3.1  背景介绍    

    2024年02月12日
    浏览(32)
  • 【ROS】ROS1人机界面开发:第一个最简ROS+QtGui程序(按钮启动发布者)

    1)新建工程:Other Project -- ROS Workspace 2)设置工程名称、路径 3)可以通过点击“Browse”来创建目录 注意:使用自带ros插件的qtcreator-ros,无法创建目录、也不能选择目录,这是个bug,因此需要在终端手动创建目录,并将目录路径手动输入“Workspace Path”中 4)如果是作为子工

    2024年02月16日
    浏览(46)
  • ROS2学习笔记三:话题Topic

    目录 前言 1 话题简介 2 常用指令 3 RCLCPP实现实现话题 3.1 创建工作空间 3.2 代码编写 3.2.1 发布端编写 3.2.2 发布端编写 ROS2中的一个重要概念是话题(Topic)。话题是一种通过发布者和订阅者之间进行异步通信的机制。发布者(Publisher)将消息发布到特定的话题上,而订阅者(

    2024年01月20日
    浏览(32)
  • [ros][ubuntu]ros在ubuntu18.04上工作空间创建和发布一个话题

    构建catkin工作空间  mkdir -p ~/catkin_ws/src    cd ~/catkin_ws/src  catkin_init_workspace  cd ~/catkin_ws/  catkin_make 配置环境变量  echo \\\"source ~/catkin_ws/devel/setup.bash\\\"  ~/.bashrc  source ~/.bashrc 检查环境变量  echo $ROS_PACKAGE_PATH 遇到错误:上面操作不需要用sudo 进行操作,但是由于初学者可能存在

    2024年02月10日
    浏览(34)
  • 学习SLAM:SLAM进阶(九)以激光点云赋色为例讲述如何自定义ROS的消息格式并实现消息的订阅与发布

    目录 1 为什么需要自定义的ROS消息格式 1.1 简介 1.2 ROS自定义消息格式的通用结构

    2024年02月09日
    浏览(26)
  • 【ROS】ROS 发布和订阅压缩图像消息 CompressedImage

    参考 cv_bridge 文档 其中 “jpg” 表示将图像压缩的目标格式,还有很多其他参数可选,如下所示 但亲测 “jpg” 压缩比最大,图像传输占用的带宽最少 其中 “bgr8” 表示将图像解析为 “bgr8” 格式,也是 opencv 默认的图像格式 参考 rospy wiki 教程 参考 opencv 中 imencode 与 imdecod

    2024年04月16日
    浏览(27)
  • ROS学习——通信机制(话题通信③—注意事项)

    2.1.2 话题通信基本操作A(C++) · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程   043话题通信(C++)4_注意事项_Chapter2-ROS通信机制_哔哩哔哩_bilibili 1. int main(int argc, char const *argv[]){} vscode 中的 main 函数 声明 int main(int argc, char const *argv[]){},默认生成 argv 被 const 修饰,需要

    2024年02月08日
    浏览(34)
  • (七)「消息队列」之 RabbitMQ 发布者确认(使用 .NET 客户端)

    发布者确认 是一个 RabbitMQ 扩展,用于实现可靠的发布。当在通道上启用发布者确认时,客户端发布的消息将由代理 异步确认 ,这意味着它们已在服务器端得到处理。 先决条件 本教程假设 RabbitMQ 已安装并且正在 本地主机 的标准端口( 5672 )上运行。如果您使用了不同的主

    2024年02月16日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包