Skip to content

feat(evals): ground-truth store, predicate library, xarm7 tabletop suite - #4040

Open
Jerrybery wants to merge 3 commits into
dimensionalOS:mainfrom
Jerrybery:feat/evals-gt-store
Open

feat(evals): ground-truth store, predicate library, xarm7 tabletop suite#4040
Jerrybery wants to merge 3 commits into
dimensionalOS:mainfrom
Jerrybery:feat/evals-gt-store

Conversation

@Jerrybery

Copy link
Copy Markdown

Summary

Part 2 of 2 for #3594 (privileged ground-truth channel for interactive eval scoring), stacked on #3960 (the MujocoSimModule opt-in GT pose stream). The diff will shrink to just the eval-side commit once #3960 lands.

This PR adds the eval-side consumption of the GT stream introduced in #3960:

  • GTRecorder (dimos/evals/gt_recorder.py): Recorder subclass subscribing /gt_object_poses over LCM into its own per-case db — ground truth stays out of the agent-visible recording. Uses direct subscribe() rather than handle_<stream> auto-subscription, per the single-slot LATEST mailbox caveat noted in feat(simulation): opt-in ground-truth object pose stream for eval scoring #3960.
  • EvalRunner.gt_store() + two-arg GTScore scorers (dimos/evals/runner.py): score(store, gt) alongside the existing score(store); sample() wires the GT store in when the scorer asks for it. The runner deploys GTRecorder in-process for cases declaring ground_truth=True and passes --mujoco-publish-ground-truth (new GlobalConfig flag) so any mujoco blueprint emits GT during eval runs.
  • dimos/evals/predicates.py: spatial predicates over the GT store (inside_region, lifted, ...). grasped() is kept as a placeholder until the GT stream carries contact data.
  • suites/xarm7_tabletop.py: regression suite scoring pick/place against GT object poses.

Ground truth is privileged scoring data — never consumed by the agent.

Test plan

  • New tests: dimos/evals/test_predicates.py (predicates against a synthetic GT store), dimos/evals/test_mem2_wiring.py (GTRecorder wiring), extended dimos/evals/test_evals.py (two-arg scorer dispatch, gt_store lifecycle)
  • pytest dimos/evals/ — 125 passed locally (Linux, lockfile-pinned MuJoCo 3.10.0)

Stacked on #3960.

…ring

MujocoSimModule gains publish_ground_truth (default off) and
ground_truth_hz (20 Hz). When enabled, world poses of every free-joint
scene body (robot root excluded — odom already covers it) publish on a
new gt_object_poses Out[PoseStamped] stream, frame_id = body name.

