Mastering Holonomic Control with NVIDIA Isaac Sim and ROS2: A Guide for the Kaya Robot

Kabilankb
5 min readAug 18, 2024

--

Introduction

Holonomic movement is a crucial feature in modern robotics, enabling robots to move in any direction without the need to rotate first. This ability to maneuver with ease is essential for tasks that require high precision in confined spaces, such as warehouse automation, service robotics, and more. The NVIDIA Kaya robot, designed with a holonomic drive system, exemplifies this capability. In this guide, we will explore how to set up and control the Kaya robot using NVIDIA Isaac Sim, with a focus on ROS2 integration.

NVIDIA Isaac Sim provides a powerful simulation environment, and its OmniGraph system plays a pivotal role in managing the robot’s actions and interactions, similar to how ROS2 nodes and topics work. We’ll dive into setting up a holonomic robot in the simulation, utilizing key components like the Articulator Controller and Holonomic Driver, and understanding the USD setup that underpins the robot’s behavior. Finally, we’ll walk through the kaya_drive.py code, which implements ROS2 control of the Kaya robot.

Understanding Holonomic Movement

Holonomic robots can move in any direction with three degrees of freedom: forward/backward, sideways, and rotational movements. Unlike differential drive robots, holonomic robots are equipped with omnidirectional wheels or other mechanisms that allow for instant directional changes without altering the robot’s orientation. This makes them ideal for environments where agility and precision are required.

The Kaya Robot

The Kaya robot, developed by NVIDIA, is a small, versatile robot equipped with a holonomic drive system. It is built on the Jetson Nano platform, making it ideal for AI and robotics applications. The Kaya robot is specifically designed for easy integration with NVIDIA Isaac Sim, allowing for seamless simulation and real-world deployment. Its holonomic drive consists of three omnidirectional wheels, providing it with the ability to move smoothly in any direction.

OmniGraph and Action Graph: ROS2 Context

In NVIDIA Isaac Sim, OmniGraph is a powerful tool used to create complex simulations by connecting nodes, similar to how ROS2 nodes communicate via topics and services. For controlling the Kaya robot, several key nodes are utilized within the OmniGraph:

  • Break 3 Vector: This node is used to decompose a 3D vector into its individual components (x, y, z). In the context of controlling the Kaya robot, this is crucial for managing the individual movement axes.
  • Make 3 Vector: This node reassembles the individual x, y, and z components into a single 3D vector. This vector is then used to define the robot’s desired movement direction.
  • Articulator Controller: This node is responsible for controlling the robot’s joints and actuators. It translates the desired movement vector into actual physical movements of the robot’s wheels.
  • Holonomic Driver: This specialized driver manages the holonomic drive system, ensuring that the robot moves smoothly in the intended direction with the correct velocity.

USD Setup for Holonomic Robot

In the simulation, Universal Scene Description (USD) files define the physical and visual properties of the robot. Setting up a holonomic robot in NVIDIA Isaac Sim involves configuring the USD to accurately represent the robot’s kinematics and dynamics. The USD file for the Kaya robot includes details about the robot’s wheels, sensors, and actuators, all of which are crucial for realistic simulation. The Holonomic Driver and Articulator Controller nodes reference these USD configurations to control the robot effectively.

OmniGraph Explained: Connecting the Dots

The OmniGraph for controlling the Kaya robot involves a sequence of connected nodes:

  1. Input Handling: The movement commands are generated based on user input or sensor data, which are then passed through the Break 3 Vector node.
  2. Movement Vector Assembly: The x, y, and z components are processed and recombined using the Make 3 Vector node to form the desired movement vector.
  3. Articulator Control: This movement vector is fed into the Articulator Controller, which determines the necessary actions for each wheel to achieve the desired movement.
  4. Holonomic Drive Execution: Finally, the Holonomic Driver ensures that the robot’s wheels move in unison, allowing for smooth holonomic movement in the simulation environment.

Implementing ROS2 Control: The kaya_drive.py Code

To control the Kaya robot via ROS2, we create a node that publishes velocity commands to the robot’s /cmd_vel topic. Here’s a breakdown of the kaya_drive.py script:

import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist

class KayaControlNode(Node):
def __init__(self):
super().__init__('kaya_control_node')

# Publisher to send velocity commands to the Kaya robot
self.cmd_vel_publisher = self.create_publisher(Twist, '/cmd_vel', 10)

# Timer to control the rate of publishing
self.timer = self.create_timer(1.0, self.move_kaya) # Update every second

# Define movement sequence
self.movement_sequence = [
'forward',
'rotate_left',
'backward',
'rotate_right'
]
self.current_index = 0
self.sequence_duration = 5.0 # Duration for each movement in seconds
self.start_time = self.get_clock().now()

# Define velocities for different movements
self.velocity = Twist()

def move_kaya(self):
# Determine the elapsed time for current movement
current_time = self.get_clock().now().to_msg().sec
elapsed_time = current_time - self.start_time.to_msg().sec

# Check if it's time to switch to the next movement in the sequence
if elapsed_time > self.sequence_duration:
self.current_index = (self.current_index + 1) % len(self.movement_sequence)
self.start_time = self.get_clock().now()

# Set velocity based on the current movement in the sequence
self.set_movement(self.movement_sequence[self.current_index])

# Publish the velocity command
self.cmd_vel_publisher.publish(self.velocity)
self.get_logger().info(f'Movement State: {self.movement_sequence[self.current_index]} | Publishing: x={self.velocity.linear.x}, y={self.velocity.linear.y}, z={self.velocity.angular.z}')

def set_movement(self, state):
# Set the velocity based on the movement state
if state == 'forward':
self.velocity.linear.x = 0.2
self.velocity.linear.y = 0.0
self.velocity.angular.z = 0.0
elif state == 'backward':
self.velocity.linear.x = -0.2
self.velocity.linear.y = 0.0
self.velocity.angular.z = 0.0
elif state == 'rotate_left':
self.velocity.linear.x = 0.0
self.velocity.linear.y = 0.0
self.velocity.angular.z = 0.2
elif state == 'rotate_right':
self.velocity.linear.x = 0.0
self.velocity.linear.y = 0.0
self.velocity.angular.z = -0.2
else:
# Default to no movement if state is unknown
self.velocity.linear.x = 0.0
self.velocity.linear.y = 0.0
self.velocity.angular.z = 0.0

def main(args=None):
rclpy.init(args=args)
node = KayaControlNode()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()

if __name__ == '__main__':
main()

In this code:

  • Publisher Initialization: The node initializes a publisher to send velocity commands.
  • Movement Command: The move_kaya method sets the linear and angular velocities. For a holonomic drive, both linear.x and linear.y can be used to move in any direction.
  • Execution: The node runs continuously, publishing movement commands at regular intervals.

Conclusion

By leveraging the NVIDIA Isaac Sim and ROS2, controlling the Kaya robot’s holonomic drive becomes a seamless process. The integration of OmniGraph with the USD setup allows for accurate simulation and control, while ROS2 provides the necessary tools for real-time robot manipulation. The kaya_drive.py script offers a simple yet powerful way to implement movement control, making it an excellent starting point for more complex robotic applications. Whether you're simulating in Isaac Sim or deploying in the real world, this guide provides a solid foundation for mastering holonomic control with the NVIDIA Kaya robot.

--

--