【ROS2】类ROS1的rate定时器写法(c++&python例子)

2023-05-16

在ROS2官方教程里,代码和ROS1例程有很大不同,大部分节点都使用了类的写法,并且用到了很多C++的新功能。其中,发布消息是采用了一个定时器timer,并且注册一个回调函数实现的。那么,可不可以还是采用ROS1的rate sleep写法呢,答案是可以的。
例程如下:

#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include "tutorial_interfaces/msg/num.hpp"
#include "tutorial_interfaces/msg/sphere.hpp"

class MinimalPublisher : public rclcpp::Node {
 public:
  MinimalPublisher() : Node("minimal_publisher"), count_(0) {
    publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
    publisher2_ =
        this->create_publisher<tutorial_interfaces::msg::Num>("topicNum", 10);
    publisher3_ =
        this->create_publisher<tutorial_interfaces::msg::Sphere>("topicSp", 10);
    f = std::bind(&MinimalPublisher::pub_msg, this);
  }
  std::function<void(void)> f;

 private:
  // rclcpp::TimerBase::SharedPtr timer_;
  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
  rclcpp::Publisher<tutorial_interfaces::msg::Num>::SharedPtr publisher2_;
  rclcpp::Publisher<tutorial_interfaces::msg::Sphere>::SharedPtr publisher3_;
  size_t count_;
  void pub_msg() {
    auto message = std_msgs::msg::String();
    auto message2 = tutorial_interfaces::msg::Num();
    auto message3 = tutorial_interfaces::msg::Sphere();
    message3.radius = 223;
    message3.center.x = 33.4 + this->count_;
    message2.num = this->count_;
    message.data = "Hello, world! " + std::to_string(count_++);
    RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
    RCLCPP_INFO_STREAM(this->get_logger(),
                       "Publishing: '" << message2.num << "'");
    RCLCPP_INFO_STREAM(this->get_logger(),
                       "Publishing: '" << message3.center.x << "'");
    publisher_->publish(message);
    publisher2_->publish(message2);
    publisher3_->publish(message3);
  }
};

int main(int argc, char* argv[]) {
  rclcpp::init(argc, argv);
  std::shared_ptr<MinimalPublisher> pp(new MinimalPublisher());
  //auto pp = std::make_shared<MinimalPublisher>();

  rclcpp::WallRate loop_rate(10);
  while (rclcpp::ok()) {
    rclcpp::spin_some(pp);
    pp->f();
    loop_rate.sleep();
  }
  rclcpp::shutdown();
  return 0;
}

类MinimalPublisher 继承了rclcpp::Node基类,作为节点类,在它的构造函数中,构建了3个publisher。

主函数中,首先新建了一个MinimalPublisher 的实例,并用一个智能指针pp指向它,这里也有好几种写法,既可以直接new,也可以用make_shared方法。后面rclcpp的spin函数都需要节点指针作为参数。C++11中引入了智能指针(smart pointer)的概念,其中shared_ptr是其中一个最为常用的智能指针。相对于裸指针,shared_ptr是一个功能强大的智能指针,提供了更好的内存管理,减少了手动管理内存的烦恼,并且可以用于STL容器中,非常方便。

rclcpp中实现了两个rate类,分别是WallRate和Rate,二者的区别是,rclcpp::Rate类使用系统时钟来控制程序的运行速率,rclcpp::WallRate类则使用墙上时钟(Wall Clock)来控制程序的运行速率,墙上时钟可以理解为系统的真实时间,它不会受到时间调整和时钟漂移等因素的影响。该类中的主要成员函数也是sleep(),用法与rclcpp::Rate类类似。墙上时钟使用的是真实时间,误差相对较小,稳定性较好。而系统时钟是基于计算机硬件的时钟,分辨率可以很高,误差相对较小,但是受到外部干扰的影响比较大,稳定性相对较差。因此,从精确度的角度来看,墙上时钟和系统时钟各有优缺点,应根据实际需求选择适当的时钟。如果需要高精度和高稳定性,则可以使用墙上时钟。如果需要高分辨率和较高精度,则可以使用系统时钟。以上是GPT的回答,实际上我使用没发现大的区别:P

