ROS Tutorials (Linux Only)

Driving TurtleBot via ROS messages

ROS bridge comes with a few popular ros topics that are packaged for ease of use
(More details are in the ROS & ROS2 Bridge)
Focus on the procedures in using them
-Steps to connect Omniverse Isaac Sim to ROS can be done in?
Entirely in the UI
Scripting inside the extension workflow
Scripting inside the standalone Python workflow
(Refer to Isaac Sim Workflows for details of different workflows)
Demonstrate the UI method using existing Omnigraph nodes

Learning Objectives

(1)Enable a Turtlebot3 to drive around and subscribe to a twist message through the ROS network
(2)Learn to Add controllers to Turtlebot3
(3)Introduce the ROS bridge and ROS OmniGraph (OG) nodes
(4)Setup the robot to be driven by a ROS Twist message

Getting Started

Prerequisites
Have a rigged Turtlebot, or completed URDF Import: Turtlebot
ROS bridge enabled
roscore is running

Main Concepts

Driving the Robot
Preview
At the end of URDF Import:
Turtlebot(the robot)
Has drivable joints
When given a target position or velocity, can move the joints to match the targets
-Most cases want to be controlling the vehicle speed and not the individual wheel speed
First want to add the appropriate controllers
Ex. Turtlebot3, a wheeled-robot with two wheels
Nodes needed are Differential Controller and Articulation Controller
Differential Controller node: Convert vehicle speed to wheel speed
Artciulation Controller node: Send the commands to the joint drives
Detailed instructions on how to connect these nodes can be found in OmniGraph for a similar robot (NVIDIA Jetbot)
Connecting to ROS
As part of our ROS bridge, certain nodes are provided
Nodes that are subscribers and publisher of specific messages
Utility nodes such as keeping track of simulation time
Helper Nodes, which are gateways to more complex Omnigraphs that we abstract away from users
Process to establish a ROS bridge for a specific topic
(1)Open an action graph
(2)Add the OG nodes relevant to the desired ros topics
(3)Modify any properties as needed
(4)Connect the data pipeline
ROS publisher nodes:
Where Omniverse Isaac Sim data gets packaged into ROS message and sent out to the ROS network
ROS subscriber nodes:
Where ROS messages are received and allocated to the corresponding Omniverse Isaac Sim parameters
To use them, we simply have to pipe in and out the necessary data, as directed by the properties of each node
Custom Message, Omnigraph:
If needed to publish or subscribe to messages beyond the ones we provided
Custom Python Nodes, or Omnigraph: Custom C++ Nodes for ways to integrate custom messages

Putting it Together

Building the Graph
(1)Open Visual Scripting:
Window > Visual Scripting > Action Graph


Action Graph window will appear on the bottom (Can dock it wherever that’s convenient)
(2)Create action graph

Click on the New Action Graph Icon (In middle of the Action Graph Window)
(3)Check OmniGraph Nodes (or OG nodes)
Inside the Action Graph window, there is a panel on the left hand side with all the OmniGraph Nodes (or OG nodes)
ROS related OG nodes are listed under Isaac Ros (Can also search for nodes by name)
(4)Place nodes in the graph

Drag it from the node list into the graph window
(5)Practice building a graph
![Driving_TurtleBot_Via_Messages1](https://github.com/growingpenguin/growingpenguin.github.io/assets/110277903/eee3ed2f-b7c3-4323-b154-a7b5b5fa61d6)
Build a graph that matches the one above

-Note for the Make Array node, use the +/- buttons in the property tab to add additional inputs
### Graph Explained **On Playback Tick Node**:

Producing a tick when simulation is “Playing”.
Nodes that receives ticks from this node will execute their compute functions every simulation step.
**ROS Subscribe Twist Node**:

Subscribing to a Twist message
-Specify the Rostopic’s name /cmd_vel in the topicName field in its Property Tab
-Often have a Exec Out field
Act similar to a tick and will send a signal when a message is received by the subscriber
ex. In this case, we want to only calculate the differential commands when a new twist message arrives
=> Differential Node’s Exec In is ticked by the output of the subscriber node and not by On Playback Tick
**Scale To/From Stage Unit Node**:

Convert assets or inputs to stage unit
**Break 3-Vector Node**:

Output of the Twist subscriber node is linear and angular velocities, both 3-dimensional vectors
But the input of the differential controller node only takes a forward velocity and rotation velocity in z-axis
Therefore we need to decompose the array and extract the corresponding elements before feeding them into the differential controller node
**Differential Controller Node**:

Receives desired vehicle speed and calculates the wheel speed of the robot
Needs the wheel radius and distance between the wheels to make that calculation
-Can also receive optional speed limit parameters to cap off wheel speed
-Type in the property tab the wheel radius, the distance between the wheels, and the maximum linear speed for the vehicle as seen in table below to match the Turtlebot
![Driving_TurtleBot_Via_Messages2](https://github.com/growingpenguin/growingpenguin.github.io/assets/110277903/81b211ea-ebd8-4487-96f0-c5caa4c63328)
**Articulation Controller Node**:

Node is assigned to a target robot, then takes in the names or the indices of the joints that needs to be moved, and move them by the commands given in either Position Commands, Velocity Commands, or Effort Commands
Note the Articulation Controller node is ticked by On Playback Tick
So that if no new Twist message arrives, it will continue to execute whatever command it had received before
Process to assign the Articulation Controller node’s target to be the Turtlebot
-In the property tab, unselect Use Path, and click on Target for the Prim to find Turtlebot prim in the popup box

-Make sure the robot prim you select is also where the Articulation Root API is applied
Sometimes it is the robot’s parent prim. But often times for mobile robots, it is the chassis prim instead
-If you used the URDF importer following our previous tutorial, the Articulation Root API can be found on turtlebot3_burger/base_footprint.
More about Articulation API can be found in [Add Articulation](https://docs.omniverse.nvidia.com/isaacsim/latest/gui_tutorials/tutorial_gui_simple_robot.html#isaac-sim-app-tutorial-gui-simple-robot-articulation)
-To put the names of the wheel joints in an array format, type in the names of the wheel joints inside each of the Constant Token nodes, and feed the array of the names into the Make Array Node

The names of the joints for the Turtlebot are wheel_left_joint and wheel_right_joint
(Why not put the names in Constant String node, it’s because OmniGraph does not have string-array data type, therefore if strings needed to be put in an array format to be used by a node, it needs to be token type instead)
**Verifying ROS connections**
(1)Press Play to start ticking the graph and the physics simulation

(2)In a separate ROS-sourced terminal, check that the associated rostopics exist with rostopic list
rostopic list
/cmd_vel should be listed in addition to /rosout and /rosout_agg
(3)Now that a twist subscriber is setup, a twist message can be published to /cmd_vel topic to control the robot
rostopic pub /cmd_vel geometry_msgs/Twist '{linear: {x: 0.2, y: 0.0, z: 0.0}, angular: {x: 0.0,y: 0.0,z: 0.0}}'
In a separate ROS-sourced terminal, send drive forward command
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
Alternatively, you can also setup keyboard device interface inside OmniGraph. More of that can be found in OmniGraph: Input Devices

Reference:
https://docs.omniverse.nvidia.com/isaacsim/latest/ros_tutorials/tutorial_ros_drive_turtlebot.html
https://docs.omniverse.nvidia.com/isaacsim/latest/gui_tutorials/tutorial_gui_omnigraph.html#isaac-sim-app-tutorial-gui-omnigraph