M5ATOMS3基础04给ROS2发一个问候(micro-ROS)

参考以往部分历程:

1. esp32与ros2的欢乐启程 2021

2. micro-ROS之esp32与ros2资料(freertos) 2021

3. esp32发布机器人电池电压到ros2(micro-ros+CoCube) 2022

4. CoCube和Micro-ROS简单案例演示 2022


不需要僵化的区分ROS1和ROS2,借助人工智能工具,提出需求让AI解决就好。

M5ATOMS3基础03给ROS1发一个问候(rosserial)


ROS1使用:

  • rosserial

ROS2使用:

  • micro-ROS

这两种方式并不是唯一的,但是最为方便,网络上资料多,AI也熟悉并且能写出没有错误的代码。

2023年,使用端口号2023

./MicroXRCEAgent udp4 -p 2023

连接M5AtomS3成功后会显示:


 下面资料提供给人工智能,让它完成代码就好。 

#include <micro_ros_arduino.h>#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>#include <std_msgs/msg/int32.h>rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;#define LED_PIN 13#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}void error_loop(){while(1){digitalWrite(LED_PIN, !digitalRead(LED_PIN));delay(100);}
}void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{  RCLC_UNUSED(last_call_time);if (timer != NULL) {RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));msg.data++;}
}void setup() {set_microros_transports();pinMode(LED_PIN, OUTPUT);digitalWrite(LED_PIN, HIGH);  delay(2000);allocator = rcl_get_default_allocator();//create init_optionsRCCHECK(rclc_support_init(&support, 0, NULL, &allocator));// create nodeRCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));// create publisherRCCHECK(rclc_publisher_init_default(&publisher,&node,ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),"micro_ros_arduino_node_publisher"));// create timer,const unsigned int timer_timeout = 1000;RCCHECK(rclc_timer_init_default(&timer,&support,RCL_MS_TO_NS(timer_timeout),timer_callback));// create executorRCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));RCCHECK(rclc_executor_add_timer(&executor, &timer));msg.data = 0;
}void loop() {delay(100);RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}

这段代码是一个使用MicroROS的Arduino库来创建一个ROS节点并发布一个整数消息的示例。

首先,代码包含了一些必要的头文件,包括micro_ros_arduino.h、stdio.h、rcl.h、rclc.h、std_msgs.h等。

然后,定义了一些全局变量,包括publisher、msg、executor、support、allocator、node和timer,这些变量将在后面的函数中使用。

接下来,定义了一些宏函数,包括RCCHECK和RCsoftCHECK,用于检查ROS函数的返回值并处理错误。

然后,定义了一个error_loop函数,用于在出现错误时进入一个无限循环,通过LED的开关状态来指示错误状态。

在setup函数中,进行一些初始化设置。首先,设置MicroROS传输层。然后,设置LED引脚为输出模式,并初始化为高电平。

之后,延迟2秒钟,然后初始化ROS相关组件。首先,获取默认分配器。然后,使用rclc_support_init函数初始化support。接下来,使用rclc_node_init_default函数创建节点。然后,使用rclc_publisher_init_default函数创建发布者,并指定消息类型和话题名称。接着,使用rclc_timer_init_default函数创建计时器,并指定回调函数和超时时间。最后,使用rclc_executor_init函数初始化执行器,并使用rclc_executor_add_timer函数将计时器添加到执行器中。

在loop函数中,延迟100毫秒,然后使用rclc_executor_spin_some函数让执行器处理一些消息。

总体而言,这段代码创建了一个ROS节点,该节点每秒发布一个整数消息,并通过LED的开关状态来显示发布的状态。

然后,让人工智能完成字符串发送的代码。

