ROS2机器人编程简述humble-第二章-Publishing and Subscribing .3.2

news2024/11/14 15:25:06

ROS2机器人编程简述humble-第二章-Controlling the Iterative Execution .3.1

官方示例pub和sub使用std_msgs/msg/string.hpp,数据类型std_msgs::msg::String。

这本书中使用是std_msgs/msg/int32.hpp,数据类型:std_msgs::msg::Int32。

对于机器人系统而言,实际情况下pub/sub对应于传感器数据的发布和接收。

比如激光/图像等。

ros2案例通常都用类来实现各种功能,需要具备现代C++基础。

具体参考:

蓝桥ROS机器人之现代C++学习笔记支持C++17(已完成)

推荐掌握C++17/20之后,也就是在此基础上开启ROS2的学习之路。

不推荐如下方式:

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/int32.hpp"

using namespace std::chrono_literals;

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);

  auto node = rclcpp::Node::make_shared("publisher_node");
  auto publisher = node->create_publisher<std_msgs::msg::Int32>(
    "int_topic", 10);

  std_msgs::msg::Int32 message;
  message.data = 0;

  rclcpp::Rate loop_rate(500ms);
  while (rclcpp::ok()) {
    message.data += 1;
    publisher->publish(message);

    rclcpp::spin_some(node);
    loop_rate.sleep();
  }

  rclcpp::shutdown();
  return 0;
}

std_msgs::msg::Int32推荐如下

pub发布:

#include "rclcpp/rclcpp.hpp"

#include "std_msgs/msg/int32.hpp"

using namespace std::chrono_literals;
using std::placeholders::_1;

class PublisherNode : public rclcpp::Node
{
public:
  PublisherNode()
  : Node("publisher_node")
  {
    publisher_ = create_publisher<std_msgs::msg::Int32>("int_topic", 10);
    timer_ = create_wall_timer(
      500ms, std::bind(&PublisherNode::timer_callback, this));
  }

  void timer_callback()
  {
    message_.data += 1;
    publisher_->publish(message_);
  }

private:
  rclcpp::Publisher<std_msgs::msg::Int32>::SharedPtr publisher_;
  rclcpp::TimerBase::SharedPtr timer_;
  std_msgs::msg::Int32 message_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);

  auto node = std::make_shared<PublisherNode>();

  rclcpp::spin(node);

  rclcpp::shutdown();
  return 0;
}

String

#include <chrono>
#include <functional>
#include <memory>
#include <string>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

/* This example creates a subclass of Node and uses std::bind() to register a
* member function as a callback from the timer. */

class MinimalPublisher : public rclcpp::Node
{
  public:
    MinimalPublisher()
    : Node("minimal_publisher"), count_(0)
    {
      publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
      timer_ = this->create_wall_timer(
      500ms, std::bind(&MinimalPublisher::timer_callback, this));
    }

  private:
    void timer_callback()
    {
      auto message = std_msgs::msg::String();
      message.data = "Hello, world! " + std::to_string(count_++);
      RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
      publisher_->publish(message);
    }
    rclcpp::TimerBase::SharedPtr timer_;
    rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
    size_t count_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalPublisher>());
  rclcpp::shutdown();
  return 0;
}

sub接收:

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/int32.hpp"

using std::placeholders::_1;

class SubscriberNode : public rclcpp::Node
{
public:
  SubscriberNode()
  : Node("subscriber_node")
  {
    subscriber_ = create_subscription<std_msgs::msg::Int32>(
      "int_topic", 10,
      std::bind(&SubscriberNode::callback, this, _1));
  }

  void callback(const std_msgs::msg::Int32::SharedPtr msg)
  {
    RCLCPP_INFO(get_logger(), "Hello %d", msg->data);
  }

private:
  rclcpp::Subscription<std_msgs::msg::Int32>::SharedPtr subscriber_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);

  auto node = std::make_shared<SubscriberNode>();

  rclcpp::spin(node);

  rclcpp::shutdown();
  return 0;
}

String

#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using std::placeholders::_1;

class MinimalSubscriber : public rclcpp::Node
{
  public:
    MinimalSubscriber()
    : Node("minimal_subscriber")
    {
      subscription_ = this->create_subscription<std_msgs::msg::String>(
      "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1));
    }

  private:
    void topic_callback(const std_msgs::msg::String & msg) const
    {
      RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg.data.c_str());
    }
    rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalSubscriber>());
  rclcpp::shutdown();
  return 0;
}

