Skip to content

ROS → RDF conversion

ROS 2 defines its own message types for data like timestamps, points, integers, and polygons. To store these in the knowledge base, they need to be converted to typed RDF literals.

The conversion module (triplestar_core.conversions) handles this automatically — both forward (ROS → RDF) and reverse (RDF → Python / Shapely).

Conversion table

ROS message type Python / Shapely type RDF literal type
geometry_msgs/Point, Point32, PointStamped shapely.geometry.Point geo:wktLiteral
geometry_msgs/Pose shapely.geometry.Point geo:wktLiteral
geometry_msgs/Vector3, Vector3Stamped shapely.geometry.Point geo:wktLiteral
geometry_msgs/Polygon, PolygonStamped, PolygonInstance, PolygonInstanceStamped shapely.geometry.Polygon geo:wktLiteral
builtin_interfaces/Time datetime.datetime xsd:dateTime
std_msgs/Float32, Float64 float xsd:double
std_msgs/Int8, Int16, Int32, Int64 int xsd:integer
std_msgs/UInt8, UInt16, UInt32, UInt64 int xsd:integer
std_msgs/Char, Byte int / str xsd:integer / xsd:string
std_msgs/Bool bool xsd:boolean
std_msgs/String str xsd:string

How it works

Forward: to_rdf_literal(msg)

from triplestar_core.conversions import to_rdf_literal

literal = to_rdf_literal(Point32(x=1.0, y=2.0, z=0.0))
# → ox.Literal("POINT (1 2)", datatype=geo:wktLiteral)

literal = to_rdf_literal(Float32(data=3.14))
# → ox.Literal("3.14", datatype=xsd:double)

For ROS messages, the function unwraps the .data field (for std_msgs) or converts geometry messages to Shapely objects, then serializes them using rdflib's literal lexicalizers.

Reverse: rdf_literal_to_python(literal)

from triplestar_core.conversions import rdf_literal_to_python

point = rdf_literal_to_python(
    ox.Literal("POINT (1 2)", datatype=ox.NamedNode(GEO.wktLiteral))
)
# → shapely.geometry.Point(1, 2)

value = rdf_literal_to_python(
    ox.Literal("42", datatype=ox.NamedNode(XSD.integer))
)
# → 42

Usage in Jinja2 templates

Insertion subscribers make the rdf filter available for converting ROS message fields inside templates:

{% raw %}
PREFIX ex: <http://example.org/>

INSERT DATA {
  ex:robot ex:position {{ msg.pose | rdf }} .
  ex:robot ex:battery {{ msg.battery | rdf }} .
}
{% endraw %}

Usage in query-time subscribers

When a query-time subscriber returns a ROS message (or a field of it), the value is automatically converted via to_rdf_literal() before being returned from the SPARQL function.

Usage in custom SPARQL functions

When you write a custom SPARQL function, arguments are automatically converted from RDF literals to Python types, and return values are converted back:

@kb_function("distance")
def distance(a: ShapelyPoint, b: ShapelyPoint) -> float:
    return a.distance(b)

Shapely bindings

The module registers geo:wktLiteral ↔ shapely.geometry.base.BaseGeometry bindings with rdflib, so Shapely geometries are automatically serialized to/from WKT strings.