
1. 项目缘起当“太空梦”遇上“桌面级”挑战几年前当我第一次看到SpaceX的猎鹰9号火箭拖着尾焰稳稳地垂直降落在海上驳船上时那种震撼感至今难忘。它彻底颠覆了人们对火箭“一次性消耗品”的认知将科幻场景变成了工程现实。作为一个模型火箭爱好者兼硬件折腾者一个念头就冒了出来能不能在桌面上用最易得的材料复现这种“垂直起降”VTVL的核心魅力不是简单的遥控而是实现一定程度的自主控制完成从发射、悬停到精准着陆的全过程。这个想法听起来有点疯狂毕竟SpaceX背后是无数工程师、超级计算机和巨额资金。但工程的美妙之处就在于核心原理是相通的只是规模和精度不同。我们的目标不是把卫星送入轨道而是让一个自制的小玩意儿在几米高的空中完成一次优雅的“鞠躬谢幕”。这其中的挑战恰恰是乐趣所在你需要理解姿态动力学、传感器融合、控制算法并用极其有限的预算和算力去实现它。于是“模型火箭完成类似SpaceX的垂直着陆”就成了我这个长期业余项目的核心。而“迷你纸板自动售货机”则是另一个完全不同的、关于机械结构与趣味交互的创意项目它展示了如何用最简单的材料纸板和基础电子元件舵机、传感器构建一个完整的自动化系统。这两个项目看似风马牛不相及但内核都是“用低成本实现高概念的自动化工程”。本文将主要深入拆解第一个项目——自主着陆模型火箭——的完整实现路径从核心原理、硬件选型、算法实现到实地测试的坑与经验。而纸板售货机我会在最后作为一个思维拓展简要分享其设计精髓你会发现很多底层逻辑是共通的。2. 核心原理拆解SpaceX着陆的“桌面平替”是什么要复现垂直着陆首先得抛开那些复杂的流体力学和材料科学抓住最本质的控制问题如何让一个不稳定的倒立摆系统在三维空间中自主保持平衡并移动到指定位置对于猎鹰9号它依靠的是格栅舵进行气动控制、冷气或燃气舵进行推力矢量控制以及多个发动机的深度节流能力。我们的模型火箭这一切都需要做“桌面级”的简化。2.1 姿态感知火箭的“内耳”和“眼睛”火箭要知道自己“歪没歪”靠的是惯性测量单元IMU。IMU通常包含三轴加速度计和三轴陀螺仪。加速度计测量的是比力包括重力加速度和运动加速度。在静止或匀速运动时它可以用来估算姿态角俯仰、横滚但一旦火箭发动机点火产生巨大加速度它的读数就会严重失真这就是所谓的“加速度计对运动敏感”。陀螺仪测量的是角速度通过对角速度积分可以得到角度变化。它的优点是不受线性运动影响但缺点是存在漂移误差积分时间一长角度误差会累积得非常大。所以单一传感器都不靠谱。这就需要传感器融合算法最经典且适合嵌入式系统的就是互补滤波或卡尔曼滤波。简单来说互补滤波的思想就是用陀螺仪的高频响应快速变化和加速度计的低频响应长期稳定进行互补。在代码层面你可以理解为一个加权平均估算角度 α * (上一刻角度 陀螺仪增量) (1 - α) * 加速度计计算出的角度其中α是一个介于0和1之间的系数需要根据传感器噪声和动态特性调试。卡尔曼滤波则更优它通过预测和更新两个步骤动态估计最优状态但实现和调参更复杂。对于入门从互补滤波开始是更稳妥的选择。2.2 姿态控制火箭的“小脑”知道姿态角后如何纠正对于模型火箭推力矢量控制TVC是最接近真实火箭的方案。这意味着我们需要一个万向节机构让发动机喷管可以小幅度偏转。当火箭向左倾斜时控制喷管向右偏产生的侧向推力分量就会产生一个纠正力矩把火箭“推”回竖直状态。这里就引出了PID控制算法它是自动控制领域的基石。PID是比例P、积分I、微分D的缩写。比例项P当前姿态误差目标角度 - 当前角度乘以一个系数。误差越大纠正力越大。但纯P控制会产生振荡永远在目标值附近来回晃。积分项I累积历史误差之和。用来消除静态误差比如有持续侧风时纯P无法完全回正。但I项太强会导致系统反应迟钝甚至失控。微分项D当前误差的变化率。它像一个阻尼器能预测误差的变化趋势抑制振荡让系统更平稳。在火箭TVC控制中我们通常用一个PID控制器来计算喷管需要偏转的角度。这个角度指令再发送给驱动万向节的舵机。调试PID参数Kp Ki Kd是整个项目中最“玄学”也最关键的环节后面会详细讲踩坑过程。2.3 位置控制火箭的“大脑”光保持直立不够我们还要让它能悬停和移动。这就需要在姿态环外面再套一个位置环。位置环的输入是目标位置比如悬停高度2米和当前位置由超声波或激光测距模块获得输出是目标姿态角或目标推力。例如想让火箭上升位置环发现当前高度低于目标高度它就会计算出一个“需要增加推力”或“需要稍微前倾以产生水平速度再转换”的指令。这个指令传递给姿态环姿态环再通过PID控制TVC让火箭实现这个姿态。这是一个典型的串级PID控制结构外环位置输出是内环姿态的目标。对于桌面级模型我们通常简化只做高度控制通过调节发动机推力如果支持节流或采用“脉冲”点火模式点火-熄火-点火来实现悬停。水平位置控制则可以通过让火箭保持一个微小的倾角产生水平推力分量来实现但这需要更复杂的导航算法如光流传感器和更安全的空间初期不建议尝试。3. 硬件选型与搭建在成本与性能间走钢丝硬件是梦想落地的基石。我的核心原则是在保证功能可实现的前提下选择最轻、最便宜、社区支持最好的部件。3.1 主控单元飞行电脑的选择备选方案1Arduino系列如Arduino Nano Pro Mini。优点是简单易用生态丰富价格低廉20-50元。缺点是性能有限缺乏硬件浮点运算单元运行复杂的滤波和控制算法比较吃力而且通常只有一个硬件串口连接多个传感器时可能需要软件模拟会引入时序问题。备选方案2STM32系列如STM32F103C8T6即“蓝色药丸”。这是更专业的选择。32位ARM Cortex-M内核主频更高72MHz有硬件浮点某些型号外设丰富多个硬件串口和定时器。价格与高端Arduino相当20-40元但需要一定的嵌入式开发基础使用STM32CubeIDE或PlatformIO进行开发。备选方案3ESP32。它集成了Wi-Fi和蓝牙对于后期数据遥测和地面站控制非常方便。双核处理器性能也足够。但它的功耗相对较高且针脚布局可能不如专为控制设计的芯片方便。我的选择与理由我最终选择了STM32F405基于STM32F4系列的一款芯片。原因如下性能充足Cortex-M4内核带硬件FPU168MHz主频运行卡尔曼滤波和双环PID游刃有余。外设专业多达多个定时器可以输出高精度PWM控制舵机多个USART和I2C/SPI接口连接传感器毫无压力。社区与生态有丰富的开源飞控项目如Betaflight iNav参考其硬件抽象层HAL库使得开发相对规范。成本可控核心板价格在60-80元左右虽然比F103贵但为了稳定的飞行控制这笔投资值得。3.2 传感器套件感知世界的窗口IMUMPU6050是绝对的首选。它集成了3轴加速度计和3轴陀螺仪价格仅10元左右通过I2C通信有海量的开源驱动和滤波代码。对于更高要求可以选MPU9250多了磁力计或BMI088性能更优但MPU6050对于入门和中级项目完全够用。气压计用于测量高度变化。BMP280或MS5611是常见选择。它们非常灵敏可以感知厘米级的高度变化但容易受发动机喷流和风扰影响适合在平稳阶段使用。价格在15-25元。测距模块用于低空尤其是着陆阶段的精准高度测量。超声波传感器HC-SR04便宜10元但波束角大容易受地面材质和形状影响且测量频率较低。激光测距模块VL53L0X精度高毫米级波束角小响应快但价格较贵40-60元且在强光下可能受影响。着陆阶段精度至关重要我强烈推荐使用VL53L0X。定位模块可选如果想实现自主返航或定点悬停需要GPS如BN-880但民用GPS精度在米级对于桌面火箭来说误差太大初期可以不考虑。3.3 执行机构动力与姿态的执行者发动机这是最大的挑战。业余固体燃料发动机如Estes无法节流或重复点火。因此可节流的液体或气体发动机几乎是唯一选择。我使用的是小型过氧化氢催化分解发动机或压缩冷气如CO2发动机。前者推力大但燃料制备有风险后者安全、可控通过一个高速比例电磁阀来控制推力但推力相对较小。安全警告任何自制发动机实验必须在专业指导、安全场地和防护下进行推力矢量控制TVC舵机这是实现姿态控制的核心。需要大扭矩、高速度、金属齿轮的舵机因为要抵抗发动机的振动和惯性。我选用的是DS3218MG或MG996R这类舵机扭矩在15-20kg·cm以上。需要两个分别控制俯仰和横滚轴。将它们正交安装在一个万向节机构上万向节中心固定发动机。万向节机构可以用3D打印PLA材料强度需验证或激光切割亚克力制作。设计要点是重心尽可能低发动机在上舵机在下活动范围适中±5-10度足够结构刚性要强避免在高频振动下产生形变谐振。3.4 电源与结构电源控制系统主控、传感器、舵机和推进系统电磁阀、点火器必须分开供电舵机在动作瞬间电流可达2-3A会对数字电路造成严重电压波动。我使用一块2S或3S锂聚合物电池7.4V或11.1V经过一个5V/3A的降压稳压模块给控制系统供电推进系统的电磁阀则直接由另一块电池驱动。箭体结构为了减重箭体可以用轻木、碳纤维管或甚至高强度PVC管制作。重心CG和压力中心CP的位置关系是静稳定性的关键。对于垂直着陆的火箭我们希望它是静不稳定的CP在CG之前这样才需要主动控制来保持稳定。这可以通过将发动机和重型电池置于箭体底部来降低CG实现。4. 软件架构与核心算法实现硬件是躯体软件是灵魂。整个控制程序遵循一个严格的定时循环例如500Hz每2毫秒执行一次。4.1 主循环设计void main_loop() { while(1) { uint32_t loop_start_time get_current_time_us(); // 1. 传感器数据读取 read_imu_data(); // 读取MPU6050原始数据 read_barometer(); // 读取气压高度 read_lidar(); // 读取激光高度仅在低空启用 // 2. 传感器数据处理与融合 estimate_attitude(); // 执行互补滤波或卡尔曼滤波得到当前俯仰、横滚角 estimate_altitude(); // 融合气压计和激光数据得到最优高度估计 // 3. 飞行状态机判断 switch(flight_state) { case LAUNCH: // 发射段开环全推力 break; case BOOST: // 加速段 break; case COAST: // 惯性滑行段 break; case LANDING: // 着陆段启动位置和姿态闭环控制 // 4. 位置环PID计算外环 target_pitch position_pid_calculate(target_altitude, current_altitude); target_roll 0; // 假设只控制俯仰进行前后移动 // 5. 姿态环PID计算内环 servo_pitch_angle attitude_pid_calculate(target_pitch, current_pitch); servo_roll_angle attitude_pid_calculate(target_roll, current_roll); break; } // 6. 执行器输出 set_servo_angle(servo_pitch_angle, servo_roll_angle); set_throttle_valve(calculated_throttle); // 控制推力 // 7. 数据记录与遥测通过串口发送到电脑地面站 send_telemetry_data(); // 严格定时延迟确保控制频率稳定 delay_until(loop_start_time 2000); // 延迟到2000微秒后500Hz } }4.2 PID参数调试的血泪史这是整个项目最磨人的部分。参数不对火箭要么反应迟钝像醉汉要么剧烈振荡直接散架。我的调试步骤与心得先姿态后位置永远先在地面测试架上调好姿态PID确保火箭能快速、平稳地跟随你的手动倾斜而反向摆动再考虑飞行和位置控制。先P后D再IP比例从一个小值开始如0.5慢慢增大直到火箭能对误差做出明显反应但开始出现小幅振荡。此时的值记为P_oscillate。D微分引入D项来抑制振荡。从P_oscillate的1/10左右开始增加D值振荡会逐渐平息。D值太大会导致系统对噪声敏感产生高频抖动。I积分最后加I。在静态测试时如用手给火箭一个持续的侧向力观察它能否慢慢修正到竖直。I值非常小通常只有P值的百分之一到千分之一。I项是双刃剑尤其在动态飞行中积分饱和会导致失控必须设置积分限幅。地面测试架至关重要用万向节把火箭挂在空中使其可以自由俯仰和横滚。这样可以在绝对安全的情况下调试PID。千万不可直接上箭调试数据记录是眼睛一定要通过串口实时将姿态角、PID输出等数据发送到电脑用Python的Matplotlib或串口绘图工具显示。看着曲线调参数比盲目猜测高效一万倍。着陆阶段的特殊处理在接近地面时比如高度1米需要切换PID参数或引入非线性。例如减小P值以防止“过冲”砸地或者引入一个基于高度的阻尼系数。5. 测试、失败与迭代从“跳跳乐”到“稳如老狗”我的第一次“飞行”测试与其说是飞行不如说是“爆炸式的跳跃”。火箭点火后不是直冲云霄而是像喝醉了一样剧烈左右摇摆然后横着拍在地上。复盘问题振动是头号杀手发动机的振动会严重污染IMU数据导致滤波算法失效。解决方案硬件上用硅胶减震垫将IMU与箭体隔离软件上在滤波前对陀螺仪和加速度计数据进行低通滤波截止频率设置在30-50Hz以滤除发动机的高频振动。重心计算错误最初的设计重心太高导致火箭本身静稳定性太强TVC舵机扭矩不足以快速纠正。重新布局内部设备将电池等重物尽可能下移。PID参数过于激进地面静态测试良好但一旦有真实推力系统惯性变大原来的D值不足导致振荡发散。必须在模拟有推力的条件下重新调试PID可以在测试架上悬挂配重来模拟。传感器延时超声波传感器测距有近百毫秒的延迟在快速下降阶段这个延迟是致命的。切换到VL53L0X激光传感器后延迟降到毫秒级着陆稳定性大幅提升。经过无数次迭代——修改结构、调整滤波参数、重调PID、改进供电——火箭终于能够离地并在1.5米左右的高度实现短暂的、摇晃的悬停。那一刻的成就感无以言表。最终版本它已经可以完成从发射到约3米高度然后关机、再点火、缓慢降落的完整循环着陆精度可以控制在直径20厘米的圆盘内。6. 思维拓展从火箭着陆到纸板售货机回过头看“迷你纸板自动售货机”虽然一个上天一个入地但工程思维是相通的需求定义售货机要识别硬币、选择商品、推出商品。对应火箭的感知、决策、执行。传感器售货机用硬币识别传感器光电或电感式和按钮相当于火箭的IMU和测距。控制器一个Arduino Nano足矣处理逻辑判断。执行器舵机控制推杆推出商品步进电机控制旋转货架。状态机程序逻辑同样是“投币 - 选择 - 出货 - 复位”的状态机。用纸板这种零成本材料构建主体结构考验的是机械设计和空间利用能力。如何用最少的舵机通过巧妙的连杆和滑槽机构实现多个货物的推出这其中的简化和优化思想和我们在火箭上拼命减重、优化控制算法如出一辙。7. 给后来者的终极建议如果你想启动类似的项目这是我的肺腑之言安全第一永远第一特别是涉及燃料、高压气体和高速运动部件的项目。在专业场地测试穿戴护具从最小推力开始。仿真先行在烧钱焊板子之前先用MATLAB/Simulink或Python用scipy和matplotlib搭建一个火箭动力学和控制系统模型。这能帮你快速验证控制算法的可行性并初步整定PID参数节省大量时间和物资。分而治之逐步集成不要想着一口吃成胖子。先让IMU数据稳定输出再让舵机在测试架上平稳响应姿态指令然后上推力测试最后整合高度控制。每一个环节都单独测试到可靠。拥抱失败记录数据每一次失败都是最宝贵的数据。拍下视频记录下所有传感器数据仔细分析是哪个环节出了问题。没有这些“黑匣子”数据调试就是盲人摸象。社区是你的后盾开源硬件社区有无数先驱。参考Ardupilot、PX4等开源飞控的代码结构在GitHub上搜索“TVCRocket”、“VTOL”等关键词你会找到很多有价值的项目和讨论。这个项目没有终点。我现在的目标是为它加上简单的光流定位实现小范围内的自主平移或者尝试更高效的推进剂。它就像一个微缩的工程宇宙每一次代码的提交每一次硬件的调整都让你离那个优雅着陆的梦想更近一步。而当你亲手打造的“小猎鹰”第一次颤颤巍巍却坚定地悬停在空中时你会明白这一切的折腾都值了。