M5ATOMS3基础03给ROS1发一个问候(rosserial)
引出问题
关于之前2020年的博客:
01. ESP8266和ROS调试一些问题汇总
02. ESP8266和ESP32配置(需使用ROS1和ROS2)
效果展示
使用M5ATOMS3与ROS1(kinetic,melodic,noetic)版本通信比较通用的是rosserial。
有之前基础测试过多次,都没有问题。

版本需求
使用rosserial版本是0.9.1。

0.7.x版本对ESP32需要修改配置和代码,不推荐。
不合适AI提示
将这个问题仍给AI,得到回复如下(不太可靠):
使用rosserial库在ESP32上与ROS1通信的详细步骤如下:
- 首先,需要在ESP32上安装rosserial库。可以通过Arduino IDE的库管理器搜索并安装rosserial库。
- 打开Arduino IDE,创建一个新的程序。在程序中,需要包含ros.h和ros_arduino.h头文件。
- 在setup函数中,需要初始化ROS节点。这可以通过调用ros::Node::init()函数来实现。
- 要发布ROS消息,需要创建一个ROS话题发布者。可以通过调用ros::Node::get()->advertise函数来创建一个发布者。在这个函数中,需要指定发布的话题名称和发布者频率。
- 在主循环中,需要定义一个回调函数来处理接收到的ROS消息。可以通过调用ros::Node::get()->spinOnce()函数来等待ROS消息。
- 在主循环中,需要设置一个循环速率。在这个函数中,程序会等待一定的时间,然后再次尝试发布ROS消息。
- 要将消息发布到ROS话题上,可以使用发布者的publish函数。在这个函数中,需要创建一个ROS消息对象,并将其数据字段设置为您要发送的消息。
- 最后,在loop函数中,可以空闲等待,以避免Arduino板子停止的问题。
注意:在使用rosserial库与ROS1通信时,需要确保您的ESP32已经连接到了ROS网络中,并且已经配置了正确的的工作节点和话题名称。
以下是一个使用rosserial库在ESP32上与ROS1通信的简单示例代码:
#include <ros.h>
#include <ros_arduino.h> void setup()
{ // 初始化ROS节点 ros::Node::init(); // 创建一个ROS话题发布者 ros::Publisher pub = ros::Node::get()->advertise<std_msgs::String>("chatter", 1000); // 定义一个回调函数来处理接收到的ROS消息 ros::Rate loop_rate(10); while (ros::Node::get()->ok()) { // 发布ROS消息 std_msgs::String msg; msg.data = "Hello, ROS1!"; pub.publish(msg); // 等待下一帧消息 loop_rate.sleep(); }
} void loop()
{ // 空函数,仅用于避免Arduino板子停止的错误
}
这个示例代码创建了一个ROS节点,发布一个名为"chatter"的ROS话题,并将一个包含"Hello, ROS1!"消息的字符串发布到该话题上。在循环中,程序会等待10毫秒,然后再次发布消息。在回调函数中,程序会检查ROS节点是否仍然存活,如果存活,则继续发布消息。如果节点已经关闭,则回调函数会退出。在循环函数中,程序会空闲等待,以避免Arduino板子停止的问题。
ESP8266资料
这里,需要给AI一些资料让AI学习,并给出更合适的代码。
ESP8266:
/** rosserial Publisher Example* Prints "hello world!"* This intend to connect to a Wifi Access Point* and a rosserial socket server.* You can launch the rosserial socket server with* roslaunch rosserial_server socket.launch* The default port is 11411**/
#include <ESP8266WiFi.h>
#include <ros.h>
#include <std_msgs/String.h>const char* ssid = "your-ssid";
const char* password = "your-password";
// Set the rosserial socket server IP address
IPAddress server(192,168,1,1);
// Set the rosserial socket server port
const uint16_t serverPort = 11411;ros::NodeHandle nh;
// Make a chatter publisher
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);// Be polite and say hello
char hello[13] = "hello world!";void setup()
{// Use ESP8266 serial to monitor the processSerial.begin(115200);Serial.println();Serial.print("Connecting to ");Serial.println(ssid);// Connect the ESP8266 the the wifi APWiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}Serial.println("");Serial.println("WiFi connected");Serial.println("IP address: ");Serial.println(WiFi.localIP());// Set the connection to rosserial socket servernh.getHardware()->setConnection(server, serverPort);nh.initNode();// Another way to get IPSerial.print("IP = ");Serial.println(nh.getHardware()->getLocalIP());// Start to be politenh.advertise(chatter);
}void loop()
{if (nh.connected()) {Serial.println("Connected");// Say hellostr_msg.data = hello;chatter.publish( &str_msg );} else {Serial.println("Not Connected");}nh.spinOnce();// Loop exproximativly at 1Hzdelay(1000);
}
AI学习ESP8266
这是一段使用ESP8266芯片和ROS库的代码,它连接到一个WiFi接入点,并发布"hello world!"消息到ROS网络中的"chatter"话题。代码的主要功能如下:
- 包含必要的库文件:ESP8266WiFi库用于连接WiFi,ros库用于ROS通信,std_msgs库用于定义消息类型。
- 定义一些常量:WiFi的SSID和密码, Rosserial服务器的IP地址和端口号,发布消息的内容。
- 在setup函数中,初始化串口通信并开始连接WiFi。在连接成功后,打印出WiFi的IP地址,并设置与Roserial服务器的连接。
- 在loop函数中,检查是否已连接到Roserial服务器。如果已连接,则发布"hello world!"消息到"chatter"话题。如果没有连接,则打印"Not Connected"。
- 使用nh.spinOnce()来处理任何未处理的ROS消息,并使用delay(1000)使循环大约以1Hz的速度运行。
总的来说,这段代码是一个简单的例子,展示了如何使用ESP8266连接到WiFi网络,并与ROS进行通信。
AI给出ESP32示例
然后,接着提问:
请用esp32替换esp8266并给出代码
#include <WiFi.h>
#include <ros.h>
#include <std_msgs/String.h> const char* ssid = "your-ssid";
const char* password = "your-password";
// Set the rosserial socket server IP address
IPAddress server(192,168,1,1);
// Set the rosserial socket server port
const uint16_t serverPort = 11411; ros::NodeHandle nh;
// Make a chatter publisher
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg); // Be polite and say hello
char hello[13] = "hello world!"; void setup()
{ // Use ESP32 serial to monitor the process Serial.begin(115200); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); // Connect the ESP32 to the wifi AP WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); // Set the connection to rosserial socket server nh.getHardware()->setConnection(server, serverPort); nh.initNode(); // Another way to get IP Serial.print("IP = "); Serial.println(nh.getHardware()->getLocalIP()); // Start to be polite nh.advertise(chatter);
} void loop()
{ if (nh.connected()) { Serial.println("Connected"); // Say hello str_msg.data = hello; chatter.publish( &str_msg ); } else { Serial.println("Not Connected"); } nh.spinOnce(); // Loop exproximativly at 1Hz delay(1000);
}
请注意,ESP32和ESP8266在一些方面有所不同,因此代码需要进行一些修改以使其适用于ESP32。在上面的代码中,仅更换了库文件和某些函数调用,其他部分保持不变。
字符串改为浮点数示例
这段代码使用的是std_msgs/String.h头文件发布字符串消息,如果要发布一个浮点数应该如何修改代码?
要发布一个浮点数消息,需要使用std_msgs/Float64.h头文件,并相应地修改代码中的消息类型。以下是一个示例修改后的代码:
#include <WiFi.h>
#include <ros.h>
#include <std_msgs/Float64.h> // 替换为浮点数消息类型 const char* ssid = "your-ssid";
const char* password = "your-password";
// Set the rosserial socket server IP address
IPAddress server(192,168,1,1);
// Set the rosserial socket server port
const uint16_t serverPort = 11411; ros::NodeHandle nh;
// Make a chatter publisher for float messages
std_msgs::Float64 float_msg; // 定义浮点数消息对象
ros::Publisher float_pub("float_topic", &float_msg); // 创建浮点数消息发布者 // Be polite and say hello
float float_value = 3.14; // 定义浮点数值 void setup()
{ // Use ESP32 serial to monitor the process Serial.begin(115200); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); // Connect the ESP32 to the wifi AP WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); // Set the connection to rosserial socket server nh.getHardware()->setConnection(server, serverPort); nh.initNode(); // Start to be polite float_msg.data = float_value; // 设置浮点数值 float_pub.publish(&float_msg); // 发布浮点数消息
} void loop()
{ if (nh.connected()) { Serial.println("Connected"); } else { Serial.println("Not Connected"); } nh.spinOnce(); // Loop exproximativly at 1Hz delay(1000);
}
这段代码是一个使用ESP32和ROS1进行通信的示例程序。下面是代码的详细分析:
-
引入必要的库文件:
WiFi.h:用于连接WiFi网络。ros.h:用于与ROS1系统进行通信。std_msgs/Float64.h:用于定义浮点数消息类型。
-
定义常量:
ssid:WiFi网络的SSID。password:WiFi网络的密码。server:ROS1 rosserial服务器的IP地址。serverPort:ROS1 rosserial服务器的端口号。
-
创建ROS节点句柄(NodeHandle):
nh:ROS1节点的句柄,用于与ROS1系统进行通信。
-
定义浮点数消息对象:
float_msg:用于存储浮点数消息的数据。
-
创建浮点数消息发布者:
float_pub:用于发布浮点数消息到ROS1网络中的指定话题。
-
定义浮点数值:
float_value:一个初始值为3.14的浮点数。
-
setup函数:- 初始化串口通信,设置波特率为115200。
- 开始连接WiFi网络。
- 循环检查连接状态,直到连接成功。
- 打印连接成功信息,并显示ESP32的IP地址。
- 设置与ROS1 rosserial服务器的连接。
- 初始化ROS节点。
- 设置浮点数值,并发布浮点数消息到指定的话题。
-
loop函数:- 检查ROS节点是否连接成功。
- 如果连接成功,则打印"Connected",否则打印"Not Connected"。
- 调用ROS节点的
spinOnce函数,处理ROS消息。 - 延迟1秒,以实现大约1Hz的循环。
总体来说,这段代码的功能是将ESP32开发板连接到WiFi网络,并与ROS1系统进行通信。它使用WiFi模块进行网络连接,使用ROS1库进行消息发布和订阅。通过修改和定义适当的数据类型,可以发布和接收浮点数消息。
在这个示例中,我们使用了std_msgs/Float64.h头文件来定义浮点数消息类型,并创建了一个名为float_msg的浮点数消息对象。然后,我们创建了一个名为float_pub的发布者,用于发布浮点数消息到指定的话题上。在setup函数中,我们设置了浮点数值,并将其发布到ROS网络中。在loop函数中,我们检查是否已连接到Roserial服务器,并使用nh.spinOnce()来处理任何未处理的ROS消息。
在与ESP32和ROS1进行通信时,需要注意以下几点:
- 硬件设置:确保ESP32开发板与计算机之间通过合适的接口进行连接,如USB口或串口。同时,确保ESP32开发板的固件烧录正确,并且已经连接到了ROS1网络中。
- 通信协议选择:ROS1支持多种通信协议,如ROS消息、ROS服务、ROS话题等。根据实际需求,选择适合的通信协议进行通信。
- 消息类型定义:在使用ROS消息进行通信时,需要定义消息的数据类型。确保ESP32和ROS1中的消息类型匹配,否则可能会导致通信失败。
- 发布者与订阅者:在ROS1中,发布者用于发布消息,订阅者用于接收消息。ESP32既可以是消息的发布者,也可以是消息的订阅者。根据实际需求,选择适当的的方式进行通信。
- ROS话题:ROS话题是一种基于发布/订阅模式的通信协议。ESP32可以发布或订阅特定的话题,以便与其他节点进行通信。确保ESP32和ROS1中的话题名称匹配,以确保正确的通信。
- ROS服务:ROS服务提供了一种请求/响应式的通信方式。ESP32可以作为服务的提供者,提供某种服务,也可以作为服务请求者,请求其他节点的服务。在使用ROS服务进行通信时,需要确保服务名称和请求的数据类型匹配。
- 网络安全:在进行ROS1通信时,需要注意网络安全问题。ESP32开发板可能会暴露在互联网上,因此需要进行适当的安全设置和保护。
综上所述,与ESP32和ROS1进行通信需要确保硬件连接正确、通信协议选择合适、消息类型定义正确、发布者与订阅者设置正确、ROS话题和服务使用正确,同时注意网络安全问题。
相关文章:
M5ATOMS3基础03给ROS1发一个问候(rosserial)
引出问题 关于之前2020年的博客: 01. ESP8266和ROS调试一些问题汇总 02. ESP8266和ESP32配置(需使用ROS1和ROS2) 效果展示 使用M5ATOMS3与ROS1(kinetic,melodic,noetic)版本通信比较通用的是…...
基于Vue3实现鼠标按下某个元素进行移动,实时改变左侧或右侧元素的宽度,以及点击收起或展开的功能
其原理主要是利用JavaScript中的鼠标事件来控制CSS样式。大致就是监听某个DOM元素的鼠标按下事件,以及按下之后的移动事件和松开事件。在鼠标按下且移动过程中,可实时获得鼠标的X轴坐标的值,通过简单计算,可计算出目标元素的宽度&…...
使用MyBatis(2)
目录 一、定义接口、实体类、创建XML文件实现接口) 二、MyBatis的增删改查 🍅1、MyBatis传递参数查询 🎈写法一 🎈写法二 🎈两种方式的区别 🍅2、删除操作 🍅3、根据id修改用户名 &#x…...
【FPGA/D6】
2023年7月25日 VGA控制器 视频23notecodetb 条件编译error时序图保存与读取??RGBTFT显示屏 视频24PPI未分配的引脚或电平的解决方法 VGA控制器 视频23 note MCU单片机 VGA显示实时采集图像 行消隐/行同步/场同步/场消隐 CRT:阴极射线管 640…...
【WebGIS实例】(10)Cesium开场效果(场景、相机旋转,自定义图片底图)
效果 漫游效果视频: 【WebGIS实例】(10)Cesium开场效果(场景、相机 点击鼠标后将停止旋转并正常加载影像底图: 代码 可以直接看代码,注释写得应该比较清楚了: /** Date: 2023-07-28 16:21…...
【Spring】IOC的原理
一、 IOC 的概念 Spring 的 IOC ,即控制反转,所谓控制反转 —— 本来管理业务对象(bean)的操作是由我们程序员去做的,但是有了 Spring 核心容器后,这些 Bean 对象的创建和管理交给我们Spring容器去做了&am…...
AI加速游戏开发 亚马逊云科技适配3大场景,打造下一代游戏体验
随着疫情的消散,中国游戏产业正在快速前进。在伴随着游戏产业升级的同时,整个行业都在面临着新的挑战与新的诉求。亚马逊云科技游戏研发解决方案和服务,覆盖端到端3大场景,为游戏公司与游戏开发人员赋能。 场景1:AI辅助…...
C++ | 继承(基类,父类,超类),(派生类,子类)
文章参考:https://blog.csdn.net/war1111886/article/details/8609957 一 .继承中的访问权限关系 1.基类,父类,超类是指被继承的类,派生类,子类是指继承于基类的类. 2…...
Commands Of Hadoop
序言 持续整理下常用的命令cuiyaonan2000163.com Command 文件拷贝 当从多个源拷贝时,如果两个源冲突,distcp会停止拷贝并提示出错信息,. 如果在目的位置发生冲突,会根据选项设置解决。 默认情况会跳过已经存在的目标文件&am…...
SQL-每日一题【620.有趣的电影】
题目 某城市开了一家新的电影院,吸引了很多人过来看电影。该电影院特别注意用户体验,专门有个 LED显示板做电影推荐,上面公布着影评和相关电影描述。 作为该电影院的信息部主管,您需要编写一个 SQL查询,找出所有影片…...
linux 精华总结
...
Eureka 学习笔记2:客户端 DiscoveryClient
版本 awsVersion ‘1.11.277’ DiscoveryClient # cacheRefreshTask // 配置shouldFetchRegistry if (clientConfig.shouldFetchRegistry()) {// 配置client.refresh.intervalint registryFetchIntervalSeconds clientConfig.getRegistryFetchIntervalSeconds();// 配置expB…...
okhttp原理分析
工程目录图 请点击下面工程名称,跳转到代码的仓库页面,将工程 下载下来 Demo Code 里有详细的注释 01okhttp module里 包含的设计模式:建造者设计模式、责任链设计模式 CustomInject 演示自定义注解 代码:okhttp原理分析、Andro…...
freeswitch的mod_xml_curl模块
概述 freeswitch是一款简单好用的VOIP开源软交换平台。 随着fs服务的增多,每一台fs都需要在后台单独配置,耗时耗力,心力憔悴。 如果有一个集中管理配置的配置中心,统一管理所有fs的配置,并可以实现动态的修改配置就…...
高速数据采集专家-FMC140【产品手册】
FMC140是一款具有缓冲模拟输入的低功耗、12位、双通道(5.2GSPS/通道)、单通道10.4GSPS、射频采样ADC模块,该板卡为FMC标准,符合VITA57.1规范,该模块可以作为一个理想的IO单元耦合至FPGA前端,8通道的JESD204…...
【SSM】知识集锦
项目一:狂神JAVA 功能1:实现全部书籍查询 1.思路:首页index.jsp ——>Controller——>hello.jsp 2.步骤: step1:index.jsp <% page language"java" contentType"text/html; charsetUTF-8" page…...
Flowable-中间事件-信号中间抛出事件
定义 当流程执行到达信号抛出事件时,流程引擎会直接抛出信号,其他引用了与其相同的信号捕获 事件会被触发,信号发出后事件结束,流程沿后继路线继续执行。其抛出的信号可以被信号开始事 件(Signal Start Event…...
【算法基础:动态规划】5.3 计数类DP(整数拆分、分拆数)
文章目录 例题:900. 整数划分解法1——完全背包解法2——分拆数⭐⭐⭐ 例题:900. 整数划分 https://www.acwing.com/problem/content/902/ 解法1——完全背包 容量是 n,物品的大小和价值是 1 ~ n 中的所有数字。 import java.util.*;pub…...
封装(Encapsulation)
目录 概念 好处 数据隐藏 模块化设计 代码复用 简化接口 示例 意义 概念 封装(Encapsulation)是面向对象编程的一个核心概念,它指的是将数据和相关操作封装在一个对象中,隐藏了实现的细节。(就是实现数据封装和…...
php 原型模式
一,原型模式,就是先创建好一个原型对象,然后通过拷贝原型对象来生成新的对象。适用于大对象的创建,因为每次new一个大对象会有很大的开销,原型模式仅需内存拷贝即可。 原型模式中的主要角色: 1,…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
