Files
hexapod-robot/2026-current/sim/README.md
T
mangavalkandClaude Opus 5.5 935526eab5 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>
2026-09-29 00:37:12 +02:00

121 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Firmware simulation (software-in-the-loop)
This folder compiles the **unchanged** robot firmware (`robot/*.cpp` plus
`robot.ino`) into a Windows DLL. The Unity project
(`Hexapod_Simulation_Unity/`) runs that DLL, so the code you test in the
simulation is exactly the code you flash to the Teensy. `robot/` has no
`#ifdef SIM` anywhere.
```
robot/ (unchanged) ──► PlatformIO + Teensy core ──► Teensy 4.0 firmware
└─► CMake + g++ + sim/shim/ ──► sim/build/hexapod_sim.dll ──► Unity
```
## How it works
`shim/` provides PC stand-ins for the only hardware the firmware touches:
| Firmware uses | Simulated as |
|---|---|
| `Servo::writeMicroseconds()` | the pulse stored per pin, decoded back to angles with `Config.h`'s `SERVO_US_*` |
| `Wire` + MPU6050 registers | a register-level fake MPU6050 at 0x68, fed from the simulated body's tilt and rotation |
| `RF24` | a simulated radio: packets are received only if channel, address, data rate and **payload size** match, and the RX FIFO holds 3 |
| `millis()` / `micros()` / `Serial` | a simulated clock that Unity advances, and captured serial I/O |
`robot_ino.cpp` compiles `robot.ino` itself and exposes read-only views of
its globals (state machine, heading, IMU filter, gait phase) for status
display. `HexapodSimApi.h` is the C API. Its forward kinematics is written
separately from `robot/Kinematics.cpp` on purpose, so it can catch IK
mistakes.
## Build
Needs a 64-bit g++ and CMake. Strawberry Perl's `C:\Strawberry\c\bin` has
g++, cmake and ninja, and the script falls back to it automatically. From
the repo root in PowerShell:
```
.\sim\build.ps1 # configure (first time) + build + smoke test
.\sim\build.ps1 -NoTest # build only
.\sim\build.ps1 -Clean # rebuild from scratch
```
To run the steps by hand, use separate lines. Windows PowerShell 5.1 has
no `&&`:
```
cmake -S sim -B sim\build -G Ninja
cmake --build sim\build
.\sim\build\sim_smoke.exe
```
Rebuild after any change in `robot/` or `shared/`. In Unity, press **Play**
(or **Reload firmware** in the panel) to pick up the new DLL. Unity copies
the DLL before loading it, so it never locks the build output and you
don't need to restart the editor.
## Headless smoke test (`tests/sim_smoke.cpp`)
It drives the firmware the way the remote would and checks:
- disarmed at power-on,
- arm lands in SIT,
- stand reaches STAND,
- **IK gives valid solutions and the feet end up at `STANCE_HEIGHT`**,
- `FLAG_WALK` leads to WALKING,
- **`+vx` moves the body forward**,
- link loss disarms,
- a wrong-size packet is ignored,
- the serial harness still works.
## Using it in Unity
Open `Hexapod_Simulation_Unity` and press Play in `Main.unity`. No scene
edits are needed: `HexapodSimBootstrap` adds a `HexapodSimulation` object,
disables the old movement scripts (`Walk`, `RotationControl`, `Leg`,
`HandleHoystick`), and binds the existing leg rig by name (`Leg` → `hip1`
/ `Hip2` / `Knie`). The on-screen panel (F1 toggles it) offers three input
sources:
- **Joystick:** the real remote as a USB controller, on input axes
`"1"`–`"6"` like the old `HandleHoystick`. Axis assignment and inversion
are set on the `SimRemote` component. The panel shows the raw axes so you
can fix them.
- **Keyboard:** test without a remote. WASD walks, Q/E turns, IJKL + U/O
drive the right stick, 1–7 flip the toggles, Backspace disarms, +/-
change speed.
- **Robot serial:** no radio at all. Keystrokes go to `robot.ino`'s own
`TEST_SERIAL_INPUT` harness.
The panel also has every remote toggle, the speed slider, simulated
handset tilt (remote gyro), a **ground tilt** slider (to test the robot
gyro), and live firmware state, joint angles, foot contact, the packet on
air and robot serial output.
The body moves **kinematically**, computed in the DLL (`SimBody.cpp`), so
Unity shows what the smoke test checks:
- The body rests on the support plane of its feet, the plane all feet are
on or above.
- Grounded feet don't slide.
- The simulated MPU6050 reads that body's tilt and rotation rate.
The sphere at each foot (`Point`) is placed by the DLL's forward
kinematics. If it doesn't sit on the tibia tip, the rig and `Config.h`
disagree.
Setup that lives in the Inspector on `HexapodSimulation`:
- `forwardAxis`: robot forward = Unity −X by default, taken from the old
scene's `invertForLeftLeg` naming.
- `unitsPerMm`: 0.1, since the model is in cm.
- `kneeRestDeg`: −90, the rig's knee pose at rotation 0.
For a custom setup instead of the bootstrap, add a `HexapodSimulation`
component to the scene yourself.
## What is not simulated
- Physics (mass, falling, slipping, servo torque and speed).
- Servo calibration. The sim decodes pulses with `Config.h`'s single
`SERVO_US_AT_0DEG` / `SERVO_US_PER_DEG`, i.e. what the firmware *intends*,
not per-servo offsets or directions.
- The remote firmware. `SimRemote.cs` mirrors its packet rules instead.