Integrating ESP32 with ROS over WiFi

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:

result

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.

Guess you like

Origin blog.csdn.net/qq_37266917/article/details/132151416