112 lines
5.1 KiB
Markdown
112 lines
5.1 KiB
Markdown
# Hexapod remote firmware (Teensy 4.1)
|
||||
|
|
|
|||
|
|
Handheld transmitter for the hexapod. It reads two 3-axis twist-grip
|
|||
|
|
joysticks and an MPU6050, takes operator commands from a Nextion
|
|||
|
|
touchscreen, and sends a `CmdPacket` (defined in
|
|||
|
|
`../shared/HexapodProtocol/HexapodProtocol.h`) to the robot over nRF24L01
|
|||
|
|
at 100 Hz.
|
|||
|
|
|
|||
|
|
## Building
|
|||
|
|
|
|||
|
|
From the repo root: `pio run -e remote`, flash with
|
|||
|
|
`pio run -e remote -t upload`, monitor with `pio device monitor -e remote`.
|
|||
|
|
|
|||
|
|
## Wiring (placeholders; edit `Config.h` to match)
|
|||
|
|
|
|||
|
|
| Part | Signal | Teensy 4.1 pin |
|
|||
|
|
|------|--------|----------------|
|
|||
|
|
| nRF24L01 | MOSI / MISO / SCK | 11 / 12 / 13 (SPI0) |
|
|||
|
|
| nRF24L01 | CE / CSN | 9 / 10 |
|
|||
|
|
| nRF24L01 | VCC | 3.3 V, with a 10–100 µF cap right at the module |
|
|||
|
|
| MPU6050 | SDA / SCL | 18 / 19 (Wire) |
|
|||
|
|
| Nextion | TX → RX2, RX ← TX2 | 7 / 8 (Serial2), 5 V supply |
|
|||
|
|
| Left stick | X / Y / twist | A0 / A1 / A2 |
|
|||
|
|
| Right stick | X / Y / twist | A3 / A6 / A7 |
|
|||
|
|
|
|||
|
|
Stick pots are wired 3.3 V – wiper – GND. **Never feed 5 V into a Teensy
|
|||
|
|
4.x analog pin.**
|
|||
|
|
|
|||
|
|
## Control scheme
|
|||
|
|
|
|||
|
|
| Input | Packet field | Meaning on the robot |
|
|||
|
|
|-------|--------------|----------------------|
|
|||
|
|
| Left stick forward/back | `vx` | walk forward/back |
|
|||
|
|
| Left stick left/right | `vy` | strafe (mode A); heading target direction (mode B) |
|
|||
|
|
| Left stick twist | `yaw_rate` | turn rate (mode A only; ignored in mode B) |
|
|||
|
|
| Right stick, **ROTATE** (default) | `rx/ry/rz` | body roll / pitch / yaw |
|
|||
|
|
| Right stick, **MOVE** (`FLAG_RSTICK_XLATE`) | `rx/ry/rz` | body X / Y / Z (height, via twist) offset |
|
|||
|
|
| Handset tilt | `remote_roll/pitch` | extra body roll/pitch while REMOTE GYRO is on |
|
|||
|
|
|
|||
|
|
Touchscreen: ARM / DISARM, SIT/STAND, TRIPOD/WAVE, DIRECT/HEADING,
|
|||
|
|
R: ROTATE/MOVE, REMOTE GYRO, ROBOT GYRO, speed slider, LEVEL (re-zero the
|
|||
|
|
handset tilt), CAL / CANCEL CAL. `NEXTION.md` has the HMI build guide.
|
|||
|
|
|
|||
|
|
### Safety interlocks (in `RemoteState`)
|
|||
|
|
|
|||
|
|
- **Arming** is refused unless every stick axis is centered, and never
|
|||
|
|
allowed during calibration.
|
|||
|
|
- **Disarming** always clears the stand request. The robot arms into SIT,
|
|||
|
|
so re-arming never stands it up by itself.
|
|||
|
|
- **Link loss:** if no ack arrives for `LINK_LOST_MS` (300 ms, matching the
|
|||
|
|
robot's failsafe), the remote disarms itself. When the link comes back
|
|||
|
|
the robot stays down until you re-arm deliberately.
|
|||
|
|
- **Sit/stand** requests are only accepted while armed. `FLAG_WALK` is only
|
|||
|
|
sent while standing is requested.
|
|||
|
|
- While disarmed or calibrating, all motion fields are sent as zero.
|
|||
|
|
|
|||
|
|
### Smoothing
|
|||
|
|
|
|||
|
|
- **Speed scale** ramps toward the slider at `SPEED_SCALE_RATE_PER_SEC`.
|
|||
|
|
The robot uses speed scale directly on the walking twist, so a slider
|
|||
|
|
jump would otherwise be a velocity step.
|
|||
|
|
- **Remote tilt** fades in/out over ~0.5 s when REMOTE GYRO is toggled, and
|
|||
|
|
the handset re-zeroes its "level" at the moment you enable it.
|
|||
|
|
- **FLAG_WALK** lingers 250 ms after the left stick centers, so hovering at
|
|||
|
|
the deadzone edge doesn't make the robot chatter between STAND and
|
|||
|
|
WALKING.
|
|||
|
|
- Body pose smoothing is left to the robot's `BodyPose` rate limiters.
|
|||
|
|
|
|||
|
|
## Stick calibration
|
|||
|
|
|
|||
|
|
1. Power on with both sticks released and the remote held still. Each
|
|||
|
|
axis's resting center is captured automatically.
|
|||
|
|
2. For full calibration, disarm, then tap **CAL** (or press `c` on the
|
|||
|
|
serial console). Move every axis of both sticks to both limits, release
|
|||
|
|
them, and tap **SAVE CAL** (`c`). The result is saved to EEPROM.
|
|||
|
|
3. If any axis moved less than `CAL_MIN_HALF_SPAN` either side of center,
|
|||
|
|
the save is refused and you stay in calibration mode. **CANCEL CAL**
|
|||
|
|
(`x`) aborts.
|
|||
|
|
4. `p` prints the calibration in a form you can paste into `Config.h`
|
|||
|
|
defaults. `R` wipes EEPROM back to the `Config.h` defaults.
|
|||
|
|
|
|||
|
|
## Serial console (USB, 115200, single keystrokes)
|
|||
|
|
|
|||
|
|
Every touchscreen control is available here, so you can bench-test with no
|
|||
|
|
display attached.
|
|||
|
|
|
|||
|
|
| Key | Action | Key | Action |
|
|||
|
|
|-----|--------|-----|--------|
|
|||
|
|
| `a` | toggle arm | `k` | disarm |
|
|||
|
|
| `s` | toggle sit/stand | `g` | tripod ↔ wave |
|
|||
|
|
| `m` | direct ↔ heading-hold | `t` | right stick rotate ↔ translate |
|
|||
|
|
| `r` | remote gyro on/off | `b` | robot gyro on/off |
|
|||
|
|
| `+` / `-` | speed ±25 | `z` | zero handset level |
|
|||
|
|
| `c` | start / save calibration | `x` | cancel calibration |
|
|||
|
|
| `p` | print status (raw + mapped sticks, IMU, link, state, cal) | `d` | toggle 10 Hz packet dump |
|
|||
|
|
| `R` | reset stick cal to Config defaults | | |
|
|||
|
|
|
|||
|
|
## Bench-check checklist
|
|||
|
|
|
|||
|
|
1. **Stick directions:** with `p`, confirm each logical axis reads
|
|||
|
|
positive for right / forward / counterclockwise twist. Flip it in
|
|||
|
|
`STICK_INVERT[]` if not.
|
|||
|
|
2. **IMU mounting:** with `p`, dip the right edge down to get +roll, and
|
|||
|
|
tip the far edge down to get +pitch. If not, fix `IMU_AXIS_FROM_CHIP` /
|
|||
|
|
`IMU_AXIS_SIGN`.
|
|||
|
|
3. **Nextion baud:** `bauds=115200` must be in Program.s, or the display
|
|||
|
|
shows nothing useful.
|
|||
|
|
4. **Radio:** with the robot powered, `tLink` / `p` should show ~100%. If
|
|||
|
|
it reads NO LINK, check that both boards were built from the same
|
|||
|
|
`HexapodProtocol.h`. The static payload size is part of the handshake.
|
|||
|
|
5. **End to end with the robot on a stand:** use `d` to dump packets and
|
|||
|
|
confirm each field changes the way the table above says.
|