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

news2024/11/16 21:35:08

引出问题

关于之前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通信的详细步骤如下:

  1. 首先,需要在ESP32上安装rosserial库。可以通过Arduino IDE的库管理器搜索并安装rosserial库。
  2. 打开Arduino IDE,创建一个新的程序。在程序中,需要包含ros.h和ros_arduino.h头文件。
  3. 在setup函数中,需要初始化ROS节点。这可以通过调用ros::Node::init()函数来实现。
  4. 要发布ROS消息,需要创建一个ROS话题发布者。可以通过调用ros::Node::get()->advertise函数来创建一个发布者。在这个函数中,需要指定发布的话题名称和发布者频率。
  5. 在主循环中,需要定义一个回调函数来处理接收到的ROS消息。可以通过调用ros::Node::get()->spinOnce()函数来等待ROS消息。
  6. 在主循环中,需要设置一个循环速率。在这个函数中,程序会等待一定的时间,然后再次尝试发布ROS消息。
  7. 要将消息发布到ROS话题上,可以使用发布者的publish函数。在这个函数中,需要创建一个ROS消息对象,并将其数据字段设置为您要发送的消息。
  8. 最后,在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 process
  Serial.begin(115200);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  // Connect the ESP8266 the 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);
}

AI学习ESP8266

这是一段使用ESP8266芯片和ROS库的代码,它连接到一个WiFi接入点,并发布"hello world!"消息到ROS网络中的"chatter"话题。代码的主要功能如下:

  1. 包含必要的库文件:ESP8266WiFi库用于连接WiFi,ros库用于ROS通信,std_msgs库用于定义消息类型。
  2. 定义一些常量:WiFi的SSID和密码, Rosserial服务器的IP地址和端口号,发布消息的内容。
  3. 在setup函数中,初始化串口通信并开始连接WiFi。在连接成功后,打印出WiFi的IP地址,并设置与Roserial服务器的连接。
  4. 在loop函数中,检查是否已连接到Roserial服务器。如果已连接,则发布"hello world!"消息到"chatter"话题。如果没有连接,则打印"Not Connected"。
  5. 使用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进行通信的示例程序。下面是代码的详细分析:

  1. 引入必要的库文件:

    • WiFi.h:用于连接WiFi网络。
    • ros.h:用于与ROS1系统进行通信。
    • std_msgs/Float64.h:用于定义浮点数消息类型。
  2. 定义常量:

    • ssid:WiFi网络的SSID。
    • password:WiFi网络的密码。
    • server:ROS1 rosserial服务器的IP地址。
    • serverPort:ROS1 rosserial服务器的端口号。
  3. 创建ROS节点句柄(NodeHandle):

    • nh:ROS1节点的句柄,用于与ROS1系统进行通信。
  4. 定义浮点数消息对象:

    • float_msg:用于存储浮点数消息的数据。
  5. 创建浮点数消息发布者:

    • float_pub:用于发布浮点数消息到ROS1网络中的指定话题。
  6. 定义浮点数值:

    • float_value:一个初始值为3.14的浮点数。
  7. setup函数:

    • 初始化串口通信,设置波特率为115200。
    • 开始连接WiFi网络。
    • 循环检查连接状态,直到连接成功。
    • 打印连接成功信息,并显示ESP32的IP地址。
    • 设置与ROS1 rosserial服务器的连接。
    • 初始化ROS节点。
    • 设置浮点数值,并发布浮点数消息到指定的话题。
  8. 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进行通信时,需要注意以下几点:

  1. 硬件设置:确保ESP32开发板与计算机之间通过合适的接口进行连接,如USB口或串口。同时,确保ESP32开发板的固件烧录正确,并且已经连接到了ROS1网络中。
  2. 通信协议选择:ROS1支持多种通信协议,如ROS消息、ROS服务、ROS话题等。根据实际需求,选择适合的通信协议进行通信。
  3. 消息类型定义:在使用ROS消息进行通信时,需要定义消息的数据类型。确保ESP32和ROS1中的消息类型匹配,否则可能会导致通信失败。
  4. 发布者与订阅者:在ROS1中,发布者用于发布消息,订阅者用于接收消息。ESP32既可以是消息的发布者,也可以是消息的订阅者。根据实际需求,选择适当的的方式进行通信。
  5. ROS话题:ROS话题是一种基于发布/订阅模式的通信协议。ESP32可以发布或订阅特定的话题,以便与其他节点进行通信。确保ESP32和ROS1中的话题名称匹配,以确保正确的通信。
  6. ROS服务:ROS服务提供了一种请求/响应式的通信方式。ESP32可以作为服务的提供者,提供某种服务,也可以作为服务请求者,请求其他节点的服务。在使用ROS服务进行通信时,需要确保服务名称和请求的数据类型匹配。
  7. 网络安全:在进行ROS1通信时,需要注意网络安全问题。ESP32开发板可能会暴露在互联网上,因此需要进行适当的安全设置和保护。

综上所述,与ESP32和ROS1进行通信需要确保硬件连接正确、通信协议选择合适、消息类型定义正确、发布者与订阅者设置正确、ROS话题和服务使用正确,同时注意网络安全问题。

 


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

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

相关文章

BUU [网鼎杯 2020 朱雀组]phpweb

BUU [网鼎杯 2020 朱雀组]phpweb 众生皆懒狗。打开题目&#xff0c;只有一个报错&#xff0c;不知何从下手。 翻译一下报错&#xff0c;data()函数:,还是没有头绪&#xff0c;中国有句古话说的好“遇事不决抓个包” 抓个包果然有东西&#xff0c;仔细一看这不就分别是函数和参…

【算法基础:贪心】6. 贪心

