ROS 2 Custom C++ OmniGraph Node#
Learning Objectives#
In this example we will learn how to
Write our custom C++ OmniGraph node to use with Isaac Sim
Note
This tutorial is currently supported only on Linux with ROS 2 Humble
Getting Started#
Prerequisite
Basic understanding of building ROS 2 packages
Building a Custom Message Package#
To use our custom message with Isaac Sim we fist need to build our custom message package with ROS 2. We will follow the custom message sample in the official ROS 2 documentation. The definition of the message is:
geometry_msgs/Point center
float64 radius
Follow the instructions on the ROS 2 Humble Documentation for building the custom humble message package.
You only need to complete the steps up to confirming humble message creation (step 6)
Important
Please make sure you follow the package and message naming terminologies provided in the official tutorials, they are important when we will build our own C++ OmniGraph nodes.
Setting up Kit Extension C++ Template#
In order to use our custom ROS 2 OmniGraph nodes, we will need to build our own extension which contains the necessary C++ code. We strongly recommend spending some time understanding how Omniverse Kit Extension Template C++ works, the ReadMe provided with the repository is a good starting point for this.
Run
./build.sh
inside the directory to build the sample extensionsEnsure that
./_build/linux-x86_64/release/omni.app.kit.dev.sh
works as expectedNext, download a sample custom extension which will be used for this tutorial:
Extract the
omni.example.cpp.omnigraph_node_ros
folder intosource/extensions
under theKit Extension C++ template folder
which you cloned in the previous steps.Add the following lines at the end of the
deps/kit-sdk-deps.packman.xml
file, before the</project>
closing tag<dependency name="system_ros" linkPath="../_build/target-deps/system_ros" tags="${config}"> <source path="<path_to_your_system_ros_install>" /> </dependency> <dependency name="additional_ros_workspace" linkPath="../_build/target-deps/additional_ros" tags="${config}"> <source path="<path_to_custom_message_ws_created_in_step1>/install/tutorial_interfaces" /> </dependency>
Adding this ensures that the
premake5.lua
file can find the relevant ROS 2 headers and libraries on your system. These are needed for building our custom nodes.Run
./build.sh
to build our new extension with ROS 2 OmniGraph nodesImportant
Provide the complete paths for the
source_path
under both the dependencies. This is needed to ensure the extension is built against your local ROS workspace and installation.
Adding the Extension to Isaac Sim#
For adding the extension and corresponding nodes into Isaac Sim, we need to:
Source your ROS 2 installation.
Source your workspace containing the
tutorial_interfaces
package which you created in the previous section.Run Isaac Sim from this terminal.
Go to
Window->Extensions
, look for thehamburger
symbol (1) to the right side of the search bar (just aboveThird Party
tab). ClickSettings
(2).Click the
+
icon underExtension Search Paths
and add the path to your built extension in the previous section (your built extensions are underkit-extension-template-cpp/_build/linux-x86_64/release/exts
).Your new extensions will now show up under the
Third Party
tab (3).Enable the
Custom ROS2 OGN Example Extension
.Note
If you see an error such as below it is likely because your custom
tutorial_interfaces
package is not sourced correctly:Error: libtutorial_interfaces__rosidl_typesupport_c.so: cannot open shared object file: No such file or directory (Additional information may be available by running the process with the LD_DEBUG environment variable set)
Building the Action Graph and Running the nodes#
Ensure you have followed all the steps in the previous sections.
With the Custom ROS2 OGN Example Extension
enabled, we will create an ActionGraph with the new ROS 2 nodes.
Go to
Window > Graph Editors > Action Graph
:Search for
ROS 2
in the Action Graph tab, drag both the nodes:ROS 2 Publish Custom Message Node
andROS 2 Publish String
in the graph.Search for
Playback Tick
and drag the node into the graph.Connect
Tick
from theOn Playback Tick
node toExec In
for both the ROS 2 nodes.
Hit
Play
on the scene and the nodes should start publishing to ROS 2.You can verify by opening a new terminal and sourcing your ROS 2 workspace in it. Then, running
ros2 topic list
should show the 2 available topics:/custom_node/my_string # This topic has a string being published /custom_node/sphere_msg # This topic has the custom "SphereMsg" created in step 1 being published
Deeper Dive into Nodes and Extension#
The
premake5.lua
handles building of the extension, lets look at the section which handles the compiling and linking against our specified ROS install paths:
-- Build the C++ plugin that will be loaded by the extension.
project_ext_plugin(ext, ogn.plugin_project)
-- It is important that you add all subdirectories containing C++ code to this project
add_files("source", "plugins/"..ogn.module)
add_files("nodes", "plugins/nodes")
-- Add the standard dependencies all OGN projects have; includes, libraries to link, and required compiler flags
add_ogn_dependencies(ogn)
includedirs {
-- System level ROS includes
"%{target_deps}/system_ros/include/std_msgs",
"%{target_deps}/system_ros/include/geometry_msgs",
"%{target_deps}/system_ros/include/rosidl_runtime_c",
"%{target_deps}/system_ros/include/rosidl_typesupport_interface",
"%{target_deps}/system_ros/include/rcl",
"%{target_deps}/system_ros/include/rcutils",
"%{target_deps}/system_ros/include/rmw",
"%{target_deps}/system_ros/include/rcl_yaml_param_parser",
-- Additional sourced ROS workspace includes
"%{target_deps}/additional_ros/include/tutorial_interfaces",
}
libdirs {
-- System level ROS libraries
"%{target_deps}/system_ros/lib",
-- Additional sourced ROS workspace libraries
"%{target_deps}/additional_ros/lib",
}
links{
-- Minimal ROS 2 C API libs needed for your nodes to work
"rosidl_runtime_c", "rcutils", "rcl", "rmw",
-- For the simple string message, add the deps
"std_msgs__rosidl_typesupport_c", "std_msgs__rosidl_generator_c",
-- Add dependencies of the custom message with its libs
"geometry_msgs__rosidl_typesupport_c", "geometry_msgs__rosidl_typesupport_c",
"tutorial_interfaces__rosidl_typesupport_c", "tutorial_interfaces__rosidl_generator_c",
}
filter { "system:linux" }
linkoptions { "-Wl,--export-dynamic" }
cppdialect "C++17"
- The OmniGraph nodes are present under
plugins/nodes
. We use thercl
ROS 2 API for creating and working with the ROS 2 components in our OmniGraph node: In the C++ Node,
compute()
is called when theExec In
condition is true, this is where the node and publisher is initially created. The message is also published from this function.
- The OmniGraph nodes are present under
Summary#
This tutorial covered the following topics:
Building our own extension which contains ROS 2 C++ OmniGraph nodes
Using these nodes with Isaac Sim
Next Steps#
Continue on to the next tutorial in our ROS2 Tutorials series, ROS 2 Launch to learn how to deploy Isaac Sim via ROS 2 Launch.