#include <micro_ros_arduino.h>  #include <stdio.h>  
#include <rcl/rcl.h>  
#include <rcl/error_handling.h>  
#include <rclc/rclc.h>  
#include <rclc/executor.h>  #include <std_msgs/msg/string.h>  rcl_publisher_t publisher;  
std_msgs__msg__String msg;  
rclc_executor_t executor;  
rclc_support_t support;  
rcl_allocator_t allocator;  
rcl_node_t node;  
rcl_timer_t timer;  #define LED_PIN 13  #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}  
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}  void error_loop(){  while(1){  digitalWrite(LED_PIN, !digitalRead(LED_PIN));  delay(100);  }  
}  void timer_callback(rcl_timer_t * timer, int64_t last_call_time)  
{    RCLC_UNUSED(last_call_time);  if (timer != NULL) {  RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));  msg.data = "Hello ROS!";  }  
}  void setup() {  set_microros_transports();  pinMode(LED_PIN, Output);  digitalWrite(LED_PIN, HIGH);    delay(2000);  allocator = rcl_get_default_allocator();  //create init_options  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));  // create node  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));  // create publisher  RCCHECK(rclc_publisher_init_default(  &publisher,  &node,  ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, String),  "micro_ros_arduino_node_publisher"));  // create timer,  const unsigned int timer_timeout = 1000;  RCCHECK(rclc_timer_init_default(  &timer,  &support,  RCL_MS_TO_NS(timer_timeout),  timer_callback));  // create executor  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));  RCCHECK(rclc_executor_add_timer(&executor, &timer));  msg.data = "";  
}  void loop() {  delay(100);  RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));  
}#include <micro_ros_arduino.h>  #include <stdio.h>  
#include <rcl/rcl.h>  
#include <rcl/error_handling.h>  
#include <rclc/rclc.h>  
#include <rclc/executor.h>  #include <std_msgs/msg/string.h>  rcl_publisher_t publisher;  
std_msgs__msg__String msg;  
rclc_executor_t executor;  
rclc_support_t support;  
rcl_allocator_t allocator;  
rcl_node_t node;  
rcl_timer_t timer;  #define LED_PIN 13  #define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}  
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}  void error_loop(){  while(1){  digitalWrite(LED_PIN, !digitalRead(LED_PIN));  delay(100);  }  
}  void timer_callback(rcl_timer_t * timer, int64_t last_call_time)  
{    RCLC_UNUSED(last_call_time);  if (timer != NULL) {  RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));  msg.data = "Hello ROS!";  }  
}  void setup() {  set_microros_transports();  pinMode(LED_PIN, Output);  digitalWrite(LED_PIN, HIGH);    delay(2000);  allocator = rcl_get_default_allocator();  //create init_options  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));  // create node  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));  // create publisher  RCCHECK(rclc_publisher_init_default(  &publisher,  &node,  ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, String),  "micro_ros_arduino_node_publisher"));  // create timer,  const unsigned int timer_timeout = 1000;  RCCHECK(rclc_timer_init_default(  &timer,  &support,  RCL_MS_TO_NS(timer_timeout),  timer_callback));  // create executor  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));  RCCHECK(rclc_executor_add_timer(&executor, &timer));  msg.data = "";  
}  void loop() {  delay(100);  RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));  
}

这个示例与之前的示例类似,不同之处在于发布者发布的是字符串消息而不是整数消息。在timer回调函数中,我们将字符串消息的数据设置为"Hello ROS!",然后进行发布。其他部分与之前的示例相同。 


并不准确的AI总结

在MicroROS与ROS2之间进行通信时,需要注意以下事项:

  1. 兼容性:MicroROS和ROS2在消息传递和通信方面有所不同,因此需要确保两者之间的兼容性。在编写节点时,需要使用兼容的通信库和API。
  2. 通信协议:MicroROS和ROS2使用不同的通信协议。因此,在通信过程中,需要确保使用正确的通信协议进行消息传递。
  3. 消息格式:MicroROS和ROS2使用的消息格式可能不同。在通信过程中,需要确保消息格式的正确性,以便正确解析和传递消息。
  4. 节点间互操作性:MicroROS和ROS2之间的节点可能具有不同的功能和能力。在通信过程中,需要确保节点之间的互操作性,以便正确地交换数据和服务。
  5. 数据同步:如果MicroROS和ROS2之间存在数据同步的需求,需要确保数据在正确的时间和顺序进行传递和更新。
  6. 错误处理:在通信过程中,可能会出现各种错误和异常情况。因此,需要适当的处理和记录这些错误,以确保系统的正常运行。
  7. 跨平台支持:MicroROS和ROS2都可以在不同的操作系统和平台上运行。在通信过程中,需要考虑跨平台支持,以确保通信的稳定性和可靠性。

综上所述,在进行MicroROS与ROS2之间的通信时,需要注意这些事项,以确保通信的正确性和可靠性。

ESP32是一种嵌入式系统开发板,具有强大的处理能力和丰富的的学习资源。在ROS(机器人操作系统)通信方面,它可以同时支持ROS1和MicroROS与ROS2之间的通信。下面将比较这三种通信方式之间的差异:

1 ROS1与MicroROS

ROS1是早期的ROS版本,使用master仲裁机制进行通信。它不支持跨网络通信,因此需要使用ROS自带的ROS Master来实现节点之间的通信。而MicroROS是ROS的精简版本,专门为嵌入式系统设计,具有更小的内存占用和更快的运行速度。它支持跨网络通信,可以使用多种通信协议进行节点之间的通信。

2 MicroROS与ROS2

