Integrating ESP32 with ROS over WiFi
This blog describes how to use WiFi to connect the ESP32 development board to the Robot Operating System (ROS).
The project Github:
https://github.com/Xiangyu-Fu/ESP32_ROS_wifi
prerequisites
Before we begin, make sure you have the following development environment:
- Ubuntu 20.04
- ROS Noetic
- PlatformIO espressif32
- ESP32 Arduino Framework
- frankjoshua/Rosserial Arduino Library@^0.9.1
You can also use a Raspberry Pi instead of a PC.
Environment settings
On PC or Raspberry Pi
The required ROS packages need to be installed. Use the following command in the terminal:
$ sudo apt-get install ros-${ROS_DISTRO}-rosserial-arduino
$ sudo apt-get install ros-${ROS_DISTRO}-rosserial
After installing the necessary packages, start the ROS master node:
$ roscore
Then, in a new terminal window, run rosserial node:
$ rosrun rosserial_python serial_node.py tcp
This will start the ROS node that will connect to our ESP32 via TCP.
On an embedded device (here ESP32)
Make sure you have flashed the appropriate sample code to the board. This can be achieved using the PlatformIO environment or the Arduino IDE.
Run the example
The complete code is as follows,
/*
* 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());
}
Next, let’s talk about the use of each part in detail.
Dependencies
The first step is to include the necessary libraries. These libraries are the Arduino core library, the WiFi library for connecting to the network, and the ROS library for interacting with the ROS system.
#include <arduino.h>
#include "WiFi.h"
#include <ros.h>
#include <std_msgs/String.h>
We define several global variables:
- The IP addresses of the Arduino development board and ROS server.
- The server port of the ROS server.
- The SSID and password of the WiFi network.
- The message we will send to the ROS server ("hello world!") and how often we will send it.
- A handle to the ROS node and the publisher that sends messages to the ROS system.
Connect to WiFi
Our setupWiFi()
function connects the Arduino board to the WiFi network. It repeatedly checks the connection status and prints a period for each attempt until a connection is established. Once the connection is successful, it will print out the SSID and local IP address of the WiFi connection.
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());
}
Main settings
In setup()
the function, we initialize the serial communication for debugging, set up the WiFi connection, establish the connection to the ROS server, initialize the ROS node, and publish the publisher.
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);
}
main loop
In the main loop()
, we check the time and if enough time has passed since the last message, we send a new message. We also check the connection status and print a message to the serial monitor accordingly. After these checks, we call nh.spinOnce()
handle any incoming messages and then delay for one millisecond.
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);
}
You are now ready to start using your Arduino to interact with ROS over WiFi.
After everything is set up and the ESP32 is connected to the same network as your PC or Raspberry Pi, the ESP32 should start sending "hello world!" messages to the ROS system. This output can be visualized using a tool like rqt_console, or simply monitor the output in the terminal.
If everything is set up correctly, you should see a screen similar to the following:
The ESP32 is now connected to ROS via WiFi. This basic framework can become the basis for more complex projects where ESP32 interacts with ROS to control robots or other devices.