另外还要指出的是,ROS2里面c++中没有spinonce,而是用spin_some替代了,关于二者区别,这里再次copy GPT的回答(真是方便偷懒啊):在ROS 1中,spinOnce()是一个函数,其作用是运行一个循环来处理ROS消息,直到没有新的消息到达。而在ROS 2中,没有spinOnce()函数,取而代之的是spin_some()函数。
spin_some()函数与spinOnce()函数的功能相似,都是处理ROS消息。不同之处在于,spin_some()函数只处理已经到达的消息,而不会等待新的消息到达。这意味着,如果没有新消息到达,spin_some()函数将立即返回,而不会进入一个死循环等待新消息。
在ROS 1中,使用spinOnce()函数可以确保ROS节点能够及时处理所有的ROS消息。但是,如果不加限制地使用spinOnce()函数,可能会导致ROS节点长时间占用CPU资源,降低整个系统的性能。因此,ROS 2中引入了spin_some()函数,以提高ROS节点的性能和稳定性。
总的来说,spin_some()函数相对于spinOnce()函数更加灵活和高效,可以更好地处理ROS消息。但是,需要注意的是,在使用spin_some()函数时,需要自行控制循环的次数或者时间间隔,以确保ROS节点能够及时处理所有的ROS消息。

最后,在while循环中发送消息时,测试了一下std::function和std::bind的用法,这是不必要的代码,仅仅为测试功能,注意到在构造函数中,有这样一句代码:

f = std::bind(&MinimalPublisher::pub_msg, this);

这是利用bind将类的私有方法MinimalPublisher::pub_msg重新打包成一个新函数。因为类的成员函数都会有个一个隐藏参数,就是类的指针,所以bind的时候要加上this去掉这个指针参数。我们会注意到在ROS2官方例程中,将类的成员函数注册为回调函数时有很多这样的用法。

最后,python一样可以用rate和while循环实现程序架构,见下面的例程:

import rclpy
from rclpy.node import Node

from std_msgs.msg import String


class MinimalPublisher(Node):

    def __init__(self):
        super().__init__('minimal_publisher')
        self.publisher_ = self.create_publisher(String, 'topic', 10)
        #timer_period = 0.5  # seconds
        #self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = String()
        msg.data = 'Hello World: %d' % self.i
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.i += 1


def main(args=None):
    rclpy.init(args=args)

    minimal_publisher = MinimalPublisher()
    rate = minimal_publisher.create_rate(10)
    while rclpy.ok():
        rclpy.spin_once(minimal_publisher)
        minimal_publisher.timer_callback()
        rate.sleep()

    # Destroy the node explicitly
    # (optional - otherwise it will be done automatically
    # when the garbage collector destroys the node object)
    minimal_publisher.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【ROS2】类ROS1的rate定时器写法(c++&python例子) 的相关文章

  • 一招教你如何写好技术文档?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 方案设计文档该怎么写 xff1f 你是不是从来没有想过这个问题 xff1f 很多技术人自己非常轻视技术文档的书写 xff0c 然而又时常抱怨文档不完
  • 太卷了!为随时随地敲代码,他手撸了一台Linux掌上电脑

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 手搓一台巴掌大小Linux电脑 xff0c 只需树莓派加点儿零件就行 xff1f 是的 xff0c 你没看错 xff0c 有人都做出来了 xff01
  • 中国智造人形机器人,刑天!技术水平如何?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 今年10月 xff0c 特斯拉举办2022 AI Day活动 xff0c Tesla Bot人形机器人擎天柱 xff08 Optimus xff09
  • 设计完美的PCB,这些细节要注意

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 01 布局 元器件布局的10条规则 xff1a 1 遵照 先大后小 xff0c 先难后易 的布置原则 xff0c 即重要的单元电路 核心元器件应当优
  • 计算机,会是下一个土木专业吗?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 大家好 xff0c 我是麦叔 最近看到一个热门问题 xff1a 计算机专业是否会成为下一个土木工程 xff1f 这个问题我想大多数准备学习计算机方向
  • 改变世界的数学公式,yyds

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 数学一直是我认为非常神奇的学科 上学期间不知数学有何用 xff0c 甚至觉得数学专业连工作都找不到 xff0c 才知道自己原来的认知简直太渺小了 x
  • 你们都开工了,我才刚开始复盘

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 大家好 xff0c 我是小麦 自从阳康之后已经连续忙了快一个月 甚至春节都没有休息 xff0c 大年初一还工作到凌晨 地球不爆炸 xff0c 我们不
  • 卖网红饮品喜茶配方,他一年赚50万

    前两天我去了一趟广州 xff0c 参加了一个内部圈子的交流会 xff0c 加过我微信的朋友可能会看到 在交流会上 xff0c 认识了一个年轻小伙子 xff0c 大伙称呼他为豪哥 xff0c 在分享会上他讲述了自己卖喜茶配方年赚50万的创业历
  • 入职新公司被要工资流水!这背后到底有什么猫腻?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 关于 什么时候工资流水成了新人入职必须提供的资料项之一 这件事 xff0c 作为一个打工人还是多少了解一下背后的原因的 其实要说以前 xff08 不
  • 俄罗斯自研的CPU,能用吗?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 从 2014 年吞并克里米亚到 2022 年的俄乌战争 xff0c 俄罗斯和西方世界的冲突愈发加剧 xff0c 在能源和科技上的相互制裁不断升级 在
  • 爆一下年终奖

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 各个公司的年终奖大多尘埃落定了 xff0c 大环境说实话不是很好 xff0c 有人欢喜有人愁 xff0c 汇总了一波 xff0c 大概50位小伙伴的
  • ChatGPT火爆,背后的核心到底是什么?

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 2022年12月份的时候 xff0c ChatGPT还只是个被人各种撩的聊天工具 但进入2023年后 xff0c 已经向着效率工具迈进了 微软宣布正
  • 不小心当上CTO了

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 大家好 xff0c 我是小麦 在知乎上看到一篇从创业公司的工程师一路成长为CTO的真实故事 看完我获益匪浅 在这里分享给大家 01 创业初期 在创业
  • 盘点一下电子嵌入式相关的公司

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达 大家好 xff0c 我是小麦 最近入坑电子信息工程专业的表弟问我毕业能去干什么 xff1f 于是在这里盘点了一下电子嵌入式相关的公司 在这里和大家分
  • C# 解析ini类型文件详解

    1 什么是ini文件 INI文件是一种配置文件格式 xff0c 通常用于Windows操作系统中的应用程序中 它是一种文本文件 xff0c 由多个节和键值对组成 xff0c 用于存储应用程序的配置信息 INI文件的特点包括 xff1a IN
  • CAN总线显性电平和隐性电平详解

    相关文章 CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 CAN 信号线 CAN 传输的两条信号线被称为 CAN H 和CAN L 通电状态 xff1a CAN H xff08 2 5V xff
  • STM32的CAN总线调试经验分享

    相关文章 CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 文章目录 相关文章背景CAN总线CAN控制器CAN收发器 调试过程硬件排查CAN分析仪芯片CAN控制器调试 总结 背景 最近负责的一个项
  • 我的新副业

    大家好 xff0c 我是麦叔 聊聊我的新副业吧 尝试做了一段时间餐饮 xff0c 差不多有半年时间了 感触很深 在这里和大家分享一下 缘起 去年10月份朋友的店铺转让 xff0c 于是我就盘下来了 店面不大 xff0c 投入也不是很大 xf
  • 螺旋桨拉力

    介绍 螺旋桨拉力计算公式 直径 xff08 米 xff09 X 螺距 xff08 米 xff09 X 桨宽度 xff08 米 xff09 X 转速 xff08 转 秒 xff09 X 经验系数 xff08 0 25 xff09 61 拉力
  • 爆炸了!但YYDS

    正文共 xff1a 2962字 预计阅读时间 xff1a 8分钟 成功发射 xff0c 但在空中爆炸了 这一刻 xff0c 我们都仰望星空 北京时间 4 月 20 日晚 9 点半 xff0c 随着倒计时声音的结束 xff0c 在 Space

