Skip to content

Balance bot: ESP32 PID balance controller with BLE dashboard#3

Open
JaredBaileyDuke wants to merge 5 commits into
mainfrom
balance-bot
Open

Balance bot: ESP32 PID balance controller with BLE dashboard#3
JaredBaileyDuke wants to merge 5 commits into
mainfrom
balance-bot

Conversation

@JaredBaileyDuke
Copy link
Copy Markdown
Collaborator

@JaredBaileyDuke JaredBaileyDuke commented May 12, 2026

Summary

  • packages/pid — standalone ESP-IDF PID component with anti-windup clamping and integral reset
  • packages/sensors — MPU6050 I2C driver; filter selected at build time via Kconfig
  • packages/complementary — standalone complementary filter (comp_filter_t); stack-allocated, zero tuning required
  • packages/kalman — 2-state C++ Kalman filter (angle + gyro-bias estimation), with C wrapper API; lower phase lag and online bias correction vs complementary
  • firmwarebalance.c 100 Hz FreeRTOS balance controller (Core 1); compile-time gated by CONFIG_BALANCE_BOT_ENABLED; 4 new BLE GATT characteristics (BALANCE_CMD, BALANCE_PID, BALANCE_STATE, BALANCE_TARGET); goto is a Phase-1 stub pending cv branch merge
  • protocol — 4 new UUIDs (da6–da9), regenerated across uuids.js, uuids.h, uuids.py
  • dashboardbalance-bot capability: joypad (lean + turn), live PID inputs, I-dump dropdown, goto section

Filter selection

idf.py menuconfigIMU filter

Filter Kconfig symbol Tuning params
Complementary (default) BALANCE_BOT_IMU_FILTER_COMPLEMENTARY Alpha ×100 (default 98 = 0.98)
Kalman BALANCE_BOT_IMU_FILTER_KALMAN Q_angle, Q_bias, R_measure (each ×1000)

Both packages are always linked; imu.c selects between them with #if. Dead code is eliminated at link time. balance.c is unaffected — it calls imu_update() / imu_pitch_deg() regardless of which filter is active.

Test plan

  • Build with CONFIG_BALANCE_BOT_ENABLED=y, complementary filter — confirm no errors
  • Build with Kalman filter selected — confirm no errors
  • Build without CONFIG_BALANCE_BOT_ENABLED — confirm existing motor builds unaffected
  • Flash and verify IMU init log shows correct filter name (complementary or kalman)
  • Connect dashboard, verify joypad writes BALANCE_CMD and BALANCE_STATE notifies live pitch
  • Tune Kp/Ki/Kd via PID inputs; confirm writes round-trip through BALANCE_PID notify
  • Verify 2 s command timeout snaps lean/turn to 0 on BLE disconnect
  • Switch to Kalman via menuconfig and compare pitch noise vs complementary on real hardware

TODO (Phase 2)

  • Goto controller (needs cv branch merged for cvPosition)
  • IMU calibration (gyro bias subtraction on startup)
  • Pin balance-bot cap section to default-open

🤖 Generated with Claude Code

- packages/pid: standalone ESP-IDF component (generic PID with anti-windup)
- packages/sensors: standalone ESP-IDF component (MPU6050 complementary filter)
- firmware: balance.c/h, Kconfig.projbuild, 4 new BLE GATT characteristics
  (BALANCE_CMD, BALANCE_PID, BALANCE_STATE, BALANCE_TARGET); compile-time
  gated by CONFIG_BALANCE_BOT_ENABLED; goto is a Phase-1 stub pending cv merge
- dashboard: balance-bot capability (joypad, PID inputs, I-dump select, goto)
- protocol: 4 new UUIDs (da6–da9), regenerated uuids.js/uuids.h/uuids.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@JaredBaileyDuke JaredBaileyDuke self-assigned this May 12, 2026
JaredBaileyDuke and others added 3 commits May 11, 2026 21:44
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AngleFilter class (kalman.hpp): predict/update with online bias estimation,
  drop-in upgrade over complementary filter with same inputs (gyro rate + accel angle)
- C wrapper API (kalman.h): kalman_angle_create/update/get/reset/destroy for use from .c files
- Registered in firmware EXTRA_COMPONENT_DIRS; add REQUIRES kalman to any component that needs it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- packages/complementary: standalone comp_filter_t with init/update/angle API
- packages/sensors/Kconfig: BALANCE_BOT_IMU_FILTER choice (complementary default);
  alpha x100 for complementary; Q_angle/Q_bias/R_measure x1000 for Kalman
- imu.c: delegates filtering to whichever package Kconfig selects; both packages
  always linked, dead code eliminated at link time
- firmware CMakeLists: adds packages/complementary to EXTRA_COMPONENT_DIRS

Select filter via: idf.py menuconfig -> IMU filter

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Picks up motor calibration orientation, ESP32 camera lifecycle (camera_ready
→ camera_present), overhead ArUco helper relocation, and other main-line
changes since the branch's base.

Resolved:
- README.md: kept main's compact code-block layout and added the new
  packages/ entry that documents pid + sensors + filters.
- fw_info.c: kept the new #endif from balance-bot's #if CONFIG_BALANCE_BOT
  guard and adopted main's camera_ready → camera_present rename.
- uuids generated files: regenerated to fix Windows-1252 encoded em-dash
  in the file banners (gen-uuids drift).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants