Record the resolved yaw homing and the hand-written drivetrain block
This commit is contained in:
parent
f695a4eac6
commit
2191a9d8cb
|
|
@ -297,7 +297,7 @@ commit `aab1925`.
|
|||
|---|---|---|
|
||||
| 0 | Remote-flash question researched — two viable paths, design rule derived (§2) | **done, and now measured on the board: neither works** (§2). First flash needs the MicroPython REPL or BOOTSEL; remote *update* is unsolved pending a `BOOTSEL` command |
|
||||
| 2 | **Phase 2 gate: RP2040 + TMC5160-BOB at 3.3 V** | **PASSED** on tower 121, 2026-09-15: `IOIN Y=0x3000001E version=0x30`, encoder reading (`X_ENC`), one axis, `speed=3000` |
|
||||
| 3 | Yaw homing on the real drivetrain | **BLOCKED — no endstop found.** See below |
|
||||
| 3 | Yaw homing on the real drivetrain | **done** — the endstop was being sheared through at full torque; homing at 189 mA holds. See below |
|
||||
|
||||
### Phase 3, first attempt — 2026-09-16
|
||||
|
||||
|
|
@ -314,17 +314,49 @@ direction without the encoder deviation ever exceeding ~100 counts** against the
|
|||
1500 that marks a jam. The motor met no resistance at any speed.
|
||||
|
||||
Homing detects an endstop by the shaft falling behind the commanded position, so
|
||||
it cannot work if nothing stops the shaft. Two candidates, indistinguishable
|
||||
over the wire because the encoder sits on the motor side:
|
||||
it cannot work if nothing stops the shaft. Two candidates were considered,
|
||||
indistinguishable over the wire because the encoder sits on the motor side: no
|
||||
hard stop at all, or an output not following the motor.
|
||||
|
||||
1. **No hard stop on this yaw** — it rotates continuously, and stall-based homing
|
||||
is the wrong strategy for this rig.
|
||||
2. **The output is not following the motor** — a slipping coupling or a loose
|
||||
grub screw. The encoder would track the motor perfectly either way.
|
||||
### RESOLVED, 2026-09-17 — the stop was there, and losing
|
||||
|
||||
Neither. **The endstop is a screw head meeting another screw head, and the raised
|
||||
gear ratio gave the motor enough torque to shear one past the other.** The stop
|
||||
was resisting; it simply lost, every time, and a stop that yields is invisible to
|
||||
a detector watching for the shaft to fall behind.
|
||||
|
||||
The fix is to make the search weak enough that the screw wins:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Homing current | **189 mA** (IRUN 7 at GLOBALSCALER 80, 75 mΩ sense resistor) |
|
||||
| Run current | 756 mA — unchanged, because the gear ratio exists for wind stability |
|
||||
| Measured travel | **1,210,778 counts**, repeatable to 0.27 % across three homes |
|
||||
| Free-running encoder gap | ~200 counts against the 1500 latch, and it does **not** scale with speed |
|
||||
| Full homing | ~2 min at VMAX 30000 |
|
||||
|
||||
Declared per tower in `hardware.ini` as `[Motor.yaw] homing_current_ma`, converted
|
||||
to registers by the host and sent as `CURRENT` before every home — so retuning it
|
||||
is a restart, not a reflash. See [configuration.md](configuration.md) for the keys
|
||||
and `firmware/docs/hardware-notes.md` for the mechanism.
|
||||
|
||||
Three things this exposed, all since fixed:
|
||||
|
||||
- **`steps_per_rev` was inert**, still carrying the Delta's 177,000 against a real
|
||||
turn of ~1.2 M, so it passed at 14 % of a turn. It is the only guard against a
|
||||
*phantom* endstop, which reducing the current makes reachable.
|
||||
- **`STOP` did not end a homing** — it halted the motor but left the state machine
|
||||
waiting for a stall that could no longer come, until the timeout.
|
||||
- **The host abandoned homing after a hard-coded 65 s**, which this drivetrain
|
||||
needs more than. Now `[Motor] homing_timeout_s`.
|
||||
|
||||
<details><summary>What the investigation looked like before it was resolved</summary>
|
||||
|
||||
**Resolving it needs a physical observation**: did the gimbal itself rotate ~1.8
|
||||
turns, or did the motor spin while the platform stayed put? Check any cabling
|
||||
through that joint before moving the axis further.
|
||||
|
||||
</details>
|
||||
| 2 | `src/platform.h` — reset cause and free RAM behind one interface per MCU family | **done** |
|
||||
| 2 | `Serial.begin()` moved ahead of all hardware init, so a wedged image stays flashable | **done** |
|
||||
| 2 | `[env:iota_rp2040]` PlatformIO target (arduino-pico core, 8 MB flash) | **done and built** on tower 121, 2026-09-15: 49452 B flash (0.6 % of 8 MB), 9068 B RAM. `leonardo` still builds (19254 B) and the 22 native tests still pass |
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ Per-file reference for the refactored tree, plus the shared data structures.
|
|||
| [include/fgc/TelemetryParser.h](../include/fgc/TelemetryParser.h), [src/core/TelemetryParser.cpp](../src/core/TelemetryParser.cpp) | `parseTelemetryLine` (firmware `ST` line) → `std::optional<MotorTelemetry>` |
|
||||
| [include/fgc/CommandParser.h](../include/fgc/CommandParser.h), [src/core/CommandParser.cpp](../src/core/CommandParser.cpp) | `parseCommand` whitespace tokenizer → `Command` |
|
||||
| [include/fgc/HelpText.h](../include/fgc/HelpText.h), [src/core/HelpText.cpp](../src/core/HelpText.cpp) | Operator command catalog (`helpCatalog`) + `renderHelp` (console & TUI help) |
|
||||
| [include/fgc/TmcCurrent.h](../include/fgc/TmcCurrent.h), [src/core/TmcCurrent.cpp](../src/core/TmcCurrent.cpp) | Milliamps → TMC5160 `GLOBALSCALER`/`IRUN` register fields, using the sense resistor from `[Motor.<axis>]`. Pure arithmetic, so it is unit-tested; the host owns the conversion because only it knows the resistor |
|
||||
| [include/fgc/DumpParser.h](../include/fgc/DumpParser.h), [src/core/DumpParser.cpp](../src/core/DumpParser.cpp) | `parseDump` firmware `DUMP` block → `DumpData` (per-axis state + decoded TMC registers/flags); `formatDump` |
|
||||
| [include/fgc/DiagParser.h](../include/fgc/DiagParser.h), [src/core/DiagParser.cpp](../src/core/DiagParser.cpp) | `parseDiag` firmware `DG` self-test stream → `DiagResult` (per-axis tests, PASS/FAIL); `formatDiag` |
|
||||
| [include/fgc/Calibration.h](../include/fgc/Calibration.h), [src/core/Calibration.cpp](../src/core/Calibration.cpp) | `linearFit` (least-squares, R²) + `circularMeanDeg` for the IMU-referenced calibration |
|
||||
|
|
|
|||
|
|
@ -228,6 +228,53 @@ Then prove the program finds it **with nothing in the environment** - no
|
|||
> required` - a message that points at the camera rather than at the file that
|
||||
> disappeared. Verified on tower 121 by rebooting it.
|
||||
|
||||
### The drivetrain block
|
||||
|
||||
`install.sh` does not write this one - no probe can read a sense resistor off a
|
||||
board - so add it by hand, one `[Motor.<axis>]` block per axis:
|
||||
|
||||
```ini
|
||||
[Motor.yaw]
|
||||
r_sense_ohm = 0.075 ; the resistor fitted to THIS driver board
|
||||
run_current_ma = 756 ; normal motion
|
||||
homing_current_ma = 200 ; the endstop search only
|
||||
travel_deg = 340 ; mechanical angle between the hard stops
|
||||
```
|
||||
|
||||
**`homing_current_ma` is a safety setting, not a tuning one.** Homing finds a
|
||||
stop by driving into it until the shaft falls behind; that only works while the
|
||||
stop is stronger than the motor. A high gear ratio can shear a screw-head stop
|
||||
straight past its mate - on tower 121 the axis ran 1.8 turns past the stop with
|
||||
the encoder never falling behind, at full torque. Declare a reduced search
|
||||
current wherever the stop cannot survive one.
|
||||
|
||||
Getting it wrong in either direction is visible: too strong and the stop yields
|
||||
again; too weak and the motor stalls on ordinary friction mid-sweep, trips the
|
||||
same latch, and records a phantom endstop. The firmware's `steps_per_rev` guard
|
||||
is what catches the second case, so it has to be set from the real travel.
|
||||
|
||||
**`travel_deg` is a nameplate fact**, and the host divides the measured homing
|
||||
travel by it to derive `[Motor] <axis>_counts_per_deg` into `config.ini`. A rough
|
||||
angle gives a proportionally rough degree scale - 1 % out here is 1 % out on every
|
||||
bearing - until `gimbal heading setup` supersedes it with a landmark fit.
|
||||
|
||||
The startup log reports what the registers **actually** deliver, which is not
|
||||
always what was asked for:
|
||||
|
||||
```
|
||||
yaw motor current: run 756 mA (GLOBALSCALER 80, IRUN 31), homing 189 mA (IRUN 7)
|
||||
-- R_sense 0.075 ohm from hardware.ini [Motor.yaw]
|
||||
```
|
||||
|
||||
Omit the block entirely on a tower whose endstops hold against full torque: no
|
||||
`CURRENT` is sent, the firmware keeps its compile-time defaults, and nothing
|
||||
changes.
|
||||
|
||||
> **If an axis declares a reduced homing current and the firmware has not adopted
|
||||
> it, the host refuses to home** rather than driving into a stop at full torque.
|
||||
> The message names the skew; the fix is to flash the firmware, not to override
|
||||
> it.
|
||||
|
||||
> `[Serial] device` must be a `/dev/serial/by-id/` path, never `/dev/ttyACM0`.
|
||||
> Tower 121 has a 5G modem that claims three `ttyUSB` nodes, and enumeration
|
||||
> order is not stable across reboots.
|
||||
|
|
@ -686,7 +733,9 @@ gimbal pitch setup # needs an IMU; skip on a rig without one
|
|||
| Driver answers over SPI | boot banner shows `IOIN Y=0x… version=0x30` | ✅ |
|
||||
| Remote re-flash | `BOOTSEL`, then `./deploy.sh` - no hands on the board | ✅ |
|
||||
| Declared hardware matches | startup logs no presence warnings | ✅ no shadowed-key warnings |
|
||||
| Homing repeatable | `gimbal home` several times, endstop counts within `home_spread_max_counts` | ❌ **not attempted** - unknown drivetrain |
|
||||
| Homing repeatable | `gimbal home` several times, endstop counts within `home_spread_max_counts` | ✅ three homes within 0.27 % (1,210,778 / 1,208,358 / 1,207,514 counts) |
|
||||
| Endstop survives homing | inspect the stop after a home; the axis must stall against it, not push through | ✅ at 189 mA, after failing at full torque |
|
||||
| Degree scale derived | startup logs `counts_per_deg` agreeing with the homed travel | ✅ 3552.87, saved with `;prev` history |
|
||||
| Images land | `.jxl` files appear under the configured output dir | ❌ needs a capture run |
|
||||
| Survives a disconnect | `scripts/fgc start`, close ssh, reconnect, `scripts/fgc status` | ❌ not attempted |
|
||||
| Reports to a broker | topics arrive at the configured broker | ❌ no broker on this tower yet |
|
||||
|
|
|
|||
Loading…
Reference in New Issue