注意,代码的区别。

另一个重点!!!

rclcpp::QoS

pub和sub的QoS要匹配!

ROS 2提供了多种服务质量(QoS)策略,允许调整节点之间的通信。使用正确的服务质量策略集,ROS 2可以像TCP一样可靠,也可以像UDP一样尽最大努力,其间有许多可能的状态。与ROS 1不同,ROS 1主要只支持TCP,ROS 2受益于底层DDS传输在有损无线网络环境中的灵活性,在这种环境中,“尽力而为”策略更为合适,或者在实时计算系统中,需要正确的服务质量配置文件来满足截止日期。

一组QoS“策略”组合起来形成一个QoS“配置文件”。考虑到为给定场景选择正确的QoS策略的复杂性,ROS 2为常见用例(例如传感器数据)提供了一组预定义的QoS配置文件。同时,开发人员可以灵活地控制QoS配置文件的特定策略。

可以为发布者、订阅、服务服务器和客户端指定QoS配置文件。QoS配置文件可以独立地应用于上述实体的每个实例,但是如果使用不同的配置文件,则它们可能不兼容,从而阻止消息的传递。

QoS兼容性

注意:本节涉及发布者和订阅,但内容同样适用于服务器和客户端。

可以独立地为发布者和订阅配置QoS配置文件。只有当发布者和订阅之间具有兼容的QoS配置文件时,才会建立该对之间的连接。

QoS配置文件兼容性是基于“请求与提供”模型确定的。订阅请求的QoS配置文件是它愿意接受的“最低质量”,而发布者提供的QoS配置是它能够提供的“最高质量”。仅当所请求的QoS配置文件的每个策略不比所提供的QoS配置的每个策略更严格时,才进行连接。多个订阅可以同时连接到单个发布者,即使它们请求的QoS配置文件不同。发布者与订阅之间的兼容性不受其他发布者和订阅的影响。

下表显示了不同策略设置的兼容性及其结果:

可靠性QoS策略的兼容性:

Publisher

Subscription

Compatible

Best effort

Best effort

Yes

Best effort

Reliable

No

Reliable

Best effort

Yes

Reliable

Reliable

Yes

耐久性QoS策略的兼容性:

Publisher

Subscription

Compatible

Volatile

Volatile

Yes

Volatile

Transient local

No

Transient local

Volatile

Yes

Transient local

Transient local

Yes

最后期限QoS策略的兼容性:

假设x和y是任意有效的持续时间值。

Publisher

Subscription

Compatible

Default

Default

Yes

Default

x

No

x

Default

Yes

x

x

Yes

x

y (where y > x)

Yes

x

y (where y < x)

No

活泼QoS策略的兼容性:

Publisher

Subscription

Compatible

Automatic

Automatic

Yes

Automatic

Manual by topic

No

Manual by topic

Automatic

Yes

Manual by topic

Manual by topic

Yes

租赁期限QoS策略的兼容性:

假设x和y是任意有效的持续时间值。

Publisher

Subscription

Compatible

Default

Default

Yes

Default

x

No

x

Default

Yes

x

x

Yes

x

y (where y > x)

Yes

x

y (where y < x)

No

为了建立连接,所有影响兼容性的策略都必须兼容。例如,即使请求的和提供的QoS配置文件对具有兼容的可靠性QoS策略,但它们具有不兼容的耐久性QoS策略,仍然不会建立连接。

未建立连接时,发布者和订阅之间不会传递任何消息。有检测这种情况的机制,这将在后面的章节中介绍。

服务质量事件

某些QoS策略可能有与之相关的事件。开发人员可以为每个发布者和订阅提供由这些QoS事件触发的回调函数,并以他们认为合适的方式处理它们,类似于主题上接收的消息的处理方式。

开发人员可以订阅与发布者关联的以下QoS事件:

错过了提供的截止日期

发布者未在期限QoS策略规定的预期持续时间内发布消息。

失去活力

出版商未能在租约期限内表明其活跃程度。

提供不兼容的QoS

发布者遇到了同一主题的订阅,该订阅请求提供的QoS配置文件无法满足的QoS配置,导致发布者与该订阅之间没有连接。

开发人员可以订阅与订阅相关联的以下QoS事件:

请求的截止日期已错过

订阅在期限QoS策略规定的预期持续时间内未收到消息。

生活改变了

订阅已注意到订阅主题的一个或多个发布者未能在租约期限内显示其活跃状态。

请求的不兼容QoS

订阅遇到了同一主题的发布者,该发布者提供的QoS配置文件不满足请求的QoS配置,导致订阅与该发布者之间没有连接。

具体参考书和官网,如上是机器翻译。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Servlet —— Servlet API

JavaEE传送门JavaEE Servlet —— Tomcat, 初学 Servlet 程序 Servlet —— Smart Tomcat,以及一些访问出错可能的原因 目录Servlet APIHttpServletHttpServletRequest获取 GET 请求中的参数获取 POST 请求的参数HttpServletResponseServlet API 虽然 Servlet 提供的类和方法…

【UE4 第一人称射击游戏】53-制作烟雾弹

上一篇&#xff1a;【UE4 第一人称射击游戏】52-手榴弹攻击丧尸本篇效果&#xff1a;按F键掷出烟雾弹&#xff0c;伴随产生音效和烟雾效果本篇步骤&#xff1a;拷贝一份“GrenadeActor”命名为“SmokeGrenadeActor”双击打开“SmokeGrenadeActor”&#xff0c;删除如下节点改变…

尚医通-医院详情功能(二十七)

目录&#xff1a; &#xff08;1&#xff09;前台用户系统-医院详请-情接口开发 &#xff08;2&#xff09;前台用户系统-技术点-nuxt路由 &#xff08;3&#xff09;前台用户系统-医院详情-前端整合 &#xff08;1&#xff09;前台用户系统-医院详-情接口开发 现在做在页面…

13 Java异常(异常过程解析、throw、throws、try-catch关键字)

文章目录13 异常13.1 异常概念13.2 异常的产生过程解析13.3 异常的阐释和处理13.3.1 throw关键字13.3.2 throws关键字13.3.3 try-catch代码块13.3.4 try-catch-finally代码块Java中final、finally和finalize相似点和区别13.3.5 自定义异常13 异常 13.1 异常概念 异常&#xff…

SpringCloud(12):Zuul路由网关

1 为什么需要服务网关 在分布式系统系统中&#xff0c;有商品、订单、用户、广告、支付等等一大批的服务&#xff0c;前端怎么调用呢&#xff1f;和每个服务一个个打交道&#xff1f;这显然是不可能的&#xff0c;这就需要有一个角色充当所有请求的入口&#xff0c;这个角色就是…

【C++】从0到1入门C++编程学习笔记 - 实战篇:通讯录管理系统

文章目录一、需求分析二、创建项目2.1 创建新项目2.1 添加文件三、菜单功能四、退出功能五、添加联系人5.1 设计联系人结构体5.2 设计通讯录结构体5.3 main 函数中创建通讯录5.4 封装添加联系人函数5.5 测试添加联系人功能六、显示联系人6.1 封装显示联系人函数6.2 测试显示联系…

STM32F103和AIR32F103的FreeRTOS中断优先级

关于 Arm Cortex M 系列内核的中断优先级 Cortex M 的中断和优先级 首先要区分开 中断 和 中断优先级 这是两个不同的东西, 不要搞混了 对于 Cortex-M0 和 Cortex-M0 内核, 除了系统内建中断外, 支持最多 32 个中断对于 Cortex-M3 内核, 除了 16 个内核中断外, 支持最多 240…

前端初学者的Ant Design Pro V6总结(上)

前端初学者的Ant Design Pro V6总结&#xff08;上&#xff09; 一、UI组件开发流程 () > {} 通用&#xff08;异步&#xff09;函数useEmotionCss 定义CSSuseModel获取全局状态useCallback 处理React合成事件JSX 拆分组件initiateState 中CurrentUser空值处理initiateSta…

8. 数字类型讲解

python3 数字类型的使用 1. 基础知识 Python 数字数据类型用于存储数值。 数据类型是不允许改变的,这就意味着如果改变数字数据类型的值&#xff0c;将重新分配内存空间。 可以使用del语句删除一些数字对象的引用。 del var1[,var2[,var3[....,varN]]]Python 支持三种不同的…

计算机视觉算法——基于深度学习的高精地图算法(HDMapNet / VectorMapNet / MapTR / VectorNet)

计算机视觉算法——基于深度学习的高精地图算法&#xff08;HDMapNet / VectorMapNet / MapTR / VectorNet&#xff09;计算机视觉算法——基于深度学习的高精地图算法&#xff08;HDMapNet / VectorMapNet / MapTR / VectorNet&#xff09;1. HDMapNet1.1 网络结构及特点1.1.1…

