当前位置: 首页 > news >正文

ROS2 中的轻量级、自动化、受控回放

一、说明

这篇文章描述了一种在 ROS2 中实现受控重播器的轻量级方法。用以测试中将现象重新播放一遍,以实现调参或故障定位的目的。所有源代码都可以在这里找到。该帖子也可在此处获得。

二、问题:不同步重播

        任何曾经认真开发过 ROS2 的人都会知道这个问题:我们想调试我们的管道或改进算法的微小部分,但当我们反复运行管道时,我们得到了不同的结果。如果我们处于开发的早期阶段,并且我们的管道运行速度不够快,无法实时处理所有数据,我们最终会丢失消息。如果我们在代码中放置断点,我们最终会丢失消息。如果我们在后台的同一台机器上发生了一些完全不相关但半繁重的处理,我们最终会丢失消息。最糟糕的是,症状在每次运行之间可能会有所不同,从完全系统故障到对结果的影响最小,因此我们通常不会直接意识到消息丢失可能是问题所在。

        当然,我们可以非常缓慢地重播所有数据。但是,我们最终会永远等待,直到重播达到我们感兴趣的点。同样,如果我们想在CI服务器上运行管道,我们通常不知道有多少计算资源可用以及我们可以多快地运行我们的系统。

        总结:重播器以固定速率重播其消息,对于算法管道来说,这可能是快或慢。因此,我们要么失去时间,要么得到不确定的结果。

三、方法:受控回放

        解决这个问题的基本思想非常简单:我们需要一个考虑到管道当前状态的受控重放。然而,由于ROS2s的异步和松散耦合设计,实现这一点并非易事。特别是因为我们不想用“仅”开发所需的机制来混淆整个系统。

        不幸的是,ROS2 没有针对这个(在我看来非常明显)问题的构建解决方案。当然,它是开源的,我们可以着手实现我们自己的 ros bag 重播器。但是,如上所述,我们希望在框架内开发一种算法。我们不想先实现框架。幸运的是,到目前为止,ROS2工具已经发展了很多,并且只需相对较少的努力,我们就可以应用一种在实践中可以很好地工作的解决方法。

        这个概念是有一个额外的节点,就像重播者的遥控器一样。每当所有节点通知远程节点它们已准备就绪时,它都会触发新消息的重播。

四、实施

        使用服务客户端体系结构可以相对直接地完成实现,如下所述。包括一个小示例在内的所有代码都可以在这里找到。它也可以很容易地作为 ROS 包包含在内。

        远程是一个附加节点,充当rosbag2_replayer的代理。它使用“突发”服务每 T 秒触发接下来的 N 条消息,并等待每个节点的确认。实现自定义服务确实在调用方的身份旁边传输“就绪”信号。不幸的是,当我们使用突发调用“跳过”袋子时,重播者不会自动关闭。因此,额外的计时器会定期检查模拟时间是否仍在增加,以确定重播是否已结束。这要求重播者发布时钟(-clock),并使用 use-sim-time 参数集运行遥控器。然后,节点可以在重放结束时关闭自身/其整个组合。

        我们可以将其作为可组合节点包含,也可以通过以下方式启动它:

ros2 run controllable_replay remote --ros-args -p use_sim_time:=True -p batch_size:=10 -p period:=0.01 -p automatic_shutdown:=5

这将每 10 毫秒播放 10 条消息,并在重播者处于非活动状态 5 秒后关闭节点。

五、算法节点

        在算法方面,我们需要一些逻辑来通知遥控器我们已经准备好了。在简单节点中,我们可以在每个回调的末尾添加它。在更复杂的节点中,消息和回调之间可能没有一对一的映射。在这种情况下,需要一些额外的逻辑来监视节点的工作负载,例如通过观察输入队列大小。

        对于一个简单的示例,我们将创建一个字符串侦听器节点,该节点计算收到的消息数并模拟具有特定时间长度的繁重任务。任务完成后,它将发布自己的消息并通知远程设备已准备就绪。