ROS2是ROS的最新版本,引入了新的通信机制,包括数据分发和服务质量(QoS)。它支持跨网络通信,具有更好的可靠性和实时性。MicroROS与ROS2之间的主要区别在于通信协议和QoS的支持。MicroROS使用基于UDP的通信协议,而ROS2支持多种通信协议,包括TCP和UDP。此外,MicroROS不支持QoS,而ROS2可以根据需要选择不同的QoS等级。

3 ESP32与ROSSerial

rosserial是ROS的一个串口库,可以在ESP32等嵌入式系统中使用。它支持通过串口与ROS节点进行通信,并可以进行消息的发布和订阅。在ESP32上使用rosserial进行通信时,需要配置串口参数和波特率,以确保与ROS Master的正常通信。

综上所述,ESP32可以使用rosserial与ROS1通信,使用MicroROS与ROS2通信。虽然这三种通信方式之间存在一些差异,但都可以实现ESP32与ROS节点之间的通信。选择哪种通信方式取决于具体应用场景和需求,例如对通信实时性、可靠性和网络的要求等。


Micro-ROS其实是支持QoS的。

The DDS-XRCE wire protocol is specified to be in at least TCP and UDP transport protocol, but there is room to expand to other protocols. Currently, implementations are supporting Serial links and possible to be extended to any other such Zigbee, 6LoWPAN, and more. DDS-XRCE allows setting two different delivery QoS:

  • Reliable.
  • Best-effort.

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript数据结构与算法-初始栈结构

文章目录 一、初始栈结构1.1 特性1.2 注意事项 二、栈结构的封装2.1 封装简单栈结构2.2 利用栈将十进制转二进制 一、初始栈结构 1.1 特性 类似于汉诺塔&#xff0c;后进先出&#xff0c;每次只能操作栈顶的元素。关键词&#xff1a;压栈、退栈 简单示意图&#xff1a; 1.…

windows下tomcat无故宕机,检测http或https服务,并自动重启Tomcat服务

一、问题描述及解决原理 把项目发布到windows服务器中&#xff0c;如tomcat工程不稳定&#xff0c;会有无故宕机的问题。如果通过程序无法解决&#xff0c;并且重启tomcat服务能够生效的话&#xff0c;可以做一个自动检测并重启的脚本。 脚本通过检测tomcat对应的工程链接&…

Flask学习笔记_异步论坛(四)

Flask学习笔记_异步论坛&#xff08;四&#xff09; 1.配置和数据库链接1.exts.py里面实例化sqlalchemy数据库2.config.py配置app和数据库信息3.app.py导入exts和config并初始化到app上 2.创建用户模型并映射到数据库1.models/auth.py创建用户模型2.app.py导入模型并用flask-mi…

RabbitMQ 教程 | 第4章 RabbitMQ 进阶

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

HCIA云计算 V5.0题库

云计算&#xff0c;这是近几年听得最多词了&#xff0c;云计算对于网络的发展帮助非常大&#xff0c;它自身所产生的价值是不可估量的&#xff01;所以云计算的岗位对于很多IT公司来说&#xff0c;都是有一定地位的。华为认证云计算面向的对象很简单就是对云计算技术感兴趣的人…

【Spring】(四)Bean 的作用域和生命周期

文章目录 前言一、Bean 的作用域1.1 被修改的 Bean 案例1.2 作用域的定义1.3 Bean 的六种作用域1.4 Bean 作用域的设置 二、Spring 的执行流程 和 Bean 的生命周期2.1 Spring 的执行流程2.2 Bean 的生命周期2.3 Bean 生命周期的演示 前言 Bean 是 Spring 框架中的一个核心概念…

iphone内存不足导致白苹果?可以使用这2种办法解决!

因为iPhone内存不足没及时清理导致打开任何软件闪退&#xff0c;这时很多小伙伴会重启手机来解决闪退问题&#xff0c;但就会出现白苹果问题&#xff0c;无法正常进入手机系统、实现任何操作的一种状态。 内存不足导致iPhone白苹果的问题很常见&#xff0c;可以说是苹果最常见…

排序进行曲-v4.0

文章目录 小程一言快速排序步骤详细解释具体步骤 举例总结 复杂度分析时间复杂度分析&#xff1a;空间复杂度分析&#xff1a;注意 应用场景总结 实际举例结果总结 代码实现结果解释 小程一言 这篇文章是在排序进行曲3.0之后的续讲&#xff0c; 这篇文章主要是对快速排序进行细…

nodejs中的path.json和path.resolve的区别