随机推荐

  • 赞爆了!Tabby 这款开源工具真的好用!

    点击上方 小麦大叔 xff0c 选择 置顶 星标公众号 福利干货 xff0c 第一时间送达
  • 惠普暗影精灵VMware安装CentOS7显示[此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态]

    进入BIOS页面开启CPU虚拟化处理技术 电脑开机时按 ESC 键进入系统启动菜单 然后按F10进入BIOS页面 xff0c 开启 处理器虚拟化技术
  • Python的main函数

    在 Python 中 xff0c 程序的入口点通常指的是一个特定的函数 xff0c 即 main 函数 这个函数是程序的起点 xff0c 也是程序的入口 xff0c 通过调用 main 函数 xff0c 程序开始执行 在 Python 中
  • CMakeList静态库多层嵌套问题 undefined reference to

    前言 被一个问题缠绕了很长时间 xff0c 这两天花精力好好研究了一下 xff0c 总算解决了 xff0c 翻过来看 xff0c 就是自己不注意造的很多小问题 我的想法是把一些代码封装起来 xff0c 但是有些部分要求能让现场工作同事有一定
  • gazebo仿真环境中 加入传感器

    1 传感器加入自己的模型中需要那些步骤 1 节点说明 xff0c 链接关系 lt robot name 61 test gt lt link name 61 34 link1 34 gt lt link name 61 34 link2 3
  • 以下为Windows NT 下的32 位C++程序,请计算sizeof 的值

    char str 61 Hello char p 61 str int n 61 10 请计算 sizeof str 61 sizeof p 61 sizeof n 61 答案 6 4 4 void Func char str 100 请计
  • vue实现显示10条数据点击查询看更多

    vue实现显示10条数据点击查询看更多 要求如下 当页面的数据超过10条时只显示10条 且显示 点我查看更多喔 每次点击 页面数据增加10条 思路解析 如题 假设有20条数据 只显示10条 点击查看更多按钮 span class token
  • 433和2.4G无线通信比较

    DSSS 2 4G无线数据传输系统优势 一 很正常的升级换代 xff1a 系统工作的长期稳定性和可靠性 xff0c 是一个无线通信系统最重要的指标 由于一般433兆及915兆产品使用的是低频窄带通信技术 xff0c 它们的工作频率范围很窄5
  • Android adb dumpsys 命令总结

    adb shell dumpsys 有哪些命令可以用 xff0c 可以使用adb shell service list来查看 查看package这个service的帮助信息 adb shell dumpsys package h 查看act
  • 在STM32中实现ROS节点——Rosserial的用法

    目录 内容介绍前言生成要移植到stm32的自定义消息和服务生成针对stm32的移植库包roslibs在Mdk中实现C和C 43 43 代码混合编译修改mdk配置修改stm32 ROS通讯接口驱动测试补充说明 内容介绍 本文介绍如何将stm3
  • ubuntu下用apt-get install 安装软件时出现 initramfs-tools错误

    错误提示 xff1a gzip stdout No space left on device E mkinitramfs failure cpio 141 gzip 1 update initramfs failed for boot in
  • ubuntu虚拟机下桥接模式,静态ip上网

    近期使用VM安装了ubuntu12 10玩玩 xff0c 途中也遇到了许多问题 xff0c 安装完成后 xff0c 系统默认是选择NAT连接方式的 xff0c 可以直接通过火狐浏览器上网 xff08 不需任何设置 xff0c 系统自己配置好
  • Windows下安装GTK+(整理)

    以下为网上摘的 xff0c 自己把它整理在了一起 WINDOWS下实现GTK 43 GTKMM的编程 xff08 一 xff09 下载软件包 1 下载dev C 43 43 开发软件 xff08 我的版本是4 9 9 2 xff09 2 下
  • windows gtk+开发环境搭建方法详解(图解)

    GTK 43 开发环境搭建 工欲善其事 必先利其器 首先介绍一下GTK 43 开发环境的搭建 网上很多所谓的GTK的开发环境的搭建基本都是抄来抄去 也不知道有没有人使用他们介绍的方法搭建并编译成功 很不幸的是我使用他们写的方法没有搭建成功
  • GTK在Linux下的安装

    linux gtk 是linux平台下的图形界面开发接口 xff0c 它不同于qt xff0c 它是完全免费的 xff0c Qt是基于c 43 43 的商业开发包 xff0c 涉及版权等问题 xff0c gtk则是基于c的全免费的 xff0
  • android SDK下各目录的用途,以及在不同系统下哪些是通用的。

    Android SDK 目录下有很多文件夹 xff0c 主要都是干什么的呢 1 add ons 这里面保存着附加库 xff0c 比如google Maps xff0c 当然你如果安装了OPhone SDK xff0c 这里也会有一些类库在里
  • Linux系统文件系统基础罗列

    Linux 文件系统是linux的一个十分基础的知识 xff0c 同时也是学习linux的必备知识 本文将站在一个较高的视图来了解linux的文件系统 xff0c 主要包括了linux磁盘分区和目录 挂载基本原理 文件存储结构 软链接硬链接
  • 至今互联网上收集最全的精品教育资源【转载+补充】

    海慧为您奉上 xff01 xff01 xff01 操作指引 xff1a 第一步 xff1a 注册一个360云盘账号 xff0c 注册地址 xff1a yunpan 360 cn xff0c 拥有自己的账号和密码 第二步 xff1a 下载36
  • Linux Android 真机调试配置

    1 USB 链接手机 xff0c 打开USB调试 2 在终端中输入lsusb命令 xff0c 查看USB设备信息 xff0c 找到手机对应的USB信息 eg Bus 002 Device 003 ID 12d1 1035 Huawei Te
  • 【ROS2】类ROS1的rate定时器写法(c++&python例子)

    在ROS2官方教程里 xff0c 代码和ROS1例程有很大不同 xff0c 大部分节点都使用了类的写法 xff0c 并且用到了很多C 43 43 的新功能 其中 xff0c 发布消息是采用了一个定时器timer xff0c 并且注册一个回调