Skip to content

Add optional motor telemetry to SO-follower recording#3456

Draft
Nick0-ai wants to merge 1 commit intohuggingface:mainfrom
Nick0-ai:feat/so-follower-motor-telemetry
Draft

Add optional motor telemetry to SO-follower recording#3456
Nick0-ai wants to merge 1 commit intohuggingface:mainfrom
Nick0-ai:feat/so-follower-motor-telemetry

Conversation

@Nick0-ai
Copy link
Copy Markdown

Summary / Motivation

SO-follower currently records joint positions only, even though the Feetech STS motors used by SO-100 and SO-101 expose velocity (reg 58), load (reg 60), and temperature (reg 63) for free. This PR adds a record_telemetry flag to SOFollowerConfig that, when enabled, includes these three signals per motor in the observation dict — enabling downstream policy debugging, teleop data quality analysis, and post-hoc mechanical diagnostics without changing any default behavior.

Gated behind an opt-in flag because the 3 extra sync_read calls cost ~15-30ms on a 6-motor bus at 1Mbaud, which matters at 60Hz. A follow-up PR could add a batched multi-register read API to motors_bus.py to reduce this to a single transaction (addresses 56-63 are contiguous on STS3215).

Opening as draft to gather feedback on the API surface (flag name, register selection, whether this should be generalized to koch_follower / other Dynamixel/Feetech followers in the same PR) before polishing.

Related issues

  • Related: none open — happy to link if maintainers are aware of prior discussion.

What changed

  • Added record_telemetry: bool = False field to SOFollowerConfig (keeps default behavior identical).
  • Extended SOFollower._motors_ft to emit {motor}.vel, {motor}.load, {motor}.temp keys per motor when telemetry is enabled.
  • Extended SOFollower.get_observation() to conditionally read Present_Velocity, Present_Load, Present_Temperature and populate the observation dict.
  • Not a breaking change: policies trained on position-only datasets are unaffected; new datasets recorded with the flag enabled simply contain additional observation columns.

How was this tested (or how to run locally)

  • Added tests/robots/test_so100_follower.py::test_observation_features_includes_telemetry — asserts .vel, .load, .temp features are declared when flag is set.
  • Added tests/robots/test_so100_follower.py::test_get_observation_with_telemetry — asserts get_observation() populates telemetry keys with values from their respective registers (via a mocked bus that returns distinct values per register).
  • Existing test_connect_disconnect, test_get_observation, test_send_action still pass unchanged — regression-proves backward compatibility.
  • Full test file:
    pytest -q tests/robots/test_so100_follower.py
    # 5 passed
    
  • Hardware validation (SO-101): not performed by the PR author; requesting a reviewer with hardware to verify real reads populate sensible values. Happy to iterate on perf if measurements differ from the ~15-30ms estimate.

Checklist (required before merge)

  • Linting/formatting run (ruff check and ruff format --check clean on modified files)
  • All tests pass locally (pytest tests/robots/test_so100_follower.py)
  • Documentation updated (docs/source/robots/so100.mdx — will add a short config note in a follow-up commit if the API is approved)
  • CI is green
  • Community Review: I have reviewed another contributor's open PR and linked it here — will address before marking ready for review

Reviewer notes

  • API naming: record_telemetry was chosen as a neutral, opt-in name. Open to alternatives (include_motor_state, extra_motor_features, …).
  • Register selection: opted for Velocity + Load + Temperature as the set most useful for post-hoc analysis. Present_Voltage (reg 62) and Present_Current (reg 69, STS only) are also available and could be added — wanted to ship a minimal set first.
  • Perf: three extra sync_read calls is the bottleneck. A batched read API on FeetechMotorsBus (registers 56-63 are contiguous → single transaction) would eliminate this; flagged as a natural follow-up. Keeping it out of this PR to minimize review surface.
  • Scope: intentionally limited to SO-follower. koch_follower and similar arms expose equivalent Dynamixel registers — happy to generalize in a follow-up once this API lands.

SO-follower currently records joint positions only, even though the
Feetech STS motors expose velocity (reg 58), load (reg 60), and
temperature (reg 63) for free. This PR adds a `record_telemetry` flag
to `SOFollowerConfig` that, when enabled, includes these three signals
per motor in the observation dict — enabling downstream policy
debugging and post-hoc mechanical diagnostics without changing any
default behavior.

Gated behind an opt-in flag because the 3 extra `sync_read` calls cost
~15-30ms on a 6-motor bus at 1Mbaud, which matters at 60Hz. A follow-up
PR could add a batched multi-register read API to `motors_bus.py` to
reduce this to a single transaction (addresses 56-63 are contiguous on
STS3215).

Changes:
- Add `record_telemetry: bool = False` to SOFollowerConfig
- Extend `_motors_ft` and `get_observation()` to conditionally emit
  `.vel`, `.load`, `.temp` keys per motor
- Add tests for both default (pos-only) and telemetry-enabled paths

Default `False` preserves backward compatibility — existing policies
trained on position-only datasets are unaffected.
@eliasab16
Copy link
Copy Markdown

Since you mentioend that including all 3 might add some latency, maybe consider allowing fine-grained optin selection. Instead of having just one flag for all three, allow users to enable just what they need, reducing the overall impact.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants