This is an ESP32 firmware for a mobile base that can run in multiple hardware modes:
- UGV base only
- UGV + RoArm-M2 manipulator
- UGV + Pan/Tilt gimbal
Core runtime is in loop and command dispatch is in jsonCmdReceiveHandler.
pan_tilt_base_v0.9.ino- Includes all modules
- Initializes peripherals and subsystems in
setup() - Runs periodic behavior in
loop()
movtion_module.h: motor PWM, encoder speed reading, PID speed control, heartbeat stopgimbal_module.h: pan/tilt servo control, feedback, steady mode helpersRoArm-M2_module.h: arm kinematics, servo control, trajectory interpolation, torque/PID helpersIMU_ctrl.h,IMU.cpp,QMI8658.cpp,AK09918.cpp: IMU stack
uart_ctrl.h: JSON command parsing and switch-case dispatchjson_cmd.h: command IDs and protocol constantshttp_server.h: web API endpoint/jsweb_page.h: embedded HTML/CSS/JS control panelesp_now_ctrl.h: ESP-NOW command/flow integration
wifi_ctrl.h: AP/STA/AP+STA config and statusfiles_ctrl.h: LittleFS file operationsugv_advance.h: missions, feedback packaging, runtime settingsoled_ctrl.h,battery_ctrl.h,ugv_led_ctrl.h
ugv_config.h: global runtime config and shared statedata/wifiConfig.json,data/devConfig.json: persisted settings
From setup:
- Serial + I2C init
- Power/battery + OLED init
- IMU init
- LED + filesystem init
- Motor pin/PWM init via
movtionPinInit - Servo UART init + servo checks
- Wi-Fi init + HTTP server + ESP-NOW
- Encoder init + PID init
- Creates/plays boot mission (
boot)
From loop:
- Serial command input
- Web server client handling
- Module-specific update:
- arm mode: constant control + arm feedback
- gimbal mode: gimbal feedback + steady processing
- ESP-NOW deferred command handling
- Left/right speed read + PID compute (split compute)
- OLED update
- IMU update
- Base feedback flow via
baseInfoFeedback - Heartbeat timeout stop via
heartBeatCtrl
mainType(vehicle kinematics preset)moduleType(0 none, 1 arm, 2 gimbal) Defined inugv_config.h, set bymm_settings.
- Speed API:
setGoalSpeed - PID API:
pidControllerInit,Left/RightPidControllerCompute - Heartbeat safety:
heartBeatCtrl
- Direct commands:
gimbalCtrlSimple,gimbalCtrlMove,gimbalCtrlStop - User-shell mapping:
gimbalUserCtrlShellmaps differential speeds to pan/tilt directional commands
- Kinematics + path smoothing (
besselCtrl, IK/FK helpers) - Absolute/relative axis and joint control
- Mission integration through command queue/file steps
- Command IDs are centralized in
json_cmd.h - Parsing and dispatch in
jsonCmdReceiveHandler - Web panel examples are in
web_page.h
Notable command groups:
- Mobility:
T=1,11,13,138..140 - Gimbal:
T=133..137,141 - Arm:
T=101..123,+ - File/Mission:
T=200..231,241+ - System:
T=600..605,900
-
Global shared state is heavy
Most modules mutate globals fromugv_config.h. Keep side effects explicit. -
Command contract stability matters
Avoid changing existingTIDs injson_cmd.h; UI and external tools depend on them. -
Safety behavior exists but is distributed
- Heartbeat timeout stop in motion module
- Servo torque release controls in arm/gimbal paths
- Mission abort on serial activity
-
Web endpoint behavior
- HTTP endpoint implemented in
webCtrlServer - Frontend sends
GET /js?json=...inweb_page.h
- HTTP endpoint implemented in
-
Potential defects to verify
- Typo family:
movtionnaming is intentional in current codebase - In gimbal shell conditionals, comparisons like
abs(lSpd) == abs(lSpd)look suspicious (likely intended right-side variable) - HTTP response content type uses
"text/plane"(likely should be"text/plain")
- Typo family:
-
Read:
-
Then follow your feature path:
- Motion:
movtion_module.h - Gimbal:
gimbal_module.h - Arm:
RoArm-M2_module.h - Web/API:
http_server.h,web_page.h
- Motion:
-
Validate on hardware:
- No-motion boot
- Heartbeat stop
- Base feedback JSON shape
- Emergency stop path
- Normalize typo naming (
movtion->motion) only behind compatibility wrappers - Fix suspicious gimbal conditional comparisons
- Correct HTTP content-type typo
- Add lightweight command schema validation at dispatch
- Separate hardware abstraction from command parser for easier testing