added motion trajectory simulation
This commit is contained in:
@@ -41,28 +41,23 @@ Because the atlas is a single island, a click maps to exactly one 3D point.
|
||||
An earlier revision of this note reported that the **yaw +-90 deg limit made a
|
||||
quarter of the patch unalignable**, worst residual 65.1 deg, only 47 of 61
|
||||
sampled points reachable. **That was a solver bug, not a property of the
|
||||
machine.** The corrected solver solves the real surface as:
|
||||
machine.**
|
||||
|
||||
| Envelope | Worst residual | Median | Within 0.01 deg | Within 0.5 deg |
|
||||
|---|---|---|---|---|
|
||||
| pitch 360 deg, **yaw +-90 deg** (the machine) | **0.21 deg** | 0.00 deg | **98.4%** | **100%** |
|
||||
| pitch 360 deg, yaw +-180 deg | 0.24 deg | 0.00 deg | — | 100% |
|
||||
A later revision then reported the residual as 0.21 deg worst with the yaw limit
|
||||
"not the constraint". **That was also wrong**, in the opposite direction: the
|
||||
limit itself was wrong. The bench confirmed the yaw stage turns a **full half-turn
|
||||
either way (+-180 deg)**, not +-90.
|
||||
|
||||
So **every** vertex of the sensing patch is reachable, and widening the yaw range
|
||||
buys essentially nothing (0.21 deg → 0.24 deg worst). The 0.21 deg worst case is
|
||||
a genuinely clamped vertex: the sweep's own minimum at that vertex is 0.211 deg
|
||||
at the yaw clamp, so the number is physical, not lost precision.
|
||||
With the corrected envelope, solved by closed form
|
||||
(see `inverse-kinematics.md`):
|
||||
|
||||
Why the yaw limit is not the constraint, which the earlier note had backwards:
|
||||
| Envelope | Worst residual | Within 0.5 deg | In range |
|
||||
|---|---|---|---|
|
||||
| pitch 360 deg, **yaw +-180 deg** (the machine) | **1.2e-06 deg** | 100% | **1032 / 1032** |
|
||||
|
||||
- The pitch stage turns a vector around a circle in the plane **perpendicular to
|
||||
the pitch axis**.
|
||||
- The yaw stage can reach a given great circle as long as the yawed normal is not
|
||||
parallel to the pitch axis. A normal parallel to the pitch axis after yawing
|
||||
would have to be perpendicular to the tool axis already, and the finger patch
|
||||
normals — which point along sensor +Y, mapping to platform **+Z**, the tool
|
||||
direction — are nothing of the sort.
|
||||
- Pitch travel is therefore what does the work, and the 360 deg stage provides it.
|
||||
Every vertex is reachable, and the residual is at the floating-point floor rather
|
||||
than at any clamp. The "0.21 deg worst, genuinely clamped vertex" claim above was
|
||||
an artefact of the wrong limit and no longer holds.
|
||||
|
||||
**No mounting change is required for reachability.** The three options the earlier
|
||||
note listed (re-mount, state a tolerance, index the plate) are all unnecessary on
|
||||
@@ -70,6 +65,12 @@ the reachability evidence. Whether they help *repeatability* — a shorter pitch
|
||||
move, a better-conditioned contact — is a separate bench question, not a
|
||||
kinematic one.
|
||||
|
||||
One thing the corrected solve did surface: **51 of 1032 vertices end inverted**,
|
||||
whichever closed-form branch is chosen, because the tool direction is
|
||||
antiparallel to the sensor's own up axis. That is the tool-polarity question, it
|
||||
needs the bench, and it is *not* visible in the residual. See
|
||||
`inverse-kinematics.md` → *Still open*.
|
||||
|
||||
## What was wrong before, and why it is worth recording
|
||||
|
||||
**Four** solver versions preceded this one, each wrong in a way that produced
|
||||
@@ -104,9 +105,11 @@ as a number rather than as a plausible pose.
|
||||
| `sensor/uv_flat.py` | flat image + pixel→3D table; gap pixels are `None` |
|
||||
| `motion/kinematics.py` | constrained search + measured residual; stage limits are parameters; singular case reported, not guessed |
|
||||
| `ui/sensor_panel.py` | picker, readouts, point table; refuses gap pixels with a reason; picked rows kept at full precision, not re-read from the 3-decimal display text |
|
||||
| `ui/pose_preview.py` | 3D preview coloured by residual, tool axis drawn; the legend is a sibling label, because text composited over the GL surface is unreadable once it overflows |
|
||||
| `ui/pose_preview.py` | 3D preview coloured by residual, tool axis drawn; the legend is a sibling label, because text composited over the GL surface is unreadable once it overflows. The scene, the palette and the framing rule are described in [finger-preview.md](finger-preview.md) |
|
||||
| `motion/kinematics.py` | closed-form solve, exact to 1.2e-06°; the sweep is kept only as the reference the tests check it against — see [inverse-kinematics.md](inverse-kinematics.md) |
|
||||
| workspace `finger` tab | wired, checked at 1440×900 and 1920×1080 in both themes |
|
||||
| startup | the remembered bundle loads automatically, so the tab comes up working instead of showing a filled-in path over two empty views |
|
||||
| `tools/preview_snapshot.py` | photographs the 3D pane with a real GL context, at rest or mid-playback, pane-only or composited into the page |
|
||||
|
||||
Not yet built: capture of picked points into the sequence, and the live-sensor
|
||||
counterpart of the simulated pose.
|
||||
|
||||
Reference in New Issue
Block a user