This repo is a GDExtension meant to connect Robotic Operating System 2 (ROS 2) and the Godot Game Engine.
Uses cases for this extension could range from creating a control UI for a robot to creating a simulator to validate some algorithms.
This GDExtension's core concept is hooking into Godots existing MainLoop
concept and its default MainLoop implementation - the SceneTree.
Within the SceneTree::initialization() method we can call our typical ROS 2 rclcpp::init() and within the SceneTree::finalize() method we can call
rclcpp::shutdown(). With this approach, every Godot game or application
will be operating within a valid ROS 2 environment.
With the ROS 2 environment up and running, we now need ROS 2 nodes so that
we can create publishers and subscribers. Luckily, Godot also has a node
concept and we can hook directly into it by placing a rclcpp::Node shared
pointer as a member variable within a Godot::Node. This approach allows almost any Godot node (or any derivative) to also be a ROS 2 node.
The foundation described above lays the ground work - but to actually do something useful we need to implement conversion functions between Godot data types and ROS 2 data types.
-
Godot::String=>std_msgs::msg::String -
Godot::Image=>sensor_msgs::msg::Image -
Godot::Array=>sensor_msgs::msg::PointCloud
Additional types can be added.
Feel free to contribute additional type conversions or create an issue here in this repository with what you think is missing.
-
Godot::String=>std_msgs::msg::String -
Godot::Image=>sensor_msgs::msg::Image -
Godot::Array=>sensor_msgs::msg::PointCloud
Additional types can be added.
Feel free to contribute additional type conversions or create an issue here in this repository with what you think is missing.
These instructions are based on Ubuntu 24.04, Godot 4.6.3, ROS2 Lyrical.
First install dependencies:
sudo apt-get install -y unzip scons libpulse-dev git
Clone the godot-cpp library:
git clone https://github.com/godotengine/godot-cpp
You may need a specific version according to your Godot version, in that case (make sure <version> exists as a branch of godot-cpp).
git clone -b <version> https://github.com/godotengine/godot-cpp
Godot is self-contained, and its executable needs to be in the $PATH so execute:
ls -sf <path-to-godotfile> ~/.local/bin/godot
Now the extension API for Godot needs to be generated:
godot --headless --dump-extension-api
and the extension can be built (after sourcing):
source /opt/ros/$ROS_DISTRO/setup.bash
scons platform=linux custom_api_file=./extension_api.json
If this is successful, you can test loading the extension:
cd demo/
godot --headless --import
You can also refer to the CI script for the most up-to-date information on how to build this extension.
Refer to the demos for examples of GDScript using this extension. See demo/README.md for step-by-step instructions on building and running the demo on a plain Ubuntu terminal.
source /opt/ros/<distro>/setup.bash
godotSourcing of the ROS 2 underlay is extremely important, otherwise you will see an error something like:
Error: librcutils.so: cannot open shared object file: No such file or directory.If for whatever reason you want to fork and extend this package and additional
features are added - additional dependencies may be introduced to the extension
that will need to be declared in the demo/godot_ros.gdextension file.
To determine what dependencies are required:
readelf -d libgodot_ros.linux.template_debug.x86_64.so
Dynamic section at offset 0xced28 contains 31 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [librcutils.so]
0x0000000000000001 (NEEDED) Shared library: [librclcpp.so]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN]
...At the top of the list you'll see all the dependency shared libraries that are
needed to run the extension. Keep in mind you'll also need to run the same readelf
command on each dependency library in order to get a complete list of all
required dependencies.