This package provides a generic integration between ROS 2 and TypeDB (TypeDB 3). The package is designed so users can extend query behavior while reusing the existing ROS lifecycle/query interfaces.
This package is tested on Ubuntu 22.04 with ROS 2 Humble and TypeDB 3.
Typedb 2: The TypeDB 2 version is on the typedb2 branch
To use this package, install ROS 2 Humble and TypeDB 3.
Follow the official instructions.
Install TypeDB following the official documentation: https://typedb.com/docs/home/
For development, this repository provides Dockerfile with TypeDB 3 server and Python driver support.
Before running build, tests, launch, or query commands, make sure the TypeDB server is running.
Create a ROS workspace and clone the repository:
mkdir -p ~/typedb_ws/src
cd ~/typedb_ws/src
git clone https://github.com/kas-lab/ros_typedb.gitInstall dependencies:
source /opt/ros/humble/setup.bash
cd ~/typedb_ws
rosdep install --from-paths src --ignore-src -r -yBuild:
cd ~/typedb_ws
colcon build --symlink-install
source install/setup.bashThis repository contains four packages:
typedb_utils: reusable, non-ROS TypeDB 3 Python interface and helper layerros_typedb_msgs: ROS messages/services used by the TypeDB noderos_typedb: ROS lifecycle/query integration for TypeDB 3ros_typedb_tools: CLI helpers for generating schema and TypeDB 3 function diagrams from.tqlfiles
Build the TypeDB 3 image:
docker build -t ros_typedb .If you want to use TypeDB Studio, allow X access:
xhost +Start dev container with display and repository mounted:
docker run -it --rm --name ros_typedb -e DISPLAY=$DISPLAY -e QT_X11_NO_MITSHM=1 -v /dev/dri:/dev/dri -v /tmp/.X11-unix:/tmp/.X11-unix -v /etc/localtime:/etc/localtime:ro -v $HOME/typedb_ws/src/ros_typedb:/home/ubuntu-user/typedb_ws/src/ros_typedb ros_typedbStart dev container without display:
docker run -it --rm --name ros_typedb -v /etc/localtime:/etc/localtime:ro -v $HOME/typedb_ws/src/ros_typedb:/home/ubuntu-user/typedb_ws/src/ros_typedb ros_typedbStart new terminal in container:
docker exec -it ros_typedb bashStart container in background with TypeDB server running:
docker run -d --rm --name ros_typedb -v /etc/localtime:/etc/localtime:ro -v $PWD:/home/ubuntu-user/typedb_ws/src/ros_typedb ros_typedb sudo typedb serverThe repository is centered around two layers:
TypeDBInterfaceintypedb_utils/typedb_utils/typedb_interface.pyROSTypeDBInterfaceinros_typedb/ros_typedb/ros_typedb_interface.py
ROSTypeDBInterface is a ROS 2 lifecycle node exposing:
~/queryservice (ros_typedb_msgs/srv/Query.srv) for insert/delete/fetch/get/update operations~/eventstopic (std_msgs/String) for insert/delete events
TypeDBInterface manages connection, schema/data loading, and query execution against TypeDB. ros_typedb depends on typedb_utils rather than embedding that generic layer directly.
Class diagram:
classDiagram
class LifecycleNode {
<<ROS 2>>
}
class TypeDBInterface {
+connect_driver()
+database_query()
+load_schema()
+load_data()
}
class ROSTypeDBInterface {
+typedb_interface_class
+typedb_interface
+init_typedb_interface()
+query_service_cb()
}
class MyTypeDBInterface
class MyROSTypeDBInterface
LifecycleNode <|-- ROSTypeDBInterface
TypeDBInterface <|-- MyTypeDBInterface
ROSTypeDBInterface <|-- MyROSTypeDBInterface
ROSTypeDBInterface *-- TypeDBInterface : composes (instance)
MyROSTypeDBInterface *-- MyTypeDBInterface : via typedb_interface_class
Overview:
Recommended: launch the lifecycle node through the provided launch file (it auto-configures/activates):
ros2 launch ros_typedb ros_typedb.launch.py schema_path:="['/absolute/path/schema.tql']" data_path:="['/absolute/path/data.tql']"Run node directly:
ros2 run ros_typedb ros_typedbIf running directly, manage lifecycle state transitions before sending queries.
Use composition for custom features:
- Keep query/domain logic in plain Python classes.
- Inject
TypeDBInterfaceinto those classes. - Optionally create a
ROSTypeDBInterfacesubclass only to wire ROS lifecycle/services.
Custom query class (no inheritance from TypeDBInterface):
from typedb_utils.typedb_interface import TypeDBInterface
class PeopleQueries:
def __init__(self, db: TypeDBInterface):
self.db = db
def fetch_people(self):
return self.db.fetch_database(
'match $p isa person; fetch { "email": $p.email };'
)
def add_person(self, email: str):
return self.db.insert_entity('person', [('email', email)])Custom ROS interface (wiring/composition only):
from ros_typedb.ros_typedb_interface import ROSTypeDBInterface
from my_queries import PeopleQueries
class MyROSTypeDBInterface(ROSTypeDBInterface):
def __init__(self, node_name='my_typedb_node', **kwargs):
super().__init__(node_name, **kwargs)
def on_configure(self, state):
result = super().on_configure(state)
self.people_queries = PeopleQueries(self.typedb_interface)
return resultSpin ROS node:
import rclpy
from rclpy.executors import MultiThreadedExecutor
def main():
rclpy.init()
node = MyROSTypeDBInterface()
executor = MultiThreadedExecutor()
executor.add_node(node)
try:
executor.spin()
finally:
node.destroy_node()
rclpy.shutdown()Feature/integration tests in Docker:
scripts/run-tests-docker.shMandatory style/docstring checks:
scripts/run-mandatory-checks-docker.shManually:
colcon test --event-handlers console_cohesion+ --packages-select typedb_utils ros_typedb ros_typedb_toolsThe ros_typedb_tools package provides:
typedb_schema_diagramtypedb_rule_diagram
Examples:
ros2 run ros_typedb_tools typedb_schema_diagram \
--input /absolute/path/schema.tql \
--format dot \
--output /tmp/schema.dot
ros2 run ros_typedb_tools typedb_rule_diagram \
--input /absolute/path/functions.tql \
--output /tmp/functions.svgtypedb_rule_diagram now renders TypeDB 3 fun dependency/read graphs rather than TypeDB 2 rule graphs.
See ros_typedb_tools/README.md for the full CLI reference.
This work is part of the Reliable AI for Marine Robotics (REMARO) Project. For more info, please visit: https://remaro.eu/
This project has received funding from the European Union's Horizon 2020 research and innovation programme under the Marie Skłodowska-Curie grant agreement No. 956200.