Ground truth is privileged scoring data for the evals framework
(issue dimensionalOS#3594): never consumed by the agent. Part 1 of 2; part 2 adds
the eval-side gt_store() and predicate library.
Part 2 of 2 for issue dimensionalOS#3594, stacked on the MujocoSimModule GT stream.

- GTRecorder: Recorder subclass subscribing /gt_object_poses over LCM
  into its own per-case db — ground truth stays out of the agent's
  recording. The eval runner deploys it in-process for cases declaring
  ground_truth=True and passes --mujoco-publish-ground-truth (new
  GlobalConfig flag) so any mujoco blueprint emits GT.
- EvalRunner.gt_store() + two-arg GTScore scorers: score(store, gt)
  alongside the existing score(store); sample() wires the GT store in
  when the scorer asks for it.
- dimos/evals/predicates.py: spatial predicates over the GT store
  (inside_region, lifted, ...); grasped() is a placeholder until the
  GT stream carries contact data.
- suites/xarm7_tabletop.py: regression suite scoring pick/place
  against GT object poses.
@github-actions github-actions Bot added the first-time-contributor PR opened by an author who had not previously committed to this repository label Sep 10, 2026
@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 3/5

Not safe to merge until ground-truth pose delivery is made lossless and invalid publication rates are rejected.

Findings

  1. P1 Preserve Every GT Pose
  2. P1 Validate Ground Truth Rate

Summary

  • This change adds an opt-in MuJoCo ground-truth object-pose stream, records it in an evaluation-only SQLite store, supports two-store interactive scoring, introduces pose predicates, and adds xArm7 tabletop regression coverage.
  • Two issues need resolution before merging: the ground-truth recorder can discard individual object updates from its multiplexed input, and invalid publication-rate values can crash or silently disable the ground-truth stream.

Reviews (1) · Last reviewed commit: "feat(evals): ground-truth store, predica..."

names topics after it.
"""

gt_object_poses: In[PoseStamped]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Preserve Every GT Pose

This multiplexed input is recorded through the inherited recorder callback, which retains only the latest unprocessed message. MuJoCo sends one pose message per object in succession, so a later object's update can replace an earlier update when SQLite recording falls behind. The tabletop scorer can then receive no history for the cup or a bystander and fail an otherwise valid evaluation. Record this stream through a lossless serialized queue, or publish each tick's object poses as one atomic message.

Knowledge Base Used: Robot memory services

T-Rex Ran code and verified through T-Rex

# consumed by the agent. Off = zero overhead, zero behavior change.
# The global --mujoco-publish-ground-truth flag enables this too.
publish_ground_truth: bool = False
ground_truth_hz: float = 20.0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Validate Ground Truth Rate

ground_truth_hz accepts arbitrary floats, but the enabled post-step publishing path divides by it. A value of 0.0 raises ZeroDivisionError and stops the simulation loop; negative and infinite values publish every step, while NaN prevents publication. Require this value to be finite and greater than zero before starting ground-truth publication.

Knowledge Base Used: Simulation and digital twins

Artifacts

Ground-truth rate check script

  • The script executes the checked-in publication branch with valid and invalid rate values.

Executed script source

  • This capture contains the complete source used to exercise the publication-rate behavior.

Ground-truth rate results

  • The output shows a divide-by-zero error for zero and incorrect publication behavior for negative, infinite, and NaN rates.

Ground-truth rate code location

  • This capture identifies the changed declaration and the enabled publication branch that divides by the configured rate.

View artifacts

T-Rex Ran code and verified through T-Rex

@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.85269% with 57 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
dimos/evals/runner.py 53.65% 13 Missing and 6 partials ⚠️
dimos/simulation/engines/test_mujoco_sim_module.py 76.19% 15 Missing ⚠️
dimos/simulation/engines/mujoco_sim_module.py 53.33% 14 Missing ⚠️
dimos/evals/suites/xarm7_tabletop.py 78.57% 3 Missing ⚠️
dimos/evals/test_evals.py 92.85% 2 Missing ⚠️
dimos/evals/test_mem2_wiring.py 95.00% 0 Missing and 2 partials ⚠️
dimos/evals/types.py 88.23% 2 Missing ⚠️
@@            Coverage Diff             @@
##             main    #4040      +/-   ##
==========================================
- Coverage   77.86%   76.43%   -1.43%     
==========================================
  Files        1394     1433      +39     
  Lines      131706   140140    +8434     
  Branches    11430    12738    +1308     
==========================================
+ Hits       102548   107115    +4567     
- Misses      25900    29702    +3802     
- Partials     3258     3323      +65     
Components Coverage Δ
Tests 91.32% <90.77%> (-3.44%) ⬇️
Flag Coverage Δ
OS-ubuntu-24.04-arm 74.48% <83.85%> (+0.30%) ⬆️
OS-ubuntu-latest 75.05% <83.85%> (+0.36%) ⬆️
Py-3.10 75.04% <83.85%> (+0.35%) ⬆️
Py-3.11 75.04% <83.85%> (+0.36%) ⬆️
Py-3.12 75.05% <83.85%> (+0.36%) ⬆️
Py-3.13 75.04% <83.85%> (+0.36%) ⬆️
Py-3.14 75.05% <83.85%> (+0.36%) ⬆️
Py-3.14t 75.05% <83.85%> (+0.36%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
dimos/core/global_config.py 92.62% <100.00%> (+4.19%) ⬆️
dimos/evals/gt_recorder.py 100.00% <100.00%> (ø)
dimos/evals/predicates.py 100.00% <100.00%> (ø)
dimos/evals/test_predicates.py 100.00% <100.00%> (ø)
dimos/robot/all_blueprints.py 100.00% <ø> (ø)
dimos/evals/test_evals.py 97.51% <92.85%> (-0.17%) ⬇️
dimos/evals/test_mem2_wiring.py 96.59% <95.00%> (-0.60%) ⬇️
dimos/evals/types.py 93.20% <88.23%> (+1.24%) ⬆️
dimos/evals/suites/xarm7_tabletop.py 78.57% <78.57%> (ø)
dimos/simulation/engines/mujoco_sim_module.py 60.13% <53.33%> (+13.22%) ⬆️
... and 2 more

... and 119 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

first-time-contributor PR opened by an author who had not previously committed to this repository

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant