Skip to content

feat(joint-follow): host-side entry for CMD_JOINT_FOLLOW (0x08) - #14

Merged
luomaofu merged 2 commits into
mainfrom
feat/joint-follow
Sep 29, 2026
Merged

luomaofu merged 2 commits into
mainfrom
feat/joint-follow

Conversation

@luomaofu

Copy link
Copy Markdown
Contributor

Summary

Adds the host-side entry point for CMD_JOINT_FOLLOW (0x08) and pins its payload
layout against the firmware, so a caller can drive the slave arm's follow loop
without the SDK re-deriving the frame by hand.

The command is the one the isomorphic teleop stack uses on the slave. Its payload
carries four groups — target position, target velocity, kp, kd — and no tau;
the firmware computes the gravity feedforward and the limit wall itself, which is
what makes the frame round-trip cheaper than the older send_mit_all path. Nothing
in the payload is self-describing, so a drifted layout is silent until the arm
misbehaves on hardware. The new test closes that gap.

No consumer breaks. The command is additive: an arm without it answers ERR with
cmd = 0x08, which the existing capability check already treats as "not supported".

Changes

  • src/litearm/_protocol.py — register CMD_JOINT_FOLLOW = 0x08 alongside the
    other command codes.
  • src/litearm/arm.py — Arm.joint_follow(q, dq, kp, kd) sends the frame. The
    four groups are packed in firmware order and the call is a single round trip.
  • src/litearm/errors.py — map the command's error code so a rejected frame
    reports which command was refused rather than an anonymous failure.
  • tests/test_protocol_sync.py — extract the field order from the firmware header
    usb_cmd.h with a regex, then send a real frame with a distinct sentinel in every
    slot and read the bytes back segment by segment. A reordering or a dropped field
    fails the test rather than shipping.
  • tests/test_error_codes.py, tests/test_full_coverage.py — extend the existing
    tables to cover the new command code.

Testing

$ python -m pytest tests -q
.....ss................................................................. [ 76%]
........................................................................ [ 87%]
........................................................................ [ 98%]
........                                                                 [100%]
654 passed, 2 skipped in 60.92s (0:01:00)

The two skips are the live-hardware cases in tests/test_live.py, gated on
LITEARM_LIVE=1; they are skipped by design on a machine without an arm attached,
not a pre-existing failure.

The payload-layout test was mutation-checked both ways: reordering two segments in
the expected order, and dropping one, each turn it red.

Issues

None. No issue was opened for this work, so there is nothing to close.

Arm.joint_follow(q, dq, kp, kd) sends 16N bytes with no tau; the firmware computes
the feedforward itself.  Registered in COMMAND_COVERAGE so the cross-repo contract
test keeps both sides honest, and the two new error codes (payload short, non
finite values) plus the three return codes the accept function shares with
move_mit_all are in ERR_TEXT.

The contract tests caught all four omissions on their own -- the coverage list,
the exercised manifest, the symbolic site manifest and its pinned count -- which
is exactly what they are for.
审查缺口:0x08 的载荷布局(q_target | dq_ref | K | B 各 N 个 f32 = 16N 字节)
此前**没有任何判据**。test_full_coverage 只断言"这条命令发出去过",不看载荷
内容 ⇒ 只改一端(SDK 打包或固件解析)不会被任何用例发现。

新判据两头都钉:
  ① 从固件 usb_cmd.h 的声明里正则提取分段顺序(顺序/长度改了先红)
  ② 用互不相同的哨兵值发出**真实帧**,逐段核对解出的值 —— 不复述 arm.py 的
     表达式:期望值与实现同源的话判据会随实现一起错(本仓栽过:ACK/ERR 常量
     写错而测试自洽地全绿)。

判别力已双向反验:
  · 改固件声明顺序(用临时目录副本,不动真文件)⇒ 红
  · 改 SDK 打包顺序(临时改 arm.py 后还原)⇒ 红

654 passed / 2 skipped(新增 1 条)。
@luomaofu
luomaofu merged commit 51833e3 into main Sep 29, 2026
2 checks passed
@luomaofu
luomaofu deleted the feat/joint-follow branch September 29, 2026 03:01
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.1.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant