Skip to content

docs: correct the singular-pose claim, three API notes and two examples - #23

Merged
X-F-R merged 2 commits into
mainfrom
docs/first-contact-corrections
Oct 10, 2026
Merged

X-F-R merged 2 commits into
mainfrom
docs/first-contact-corrections

Conversation

@X-F-R

@X-F-R X-F-R commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to the onboarding walkthrough in #18, which already covers the quick start, the
install steps and the serial permissions. This is the part that walkthrough did not reach.

Base is docs/fix-new-user-onboarding so the diff shows only these changes. The diff
against main includes #18 as well.

The blocking one: TROUBLESHOOTING.md:144 says a cartesian move from the fully-extended
home pose "always" fails with err=1. Measured on hardware, a 1-4 mm step is
accepted
and reconstructs the arm by 13-60 deg while the tool moves 1-3 mm. The gate
catches large steps, not small ones, so "always" sends the reader the wrong way about the
one pose that is actually dangerous. Same finding as #19 §1.

examples/03_move_p.py described its default as "a small step you can step back
from".
From the zero pose the same 1 cm target reconstructs the arm by 86.88 deg
(J1 74 deg, J3 52 deg) and the script still prints move_p 到位. The mechanism is on the
firmware side and the example cannot fix it: move_p reaches the bus through
kin_runner_request_move_p (kin_runner.c:196), which has no adjacent-solution gate at
all
, while move_l / move_c / move_path go through cart_plan.c:1029 and reject a
jump beyond CART_MAX_IK_STEP = 0.35 rad. At a healthy pose the same call is 5 deg of
motion, so this is "do not start from the singularity", not "move_p is broken".

Changes

  • TROUBLESHOOTING.md, TROUBLESHOOTING.zh-CN.md — replace the "always" claim with the
    measured boundary, and add the measured ratio as a discriminator.
  • docs/DEVELOPER_GUIDE.md, docs/DEVELOPER_GUIDE.zh-CN.md — §5.1 and §5.3:
    • wait=False skips only the wait for the arm to settle. Both values block for the
      plan reply
      , so poll_cart() never yields a result from one; its real use is
      recovering a call whose ACK timed out. cart._request_and_wait calls _cart.wait
      unconditionally, which confirms it.
    • enable() returns before the state stream reflects it: 2.0-2.7 ms to return
      against 7.0-7.8 ms for get_state().enabled to turn true, so reading it on the
      next line always shows False.
  • src/litearm/arm.py — the enable() docstring carries the same measurement. This is
    the only source change in this PR; it is a docstring, not behaviour.
  • README.md, README.zh-CN.md — the API reference cartesian snippet used three
    absolute poses with rpy = (pi, 0, 0). That orientation solves only about half the
    time in a 135-pose sweep (51-53% against 100% for (0, 0, pi)); the snippet now
    offsets the measured pose. (The quick start and install sections are docs: fix the onboarding gaps found by a new-user walkthrough #18's, untouched
    here.)
  • examples/03_move_p.py — docstring corrected; the example bends a joint before
    issuing move_p.
  • examples/06_cartesian.py — same first step. From the zero pose all three of its
    cartesian entry points are refused (err=1): safe, but the example never ran.

Testing

Documentation and two example scripts, plus one docstring.

$ LITEARM_LIVE=1 python3 -m pytest -q
3 failed, 657 passed

The 3 failures are pre-existing on main and unrelated to this PR:
test_every_firmware_literal_err_code_is_registered,
test_symbolic_site_manifest_matches_firmware,
test_bench_model_axis_matches_sdk_constant. They need a litearm-stm32 checkout to run
at all, and #21 fixes them.

Both examples and the revised snippet run against the arm:

$ python3 examples/03_move_p.py --go        -> EXIT=0
$ python3 examples/06_cartesian.py --go     -> EXIT=0  (n_wp 5 / 7 / 9 / 6)

Issues

Refs #19 — the TROUBLESHOOTING.md:144 half of that report. The other half (overlapping
cartesian commands losing replies) is untouched: it is firmware-side and this PR does not
address it.

thetooler and others added 2 commits October 9, 2026 16:30
A walkthrough was run on real hardware, following only what this
repository documents. Several steps either fail outright or mislead;
this corrects the documentation without changing any code.

Quick start: the arm boots into the EMERGENCY latch, so enable() was
rejected with ERR{0x10,0x06} before a single motion. Add the reset()
that clears it, replace the fully extended joint pose -- a singular
pose no Cartesian motion can be planned out of -- with one whose
joints all stay clear of their limits, and drive the Cartesian moves
from the measured TCP instead of a hand-written pose with no IK
solution.

Also documents serial permissions, the save_params() and
clear_faults() preconditions, the state frame's mode and flags, the
ROS 2 pytest failure, and links the troubleshooting guide, which had
no entry point from the README.
Follow-up to the onboarding walkthrough in #18, which covers the quick
start, the install steps and the serial permissions. What is left here is
the part that walkthrough did not reach.

The blocking one is TROUBLESHOOTING.md:144, which says a cartesian move
from the fully-extended home pose "always" fails with err=1. Measured on
hardware: a 1-4 mm step is accepted and reconstructs the arm by 13-60 deg
while the tool moves 1-3 mm. The gate catches large steps, not small ones,
so "always" sends the reader the wrong way about the one pose that is
actually dangerous.

examples/03_move_p.py described its default as "a small step you can step
back from". From the zero pose the same 1 cm target reconstructs the arm by
86.88 deg (J1 74 deg, J3 52 deg) and the script still prints move_p arrived.
The mechanism is firmware-side: move_p reaches the bus through
kin_runner_request_move_p, which has no adjacent-solution gate, while
move_l/move_c/move_path go through cart_plan.c and reject a jump beyond
CART_MAX_IK_STEP (0.35 rad). Both this example and examples/06_cartesian.py
now leave the singularity before issuing a cartesian command.

Three API claims corrected in docs/DEVELOPER_GUIDE.md and README.md:

  * wait=False skips only the wait for the arm to settle. Both values block
    for the plan reply, so poll_cart() never yields a result from one -- its
    real use is recovering a call whose ACK timed out.
  * enable() returns before the state stream reflects it: 2.0-2.7 ms to
    return against 7.0-7.8 ms for the flag to turn true, so reading enabled
    on the next line always shows False. Also recorded in the docstring.
  * the cartesian snippet used three absolute poses with rpy=(pi,0,0), an
    orientation that solves only about half the time; it now offsets the
    measured pose.

Testing: LITEARM_LIVE=1 pytest -> 659 passed. Both examples and the revised
snippet run against the arm: 03_move_p.py --go EXIT=0,
06_cartesian.py --go EXIT=0 (n_wp 5/7/9/6).
@X-F-R
X-F-R force-pushed the docs/first-contact-corrections branch from eaaff53 to dac30ee Compare October 10, 2026 09:50
@X-F-R X-F-R changed the title docs: correct the quick start and three API claims that do not hold docs: correct the singular-pose claim, three API notes and two examples Oct 10, 2026
@X-F-R
X-F-R changed the base branch from main to docs/fix-new-user-onboarding October 10, 2026 09:51
Base automatically changed from docs/fix-new-user-onboarding to main October 10, 2026 09:54
@X-F-R
X-F-R merged commit 7e864cf into main Oct 10, 2026
2 checks passed
@X-F-R
X-F-R deleted the docs/first-contact-corrections branch October 10, 2026 09:59
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