Firmware simulation, Unity project, and sim-verified robot fixes

Simulation
- sim/: the unchanged robot firmware compiled into hexapod_sim.dll
  against PC stand-ins (Arduino, Servo, Wire + register-level MPU6050,
  RF24 with matching-config radio), a kinematic body model (support
  plane + planted-foot odometry) that also drives the simulated IMU,
  and a headless smoke test (sim_smoke). build.ps1 builds and tests.
- Hexapod_Simulation_Unity/ folded in (history kept in a bundle
  outside the repo). Assets/HexapodSim loads the DLL, drives the
  existing leg rig, and offers joystick / keyboard / robot-serial
  input plus a test panel.

Robot (all found or confirmed in the simulation)
- Config.h geometry taken from the Unity model.
- IK femur elevation sign, gait stance direction, body pose
  rotation direction, yaw lever arm.
- Stance feet integrated from the current command; gait restarts at
  mid-stance; heading integrates the applied turn rate, only while
  walking.
- Leg clearance and reach checks (Limits::feetFeasible); walk command
  and body pose scaled as a whole, pose scale rate-limited, planted
  feet guarded so the body never snaps or legs collide.
- Robot-gyro self-leveling as an integrator.
- Heading mode: steering relative to the body; S walks backward.
- Standing height from the remote (STANCE_HEIGHT_RANGE_MM).

Protocol v3 (reflash both boards)
- CmdPacket gains body_height (22 bytes).

Remote
- Height slider (Nextion hHeight/nHeight, serial [ ]).
- Fixed unspecified I2C read order in RemoteIMU.

LEGACY/: owner's old Nextion HMI and remote hardware assets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-09-29 00:37:12 +02:00
1 parent 91dac16fca
commit 935526eab5
145 files changed
+431258 -114

No files matched your search

+33 -18
View File
@@ -18,8 +18,9 @@ sketchbook `libraries/` folder and install **RF24** by TMRh20.
## Before you trust this on the floor
Everything in `Config.h` is a placeholder for a generic small hexapod. Measure
your own robot and edit:
The leg geometry in `Config.h` is taken from the Unity model
(`Hexapod_Simulation_Unity`, 1 unit = 10 mm). Everything else there is
still a placeholder. Check all of it against the real robot:
- `LEG_MOUNT_ANGLE_DEG` / `LEG_MOUNT_X_MM` / `LEG_MOUNT_Y_MM` — where each
coxa pivot actually sits on your chassis, and which way it points
@@ -27,6 +28,9 @@ your own robot and edit:
- `COXA_MIN_DEG..TIBIA_MAX_DEG` — your servos' real safe range of motion
- `STANCE_RADIUS_MM` / `STANCE_HEIGHT_MM` — how far out/down you want the
resting foot position
- `LEG_CLEARANCE_MM`: how close neighbouring legs may get. Walking speed
and body pose are scaled down to keep it, so set it to about one leg's
width.
- `SERVO_PINS` — must be PWM-capable pins on your Teensy 4.0 wiring
- `SERVO_US_AT_0DEG` / `SERVO_US_PER_DEG` — calibrate per servo, they vary
batch to batch
@@ -43,13 +47,16 @@ These are sign conventions that depend on which way your hardware is
physically mounted, and the code has a best-guess default that may be wrong
for your build:
1. **IK elbow/tibia direction** (`Kinematics.cpp`) — command one leg to a
few known foot positions by hand (e.g. via the serial harness) and watch
whether the knee bends the way you expect. Flip the sign noted in the
comment on `tibia_rad` if it bends backwards.
2. **BodyPose roll/pitch sign** (`BodyPose.cpp`) — command a small roll/pitch
offset and verify the body leans the direction you asked for, not the
opposite.
1. **IK knee direction** (`Kinematics.cpp`). The femur elevation sign bug
(the foot was solved *above* the hip) is fixed and verified in the
simulation: the stance pose comes out femur −1.2°, tibia −98.3°. Still
command one leg to a few known foot positions on the bench and check the
knee bends the way the sim shows.
2. **BodyPose roll/pitch sign** (`BodyPose.cpp`). Fixed in the simulation:
the pose was applied as the forward rotation, which inverted roll, pitch
and yaw. On the bench, command a small roll/pitch and verify the body
leans the way the protocol says (+roll = right side down, +pitch = nose
down).
3. **RobotIMU register map** (`RobotIMU.cpp`) — written for an MPU6050-style
chip (I2C addr `0x68`). If your gyro is a different part, its register
addresses and scale factors will differ; swap them in.
@@ -58,14 +65,22 @@ for your build:
If your chassis is meant to rest its belly on the ground instead, this
needs a different, sequenced approach (fold legs up rather than just
lowering).
5. **Gait travel direction** (`GaitEngine.cpp`) — the protocol defines
`+vx` = forward, `+vy` = left, `+yaw_rate` = turn left (CCW). As written,
the stance phase sweeps each foot from `neutral - half_stride` to
`neutral + half_stride`, i.e. the foot moves *with* the commanded
direction, which pushes the body the opposite way. Verify with `w` on the
bench; if the robot backs up, swap `start`/`end` in `GaitEngine::update`
(fixes translation and yaw together). The `z`/`c` harness keys were
written against the current behavior — recheck them after that fix.
5. **Gait travel direction** (`GaitEngine.cpp`). Fixed: stance now sweeps
each foot opposite to the commanded motion. The smoke test checks that
`+vx` moves the body forward and `+yaw_rate` turns it left (CCW). On
the bench, confirm `w` walks forward and `z` turns left.
6. **Per-servo calibration**. `ServoDriver` uses one
`SERVO_US_AT_0DEG` / `SERVO_US_PER_DEG` for all 18 servos, so servo
center = joint angle 0 (tibia *straight*). On this build the knee servo
center is the tibia at 90° to the femur, and the left side is mirrored
(per the old Unity/servo code). That needs a per-joint offset and
direction before the real robot will stand.
## Testing in the simulation
This exact code also compiles for the PC and runs in the Unity model. See
`../sim/README.md`. `sim/build/sim_smoke.exe` is a quick headless check
after every change.
## Testing without a remote yet
@@ -79,7 +94,7 @@ keystrokes) and use:
| `s` | toggle sit / stand |
| `w` / `x` | walk forward / backward (`vx` ±) |
| `q` / `e` | strafe left / right (`vy` ±) |
| `z` / `c` | yaw left / right |
| `z` / `c` | turn left / right (`yaw_rate` ±) |
| `g` | toggle gait: tripod ↔ wave |
| `m` | toggle walk mode: direct (A) ↔ heading-hold (B) |
| space | zero all velocity (stop walking, stay in current state) |