nodejs中的path.json和path.resolve的区别 我们有多少次在 Node.js 项目中遇到过path.join()和path.resolve()却没有真正理解它们之间的区别&#xff1f;本文就讲解一下这两者的区别。 重要术语 首先我们先来看看几个术语&#xff0c;便于后续我们掌握这两者的差异。 字符串…

libcurl开源的、跨平台的网络传输库,用于在程序中实现数据传输功能的编译

文章目录 前言1、libcurl关键特点和功能2、没有使用openssl以及libssh2编译libcurl的文件和使用openssl和libssh2编译3、libcurl网络库的下载4、libcurl网络库的编译4.1、直接使用cmake编译&#xff0c;不使用 OpenSSL 和 libssh2库编译的出来的libcurl库4.2、使用 OpenSSL 和 …

peerDependency到底是什么

peerDependency到底是什么 正常开发中&#xff0c;我们经常接触到的是 package.json 中的 dependencies 和 devDependencies, 本文不对上面两个进行细节分析&#xff0c;让我们来看看 peerDependencies 是什么&#xff1f; 在 NPM v7 中&#xff0c;默认安装 peerDependencies…

虹科案例|如何分析设备故障时间和次数,打破生产瓶颈?

虹科设备绩效管理系统 保障生产设备的稳定性和可靠性 生产设备的稳定性和可靠性是保证企业正常生产的重要条件之一&#xff0c;设备故障的频发严重影响企业的正常生产&#xff0c;那么如何分析设备故障时间和次数&#xff0c;查找设备故障原因&#xff0c;协助企业打破生产瓶…

Arthas协助MQ消费性能优化

背景 项目中使用AWS的SQS消息队列进行异步处理&#xff0c;QA通过压测发现单机TPS在23左右&#xff0c;目标性能在500TPS&#xff0c;所以需要对消费逻辑进行优化&#xff0c;提升消费速度。 目标 消费TPS从23提升到500 优化流程 优化的思路是先分析定位性能瓶颈&#xff…

SpringBoot使用redis作为缓存的实例

目录 什么是缓存&#xff1f; 缓存的作用&#xff1f; 缓存的成本&#xff1f; 实际项目中的应用 代码展示 什么是缓存&#xff1f; 缓存就是数据交换的缓冲区&#xff08;称作Cache [ kʃ ] &#xff09;&#xff0c;是存贮数据的临时地方&#xff0c;一般读写性能较高。 缓…

[数据集][目标检测]遛狗不牵绳数据集VOC格式-1980张

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;1980 标注数量(xml文件个数)&#xff1a;1980 标注类别数&#xff1a;5 标注类别名称:["dog","p…

C# Blazor 学习笔记(0):初识Blazor

文章目录 Blazor是什么适合人群 开始学习BlazorBlazor资源如何创建BlazorBlazor 基础知识介绍文件分布Razor和cshtml的区别Razor介绍 Blazor是什么 Blazor是微软推出的前端框架&#xff0c;有两种形式&#xff0c;以下以Blazor Server为主。具有一下特点 前端是用C#而不是JS前…

STM32使用HAL库中外设初始化MSP回调机制及中断回调机制详解

STM32使用HAL库之Msp回调函数 1.问题提出 在STM32的HAL库使用中&#xff0c;会发现库函数大都被设计成了一对&#xff1a; HAL_PPP/PPPP_Init HAL_PPP/PPPP_MspInit 而且HAL_PPP/PPPP_MspInit函数的defination前面还会有__weak关键字 上面的PPP/PPPP代表常见外设的名称为…

模板方法设计模式(C++)

定义 定义一个操作中的算法的骨架(稳定&#xff09;,而将一些步骤延迟(变化&#xff09;到子类中。Template Method使得子类可以不改变(复用&#xff09;一个算法的结构即可重定义(override重写)该算法的某些特定步骤。 ——《设计模式》GoF Template Method模式是一种非常基…

元素2D转3D 椭圆形旋转实现

椭圆旋转功能展示 transform-style: preserve-3d;&#xff08;主要css代码&#xff09; gif示例&#xff08;背景图可插入透明以此实现边框线的旋转&#xff09; 导致的无法点击遮挡问题可以参考我的另一个文章 穿透属性-----------------------css穿透属性 实时代码展示

Unity之webgl端通过vue3接入腾讯云联络中心SDK

腾讯云联络中心SDK:云联络中心 Web-SDK 开发指南-文档中心-腾讯云 (tencent.com) 1 首先下载Demo ​ 1.1 对其进行解压 ​ 1.2根据文档操作 查看README.md,根据说明设置server下的dev.js里的相关参数。 然后打开电脑终端&#xff0c;cd到项目的路径&#xff1a; ​ 安装…