MQTT Usage

Introduction to MQTT and Its Use in Our Hardware Platform

MQTT (Message Queuing Telemetry Transport) is a lightweight, publish-subscribe network protocol that transports messages between devices. It is designed for constrained devices and low-bandwidth, high-latency, or unreliable networks, making it ideal for Internet of Things (IoT) applications. In our hardware platform, we utilize MQTT for efficient communication between various components of the robot.

MQTT Basics

Publish-Subscribe Model

MQTT uses a publish-subscribe model where devices (clients) can publish messages to topics and subscribe to topics to receive messages. This decoupling of publishers and subscribers allows for scalable and flexible communication.

Topics

Topics in MQTT are hierarchical strings that represent different channels of communication. For example, in our system, we use topics like /localization/robot_pose and /mapping/traversability_grid to organise different types of messages.

All of the message definitions and the topic names are defined in the TOML configuration file bot_quickstart_msgs.toml

Implementation in Our Hardware Platform

MQTT Broker

We use a local MQTT broker running on the robot itself. The broker address is typically set to localhost or the robot's IP address. This is already running by default at boot if you ran the initial setup scripts.

Advantages of Using MQTT

  1. Decoupled Communication: Components can communicate without direct dependencies.
  2. Scalability: Easy to add new features or sensors by introducing new topics.
  3. Lightweight: Minimal overhead, suitable for resource-constrained devices.
  4. Reliability: Supports various quality of service levels for message delivery.

Key Topics

Our system utilizes several MQTT topics for different functionalities. Note that all of these topics are available after running the default nodes/start_all_nodes.py script.

  1. /imu/gyro: Publishes gyroscope data including roll, pitch, and yaw.
  2. /imu/raw_imu: Publishes raw IMU data including accelerometer and gyroscope readings.
  3. /imu/raw_imu_unscaled_biased: Publishes unscaled and biased raw IMU data.
  4. /localization/processed_imu: Publishes processed IMU data for localization purposes.
  5. /wheel_velocities_mps: Publishes wheel velocities in meters per second.
  6. /localization/extended_pose_state: Publishes extended pose state data including position, velocity, orientation, and biases.
  7. /localization/initialized_flag: Publishes a flag indicating whether localization has been initialized.
  8. /localization/robot_pose: Publishes the robot's pose including position and orientation.
  9. /localization/robot_extended_pose: Publishes the robot's extended pose including position, velocity, and orientation in metric units.
  10. /mapping/robot_pose_grid_coords: Publishes the robot's pose in grid coordinates.
  11. /mapping/occupancy_grid: Publishes occupancy grid data for mapping.
  12. /mapping/traversability_grid: Publishes traversability grid data for mapping.
  13. /planning/path_plan: Publishes a list of poses representing a planned path.
  14. /planning/target_point: Publishes the target point in grid coordinates for planning.
  15. /control/target_velocity: Publishes target linear and angular velocities for control.
  16. /mapping/tof_map: Publishes Time-of-Flight sensor data for mapping.
  17. /mapping/wavemap_occupied_points: Publishes a list of occupied points in the wave map for mapping.

MQTT Utilities Documentation

This document provides an overview of the MQTTSubscriber and MQTTPublisher classes found in mqtt_utils.py, and includes examples on how to set up a subscriber and publisher in a node.

Overview

The MQTTSubscriber and MQTTPublisher classes are designed to facilitate communication over MQTT, a lightweight messaging protocol. These classes allow for easy setup of MQTT clients that can publish and subscribe to topics, enabling message exchange between different components of a system.

MQTTPublisher

The MQTTPublisher class is responsible for publishing messages to specified MQTT topics. It connects to an MQTT broker and sends messages in a structured format.

Key Features:

  • Connects to an MQTT broker.
  • Publishes messages to specified topics.
  • Supports JSON payloads and custom message objects.

MQTTSubscriber

The MQTTSubscriber class is responsible for subscribing to specified MQTT topics and receiving messages. It runs in a separate thread to continuously listen for incoming messages.

Key Features:

  • Connects to an MQTT broker.
  • Subscribes to specified topics.
  • Processes incoming messages and stores the latest message for each topic.

Setting Up a Publisher

To set up an MQTT publisher, follow these steps:

  1. Initialize the Publisher:

    Create an instance of the MQTTPublisher class, providing the broker address and a dictionary mapping topics to message classes.

    from lib.messages.mqtt_utils import MQTTPublisher
    from lib.messages.target_point_msg import TARGET_POINT_MSG
    from lib.messages.topic_to_message_type import (TOPIC_TARGET_POINT)
    
    publisher = MQTTPublisher(broker_address="localhost", topic_to_message_map={TOPIC_TARGET_POINT: TARGET_POINT_MSG})
  2. Connect and Start the Publisher:

    Connect to the broker and start the MQTT loop.

    publisher.run()
  3. Publish to a Topic:

    Use the publish_dict or publish_msg method to send messages to a topic.

    target_point_msg = TARGET_POINT_MSG()
    target_point_msg.timestamp = time.time()
    target_point_msg.x_grid = 200
    target_point_msg.y_grid = 210
    publisher.publish_msg(TOPIC_TARGET_POINT, target_point_msg)
  4. Stop the Publisher:

    When done, stop the publisher to disconnect from the broker.

    publisher.stop()

Setting Up a Subscriber

To set up an MQTT subscriber, follow these steps:

  1. Initialize the Subscriber:

    Create an instance of the MQTTSubscriber class, providing the broker address and a dictionary mapping topics to message classes.

    from lib.messages.mqtt_utils import MQTTSubscriber
    from lib.messages.target_point_msg import TARGET_POINT_MSG
    from lib.messages.topic_to_message_type import (TOPIC_TARGET_POINT)
    
    subscriber = MQTTSubscriber(broker_address="localhost", topic_to_message_map={TOPIC_TARGET_POINT: TARGET_POINT_MSG})
  2. Start the Subscriber:

    Start the subscriber to begin listening for messages.

    subscriber.start()
  3. Retrieve Messages:

    Use the get_latest_message method to retrieve the latest message for a specific topic.

    target_point_msg = subscriber.get_latest_message(TOPIC_TARGET_POINT)
    if target_point_msg is not None:
        print("Received message:", target_point_msg.x_grid)
  4. Stop the Subscriber:

    When done, stop the subscriber to disconnect from the broker.

    subscriber.stop()