文章目录 区间问题905. 区间选点&#xff08;排序 贪心&#xff09;908. 最大不相交区间数量&#xff08;排序 贪心&#xff09;906. 区间分组&#xff08;排序 优先队列 贪心&#xff09;⭐907. 区间覆盖&#xff08;排序 贪心&#xff09; Huffman树148. 合并果子&#…

【LeetCode 75】第十四题(643)子数组最大平均数

题目: 示例: 分析: 给一个数组,问数组里长度为k的连续数组中的最大平均值是多少. 这题已经把意思说的很明白了,并且连子数组的长度都固定了,并且是连续的,这里可以直接使用固定长度的滑动窗口来计算. 用两个指针来在数组里划定一个长度为k的范围,然后计算指针范围内的平均数…

数组传参,指针传参

文章目录 一维数组传参二维数组传参一级指针传参二级指针传参 一维数组传参 二维数组传参 一级指针传参 二级指针传参

CentOS 8 上安装 Nginx

Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;以其轻量级和高效能而广受欢迎。在本教程中&#xff0c;我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1&#xff1a;更新系统 在安装任何软件之前&#xff0c;让我们先更新系统的软件包列表和已安…

【树链剖分+MST】CF609E

Problem - E - Codeforces 题意&#xff1a; 思路&#xff1a; 先把全局的MST求出来&#xff0c;然后对于一条边&#xff0c;如果它本来就在MST中&#xff0c;说明代价就是MST的权值和&#xff0c;否则它加入MST中&#xff0c;此时MST形成了环&#xff0c;我们把环中最大的那…

深入探究Java面向对象的三大特征:封装、继承、多态

文章目录 1. 封装&#xff08;Encapsulation&#xff09;2. 继承&#xff08;Inheritance&#xff09;3. 多态&#xff08;Polymorphism&#xff09;结语 导语&#xff1a;Java是一门面向对象的编程语言&#xff0c;其核心思想是将现实世界中的事物抽象成对象&#xff0c;并通过…

Python(五十二)列表元素的判断及遍历

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

自己整理的JAVA集合

概括&#xff1a; 数组&#xff0c;链表&#xff0c;散列表&#xff0c;二分查找树&#xff0c;红黑树是五种不同的数据结构&#xff0c;它们有各自的特点和用途。ArrayList&#xff0c;LinkedList&#xff0c;HashTable&#xff0c;LinkedHashMap&#xff0c;HashMap 是 Java…

Camera组件

Clear Flags&#xff1a; Skybox&#xff1a;天空盒 Solid Color&#xff1a;填充颜色&#xff0c;当有空白处时填充背景颜色 Depth Only&#xff1a;只渲染想要渲染的层级 Dont Clear&#xff1a;不清除上一帧所留下来的数据&#xff0c;可以做类似残影的效果 Culling Mas…

Unity Addressable

Unity重要目录 工程中的几个重要目录 Assets存放资源、代码、配置Library大部分的资源导入到Assets目录之后&#xff0c;会转化成Unity认可的文件&#xff0c;转化后的文件会存储在这个目录Logs日志文件Packages第三方插件ProjectSettings存放各种项目设定UserSettings用户偏好…

CentOS 8 错误: Error setting up base repository

配置ip、掩码、网关、DNS VMware网关可通过如下查看 打开网络连接 配置镜像的地址 vault.centos.org/8.5.2111/BaseOS/x86_64/os/

java 阿里云 发送短信功能实现

1. 注册短信平台(以阿里云为例) 常用短信服务平台&#xff1a;阿里云、华为云、腾讯云、京东、梦网、乐信等 2. 注册成功后&#xff0c;开通短信服务 3. 设置短信签名、短信模板、AccessKey AccessKey 是访问阿里云 API 的密钥&#xff0c;具有账户的完全权限&#xff0c;我们…

C语言实现三子棋游戏

test.c源文件 - 三子棋游戏测试 game.h头文件 - 三子棋游戏函数的声明 game.c源文件 - 三子棋游戏函数的实现 主函数源文件&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1#include"game.h" //自己定义的用"" void menu() {printf("*************…

代码随想录算法训练营day43

文章目录 Day43 最后一块石头的重量II题目思路代码 目标和题目思路代码 一和零题目思路代码 Day43 最后一块石头的重量II 1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 题目 有一堆石头&#xff0c;每块石头的重量都是正整数。 每一回合&#xff0…

2023-07-30 LeetCode每日一题(环形链表 II)

2023-07-30每日一题 一、题目编号 142. 环形链表 II二、题目链接 点击跳转到题目位置 三、题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 n…

【探索C++中的顺序表】手动实现vector容器

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对…

Fourier变换及其应用(Brad G. Osgood)——第2章——Fourier变换

第2章 Fourier变换 2.1 初识Fourier变换(A First Look at the Fourier Transform) 我们即将从Fourier级数过渡到Fourier变换。“过渡(transition)”是合适的词&#xff0c;因为我们选择了Fourier变换从周期函数到非周期函数的引出路径。 为了完成这一旅程&#xff0c;我们将把…

【优选算法题练习】day10

文章目录 一、137. 只出现一次的数字 II1.题目简介2.解题思路3.代码4.运行结果 二、剑指 Offer 53 - II. 0&#xff5e;n-1中缺失的数字1.题目简介2.解题思路3.代码4.运行结果 三、153. 寻找旋转排序数组中的最小值1.题目简介2.解题思路3.代码4.运行结果 总结 一、137. 只出现一…

登录报错 “msg“:“Request method ‘GET‘ not supported“,“code“:500

1. 登录失败 2. 排查原因, 把 PostMapping请求注释掉, 或改成GetMapping请求就不会报错 3. 找到SecurityConfig.java , 新增 .antMatchers("/**/**").permitAll() //匹配允许所有路径 4. 登录成功