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

released Shipped in a release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant