轮足机器人
BipedBot
基于 ESP32 的轮足机器人,结合双足步态和轮式运动。使用 PID 控制实现自平衡,MPU6050 姿态检测,支持遥控与自主运动模式。
详解 · Deep Dive
项目详解
这个项目能带来什么、适合什么样的学生、又如何成为大学申请文书里的真实素材。
项目说明 · OVERVIEW
两轮自平衡机器人,全手工制作。耗时12天,从裸板焊接、平衡代码编写到PID调参全独立完成。支持手机蓝牙遥控前进后退,机身外壳自主设计3D打印。从不稳到站稳,完整经历了一个小型机电系统的诞生。
A two-wheeled self-balancing robot, built entirely by hand. Over 12 days — bare-board soldering, writing the balance code, PID tuning — every step done independently. It drives forward and back by phone Bluetooth, with a self-designed, 3D-printed shell. From wobbling to standing steady, the student lives the birth of a small electromechanical system end to end.
适合谁 · WHO IT'S FOR
电子/机械工程方向
· EE/ME-Inclined Builders如果你已经倾向于电子或机械工程方向,这个项目把两边的本事各交一段到你手上,并且要求它们在同一台机器里合在一起、自己站稳。电子侧是真刀真枪的控制:用 SimpleFOC 驱动 2808 无刷电机做磁场定向控制(FOC)、读编码器反馈、I2C 读取 MPU6050 六轴姿态,再调通直立环+速度环+转向环的串级 PID,让倒立摆真的不倒——这正是机器人、电机驱动、机电一体化最核心的反馈控制。机械侧用 Fusion 360 建模、PLA 打印底盘与轮足结构,让轮距、电机座、电池仓对得上、重心落到该落的位置。你手上已有的——焊过几个套件、写过几段 Arduino——是合理的起点而不是缺口:到第十二天,你带走的是一块能自己调试的板子、一组能重新整定的控制器、和一个能自己改版的外壳,全在同一台能自己站稳的整机里。而因为它一通电就拒绝倒下,电子与机械两半不再是各做各的实验,而是同一台会动的整机。
If you already lean toward electrical or mechanical engineering, this project hands you a genuine slice of each — and fuses them in one machine that has to keep itself upright. On the EE side you drive a 2808 BLDC motor with field-oriented control (SimpleFOC), read the encoder, talk to the MPU6050 over I2C, and tune a cascade PID (upright + speed + turn loops) until the inverted pendulum holds its balance — the kind of feedback-control work that sits at the heart of robotics, motor drives, and mechatronics. On the ME side you model the chassis and leg structures in Fusion 360 and print them in PLA, so that the wheelbase, motor mounts, and battery bay line up and the center of mass lands where the math said it should. You arrive with whatever you already know — a soldered kit, a few Arduino sketches — and that is a fair starting point, not a gap: by day twelve you leave with a board you can debug, a controller you can retune, and a frame you can redesign, all in the same self-balancing robot. And because it literally refuses to fall over the moment you power it on, the electronics and the mechanics stop being separate lab exercises and become one living machine.
想选工程、方向还没定的探索者
· Direction-Still-Exploring Students如果你确定要选工程,但具体往哪个细分方向走还没想清楚,这个项目是用十二天把几个主流方向一次性都摸一遍的好机会——而且它们都装在同一台能自己站稳的机器人里。在这台整机中你会同时碰到嵌入式固件(在 PlatformIO 里用 C++ 写 ESP32、I2C 读 MPU6050、PWM 驱动)、电机与控制理论(用 SimpleFOC 库对 2808 无刷电机做 FOC 磁场定向控制,再手调直立环+速度环+转向环的串级 PID)、物理建模(倒立摆的传递函数,搞懂它为什么不会倒)、无线通信(蓝牙/WiFi 遥控和握手指令协议)、以及数字化制造(Fusion 360 建模、PLA 3D 打印结构件)。每天最让你期待的那一块,就是下一步方向最诚实的信号;而不那么来电的部分,也已经变成了你身上的实打实技能。等到演示日,你不仅知道自己真正想往哪走,身后还有一台能两轮自平衡、听你手机指挥的整机——而不是一堆互不搭界的体验模块。
If you're set on engineering but haven't pinned down the specific direction yet, this project is an efficient way to sample several at once in twelve days — all inside one machine that holds itself up. Across the build you touch embedded firmware (C++ on the ESP32 in PlatformIO, reading the IMU over I2C, driving PWM), motor control and control theory (FOC field-oriented control on the 2808 BLDC with the SimpleFOC library, then a cascaded PID loop — upright / speed / turn — tuned by hand), physical modeling (the inverted-pendulum transfer function behind why it stays up), wireless comms (Bluetooth/WiFi remote control and a handshaking protocol), and digital fabrication (modeling parts in Fusion 360 and 3D-printing them in PLA). Whichever day you look forward to most is the most honest signal for your next step — and the parts that don't grab you are still skills you keep. By demo day you know where your interest actually points, and behind you stands a robot that balances on two wheels and obeys your phone — not a pile of disconnected taster modules.
有理论基础、缺动手经验
· Theory-Solid, Hands-On-New如果你的物理和数学底子不错——牛顿定律、矢量、一点微积分,可能还翻过控制理论的章节——但还很少把一台真正的设备从零一路做到通电、再让它靠自己站稳,这个项目正是为合上这道缝而设计的。课程从你已会的入手:PlatformIO 环境搭建、ESP32 的 GPIO 与 I2C、读 MPU6050 六轴原始数据是头几节课而非默认前提。再带你一步步往上走——PWM 驱动 2808 无刷电机、用 SimpleFOC 把磁场定向控制跑通、推导你在课堂里已有感觉的倒立摆传递函数、最后把串级 PID(直立环+速度环+转向环)调到机器人真的稳稳站住。整个过程是刻意搭好台阶的:你已经掌握的理论会稳稳托住你走向还没碰过的部分——焊线、接线、Fusion 360 建模、3D 打印结构件。当你亲手调的参数第一次让机器人自己站稳、手机蓝牙一推它就往前走的那一刻,那些方程就不再是纸上的了。
If you've done well in physics and math — Newton's laws, vectors, a bit of calculus, maybe a chapter on control systems — but you've rarely carried a real device all the way to power-on and stood it up on its own, this project is built to close exactly that gap. The curriculum meets you where you are: PlatformIO environment setup, ESP32 GPIO and I2C, and reading the MPU6050's raw six-axis data are the first few lessons, not assumed prerequisites. From there it climbs in deliberate steps — PWM driving the 2808 BLDC, bringing it up under SimpleFOC field-oriented control, deriving the inverted-pendulum transfer function you already sense from class, then tuning the cascaded PID (balance + speed + steering loops) until the robot actually holds its balance. The scaffolding is intentional: the theory you already command steadies you through the parts you don't — soldering, wiring, Fusion 360 modeling, 3D-printing the frame. Your equations stop being abstract the moment a gain you tuned yourself keeps the robot standing steady for the first time, and the phone in your hand drives it forward by Bluetooth.
申请季、缺一个大项目的同学
· Application-Season, Project-Seeking如果你一直把重心放在课业和学术上,到了申请季才发觉还缺一个有分量的项目来撑起文书,那这个项目正是让这份投入开始复利增长的地方。你已经练成的本事——精读、严谨推理、把一整套量化系统装进脑子——会直接迁移到 Day 4 推导倒立摆的传递函数、Day 6 整定串级 PID 的三个环(直立环、速度环、转向环)、读 MPU6050 的 I2C 寄存器表上。你带来的是真实的优势而非短板:只搭过套件的同学,很少能像你这样去追问"为什么速度环必须慢于直立环"。而因为这台整机是从 FOC 力矩控制、IMU 姿态融合、串级 PID,到蓝牙/WiFi 遥控、Fusion 360 建模与 3D 打印结构件一路打通的,十二天里你从空白的 PlatformIO 工程走到一台能自己站稳的机器人,写出来的会是一个有层次、有自己故事的原创项目——而不是一道通用练习题。等到演示日,你手里会有一台响应你调参、稳稳站住的轮足机器人,和一段具体、属于你、能在文书里讲得出细节的工程经历。
If you've poured yourself into coursework and now, entering application season, realize you're missing one substantial project to anchor your file, this is where that effort starts to compound. The strengths you've already trained — disciplined study, careful reasoning, holding a quantitative system in your head — transfer directly to deriving the inverted pendulum transfer function on Day 4, tuning the cascaded PID's three loops (balance, speed, steering) on Day 6, and reading the MPU6050's I2C register map. You arrive with a real edge, not a deficit: students who've only assembled kits rarely reason about why the speed loop must lag the balance loop the way you can. And because this build runs genuinely end-to-end — FOC torque control on the 2808 BLDC motors, IMU attitude fusion, cascaded PID, Bluetooth/WiFi teleoperation, Fusion 360 modeling and 3D-printed structural parts — over twelve days you go from an empty PlatformIO project to a robot that stands on its own, giving you a layered, original story rather than a generic exercise. By demo day you'll have a self-balancing robot that responded to your tuning, and a specific, personal engineering journey your application essays can speak to concretely.
文书方向 · ESSAY TAKEAWAYS
夏令营期间每个部分都会有基础了解;任意一个方向,只要你的申请方向在 CS / 工程相关,都可以延展为文书的主要收获。以下 8 个方向各自对得上项目里的具体知识点。
3D 打印结构件:Fusion 360 参数化建模与强度-重量-重心的工程取舍
3D-printed chassis: parametric modeling and the design trade-off between strength, weight, and center of gravity
项目对应 · IN THE PROJECT
Day 10 工作:获取并分析 StackForce 开源模型集(gitee.com/StackForce/bipedal_wheeled_robot,含 框架.stl、大腿1~4.stl、前/后小臂.stl、电机固定.stl、舵机接口.stl、轮毂.stl、电池架.stl、上盖.stl 等十余件),在 Fusion 360 中基于原始 STL 修改并定制零件——把电池仓改为适配本项目 3S 11.1V 锂电池包、把轮毂轴孔从 5mm 改为 8mm 以适配不同 BLDC 电机轴、为 ESP32 开发板设计带 2.5mm 内径固定柱与 USB 缺口的安装座;在 Cura 中按受力件(层高 0.15mm、壁厚 2.0mm、填充 30-50% 陀螺仪图案、树状支撑)与装饰件(0.20mm、1.2mm 壁厚、15-20% 填充)分别切片,PLA 打印后打磨试装、锉刀微调公差,最终装配到 StackForce 框架上。
Day 10 work: obtaining and analyzing the StackForce open-source model set (gitee.com/StackForce/bipedal_wheeled_robot, files including 框架.stl, 大腿1-4.stl, 前/后小臂.stl, 电机固定.stl, 舵机接口.stl, 轮毂.stl, 电池架.stl, 上盖.stl), then in Fusion 360 modifying and customizing parts — e.g. redesigning the battery holder to fit the project's 3S 11.1V lithium pack, adjusting wheel-hub bore from 5mm to 8mm to fit a different BLDC motor shaft, and designing an ESP32 dev-board mount with 2.5mm-ID mounting posts and a USB-port notch — slicing each part in Cura with differentiated settings (load-bearing parts: 0.15mm layer height, 2.0mm walls, 30-50% gyroid infill, tree supports; decorative covers: 0.20mm, 1.2mm walls, 15-20% infill) and printing in PLA, then hand-fitting and filing to tolerance before final assembly onto the StackForce frame.
知识点 · KNOWLEDGE
Fusion 360 参数化建模流程(草图→尺寸约束/几何约束→拉伸/旋转→倒角/圆角→导出 STL)、零件间装配公差设计(针对 FDM 收缩与螺丝配合预留 0.2-0.3mm 间隙)、Cura 切片参数控制(层高、壁厚线数、填充密度/图案、树状 vs 普通支撑、裙边/底座附着)、FDM 层附着与打印朝向取舍、针对倒立摆机器人的重心控制设计约束(电池下沉居中、IMU 靠近旋转轴、重型件对称布置)、强度与重量平衡(受力件壁厚≥3mm、非受力件 1.5-2mm、不含电池总重<500g)。
Parametric 3D modeling workflow in Fusion 360 (sketch → dimension/constraint → extrude/revolve → fillet/chamfer → STL export), part-to-part assembly tolerance design (0.2-0.3mm clearance for FDM shrinkage and screw fit), Cura slicer parameter control (layer height, wall count, infill density/pattern, tree vs. normal supports, brim/skirt adhesion), FDM layer-adhesion and print-orientation reasoning, center-of-gravity control as a design constraint specific to an inverted-pendulum robot (battery low and centered, IMU near the rotation axis, symmetric heavy-component layout), strength-to-weight balancing (load-bearing walls ≥3mm vs. non-load-bearing 1.5-2mm, target <500g excluding battery).
文书角度 · ESSAY ANGLE
用 PLA 打印并反复修改 StackForce 框架与电池仓/IMU 安装座,使最重的 3S 电池下沉到轮轴正下方、IMU 贴近俯仰轴,体现申请者理解自平衡机器人首先是机械问题:倒立摆的稳定裕度由零件几何与打印朝向决定,电机座壁厚、0.2-0.3mm 装配公差、受力件填充率都不是装饰,而是直接关系到控制器能否成立的工程取舍——这是把 CAD 闭环到可制造实物、并让结构与控制算法互相成就的能力。
Printing the robot's structural parts in PLA and iteratively modifying the StackForce frame so the 3S battery sits low and the MPU6050 mounts near the pitch axis shows the applicant understands that a self-balancing robot is a mechanical system first: the inverted-pendulum controller's margin of stability is set by part geometry and print orientation, and decisions like wall thickness on the motor mount or 0.2-0.3mm assembly tolerances are deliberate engineering trade-offs tied to the control problem, not styling choices.
ESP32 嵌入式固件与 PlatformIO/C++ 工具链:从板级配置到 10ms 控制循环
ESP32 firmware & the PlatformIO/C++ toolchain: from board config to a 10 ms control loop
项目对应 · IN THE PROJECT
Day 1 学员在 VSCode + PlatformIO 下用 C++ 编写第一个固件(Blink、SOS、呼吸灯)并跑通编译烧录链路;完整项目的 software/src 则展示了后续各模块要填入的结构:platformio.ini 声明 espressif32 平台、esp32dev 板型、Arduino 框架、lib_deps 拉取 ElectronicCats/MPU6050 + askuric/SimpleFOC + madhephaestus/ESP32Encoder 三库、-O2 编译优化、921600 上传波特率、115200 监视波特率;config.template.h 把每个外设映射到物理 GPIO——两路电机的 PWM(GPIO25/27)与方向(26/14)、编码器(32/33/4/16)、I2C SDA/SCL(21/22,MPU6050 地址 0x68)、电池 ADC(35);main.cpp 运行 setup()→loop()→10ms controlLoop() 三层骨架与四状态状态机(IDLE/BALANCING/REMOTE_CONTROL/FALLING),供后续 PID 代码填入。
Day 1 students set up the VSCode + PlatformIO toolchain and write their first C++ firmware (Blink, SOS, breathing-LED) in src/main.cpp for the ESP32, learning the platformio.ini that the full project later fills in (platform=espressif32, board=esp32dev, framework=arduino, lib_deps for MPU6050/SimpleFOC/ESP32Encoder, -O2 optimization, 921600-baud upload, 115200 monitor). The committed software/src then exposes the structure the rest of the project fills: config.template.h maps every peripheral to physical GPIO — PWM (25/27) and direction (26/14) for the two motors, encoders (32/33/4/16), I2C SDA/SCL (21/22) for the MPU6050 at 0x68, an ADC pin (35) for battery monitoring — and main.cpp runs a setup()->loop()->10 ms controlLoop() skeleton with a four-state machine (IDLE/BALANCING/REMOTE_CONTROL/FALLING) that the PID code drops into.
知识点 · KNOWLEDGE
PlatformIO 工具链(platformio.ini:platform=espressif32、board=esp32dev、framework=arduino、lib_deps 拉取 ElectronicCats/MPU6050 + askuric/SimpleFOC + madhephaestus/ESP32Encoder 三库、-O2 编译优化、921600 上传波特率 / 115200 监视波特率)、esp32dev 板型对应的 240MHz 双核 Xtensa MCU + 520KB SRAM + 片内 WiFi/BT、GPIO 复用与仅输入引脚约束(GPIO 34/35/36/39 不能做 PWM)、电机驱动的 PWM 频率/分辨率权衡(20kHz/8-bit)、I2C 总线与 MPU6050 @ 0x68 从机地址、ADC 分压电池监测、Arduino 框架的 setup()/loop() 结构、以及用 millis() 实现固定 10ms(100Hz)周期的定时控制循环。
PlatformIO toolchain (platformio.ini: platform=espressif32, board=esp32dev, framework=arduino, lib_deps pulling ElectronicCats/MPU6050 + askuric/SimpleFOC + madhephaestus/ESP32Encoder, -O2 build flags, 921600-baud upload / 115200 monitor), the dual-core Xtensa MCU @ 240 MHz with 520 KB SRAM and integrated WiFi/BT targeted by the esp32dev board, GPIO multiplexing and input-only pins (GPIO 34/35/36/39 cannot do PWM), PWM frequency/resolution trade-offs (20 kHz / 8-bit) for motor drive, I2C bus with MPU6050 @ 0x68, ADC battery monitoring via voltage divider, Arduino-framework setup()/loop() structure, and a timed control loop driven by millis() at a fixed 10 ms (100 Hz) period.
文书角度 · ESSAY ANGLE
在 PlatformIO(VSCode + platformio.ini 声明板型/框架/库依赖/编译优化)而非"一键编译"的 Arduino IDE 上用 C++ 写出机器人主固件 main.cpp,把每一个外设映射到 config.h 里具体的物理 GPIO 引脚,并搭建 setup()→loop()→10ms controlLoop() 三层结构与四状态状态机(IDLE/BALANCING/REMOTE_CONTROL/FALLING)骨架供后续 PID 代码填入,体现申请者已经在用大学课程级别的嵌入式开发流程——引脚分配、编译选项、实时循环周期都是有据可查的工程决策,而非被图形化 IDE 隐藏的默认值,这正是"提前使用大学级硬件/工具链"的可信证据。
Building the robot's main firmware in C++ on the PlatformIO toolchain (VSCode + platformio.ini pinning board/framework/lib_deps/-O2) rather than a click-to-compile IDE, mapping every peripheral to a physical GPIO in a config.h header, and writing a setup()->loop()->10 ms controlLoop() skeleton with a four-state state machine (IDLE/BALANCING/REMOTE_CONTROL/FALLING) that the later PID code drops into, shows the applicant already works at the university-course level of embedded development — making explicit, defensible engineering decisions about pin assignment, compile flags, and real-time loop timing that a beginner-friendly IDE keeps hidden.
FOC 磁场定向控制与 BLDC 驱动:从六步换向到矢量力矩
FOC field-oriented control & BLDC drive: from six-step commutation to vector torque
项目对应 · IN THE PROJECT
Day 2 学员经 StackForce Dual FOC 驱动板驱动两只带编码器的 2808 BLDC 电机:先用手转轴验证正交编码器 4 状态转换表与 4 倍频解码(11 线 → 44 计数/圈),再接 A/B/C 三相动力线,在 software/src/motor_control.cpp 中配置 ESP32 LEDC PWM(20kHz/8-bit、左电机通道 0、右电机通道 1)。已发布的 MotorControl 类通过 setSingleMotor() 闭合回路:施加 MOTOR_DEAD_ZONE=30 的死区补偿(低于此 PWM 电机不启动,故小指令被抬到死区边界)、并在 setSpeed() 中把右电机方向取反以抵消镜像安装。FOC 矢量闭环本身——BLDCMotor(7 极对) + BLDCDriver3PWM、motor.initFOC()/loopFOC() 让定子磁场与转子保持 90°——作为 Day 2 的进阶选做 SimpleFOC 练习教授(并在 MotorControl::initFOC() 中以预留桩形式留给学生扩展);该课解释了为何电机是一个由转子角度反馈支配的系统,而非黑箱。
On Day 2 students drive two 2808 BLDC motors with encoders via the StackForce Dual FOC driver board: first reading the quadrature encoder by hand to verify the 4-state transition table and 4x decoding (11 lines → 44 counts/rev), then wiring the A/B/C phase leads and configuring ESP32 LEDC PWM at 20 kHz/8-bit (left motor channel 0, right motor channel 1) in software/src/motor_control.cpp. The released MotorControl class closes the loop with setSingleMotor(), which applies a MOTOR_DEAD_ZONE=30 dead-zone compensation (motors stall below this PWM, so small commands are boosted to the dead-zone edge) and inverts the right motor's direction in setSpeed() to offset its mirrored mounting. The FOC vector loop itself — BLDCMotor(7 pole pairs) + BLDCDriver3PWM, motor.initFOC()/loopFOC() keeping the stator field at 90° to the rotor — is taught as the day-02 advanced/optional SimpleFOC exercise (and reserved as a stub in MotorControl::initFOC() for students to extend); the lesson explains why a motor is a rotor-angle-feedback system rather than a black box.
知识点 · KNOWLEDGE
BLDC 三相定子/转子结构与六步换向、FOC 磁场定向控制信号链(转子角度 → Clarke 变换 → Park 变换 → PI 电流控制 → 逆 Park → 逆 Clarke → SVPWM 三相输出)、定子磁场与转子磁场保持 90° 夹角以获最大力矩的原理、增量式正交编码器 A/B 相 90° 相位差解码与 4 倍频(11 线 → 44 计数/圈)、ESP32 LEDC PWM 通道/占空比/分辨率配置(左电机通道 0、右电机通道 1)、PWM 频率高于可听频段(20kHz)的取舍、电机死区非线性与补偿(MOTOR_DEAD_ZONE=30)、镜像安装的方向取反。
BLDC three-phase stator/rotor structure and six-step commutation, FOC field-oriented control signal chain (rotor angle → Clarke transform → Park transform → PI current control → inverse Park → inverse Clarke → SVPWM three-phase output), the 90° stator-rotor field angle for maximum torque, incremental quadrature encoder A/B-phase 90° phase-difference decoding and 4x quadrature multiplication (11-line → 44 counts/rev), ESP32 LEDC PWM channel/duty/resolution configuration (left motor ch0 / right motor ch1), PWM frequency above the audible band (20 kHz), motor dead-zone nonlinearity and compensation (MOTOR_DEAD_ZONE=30), mirrored-mounting direction inversion.
文书角度 · ESSAY ANGLE
把 2808 BLDC 驱动到"可控出力"而非"通电就转"——在 motor_control.cpp 里把 PWM 频率设到 20kHz 越过人耳听阈、在 setSingleMotor() 中施加 30 的死区补偿修正低占空比下电机不启动的非线性、并把右电机方向取反以抵消镜像安装——体现申请者把电机理解为一个机电系统,而非"给电压就转"的黑箱。Day 2 课程进一步把这一理解推进到 FOC 磁场定向控制:让定子磁场与转子保持 90° 夹角以获最大力矩(Clarke→Park→PI→逆 Park→SVPWM 信号链,由 SimpleFOC 的 initFOC()/loopFOC() 封装)——作为进阶选做练习,它解释了电机为何如此表现。其中的取舍(PWM 频率 vs. 开关损耗、死区 vs. 线性度、电压限制保安全)都是有意为之的工程决策,是电机控制工程的根基。
Driving the 2808 BLDC so it produces controllable torque rather than just spinning wild — setting 20 kHz PWM above the audible band, applying a 30-count dead-zone compensation in setSingleMotor() so the motor actually starts at low command instead of stalling, and inverting the right motor's direction to offset its mirrored mounting — shows the applicant understands a motor as a closed electromechanical system, not a black box that turns when you give it voltage. The day-02 lesson carries this further into FOC field-oriented control: keeping the stator field at 90° to the rotor (the maximum-torque angle) via the Clarke→Park→PI→inverse-Park→SVPWM chain that SimpleFOC's initFOC()/loopFOC() wraps — studied as the advanced/optional exercise that explains why the motor behaves the way it does. The trade-offs (PWM frequency vs. switching loss, dead-zone vs. linearity, voltage limit for safety) are deliberate engineering decisions, the foundation of motor control engineering.
传感器融合:用互补滤波把噪声满满的六轴 IMU 变成可信的倾角估计
Sensor fusion: turning a noisy 6-axis IMU into a trustworthy tilt estimate via the complementary filter
项目对应 · IN THE PROJECT
Day 3 在 software/src/imu.cpp 与 imu.h 中编写 IMU 模块:通过 I2C(SDA=GPIO21/SCL=GPIO22,400kHz)经 WHO_AM_I 寄存器(期望 0x68)校验 MPU6050 身份后用 PWR_MGMT_1 唤醒,从 0x3B 寄存器一次性突发读取 14 字节原始数据(6 加速度+2 温度+6 陀螺仪),减去静态平均校准零偏,用 atan2(ax, az) 从加速度计算倾斜角,再用互补滤波(config.h 中 COMPLEMENTARY_ALPHA=0.97,DLPF 带宽在 CONFIG 寄存器配置)融合陀螺仪积分,输出 getAngle()/getGyroY()/getGyroZ() 供 main.cpp 控制环中的直立环 P/D 项与转向环使用。
On Day 3, in software/src/imu.cpp + imu.h, the IMU module drives the MPU6050 6-axis sensor: it verifies the chip via the WHO_AM_I register (expecting 0x68) over I2C (SDA=GPIO21/SCL=GPIO22, 400kHz), wake via PWR_MGMT_1, burst-reads 14 bytes from register 0x3B (6 accel + 2 temp + 6 gyro), subtracts the gyroscope zero-bias from static-average calibration, computes the accelerometer tilt with atan2(ax, az), and fuses the two via the complementary filter (α=0.97 set as COMPLEMENTARY_ALPHA in config.h, with DLPF bandwidth configured in the CONFIG register). The resulting getAngle()/getGyroY()/getGyroZ() feed the upright loop's proportional/D terms and the steering loop in main.cpp's control loop.
知识点 · KNOWLEDGE
I2C 总线协议(START/ACK/STOP、7 位从机地址 0x68/0x69、重复起始条件下的 14 字节连续突发读)、MPU6050 寄存器映射(WHO_AM_I 身份校验、PWR_MGMT_1 唤醒、GYRO_CONFIG/ACCEL_CONFIG 量程、CONFIG 数字低通滤波器 DLPF、SMPLRT_DIV 采样率分频)、大端序高低字节拼成 int16_t、陀螺仪灵敏度换算(131/2^range LSB/(°/s));基于 atan2(ax, az) 的加速度计倾角解算(优于 arcsin,在 ±90° 附近不失敏)、陀螺仪积分漂移、互补滤波作为高通(陀螺仪)+低通(加速度计)的频域互补融合及系数 α 的物理含义;陀螺仪零偏的静态平均校准,以及与卡尔曼滤波(预测-修正、协方差驱动的卡尔曼增益)的对比。
I2C bus protocol (START/ACK/STOP, 7-bit slave addressing 0x68/0x69, repeated-start burst read of 14 bytes), MPU6050 register map (WHO_AM_I identity check, PWR_MGMT_1 wake, GYRO_CONFIG/ACCEL_CONFIG range, CONFIG DLPF, SMPLRT_DIV sample rate), big-endian high/low byte combination into int16_t, gyroscope sensitivity scaling (131/2^range LSB per °/s); accelerometer tilt via atan2(ax, az) (superior to arcsin near ±90°), gyroscope integration drift, complementary filter as high-pass(gyro)+low-pass(accel) fusion with coefficient α; gyroscope zero-bias calibration by static averaging, and the contrast with Kalman filtering (predict-correct, covariance-driven Kalman gain).
文书角度 · ESSAY ANGLE
把噪声大但长期指向重力的加速度计、与短期精确但积分漂移的陀螺仪,用互补滤波一行公式 α×(角度+角速度×dt)+(1−α)×加速度计角度融合成一个可信的倾斜角,是两轮机器人能"知道哪边是下"并据此站立的前提。在电机转动会污染加速度计读数的真实约束下,申请者从频域取舍(陀螺仪漂移 vs. 加速度计噪声)出发选定 α=0.97 与 DLPF 带宽,并说明为何 atan2 优于 arcsin(在 ±90° 附近不失敏)、为何固定比例互补滤波胜过任一单传感器。这体现的是"在正确的时间尺度上信任正确的传感器"这一工程判断力,是机器人状态估计的根基。
Fusing a noisy accelerometer (long-term-accurate but vibration-corrupted) with a drifting gyroscope (short-term-accurate but integration-error-accumulating) into a single trustworthy tilt estimate via the complementary filter formula α×(angle + gyro·dt) + (1−α)×accel_angle is what lets a two-wheeled robot know which way is "down" fast enough to stand. Facing the real constraint that motor vibration contaminates the accelerometer reading, the applicant reasoned from the frequency-domain trade-off (gyro drift vs. accel noise) to pick α=0.97 and the DLPF bandwidth, and explained why atan2 beats arcsin near ±90° and why a fixed-ratio complementary filter beats either sensor alone for this robot. This shows the engineering judgement of trusting the right sensor at the right time-scale, the foundation of robotics state estimation.
串级 PID:直立环+速度环+转向环三环嵌套与让机器人站稳的参数整定
Cascaded PID: nested balance/velocity/yaw loops and tuning a self-balancing robot to stand
项目对应 · IN THE PROJECT
Day 5-6 在 balance_controller 模块(software/src/balance.cpp、balance.h)中实现通用 PIDController 类与 BalanceController 三环控制器:速度环(PI)以(目标速度−平均轮速)为误差,输出"目标倾角"作为直立环的设定值;直立环(PD)以(目标角度−实测倾角)为误差,并把陀螺仪 Y 轴角速度直接当 D 项,输出基础 PWM;转向环(PID)输出左右差速,最终 leftPWM = basePWM − yawPWM、rightPWM = basePWM + yawPWM,全部钳位到 MOTOR_MAX_PWM。控制周期上,平衡环跑 200Hz、速度环跑 50Hz(约四倍慢,由 config.h 中 CONTROL_LOOP_PERIOD_MS 与 VELOCITY_LOOP_DIVIDER 设定)。三组增益(BALANCE_KP/KI/KD、VELOCITY_*、YAW_*)写在 config.h 里,靠 Ziegler-Nichols 与试凑在两轮 2808 BLDC 实车上反复调参直到机器人稳稳站立。
Day 5-6 work in the balance_controller module (software/src/balance.cpp / balance.h): implementing the generic PIDController class and the three-loop BalanceController. The velocity PI loop takes (targetVelocity − avgSpeed) and outputs a target lean angle; the upright PD loop takes (targetAngle − tilt) with gyroY fed in directly as the derivative term and outputs base PWM; the yaw PID loop outputs a left-right differential. Final leftPWM = basePWM − yawPWM, rightPWM = basePWM + yawPWM, all clamped to MOTOR_MAX_PWM. The balance loop is scheduled at 200 Hz and the velocity loop at 50 Hz (about 4x slower, set via CONTROL_LOOP_PERIOD_MS and VELOCITY_LOOP_DIVIDER in config.h). Gains (BALANCE_KP/KI/KD, VELOCITY_*, YAW_*) live in config.h and are tuned by hand (Ziegler-Nichols + trial-and-error) on the real robot until it stands on two 2808 BLDC wheels.
知识点 · KNOWLEDGE
串级控制架构(外环速度环输出角度补偿量作为内环直立环的目标角度,前倾则加速、后仰则减速)、各环作用与增益类型选择(直立环 PD、速度环 PI、转向环 PID)、Ziegler-Nichols 法与试凑法整定及"内环平衡环 200Hz、外环速度环 50Hz(约四倍快)"的整定原则、积分饱和与积分限幅(integralLimit = 0.5 × 输出上限)、微分测量替代(直接用陀螺仪角速度作 D 项,避免对噪声角度求导放大噪声)、输出/PWM 限幅、控制周期时序与设定值/扰动抑制的权衡。
Cascade control architecture (outer velocity loop's angle-offset output feeding the inner upright loop's setpoint, so leaning forward accelerates and leaning back brakes), per-loop role and gain type (upright PD, velocity PI, yaw PID), Ziegler-Nichols and trial-and-error tuning with the inner balance loop running at 200 Hz and the outer velocity loop at 50 Hz (about 4x faster, per the day-06 design), integral windup and clamping (integralLimit = 0.5 × outputMax), derivative-on-measurement (feeding gyroY directly as the D term to avoid amplifying angle noise), output and PWM saturation, control-cycle timing and the setpoint/disturbance trade-off.
文书角度 · ESSAY ANGLE
让一台两轮机器人稳稳站住,靠的不是单环 PID,而是把直立 PD 环嵌进速度 PI 环里——想要前进时,外环先让车身主动前倾,内环再去追这个倾斜角;并按"内环须快于外环"的级联原则逐环整定 Kp/Ki/Kd,让内环平衡环跑在 200Hz、外环速度环跑在 50Hz(约四倍快,因为速度变化没那么紧急),在积分饱和限幅(限到输出上限的一半)与用陀螺仪角速度替代噪声角度微分之间做取舍,体现申请者理解多环控制不是死记公式,而是按时间尺度分层、按信号质量选结构的工程判断,能把一个不稳定的欠驱动系统从模型一路推到能站住的真实增益。
Making a two-wheeled robot stand by nesting an upright PD loop inside a velocity PI loop so that wanting to move forward first makes the body lean (and only then do the wheels chase), and tuning each loop's gains by hand so the inner balance loop runs at 200 Hz while the outer velocity loop runs at 50 Hz — about four times faster, deliberately slower because speed changes are less urgent — with integral windup clamped to half the output ceiling and the D-term taken straight from the gyro rather than differentiated from a noisy angle, shows the applicant grasps that multi-loop control is about deliberate timescale separation and signal-conditioning trade-offs, not memorized formulas, and that they can reason an unstable, under-actuated plant from a model to working gains.
倒立摆建模:从力矩平衡到能预测"必倒"的传递函数
Inverted-pendulum modeling: from torque balance to a transfer function that predicts instability
项目对应 · IN THE PROJECT
Day 4 物理建模工作:把整车抽象成"小车+倒立摆"二自由度模型,用实测参数(轮子+电机等效质量 M ≈ 0.3 kg、车体质量 m ≈ 1.5 kg、质心到轮轴距离 L ≈ 0.08 m、轮半径 R ≈ 0.03 m)对车体列力矩平衡方程、对轮+车体列水平力平衡方程,做小角度线性化(sin θ ≈ θ),联立求解得到控制方程 θ̈ = a·θ - b·F(其中 a = (M+m)g/(ML)、b = 1/(ML));再写成状态空间 ẋ = Ax + Bu 形式,计算可控性矩阵 [B AB] 得出 det(C) = -b² ≠ 0(系统可控);最后用 Python odeint 跑"无控制自由倒下"与"PD 控制"两组仿真验证模型,得到的参数范围随后喂给 software/src/balance.cpp 里的串级 PID。
Day 4 modeling work: abstracting the self-balancing robot into a 2-DOF inverted-pendulum-on-a-cart with measured parameters (wheel+motor equivalent mass M ≈ 0.3 kg, body mass m ≈ 1.5 kg, center-of-mass-to-axle distance L ≈ 0.08 m, wheel radius R ≈ 0.03 m), writing the body's torque-balance and the wheel+body horizontal-force-balance equations, linearizing at small angle (sin θ ≈ θ), and deriving the control equation θ̈ = a·θ - b·F (a = (M+m)g/(ML), b = 1/(ML)); then writing it in state-space form ẋ = Ax + Bu, computing the controllability matrix [B AB] and concluding det(C) = -b² ≠ 0 (controllable); finally verifying with a Python odeint simulation (free-fall vs. PD-controlled) before the parameters carry over to the cascaded PID in software/src/balance.cpp.
知识点 · KNOWLEDGE
倒立摆运动方程推导(车体绕轮轴的力矩平衡 + 轮与车体整体的水平力平衡)、小角度线性化(sin θ ≈ θ、cos θ ≈ 1、忽略 θ̇²)、状态空间表示 ẋ = Ax + Bu(系统矩阵 A = [[0,1],[a,0]])、特征值与平衡点稳定性分析(λ = ±√a,正特征值即不稳定系统的数学标志)、传递函数 G(s) = -b/(s²-a) 及其右半平面极点、可控性矩阵 [B AB] 与 det(C) = -b² ≠ 0 ⇒ 存在状态反馈 u = -Kx 使系统稳定的结论、用 scipy.integrate.odeint 对微分方程组做数值积分以验证模型。
Inverted-pendulum equations of motion (body torque balance and wheel+body horizontal force balance), small-angle linearization (sin θ ≈ θ, cos θ ≈ 1), state-space representation ẋ = Ax + Bu with the system matrix A = [[0,1],[a,0]], eigenvalue/equilibrium stability analysis (λ = ±√a, the positive eigenvalue as the signature of an unstable system), transfer function G(s) = -b/(s²-a) and its right-half-plane pole, the controllability matrix [B AB] and the controllability conclusion det(C) = -b² ≠ 0 ⇒ a stabilizing state-feedback law u = -Kx exists, and scipy.integrate.odeint numerical integration of the ODE system for model verification.
文书角度 · ESSAY ANGLE
不是把机器人当作"不知怎么就站住了"的黑箱,而是对车体列力矩平衡方程、对轮+车体列水平力平衡方程,做小角度线性化后得到传递函数 G(s) = -b/(s²-a),用右半平面极点解释"不加控制必然倒下"这件事,再用 Python odeint 在 PD 控制下仿真观察不稳定极点被拉回稳定——体现申请者能在物理直觉、形式化动力学、数值仿真三端之间自由往返,更重要的是:能把一台正在倒下的机器人读懂成一个正特征值,而不是一个玄学故障。这正是"理解系统为什么这样行为"和"只知道它这样行为"之间的分水岭,是建模推导一路走到预测的能力。
Rather than treating the robot as a black box that "balances somehow," the student derives the inverted-pendulum equations of motion from a torque balance on the body and a horizontal-force balance on wheel-plus-body, linearizes with the small-angle approximation, and arrives at the transfer function G(s) = -b/(s²-a) whose right-half-plane pole is the mathematical reason an uncontrolled robot must fall — then runs a Python odeint simulation under PD control to watch the unstable pole get pulled back to stability. This shows the applicant can move between physical intuition, formal dynamics, and numerical verification in one breath, and — most importantly — can read a falling robot as the expression of a single positive eigenvalue rather than a mysterious failure. It is the kind of modeling-through-to-prediction that distinguishes a student who understands why a system behaves as it does from one who only knows that it does.
为轮足机器人设计遥控通信协议:从蓝牙到帧格式编解码
Designing a Binary Serial Protocol for Phone-Controlled Balance
项目对应 · IN THE PROJECT
Day 7 学员为 ESP32 自行设计一套二进制遥控通信协议(以 protocol.h / PacketParser / SimpleRemote.h 代码块形式写在 curriculum/day-07.md 中,由学员作为 Day-7 作业实现,并非 software/src/ 中预置的文件):帧格式为「0xAA 帧头 + 命令字节 + 长度字节 + 变长数据 + 1 字节 XOR 校验和」,定义 CMD_SPEED/CMD_TURN/CMD_MODE/CMD_PID_PARAMS/CMD_HEARTBEAT/CMD_TELEMETRY 等命令,并实现逐字节 PacketParser 状态机解析器。速度/转向等 float 值用 floatToBytes 编码为 2 字节(×100 定点、低/高字节拆分);SimpleRemote 文本命令路径(F/B/L/R/S/X,V:value/T:value)作为更简单的备选。实际 software/src/main.cpp 接好了安全侧:定义 STATE_REMOTE_CONTROL 及全局 remoteVelocity/remoteYawRate/lastRemoteTime,config.template.h 中 REMOTE_TIMEOUT_MS=500 让控制循环在 500ms 内收不到指令时清零 remoteVelocity/remoteYawRate 并切换到 STATE_BALANCING。传输走 ESP32 内置蓝牙 Classic SPP(main.cpp setup 注释段的 SerialBT.begin(BT_DEVICE_NAME="BipedalBot"),及 day-07 的 BluetoothSerial 示例)与手机蓝牙串口终端通信;config.template.h 另留 WiFi AP 模式(WIFI_SSID="BipedalBot_AP"、WIFI_CONTROL_PORT=8888)作为备选链路,并为 iOS 提供 BLE 简化版。
In Day 7 the student designs a custom binary remote-control protocol on the ESP32 (taught as inline protocol.h / PacketParser / SimpleRemote.h code blocks in curriculum/day-07.md, which the student implements as the Day-7 assignment — they are not pre-shipped files in software/src/): a frame format of 0xAA header + command byte + length byte + variable payload + 1-byte XOR checksum, with commands CMD_SPEED/CMD_TURN/CMD_MODE/CMD_PID_PARAMS/CMD_HEARTBEAT/CMD_TELEMETRY, implemented via a byte-at-a-time PacketParser state machine. The float speed/turn values are encoded into 2 bytes (floatToBytes: ×100 fixed-point, low/high byte split); a SimpleRemote text-command path (F/B/L/R/S/X, V:value/T:value) is provided as a simpler fallback. The shipped software/src/main.cpp wires the safety half: it defines STATE_REMOTE_CONTROL with global remoteVelocity/remoteYawRate/lastRemoteTime, and config.template.h's REMOTE_TIMEOUT_MS=500 makes the control loop auto-zero remoteVelocity/remoteYawRate and transition to STATE_BALANCING if no command arrives within 500 ms. Transport uses ESP32 Bluetooth Classic SPP (SerialBT.begin(BT_DEVICE_NAME="BipedalBot"), shown in the main.cpp setup comment block and the day-07 BluetoothSerial example) with a phone Bluetooth serial terminal; config.template.h also exposes WiFi AP mode (WIFI_SSID="BipedalBot_AP", WIFI_CONTROL_PORT=8888) as an alternate transport, and a BLE simplified path is provided for iOS.
知识点 · KNOWLEDGE
蓝牙 Classic(SPP 串口协议)与 BLE 的取舍(数据率/延迟/iOS 支持——iOS 不支持 SPP 故提供 BLE 简化版),ESP32 BluetoothSerial 库基于 SPP;二进制帧协议设计(固定帧头 0xAA + 命令字节 + 长度字节 + 变长数据 + 1 字节 XOR 校验和)、命令集(CMD_SPEED/CMD_TURN/CMD_MODE/CMD_PID_PARAMS/CMD_HEARTBEAT/CMD_TELEMETRY 及 CMD_STATUS)、帧定界与校验失败重同步(解析器 reset);逐字节状态机解析器(WAIT_HEADER→WAIT_CMD→WAIT_LENGTH→WAIT_DATA→WAIT_CHECKSUM)与 SimpleRemote 文本行解析路径的对比;float 定点编码(×100 缩放为 int16,拆低/高字节)以在窄带宽链路传输浮点;XOR 校验的错误检测能力与 CRC 的差异;心跳包与遥测下行;接收端安全超时(config.template.h 中 REMOTE_TIMEOUT_MS=500)——链路丢失即清零 remoteVelocity/remoteYawRate、退回自平衡模式。
Bluetooth Classic SPP vs BLE trade-offs (data rate, latency, iOS support — iOS lacks SPP so a BLE fallback is provided), ESP32 BluetoothSerial library built on the SPP profile; binary frame protocol design (fixed 0xAA header + command byte + length byte + variable-length payload + 1-byte XOR checksum), command set (CMD_SPEED/CMD_TURN/CMD_MODE/CMD_PID_PARAMS/CMD_HEARTBEAT/CMD_TELEMETRY, plus CMD_STATUS), frame delimiting and re-sync on checksum failure (parser reset); byte-at-a-time state-machine parser (WAIT_HEADER→WAIT_CMD→WAIT_LENGTH→WAIT_DATA→WAIT_CHECKSUM) versus the text-line parser used in the SimpleRemote fallback path; float-to-fixed-point encoding (scale ×100, int16 little-endian split into low/high bytes) to compress floats for narrow-band links; XOR checksum error detection and its limitations versus CRC; heartbeat/telemetry for liveness; receiver-side safety timeout (REMOTE_TIMEOUT_MS=500 in config.template.h) that zeroes remoteVelocity/remoteYawRate and falls back to self-balance on link loss.
文书角度 · ESSAY ANGLE
申请者没有把"手机遥控"当成发个字符就跑的练习,而是从零设计一条链路层通信契约:自定义 0xAA 帧头+长度+XOR 校验的二进制帧、逐字节推进的状态机解析器、float×100 的定点编码、以及 500ms 收不到指令即超时退回自平衡的安全兜底,并通过 ESP32 蓝牙 Classic SPP 与手机蓝牙串口终端完成收发验证。这体现的不是"会用蓝牙库",而是能在不可靠无线信道上设计一条"带校验、带超时、带状态机"的可信指令通道,并把协议规范、编解码、故障安全做成可验证的闭环——文书可据此呈现申请者对"系统间通信"的工程严谨度与安全思维,而非泛泛的"做了一个遥控"。
Instead of treating the phone link as a magic "send a character" exercise, the applicant designs a real binary link-layer protocol — fixed 0xAA header, length field, XOR checksum, a byte-at-a-time state-machine parser, float-scaled-to-int16 encoding, and a 500 ms command-timeout that auto-drops the robot out of remote mode back into self-balance — then validates it over ESP32 Bluetooth Classic SPP with a phone serial terminal. This reframes the work as the applicant engineering a link-layer contract from scratch: defining a frame grammar with a header that resists mis-synchronization, hardening it with a timeout safety fallback, and shipping a verifiable encode/decode round-trip — exactly the protocol-design and safety-thinking rigor a CS/EE program looks for, grounded in this project's concrete bytes rather than a generic tutorial.
轮足混合运动:用状态机守卫轮式与足式模式的安全切换
Wheeled-legged hybrid modes: a guarded state machine for wheel/leg/hybrid switching
项目对应 · IN THE PROJECT
Day 9 选做挑战(作业中标注为选做/加分项——核心 MVP 是平衡站立+蓝牙遥控):定义 MotionMode 枚举(MODE_WHEEL / MODE_LEG / MODE_HYBRID / MODE_TRANSITION)与 switchToWheelMode / switchToLegMode / switchToHybridMode 三个切换函数,用 canSwitchMode() 守卫切换安全(轮→足要求 currentSpeed<0.1,足→轮要求 isLegsStanding() 腿部回到中位 ±5°),并用 7 帧的 gaitSequence[] 步态表(站立→左抬→左伸→站立→右抬→右伸→站立)驱动 4 个腿部舵机,再由 handleRemoteCommand() 解析蓝牙 'W'/'L'/'H' 指令从手机端选择模式。Day 9 课内示例用 ESP32Servo 在 GPIO25/26/27/14 驱动 SG90 舵机;整车装配硬件则经 PCA9685 I2C 舵机驱动板接 MG996R 舵机。
Day 9 stretch challenge (marked optional/bonus in the assignments — the core MVP is balance-standing + Bluetooth remote): defining the MotionMode enum (MODE_WHEEL / MODE_LEG / MODE_HYBRID / MODE_TRANSITION) and the switchToWheelMode/switchToLegMode/switchToHybridMode handlers, with the canSwitchMode() guard (wheel→leg requires currentSpeed < 0.1; leg→wheel requires isLegsStanding() within ±5°), plus the 7-pose gaitSequence[] table (stand → left-lift → left-extend → stand → right-lift → right-extend → stand) for four leg servos, and the Bluetooth 'W'/'L'/'H' command dispatch in handleRemoteCommand() that selects the mode from a phone. The Day-9 lesson drives the servos via ESP32Servo on GPIO25/26/27/14 (SG90 in the example); the assembled robot's hardware instead routes the four leg servos (MG996R) through a PCA9685 I2C driver board.
知识点 · KNOWLEDGE
有限状态机模式仲裁(MotionMode 枚举、currentMode/targetMode、MODE_TRANSITION 过渡态)、带安全前置条件的受保护切换(canSwitchMode() 校验速度<0.1、腿部 isLegsStanding()±5°)、按序编排的切换动作序列(减速停车→禁用平衡PID→腿部站立,或收腿→启用平衡PID)、离散步态关键帧姿态表(GaitPose 数组 {hipL,kneeL,hipR,kneeR} 依次经历支撑/抬腿/前伸/落地相位)、50Hz 舵机 PWM 信号(500–2500µs 脉宽→0–180°,Day 9 课内用 ESP32Servo 在 GPIO25/26/27/14 演示;整车硬件经 I2C 地址 0x40 的 PCA9685 驱动板接 MG996R 舵机走同一组四通道)、混合模式下 BLDC 平衡环与舵机步态环的执行器仲裁。
Finite-state machine mode arbitration (MotionMode enum, currentMode/targetMode, MODE_TRANSITION transitional state), guarded transitions with safety preconditions (canSwitchMode() checking currentSpeed < 0.1 and isLegsStanding() ±5°), sequential transition choreography (decelerate wheels → disable balance PID → stand up legs, or retract legs → enable balance PID), discrete gait-cycle pose tables (GaitPose arrays of {hipL, kneeL, hipR, kneeR} stepping through support/lift/extend/strike phases), servo PWM signaling at 50Hz with 500–2500µs pulse → 0–180° (taught via ESP32Servo on GPIO25/26/27/14 in the Day-9 lesson; the production hardware routes the same four channels through a PCA9685 I2C driver at 0x40 with MG996R servos), actuator arbitration between the BLDC balance loop and the servo gait loop in hybrid mode.
文书角度 · ESSAY ANGLE
在 Day 9 选做的轮足模式切换挑战里,申请者设计了一个显式的 MotionMode 状态机,并用 canSwitchMode() 守卫把"轮→足切换必须先减速到接近零、足→轮切换必须先收回腿部到 ±5° 站立位"写成硬约束,使任何一次远程按键都不能让机器人带着速度强行进入步态而倾倒。因为这是在核心 MVP(平衡站立+蓝牙遥控)之外自选的加分项,它更说明申请者愿意超出大纲要求,把一个混合系统拆成多个安全可独立验证的模式,而非一锅端的大循环——这种"先证明安全再允许切换"的工程纪律,正是自动驾驶从巡航模式切到低速泊车模式时同样要解决的守护式状态切换问题。
Taking on the optional Day-9 stretch challenge of wheel/leg mode-switching, the applicant designed an explicit MotionMode state machine whose canSwitchMode() guard refuses a wheel-to-leg transition until wheel speed drops below 0.1 and a leg-to-wheel transition until isLegsStanding() confirms the four leg servos are within ±5° of center — so a premature Bluetooth tap can't topple the robot mid-gait. Because this was a self-elected bonus (not the core balance+remote MVP), it shows the applicant reaching past the syllabus to partition a hybrid system into safe, individually-verifiable modes rather than monolithic control, treating "don't let it fall over" as a guarded-state-transition problem — the same discipline that lets a self-driving stack move between highway-cruise and low-speed-maneuver regimes without an unsafe handoff.
技能
你将学到什么
硬件
- ESP32 开发
- FOC 电机控制
- IMU 姿态解算
- 模块化接线
软件
- C++ (PlatformIO)
- PID 算法
- FOC 控制
- 遥控协议
系统
- 运动控制
- 状态机
- 通信架构
工程
- 机械设计
- 系统调试
- 文档撰写
- 项目演示
硬件
所需材料
ESP32 开发板
双核 + WiFi+BT
MPU6050
六轴 IMU
2808 BLDC
无刷电机 ×2
StackForce Dual
FOC 驱动板
3D 打印结构件
PLA
日程
项目时间线
嵌入式基础
ESP32 入门、PWM 输出、IMU 读取
电机与平衡控制
FOC 控制、PID 调参、平衡控制
系统集成与展示
结构组装、系统调试、项目展示
资源
开源参考
本项目基于以下开源项目改编 · Adapted from the open-source project below