Overview

Due to its prevalence within the robotics community, GRID has been designed to be compatible with ROS. This page will cover how to integrate GRID with ROS, as well as how to integrate hardware with ROS.

ROS Integration currently requires a rosbridge server to be running. This can be done by running ros2 run rosbridge_server rosbridge_websocket port:=8080 in the terminal.

ROSAgent

The primary way to interact with ROS is through the use of the ROSAgent class. This is designed to create any publishers/subscribers that you need easily. There are a few clients that we have created in advance, but we also offer a generic option in the circumstance that you need additional functionality.

Client Configuration

All ROS clients share a common base configuration structure:

base_config = {
    # Required parameters
    "topic_name": "/topic/name",     # ROS topic to publish/subscribe
    "type": "client_type",          # Type of client (image, velocity, pose, generic)
    
    # Optional parameters
    "msg_type": "msg/Type",         # ROS message type
    "mode": "listener",             # "listener" or "talker" (default: "listener")
    "host": "localhost",            # ROS bridge host (default: "localhost")
    "port": 8080,                   # ROS bridge port (default: 8080)
    "verbose": False,               # Enable verbose logging (default: False)
    "queue_length": 0,             # Message queue length (default: 0 = unlimited)
    "real": False,                  # Whether the client is connected to a real robot (default: False)
}

Client Types

Image Client

Handles transmission of image data between ROS and GRID. Automatically handles encoding/decoding of image data and supports various image formats including RGB, BGR, RGBA, and grayscale.

Defaults:

  • msg_type: “sensor_msgs/Image”

Velocity Client

Manages robot movement commands by publishing or subscribing to velocity messages. Handles both linear (x, y, z) and angular (roll, pitch, yaw) velocities.

Defaults:

  • msg_type: “geometry_msgs/Twist”
  • topic_name: “/cmd_vel”

Pose Client

Handles robot positioning and orientation data. Can work with both absolute and relative positioning, and supports quaternion-based orientation.

Defaults:

  • msg_type: “geometry_msgs/Pose”
  • topic_name: “/robot_pose”
pose_config = {
    ...,  # Base configuration
    "relative": False,     # Use relative positioning
    "blocking": False,     # Wait for movements to complete
    "timeout": 5.0        # Time in seconds to wait for blocking moves
}

Generic Client

Provides flexibility for custom ROS message types not covered by the specialized clients. Allows for custom message processing through user-defined functions.

generic_config = {
    ...,  # Base configuration
    "fn": custom_processing_function,  # Function to process messages
    "args": {}                        # Additional arguments for processing function
}

Integrating Robot Plugins with ROS

The agent_dict parameter is used to connect ROS clients with real robot agents. Here’s how it’s used in each client:

Base Client (ROSClient)

agent_dict = {
    "agent": robot_instance  # Instance of the robot to control
}

The base client attempts to connect to the provided agent and prints a confirmation message if successful.

Image Client

Uses the agent to:

  • Get images from the robot’s camera when publishing (publish_agent_image())
  • The agent must implement getImage() method

Pose Client

Uses the agent to:

  • Move the robot to specified poses (moveToPose())
  • Get current position and orientation (getPosition(), getOrientation())
  • Handle relative and blocking movements based on configuration

Velocity Client

Uses the agent to:

  • Control robot movement through velocity commands (moveByVelocity())
  • The agent must implement velocity-based movement control

Generic Client

Can use the agent through custom processing functions defined in the configuration.

In the RosAgent class, agent_dict is passed to each client during creation when the real flag is set to True in the client configuration. This allows the clients to directly control the physical robot through the agent interface.

Example

from grid.comm.ros import RosAgent
from grid.robot.wheeled.airgen_car import AirGenCar

agent_dict = {
    "agent": AirGenCar()
}

client_config = {
    "topic_name": "/cmd_vel",
    "type": "velocity",
    "real": True,
}

client = RosAgent(client_config, agent_dict)

In this example, a listener will be created that will cause the AirGenCar to move when a velocity message is published to the /cmd_vel topic. This can be used to control any agent, including the phsyical robots, as long as the respective agent has the required methods implemented.

GRID Nexus

GRID Nexus is a Rust implementation of the ROS environment. It currently supports publishing and subscribing to ROS topics. We have found that by using Nexus, we can achieve higher performance and lower latency when interacting with ROS. Specifically, queuing and message transfer is handled much more efficiently and prevents stale messages from being handled, especially in the case where the publisher is publishing faster than the subscriber can handle.