SAP SD 自定义销售订单审批状态

自定义销售订单审批状态 销售订单可以在其抬头或者项目中定义审批状态&#xff0c;一般在抬头定义的话就相当于针对整单的审批&#xff0c;可以实现多级审批&#xff0c;每级审批设置能进行何种操作&#xff0c;这里就需要在IMG中定义审批状态参数文件。 一、定义状态参数文件…

[精] MySQL和Oracle下Mybatis批量操作示例和获取影响行数介绍

手打不易&#xff0c;如果转摘&#xff0c;请注明出处&#xff01; 注明原文&#xff1a;https://zhangxiaofan.blog.csdn.net/article/details/117933877 目录 前言 Mybatis 执行器 表结构定义 Mybatis批量新增 批量新增——Mysql写法 批量新增——Oracle写法 Mybatis批…

【甄选靶场】Vulnhub百个项目渗透——项目五十四:jarbas-1(类git反弹shell,计划任务提权)

Vulnhub百个项目渗透 Vulnhub百个项目渗透——项目五十四&#xff1a;jarbas-1&#xff08;类git反弹shell,计划任务提权&#xff09; &#x1f525;系列专栏&#xff1a;Vulnhub百个项目渗透 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; …

SpringMvc源码分析(四) 请求执行过程之执行MethodHandler

在上文SpringMvc源码分析&#xff08;三&#xff09;中我们分析了DispatcherServlet类中的doDispatcher方法&#xff0c; 并通过分析方法1和方法2了解了请求执行时是怎么获取MethodHandler链的&#xff0c;本文接上文继续分析方法3、方法4和方法5了解MethodHandler是如何执行的…

springboot rabbitmq 非阻塞重试机制实现

重试的应用场景 比如&#xff0c;系统之间同步数据&#xff0c;A系统发送数据给B系统&#xff0c;因为网络原因或者B系统正在重启&#xff0c;可能收不到信息&#xff0c;为了确保B能收到消息就得重试几次&#xff1b;经典的比如&#xff0c;微信支付回调 对后台通知交互时&am…

VScode远程连接Linux

文章目录一、下载安装二、使用三、连接四、基本操作五、VScode内置命令行六、推荐插件一、下载安装 下载的问题就不用多说了把&#xff0c;可能存在的问题就是下载的速度比较慢 前往官网进行下载&#xff1a;前往官网找到适合自己的版本&#xff1a; 但是由于官网是国外的&am…

DT-6_TTL-WiFi透传模块介绍

DT-6_TTL-WiFi透传模块简介TTL-WiFi模块基于ESP-M2WiFi 模块研发&#xff0c;引出串口TTL、EN、STATE等引脚。产品内置我司最新版本的串口透传固件可完成设备TTL 端口到WiFi/云的数据实时透传&#xff0c;具备低功耗控制&#xff0c;状态指示等功能。本模块可直接取代原有的有线…

【手写 Vue2.x 源码】第三十二篇 - diff算法-乱序比对

一&#xff0c;前言 上篇&#xff0c;diff算法-比对优化&#xff08;下&#xff09;&#xff0c;主要涉及以下几个点&#xff1a; 介绍了儿子节点比较的流程介绍并实现了头头、尾尾、头尾、尾头4种特殊情况比对 本篇&#xff0c;继续介绍 diff算法-乱序比对 二&#xff0c;乱…

MATLAB | 全网最全边际图绘制模板(直方图、小提琴图、箱线图、雨云图、散点图... ...)

如标题所言&#xff0c;这应该是全网最全的边际图绘制模板&#xff0c;中心图有8种格式&#xff0c;边际图有11种格式&#xff0c;共计88种组合&#xff0c;另外模板中给了8款配色&#xff0c;我愿称其为888组合&#xff0c;只需要更换一下数据就能绘制出各种类型的边际图: 甚至…

中国机器视觉市场研究报告

目录 机器视觉行业概述机器视觉行业发展现状机器视觉行业典型企业分析机器视觉行业未来发展趋势 机器视觉行业概述 机器视觉定义 机器视觉&#xff08;Machine Vision&#xff0c;MV&#xff09;是人工智能正在快速发展的一个分支。根据美国制造工程师协会&#xff08;SME&…