通过WiFi将ESP32与ROS集成
这篇博客介绍如何使用WiFi将ESP32开发板连接到机器人操作系统(ROS)。
该项目Github:
https://github.com/Xiangyu-Fu/ESP32_ROS_wifi
先决条件
在我们开始之前,请确保有以下开发环境:
- Ubuntu 20.04
- ROS Noetic
- PlatformIO espressif32
- ESP32 Arduino Framework
- frankjoshua/Rosserial Arduino Library@^0.9.1
也可以使用树莓派代替PC。
环境设置
在PC或树莓派上
需要安装所需的ROS包。在终端中使用以下命令:
$ sudo apt-get install ros-${ROS_DISTRO}-rosserial-arduino
$ sudo apt-get install ros-${ROS_DISTRO}-rosserial
安装必要的包后,启动ROS主节点:
$ roscore
然后,在一个新的终端窗口中,运行rosserial节点:
$ rosrun rosserial_python serial_node.py tcp
这将启动将与我们的ESP32通过TCP连接的ROS节点。
在嵌入式设备上(这里是ESP32)
确保已经向开发板刷入了适当的示例代码。可以使用PlatformIO环境或Arduino IDE来实现这一点。
运行示例
完整代码如下所示,
/*
* Code initializes and connects to a WiFi network using given SSID and password,
* then publishes a "Hello World!" message to a ROS topic "chatter" at regular intervals.
* Make sure to update the SSID, password, IP and server details as per your network.
*
* Create by Stan Fu on 2023/08/07
*/
#include <arduino.h>
#include "WiFi.h"
#include <ros.h>
#include <std_msgs/String.h>
IPAddress server(192, 168, 178, 48);
uint16_t serverPort = 11411;
const char* ssid = "your wifi name";
const char* password = "your wifi password";
// Be polite and say hello
char hello[13] = "hello world!";
uint16_t period = 1000;
uint32_t last_time = 0;
ros::NodeHandle nh;
// Make a chatter publisher
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
void setupWiFi();
void setup(){
Serial.begin(115200);
setupWiFi();
nh.getHardware()->setConnection(server, serverPort);
nh.initNode();
// Another way to get IP
Serial.print("ROS IP = ");
Serial.println(nh.getHardware()->getLocalIP());
// Start to be polite
nh.advertise(chatter);
}
void loop(){
if(millis() - last_time >= period)
{
last_time = millis();
if (nh.connected())
{
Serial.println("Connected");
// Say hello
str_msg.data = hello;
chatter.publish( &str_msg );
} else {
Serial.println("Not Connected");
}
}
nh.spinOnce();
delay(1);
}
void setupWiFi()
{
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500);Serial.print("."); }
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
接下来详细讲一下各个部分的用处。
依赖项
第一步是包含必要的库。这些库是Arduino核心库,用于连接网络的WiFi库,以及用于与ROS系统交互的ROS库。
#include <arduino.h>
#include "WiFi.h"
#include <ros.h>
#include <std_msgs/String.h>
我们定义了几个全局变量:
- Arduino开发板和ROS服务器的IP地址。
- ROS服务器的服务器端口。
- WiFi网络的SSID和密码。
- 我们将发送给ROS服务器的消息(“hello world!”)以及我们将发送它的频率。
- ROS节点的句柄以及向ROS系统发送消息的发布器。
连接到WiFi
我们的setupWiFi()
函数将Arduino开发板连接到WiFi网络。它反复检查连接状态,并为每次尝试打印一个句号,直到建立连接。一旦连接成功,它将打印出WiFi连接的SSID和本地IP地址。
void setupWiFi()
{
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500);Serial.print("."); }
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
主要设置
在setup()
函数中,我们初始化了串行通信以进行调试,设置了WiFi连接,建立了与ROS服务器的连接,初始化了ROS节点,并发布了发布器。
void setup(){
Serial.begin(115200);
setupWiFi();
nh.getHardware()->setConnection(server, serverPort);
nh.initNode();
Serial.print("ROS IP = ");
Serial.println(nh.getHardware()->getLocalIP());
nh.advertise(chatter);
}
主循环
在主loop()
中,我们检查时间,如果自上一条消息以来已经过了足够的时间,我们就发送一条新消息。我们还检查连接状态,并相应地向串行监视器打印一条消息。这些检查之后,我们调用nh.spinOnce()
处理任何传入的消息,然后延迟一毫秒。
void loop(){
if(millis() - last_time >= period)
{
last_time = millis();
if (nh.connected())
{
Serial.println("Connected");
str_msg.data = hello;
chatter.publish( &str_msg );
} else {
Serial.println("Not Connected");
}
}
nh.spinOnce();
delay(1);
}
现在已经准备好开始使用Arduino通过WiFi与ROS进行交互了。
完成所有设置后,ESP32连接到与个人电脑或树莓派相同的网络,ESP32应该开始向ROS系统发送"hello world!"的消息。可以使用rqt_console这样的工具可视化这个输出,或者简单地在终端中监控输出。
如果一切设置正确,应该看到类似以下的屏幕:
ESP32现在已经通过WiFi连接到ROS了。这个基本框架可以成为ESP32与ROS交互控制机器人或其他设备的更复杂项目的基础。