feat(parser_ros): object producers for FrameTransforms, OccupancyGrid, TransformStamped, RobotDescription#100
Closed
facontidavide wants to merge 5 commits into
Closed
feat(parser_ros): object producers for FrameTransforms, OccupancyGrid, TransformStamped, RobotDescription#100facontidavide wants to merge 5 commits into
facontidavide wants to merge 5 commits into
Conversation
tf2_msgs/TFMessage now produces BOTH a canonical sdk::FrameTransforms object (objectstore — for the 3D scene's per-dataset TF buffer) AND its existing flattened scalar fields (datastore — for plotting transforms as time series). This is dual registration in the schema catalog: object_type + parse_object added alongside the existing parse_scalars, the same pattern Image/PointCloud2 already use. parseFrameTransforms decodes the CDR TFMessage into one FrameTransform per TransformStamped, each carrying its OWN Header.stamp — the per-sample time the TF buffer needs for zero-order-hold scrub lookups — independent of the message receive time. Test: TFMessageProducesFrameTransformsObject verifies classifySchema reports kFrameTransforms and that parseObject decodes a 2-transform message with the correct per-transform timestamps, parent/child frames, translation, and rotation. 29/29 parser_ros tests pass against plotjuggler_core 0.3.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…on producers Extends the dual datastore+objectstore producer set with three more unambiguous, self-contained canonical types (all present in core 0.3.1): - nav_msgs/OccupancyGrid -> kOccupancyGrid: byte-backed, cells zero-copied as a Span over the payload; dual-registered with discard-large-array scalars. - geometry_msgs/TransformStamped -> kFrameTransforms: single-element, sharing the new readStampedTransform helper with the TFMessage producer. - std_msgs/String on a robot_description topic -> kRobotDescription, with a best-effort urdf/sdf/mjcf format hint sniffed from the root element. Topic-gated in bindSchema (a generic String stays a scalar), resolving the dispatch ambiguity by topic name. Deferred (ambiguous / stateful, or not in 0.3.1): Markers (type switch + action/lifetime/identity), DepthImage (encoding dispatch + CameraInfo), CameraInfo / OccupancyGridUpdate. Tests: object-route decode for each, plus a negative test that a String on a non-robot_description topic is NOT classified as RobotDescription. 33/33 parser_ros tests pass against plotjuggler_core 0.3.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…atch namespaced robot_description
Routing per design: only TFMessage and TransformStamped are dual
datastore+objectstore (their transforms are useful plotted as time series).
OccupancyGrid and RobotDescription are object-store only — a map/costmap and a
URDF/SDF/MJCF document aren't useful as scalar columns — so their parse_scalars
is dropped (SchemaHandler permits a null scalar route).
robot_description topic-gating already matched namespace-prefixed topics via
ends_with("/robot_description"); make that explicit in the comment and cover it
with a test for "/my_robot/robot_description" (which also exercises the SDF
format sniff).
34/34 parser_ros tests pass against plotjuggler_core 0.3.1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per-message, stateless conversion of Marker / MarkerArray into the canonical sdk::SceneEntities object (one SceneEntity per ADD/MODIFY marker, one SceneEntityDeletion per DELETE/DELETEALL). Decoders in a new ros_marker_handlers.cpp; catalog + bindSchema wiring; tests; MARKER_NOTES.md captures the design. - Type map: CUBE/SPHERE/CYLINDER/LINE_*/TRIANGLE_LIST/TEXT_VIEW_FACING -> matching primitives; MESH_RESOURCE -> ModelPrimitive; CUBE_LIST/SPHERE_LIST expand to N primitives; POINTS/ARROW_STRIP skipped (no canonical mapping). - (ns,id) -> length-prefixed entity id; lifetime/frame_locked carried through; ColorRGBA float->uint8; per-vertex colors only when sized to the points. - Positional CDR decode with a bindSchema sniff (uv_coordinates / mesh_file) so the humble+ texture/mesh_file tail is consumed correctly on every distro, keeping MarkerArray elements aligned. Statefulness (accumulation, lifetime expiry) is intentionally left to a future 3D scene consumer, not the parser; see MARKER_NOTES.md. Requires the SceneEntities ModelPrimitive + deletions[] additions in plotjuggler_core. Parser-side groundwork: no kSceneEntities renderer exists yet, so this is exercised by unit tests only (not yet built in this environment due to an unrelated plugin-dependency build issue). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4c1188e to
45a298b
Compare
Contributor
Author
|
Superseded by #122 — that branch is the rebased continuation of this work. #122's producer commits ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds canonical-object production to parser_ros for the ROS message types that map unambiguously and self-containedly to a builtin object available in core 0.3.1. Previously parser_ros produced only
kImageandkPointCloud; these were the remaining clean cases, and they unblock the PJ4 3D scene (TF buffer, gridmaps, robot model).tf2_msgs/TFMessagekFrameTransformsFrameTransformperTransformStamped, each with its ownHeader.stampgeometry_msgs/TransformStampedkFrameTransformsnav_msgs/OccupancyGridkOccupancyGridstd_msgs/Stringon arobot_descriptiontopickRobotDescription<ns>/robot_description)Store routing: only the TF producers are dual-stored — TF transforms are commonly plotted as time series and needed as objects for the 3D buffer. The map and the robot model are object-only (
SchemaHandlerpermits a null scalar route).Design notes
Header.stamp(the per-sample time the TF buffer needs for zero-order-hold scrub lookups), independent of message receive time.int8[]cells as aSpanover the payload (pinned by the anchor), likePointCloud2.std_msgs/Stringstays a scalar; onlyrobot_descriptionor any namespaced<ns>/robot_descriptionproduces aRobotDescription. Resolves the dispatch ambiguity by topic name (the catalog keys on type name, which can't distinguish it). Tests cover the plain topic, a namespaced topic, and a negative (non-robot String → no object).readStampedTransform()helper between the TFMessage and TransformStamped producers.Deferred (intentionally)
Ambiguous / stateful, or type not in 0.3.1: Markers (
typeswitch +action/lifetime/(ns,id)identity — a stateful accumulation stream, like OccupancyGridUpdate), DepthImage (encoding-dispatch + needs CameraInfo), CameraInfo / OccupancyGridUpdate (land in core via plotjuggler_core#98, not yet released).Verification
Clean build against
plotjuggler_core0.3.1; 34/34 parser_ros tests pass (object-route decode for each new type, namespaced robot_description, + a negative RobotDescription test).🤖 Generated with Claude Code