#include "Listener.h"
using namespace std::chrono_literals; 
namespace controlled_replay_example { 
Listener::Listener(const rclcpp::NodeOptions& options) : 
rclcpp::Node("Listener", options),
_cliReady{create_client<controlled_replay_interfaces::srv::Ready>("/ready")},
_pub{create_publisher<std_msgs::msg::String>("/hearsay", 10)},
_sub{create_subscription<std_msgs::msg::String>( "/chatter", 10, [&](std_msgs::msg::String::ConstSharedPtr msg) { _ctr++; std::this_thread::sleep_for(get_parameter("task_time").as_double() * 1000ms); // heavy taskauto rq = std::make_shared<controlled_replay_interfaces::srv::Ready::Request>();rq->isready = true; _cliReady->async_send_request(rq); // inform replayer})}, _timer{create_wall_timer(1s, [&]() { RCLCPP_INFO(get_logger(), "Received messages: %ld", _ctr); })} 
{ declare_parameter("task_time", 1.0); } } 
// namespace controlled_replay_example 
#include "rclcpp_components/register_node_macro.hpp" 
RCLCPP_COMPONENTS_REGISTER_NODE(controlled_replay_example::Listener)

我们使用一个包含 464 个字符串消息的包以 100hz 的速率测试上面的示例。我们将模拟一个算法管道,其中包含两个具有不同时间长度的链节点。第一个节点将以 100hz 运行,但第二个节点仅以 2hz 运行。因此,从理论上讲,第一个节点应该能够处理所有消息,但第二个节点会错过一些消息。

在第一次运行中,我们将在没有远程的情况下简单地运行管道。

#!/bin/bash 
ros2 run controlled_replay_example listener --ros-args -p task_time:=0.01 -r __node:=listener1 & 
ros2 run controlled_replay_example listener --ros-args -p task_time:=0.5 -r __node:=listener2 -r chatter:=hearsay -r hearsay:=hearsay1& 
ros2 bag play bag

重放期间的节点图

[INFO] [1695973373.033875499] [listener2]: Received messages: 8 
[INFO] [1695973373.732552274] [listener1]: Received messages: 445

我们可以看到,即使是第一个节点也丢失了一些消息。但是,第一个只处理了8个!

在第二次运行中,我们将使用远程运行管道。


#!/bin/bash
ros2 run controlled_replay_example listener --ros-args -p task_time:=0.01 -r __node:=listener1 &
ros2 run controlled_replay_example listener --ros-args -p task_time:=0.5 -r __node:=listener2 -r chatter:=hearsay -r hearsay:=hearsay1 &
ros2 run controlled_replay remote --ros-args -p batch_size:=1 -p use_sim_time:=True &
ros2 bag play --clock --start-paused bag

具有受控回放的节点图

[INFO] [1695973373.033875499] [listener2]: Received messages: 464 
[INFO] [1695973373.732552274] [listener1]: Received messages: 464

我们可以看到两个节点都收到了所有消息。

六、结论

        我们已经看到了一种在 ROS2 中获得可控重放的简单方法。通过添加一个额外的远程节点,我们可以将大部分任务封装在远离实际管道的地方。遥控器将重播速度减慢到节点可以处理的任何速度,从而避免丢失消息。

此处提供的远程,可以通过 ROS2 包管理包含在内。

七、未解决的问题和未来工作

  • 很快,重播者应该可以作为可组合节点使用。我希望这将进一步提高重播速度。它应该与上述实现顺利配合。
  • 使用这些服务时,ros bag 重播器会向终端发送垃圾邮件,其中包含每个服务的消息,我没有找到一种方法来阻止日志记录部分将其重定向到 /dev/null。但是,这超过了重播者的所有输出
  • 最好找到更简单的方法来监视节点的工作负载,甚至可能是外部的工作负载。例如,如果我们能以某种方式访问待处理的回调,这已经有所帮助,但我没有找到做到这一点的方法。

相关文章:

ROS2 中的轻量级、自动化、受控回放

一、说明 这篇文章描述了一种在 ROS2 中实现受控重播器的轻量级方法。用以测试中将现象重新播放一遍&#xff0c;以实现调参或故障定位的目的。所有源代码都可以在这里找到。该帖子也可在此处获得。 二、问题&#xff1a;不同步重播 任何曾经认真开发过 ROS2 的人都会知道这个问…...

Egg使用jwt拦截jtoken验证

安装 npm install egg-jwt注册插件 在config文件夹子下 plugin,js下 use strict;module.exports {//mysqlmysql: {enable: true,package: egg-mysql},//jwtjwt: {enable: true,package: egg-jwt} };使用中间件 在app文件下创建 middleware 文件夹 在middleware 文件下创建…...

装饰器模式详解和实现(设计模式 二)

装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你动态地将对象添加到现有对象中&#xff0c;以提供额外的功能&#xff0c;同时又不影响其他对象。 实现示例 1.定义一个接口或抽象类&#xff0c;表示被装饰对象的公共接口 //抽…...

面试问到MySQL模块划分与架构体系怎么办

面试问到Mysql模块划分与架构体系怎么办 文章目录 1. 应用层连接管理器&#xff08;Connection Manager&#xff09;安全性和权限模块&#xff08;Security and Privilege Module&#xff09; 2. MySQL服务器层2.1. 服务支持和工具集2.2. SQL Interface2.3. 解析器举个解析器 …...

并查集及其优化

1.并查集 #define SIZE 100 int UFSets[SIZE];void Initial(int S[]) {for (int i 0; i < SIZE; i)S[i]-1; }int Find(int S[], int x) {//查while(S[x] > 0)x S[x];return x; }void Union(int S[], int Root1, int Root2) {//并if(Root1 Root2)return;S[Root2] Roo…...

LeetCode 周赛上分之旅 #48 一道简单的树上动态规划问题

⭐️ 本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架&#xff0c;你的思考越抽象&#xff0c;它能覆盖的问题域就越广&#xff0c;理解难度…...

mysql报错:Column Count Doesn‘t Match Value Count at Row 1

mysql中执行insert、update、delete报错&#xff1a;Column Count Doesnt Match Value Count at Row 1 的解决方案 通常情况&#xff1a;字段不匹配 如&#xff1a;student有id, name, age字段 -- 错误写法 INSERT INTO student VALUES(5,horse)-- 正确写法 INSERT INTO stu…...

安卓 kuaishou 设备did和egid 学习分析

did和egid注册 接口 https://gdfp.ksapisrv.com/rest/infra/gdfp/report/kuaishou/android did 是本地生成的16进制 或者 获取的 android_id public static final Random f16237a new Random(System.currentTimeMillis()); public static long m19668a() { return f1623…...

基于Vue+ELement实现增删改查案例与表单验证(附源码)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《ELement》。&#x1f3af;&#x1f3af; &#x1…...

webpack:使用externals配置来排除打包后的某个依赖插件IgnorePlugin的使用

背景 假设&#xff0c;我们写了一个库并使用 webpack 打包输出 bundle&#xff0c;但是这个库依赖一个第三方包&#xff0c;比如依赖 lodash&#xff0c;这时候我们不想把这个库打包进 bundle 里因为体积会变大&#xff0c;而且我们的主项目里已经安装了这个 lodash&#xff0…...

2023年中国工业脱水机行业供需分析:随着自动化和智能化技术的快速发展,销量同比增长4.9%[图]

工业脱水机行业是指专门从湿润的固体物料中去除水分的设备制造和相关服务。它广泛应用于食品加工、化工、制药、纺织、环保等行业&#xff0c;用于去除物料中的水分&#xff0c;提高产品质量和降低能耗。 工业脱水机行业分类 资料来源&#xff1a;共研产业咨询&#xff08;共研…...

[论文笔记]MacBERT

引言 今天带来MacBERT的阅读笔记。论文题目是 重新审视中文自然语言处理的预训练模型。 本篇主要是探讨中文预训练语言模型在非英文语言中的有效性,然后提出了一种简单而有效的模型,称为MacBERT,它在多个方面改进了RoBERTa,特别是采用纠错型掩码语言模型(MLM as correcti…...

AI发展目前最大挑战是什么?

影响AI成本的因素包括多个方面&#xff1a; 首先&#xff0c;AI技术的复杂性是其成本高昂的一个重要原因。AI技术需要进行大量数据处理、模型训练和优化&#xff0c;这需要耗费大量的计算资源和时间。同时&#xff0c;AI技术需要高水平的专业人才进行设计、开发和维护&#xf…...

自然语言处理NLP:LTP、SnowNLP、HanLP 常用NLP工具和库对比

文章目录 常见NLP任务常见NLP工具英文NLP工具中文NLP工具 常见NLP任务 Word Segmentation 分词 – Tokenization Stem extraction 词干提取 - Stemming Lexical reduction 词形还原 – Lemmatization Part of Speech Tagging 词性标注 – Parts of Speech Named entity rec…...

百度交易中台之内容分润结算系统架构浅析

作者 | 交易中台团队 导读 随着公司内容生态的蓬勃发展&#xff0c;内容产出方和流量提供方最关注的“收益结算”的工作&#xff0c;也就成为重中之重。本文基于内容分润结算业务为入口&#xff0c;介绍了实现过程中的重难点&#xff0c;比如千万级和百万级数据量下的技术选型和…...

【索引】常见的索引、B+树结构、什么时候需要使用索引、优化索引方法、索引主要的数据结构、聚簇索引、二级索引、创建合适的索引等重点知识汇总

目录 索引的分类 什么时候需要 / 不需要创建索引&#xff1f; 有什么优化索引的方法 MySQL索引主要使用的两种数据结构是什么 为什么 MySQL 采用 B 树作为索引 聚簇索引和二级索引 根据给定的表&#xff0c;如何创建索引比较好 索引的分类 普通索引&#xff1a;最基本的…...

Egg 封装接口返回信息

中间件封装 代码 const msgArr {"200":成功,"401":token失效 } module.exports (option, app) > {return async function(ctx, next) {try{//成功是返回的信息ctx.emit(code,data,msg)>{console.log(1111,code,data,msg)ctx.body {code,data:dat…...

Android AMS——创建APP进程(五)

接上一篇,在 ActivityTaskSupervisor 中会判断进程是否存在,如果进程不存在,则会创建进程,执行 startProcessAsync() 方法。如果进程存在,则执行 realStartActivityLocked() 方法。在APP 的启动时,进程是不存在的。所以我们先来分析一下进程不存在的情况。 一、创建进程…...

凉鞋的 Unity 笔记 102. 场景层次 与 GameObject 的增删改查

102. 场景层次 与 GameObject 的增删改查 在上一篇&#xff0c;我们完成了 Unity 引擎的 Hello world 输出&#xff0c;并且完成了第一个基本循环&#xff1a; 通过这次基本循环的完成&#xff0c;我们获得了一点点的 Unity 使用经验&#xff0c;这非常重要。 有实践经验后再…...

信息安全:网络安全审计技术原理与应用.

信息安全&#xff1a;网络安全审计技术原理与应用. 网络安全审计是指对网络信息系统的安全相关活动信息进行获取、记录、存储、分析和利用的工作。网络安全审计的作用在于建立“事后“安全保障措施&#xff0c;保存网络安全事件及行为信息&#xff0c;为网络安全事件分析提供线…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...