Skip to content

Scene: add a lightweight profile and make TF authoritative for camera extrinsics #156

Description

@enkerewpo

Problem

Scene currently assumes a perception-capable target even when a deployment only needs manually annotated rooms and robot pose. This blocks low-memory Jetson devices such as Orin Nano from using the deterministic parts of Scene.

Scene's camera transform path also has unclear precedence. The authoritative body geometry already comes from the robot URDF: Soma stores the complete URDF, and the robot-description primitive publishes /robot_description, /tf, and /tf_static. Scene should read TF first. The explicit robonix/primitive/camera/extrinsics capability should only be a compatibility fallback when the required TF is unavailable.

The old system/soma/sensor_extrinsics schema is not an intended future API and should be removed rather than implemented.

Current behavior

1. No genuinely lightweight Scene target

  • Providing explicit observations without RGB/depth prevents detector construction at runtime.
  • However, Jetson build/start still downloads or checks Torch, YOLO-World, MobileSAM, OpenCLIP, ConceptGraphs, Open3D/faiss, and related heavy dependencies.
  • Core features do not require these models: robot pose, room/annotation CRUD, map binding, room lookup, annotation-only scene graph output, and occupancy-backed goal_room are deterministic paths.
  • Object memory and LLM scene-graph enrichment are also enabled by default, so omitting camera observations alone is not a complete low-memory mode.

Relevant code at dev-next 8c2551ce:

  • system/scene/scripts/build.sh
  • system/scene/scripts/start_native.sh
  • system/scene/scene_service/service.py
  • system/scene/scene_service/ingest/__init__.py
  • system/scene/scene_service/state/__init__.py

2. Scene does not consistently use TF as the authoritative camera transform

The current explicit fallback contract is:

  • robonix/primitive/camera/extrinsics
  • mode: topic_out
  • payload: geometry_msgs/TransformStamped
  • transform: T(parent <- child), normally T(base <- camera_optical)

Scene's RGB-D path can consume this contract and compose T(world <- base) @ T(base <- camera). It can also query tf2, but the precedence and validation are not strict enough.

Problems:

  • Scene does not consistently make tf2 the first source for the selected camera frame.
  • Scene does not validate the explicit transform parent/child frames against the selected RGB/depth frames.
  • Extrinsics readiness is not included in the metric-grounding status.
  • The Tiago camera fallback publishes once although the contract mentions recalibration updates.
  • Without camera_provider_id, RGB, depth, intrinsics, and extrinsics may be selected independently from different providers.
  • A flattened base-to-camera transform is not sufficient for articulated or arm-mounted cameras; current joint state plus the URDF/TF tree is required.
  • A hard-coded camera-height/axis fallback can silently produce incorrect object coordinates.
  • system/soma/sensor_extrinsics exists as unused schema only and duplicates the URDF/TF ownership model.

Relevant code:

  • capabilities/primitive/camera/extrinsics.v1.toml
  • system/scene/scene_service/ingest/ros_subscribers.py
  • system/scene/scene_service/ingest/perception_concept_graphs.py
  • system/scene/scene_service/ingest/capabilities.py
  • capabilities/system/soma/sensor_extrinsics.v1.toml
  • capabilities/lib/soma/msg/SensorExtrinsic.msg
  • capabilities/lib/soma/srv/GetSensorExtrinsics.srv

Proposed design

A. Add an explicit lightweight Scene profile

Provide a named static or core target/profile that:

  • installs only base ROS, web, Atlas/MCP, map, pose, and annotation dependencies;
  • does not import or install Torch, Ultralytics, OpenCLIP, Open3D, faiss, ConceptGraphs, or PyMilvus;
  • does not download model weights or create a CUDA context;
  • uses explicit pose and optional occupancy-grid observations;
  • disables perception wait, detector construction, graph enrichment, and object memory;
  • keeps the Scene web UI, manual room/object annotations, persistence, get_robot_context, room lookup, and occupancy-backed goal_room;
  • forwards annotation/restore configuration consistently in native and Docker targets.

Keep the current full perception target as the default for compatibility unless a separate migration decision is made.

B. Use a single transform ownership and fallback order

  1. Soma stores the complete robot URDF and component model.
  2. The robot-description primitive reads that model and publishes /robot_description, /tf, and /tf_static.
  3. Scene resolves the selected camera's current transform from TF first.
  4. If and only if that TF lookup is unavailable, Scene may use robonix/primitive/camera/extrinsics as an explicit compatibility fallback.
  5. Remove the unused system/soma/sensor_extrinsics contract and IDL instead of implementing a duplicate extrinsics service.
  6. Do not use the hard-coded camera-height/axis transform unless a deployment explicitly opts into a clearly marked degraded mode.

For the explicit camera fallback:

  • require camera_provider_id when multiple camera providers match;
  • validate RGB/depth/CameraInfo frame IDs, transform parent/child frames, timestamp/freshness, and transform direction;
  • include transform source and readiness in Scene status;
  • support republishing after recalibration when the provider claims that behavior.

Acceptance criteria

Lightweight profile

  • A clean low-memory Jetson build performs no perception-model download or heavy ML installation.
  • Scene boots without Torch, CUDA, Ultralytics, OpenCLIP, Open3D, faiss, ConceptGraphs, and PyMilvus.
  • Pose-to-room context, room listing, annotation CRUD, save/restart/restore, and annotation-only scene graph work.
  • goal_room works when an occupancy grid is present and reports a clear unavailable/deferred state when it is not.
  • No outbound VLM/LLM request occurs in this profile.
  • Five-minute idle operation creates no CUDA context and remains below an agreed RSS limit (initial target: 512 MiB excluding shared ROS middleware).

Camera transform

  • Tests prove the source order: TF first, explicit camera extrinsics only on TF lookup failure.
  • Fixed and articulated camera chains use the current URDF/TF tree correctly.
  • Parent/child mismatch, stale fallback transform, and ambiguous camera provider selection produce explicit errors.
  • Late-subscriber delivery and recalibration updates are tested for the explicit fallback.
  • Scene reports whether a camera pose came from TF, the explicit fallback, or degraded mode.
  • The unused Soma extrinsics schema is removed without affecting Soma's URDF/body-state responsibilities.
  • Existing v1 camera-extrinsics providers remain compatible as fallback providers.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions