尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

电子设计大赛H题:车载平衡滚球控制系统架构与PID算法实现

电子设计大赛H题:车载平衡滚球控制系统架构与PID算法实现 如果你是一名参加过电子设计大赛的选手或者正在为2026年的比赛做准备那么这篇文章就是为你写的。全国大学生电子设计大赛的H题历来以“硬核”和“综合性强”著称它考察的从来不是单一的知识点而是将机械、电子、控制、算法乃至软件编程融为一体的系统工程能力。2026年H题《车载平衡滚球运动控制系统》这个题目一出来很多同学的第一反应可能是这听起来像是一个“平衡车滚球游戏”的缝合怪会不会很难我的判断是这道题的难点不在于某个技术点的深度而在于如何将多个成熟但松散的技术模块整合成一个稳定、可靠、能应对现场复杂干扰的完整系统。很多队伍会花大量时间在PID调参或者机械结构上却忽略了系统架构设计、通信稳定性和抗干扰策略导致在实验室跑得好好的小车一到比赛现场就“翻车”。本文将为你拆解这道赛题。我不会只告诉你“用STM32”、“写PID”那太浅了。我会从系统顶层设计开始带你一步步构建一个完整的解决方案。你将看到如何划分功能模块、如何选择核心传感器和执行器、如何设计稳定可靠的控制算法架构、如何编写健壮的嵌入式软件以及最重要的——如何在有限的备赛时间内高效地进行调试和排错。读完本文你将获得一个清晰的、可落地的实现蓝图避开那些新手队伍最容易踩的“坑”。1. 这道题到底在考什么系统视角下的需求拆解拿到题目不要急着画电路图或写代码。第一步永远是精确理解需求。我们基于“车载平衡滚球运动控制系统”这个标题结合电子设计大赛一贯的出题风格可以推断出以下几个核心考核点“车载”与运动平台意味着需要一个可移动的底盘小车。它需要具备基本的运动能力前进、后退、转向。这通常由直流电机或步进电机驱动轮子实现。“平衡”这是第一个控制核心。什么需要平衡题目是“平衡滚球”所以平衡的对象是球而不是车本身如两轮自平衡车。车体是执行平衡动作的平台。这意味着我们需要一个能让球在上面自由滚动同时车体可以通过运动来抵消球的滚动使其稳定在目标位置的平面平台。“滚球运动控制”这是第二个控制核心。不仅要把球稳住还要能控制球在平台上进行有规划的运动比如从A点滚到B点或者沿着特定轨迹如圆形、8字形运动。这需要平台能够产生精确的倾斜角度利用重力作为驱动力来控制球。“控制系统”这指明了实现方式——一个典型的闭环反馈控制系统。我们需要传感器如摄像头、红外阵列、陀螺仪来检测球的位置和平台姿态控制器如单片机处理数据并计算控制指令执行器电机驱动平台运动从而影响球的状态形成一个闭环。因此整个系统的核心控制目标可以归结为通过控制车载平台的倾斜角度和平面运动使平台上的滚球能够稳定在指定位置并能按指令进行轨迹运动。常见的误区是只关注“平衡”忽略了“运动控制”。一个只能把球稳定在中心点的系统只能拿到基础分。要实现高分必须完成复杂的轨迹跟踪任务。2. 系统总体架构设计从需求到模块一个稳健的架构是成功的一半。我们采用分层、模块化的思想来设计整个系统。[感知层] ———— [控制决策层] ———— [执行层] (传感器) (主控制器) (电机驱动) | | | 球位置检测 算法运算 平台运动 平台姿态检测 (PID/其他) (X/Y轴) | | | [摄像头/红外] [STM32等MCU] [直流电机驱动器]2.1 感知层方案选型眼睛和耳朵这是系统的“眼睛”决定了控制精度的上限。球位置检测方案一摄像头OpenMV/OpenCV推荐这是功能最强、最灵活的方案。一个摄像头可以同时完成球的位置检测、颜色识别、轨迹识别等。使用OpenMVMicroPython或STM32H7系列裸机OpenCV库可以实时解算出球的二维坐标 (x, y)。优点信息丰富可扩展性强如识别多个球、特定图案。缺点对光照敏感算法复杂度相对高需要一定的处理能力。方案二红外对管阵列在平台下方布置网格状的红外发射管和接收管通过检测哪些光束被球遮挡来判断球的位置。优点响应快不受光照影响电路简单。缺点分辨率低取决于管数只能获得离散的网格位置难以实现平滑的高精度控制。方案三电阻式/电容式触摸板类似手机触摸屏。优点精度高。缺点成本高易磨损不适合快速滚动的球。建议对于追求高完成度和性能的队伍首选摄像头方案。它虽然入门有门槛但一旦调通将是赛场上最有力的武器。平台姿态检测必须使用MPU6050六轴传感器或MPU9250九轴。它提供三轴加速度和三轴陀螺仪数据通过传感器融合算法如互补滤波、卡尔曼滤波可以解算出平台相对于水平面的俯仰角Pitch和横滚角Roll。这是控制平台倾斜角度的直接依据。2.2 控制决策层系统的大脑主控制器STM32F4系列如F407、F429或更高性能的H7系列是主流选择。F4系列拥有DSP指令集和FPU浮点运算单元能高效运行PID等控制算法。如果采用摄像头方案H7系列更佳。核心算法内环平台姿态平衡控制。以MPU6050测得的平台实际倾斜角为反馈以目标倾斜角为设定值通过一个PID控制器输出控制量驱动电机使平台快速、稳定地达到目标角度。这相当于让平台成为一个“敏捷的托盘”。外环球位置/轨迹控制。以摄像头识别的球坐标为反馈以期望的球坐标或轨迹为设定值。这个控制器的输出不是直接给电机而是作为内环PID的目标倾斜角。例如想让球向右移动外环控制器就计算出一个平台需要向右倾斜的目标角度然后交给内环去快速执行。这是一种经典的串级PID控制结构。外环负责“战略”球去哪内环负责“战术”平台怎么动。2.3 执行层手脚平台机械结构需要实现平台在X轴和Y轴两个方向的独立倾斜。常见方案有十字轴万向节结构平台中心通过一个十字轴万向节与车体连接X、Y方向各用一个电机通过连杆或钢丝牵引平台边缘实现双向倾斜。结构紧凑但可能存在耦合。双舵机/电机直接推动两个电机呈直角布置直接顶在平台底部通过控制伸长量来调整平台角度。控制直接但需要解决支撑和受力问题。四电机悬吊结构用四个电机分布在平台四角通过收放拉线来控制平台姿态。控制灵活但结构复杂。电机与驱动对于推动平台需要一定的扭矩。直流电机编码器减速箱配合TB6612或DRV8833电机驱动模块是可靠的选择。编码器用于闭环控制电机转速/位置提高平台角度控制的精度和刚度。车体移动为了完成更复杂的任务如带着球过障碍车体本身也需要移动。这由另外的轮子驱动电机负责与控制平台倾斜的电机系统独立。3. 硬件清单与核心电路设计要点以下是一个基于摄像头和十字轴结构的参考清单模块型号/类型数量说明主控STM32F407ZGT6 或 STM32H750VBT61F4性价比高H7适合图像处理视觉传感器OV7725 摄像头模块带FIFO1或直接使用OpenMV H7 Plus模块姿态传感器MPU60501核心姿态数据源电机直流减速电机带编码器42个用于车体移动2个用于平台倾斜电机驱动TB6612FNG 模块2每模块驱动2个电机电源12V锂电池组1为电机供电稳压模块LM2596降压1将12V降为5V/3.3V给控制部分平台结构亚克力板、十字万向节、连杆1套自制需保证灵活和平滑电路设计关键点电源隔离电机大电流和控制电路小电流的电源一定要用磁珠或0欧电阻隔离并在靠近芯片处加足够多的去耦电容104 10uF防止电机启停造成的电压波动导致单片机复位。编码器接口电机编码器输出接入单片机的定时器编码器模式这是最稳定高效的方式。I2C上拉MPU6050的I2C总线SCL, SDA必须接上拉电阻通常4.7kΩ。摄像头接口如果使用带FIFO的OV7725数据口接单片机普通IO通过读FIFO标志位进行数据采集。如果使用OpenMV则通过串口通信。4. 核心软件流程与算法实现我们以STM32 HAL库为例勾勒出主程序的骨架。4.1 系统初始化// main.c int main(void) { HAL_Init(); SystemClock_Config(); // 配置系统时钟尽可能高如F4到168MHz // 1. 初始化外设 MX_GPIO_Init(); MX_DMA_Init(); MX_I2C1_Init(); // 用于MPU6050 MX_USART1_UART_Init(); // 用于调试输出 MX_TIM2_Init(); // 定时器用于系统心跳和PID计算周期 MX_TIM3_Init(); // 编码器接口模式接平台X轴电机编码器 MX_TIM4_Init(); // 编码器接口模式接平台Y轴电机编码器 MX_TIM5_Init(); // PWM输出驱动平台倾斜电机 // ... 初始化其他TIM用于车体电机和PWM // 2. 初始化传感器 MPU6050_Init(); // 初始化并校准MPU6050 Camera_Init(); // 初始化摄像头模块 // 3. 初始化控制算法 PID_Init(pid_ball_x, 1.0, 0.05, 0.3); // 球位置X轴PID参数需调试 PID_Init(pid_ball_y, 1.0, 0.05, 0.3); // 球位置Y轴PID参数 PID_Init(pid_platform_pitch, 2.5, 0.1, 0.5); // 平台俯仰角PID PID_Init(pid_platform_roll, 2.5, 0.1, 0.5); // 平台横滚角PID // 4. 启动定时器中断以固定周期执行控制循环 HAL_TIM_Base_Start_IT(htim2); // 假设htim2配置为10ms中断 while (1) { // 主循环处理非实时任务如状态显示、指令接收 Process_UART_Command(); // 处理来自上位机或蓝牙的指令 Update_Display(); // 更新OLED显示状态 } }4.2 核心控制中断服务程序这是系统的“心跳”必须在固定周期如10ms内执行。// stm32f4xx_it.c 或 单独的定时器回调文件 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM2) { // 10ms定时器 // 1. 数据采集 Get_Ball_Position(ball_x, ball_y); // 从摄像头获取球坐标 MPU6050_Read_Angle(pitch, roll); // 读取融合后的平台角度 // 2. 外环控制球位置PID - 目标平台角度 if (control_mode BALL_POSITION_MODE) { target_pitch PID_Calculate(pid_ball_y, target_ball_y, ball_y); target_roll PID_Calculate(pid_ball_x, target_ball_x, ball_x); } else if (control_mode BALL_TRAJECTORY_MODE) { // 轨迹生成例如圆形轨迹 float time HAL_GetTick() / 1000.0f; target_ball_x center_x radius * cosf(omega * time); target_ball_y center_y radius * sinf(omega * time); // 再将目标位置输入PID target_pitch PID_Calculate(pid_ball_y, target_ball_y, ball_y); target_roll PID_Calculate(pid_ball_x, target_ball_x, ball_x); } // 3. 内环控制平台角度PID - 电机PWM float output_pitch PID_Calculate(pid_platform_pitch, target_pitch, pitch); float output_roll PID_Calculate(pid_platform_roll, target_roll, roll); // 4. 输出限幅和保护 output_pitch constrain(output_pitch, -MAX_PWM, MAX_PWM); output_roll constrain(output_roll, -MAX_PWM, MAX_PWM); // 5. 设置电机PWM Set_Platform_Motor_PWM(MOTOR_PITCH, output_pitch); Set_Platform_Motor_PWM(MOTOR_ROLL, output_roll); // 6. (可选) 车体移动控制独立于平台控制 if (control_mode CAR_MOVE_MODE) { // 控制车体电机完成移动任务 } } }4.3 PID控制器实现一个简单但实用的增量式PID实现// pid.c typedef struct { float kp, ki, kd; // PID参数 float integral; // 积分项 float prev_error; // 上一次误差 float output_max; // 输出限幅 float output_min; } PID_Controller; void PID_Init(PID_Controller *pid, float kp, float ki, float kd, float out_max, float out_min) { pid-kp kp; pid-ki ki; pid-kd kd; pid-integral 0.0f; pid-prev_error 0.0f; pid-output_max out_max; pid-output_min out_min; } float PID_Calculate(PID_Controller *pid, float setpoint, float measurement) { float error setpoint - measurement; pid-integral error; // 积分限幅防止积分饱和 if (pid-integral pid-output_max) pid-integral pid-output_max; if (pid-integral pid-output_min) pid-integral pid-output_min; float derivative error - pid-prev_error; pid-prev_error error; float output pid-kp * error pid-ki * pid-integral pid-kd * derivative; // 输出限幅 if (output pid-output_max) output pid-output_max; if (output pid-output_min) output pid-output_min; return output; }5. 视觉处理用OpenMV获取球坐标如果你选择OpenMV代码会简洁很多。OpenMV IDE使用MicroPython。# main.py - OpenMV Cam 球检测与坐标发送 import sensor, image, time, pyb from pid import PID # 初始化摄像头 sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) # 320x240 sensor.skip_frames(time 2000) sensor.set_auto_gain(False) # 必须关闭自动增益 sensor.set_auto_whitebal(False) # 必须关闭白平衡 # 初始化串口与STM32通信 uart pyb.UART(3, 115200) # 根据实际接线调整 # 定义颜色阈值根据小球颜色调整例如红色小球 red_threshold (30, 100, 15, 127, 15, 127) # (L Min, L Max, A Min, A Max, B Min, B Max) in LAB # 创建PID控制器如果需要OpenMV端做初步处理 # pitch_pid PID(p0.5, i0.05, d0.1) clock time.clock() while(True): clock.tick() img sensor.snapshot() # 寻找色块 blobs img.find_blobs([red_threshold], pixels_threshold100, area_threshold100, mergeTrue) if len(blobs) 0: # 找到最大的色块假设只有一个球 largest_blob max(blobs, keylambda b: b.pixels()) # 绘制矩形和十字 img.draw_rectangle(largest_blob.rect()) img.draw_cross(largest_blob.cx(), largest_blob.cy()) # 计算归一化坐标将图像中心设为(0,0) img_center_x sensor.width() // 2 img_center_y sensor.height() // 2 ball_x_norm (largest_blob.cx() - img_center_x) / img_center_x # 范围[-1, 1] ball_y_norm (largest_blob.cy() - img_center_y) / img_center_y # 范围[-1, 1] # 通过串口发送坐标数据格式如 BALL,0.12,-0.05\n uart.write(BALL,{:.3f},{:.3f}\n.format(ball_x_norm, ball_y_norm)) else: # 没找到球发送特定值 uart.write(BALL,999,999\n) # 可以在此处添加简单的PID计算并直接输出控制指令但更推荐在STM32端做 # output_x pitch_pid.get_pid(ball_x_norm, setpoint_x) # ... 然后通过PWM引脚输出 # 打印帧率 # print(clock.fps())在STM32端你需要编写一个串口解析程序来接收并解析BALL,x,y格式的数据将其转换为实际的球位置坐标。6. 调试与参数整定从零到稳定运行这是最耗时但也最关键的环节。务必遵循从内环到外环从静态到动态的原则。硬件与基础驱动调试确保每个电机能正反转编码器读数正常。确保MPU6050能读出稳定的角度数据静止时角度接近0晃动时响应灵敏。务必进行静止校准。确保摄像头能稳定输出图像并能在不同光照下识别小球。内环平台姿态环调试断开外环将目标角度target_pitch和target_roll设为固定值如0度。先调P比例。从小到大增加P直到平台能快速响应你的手动扳动并试图“抵抗”你的扳动但可能会在目标位置附近振荡。再调D微分。增加D可以抑制振荡让平台更快稳定下来。D太大可能引入高频抖动。最后调I积分。用于消除静态误差平台始终无法精确到达0度。I要小否则会引起超调或振荡。技巧用手轻轻推动平台观察它能否快速、平稳地回到水平位置。用上位机如SerialPlot实时绘制目标角度、实际角度和PWM输出波形能极大提升调试效率。外环球位置环调试内环调好后保持内环参数不变。将球放在平台上给外环一个固定的目标位置如中心点。同样遵循P - D - I的顺序调试外环PID。关键点外环的输出是内环的目标角度所以外环的输出幅度需要限幅例如不超过±10度防止平台倾斜过大导致球掉落。观察球能否稳定在目标点。如果球来回滚动停不下来可能是外环P太大或D太小如果球响应迟钝可能是P太小。轨迹跟踪调试在外环位置控制稳定的基础上改为轨迹模式。先从简单的直线运动开始再尝试圆形或8字形。调整轨迹生成的速度omega和幅度radius使其在系统能跟上的范围内。可能需要根据轨迹特性微调外环PID参数。7. 常见问题与排查清单问题现象可能原因排查方式解决方案平台剧烈振荡甚至抖动1. PID参数不当P太大D太小或太大2. 控制周期不稳定3. 电机响应延迟或机械间隙大1. 观察角度波形看是否等幅振荡P太大或高频抖动D太大2. 检查定时器中断是否被其他高优先级中断打断3. 用手感受电机和连杆是否有空程1. 重新整定PID优先保证内环稳定2. 确保控制中断优先级最高周期固定3. 优化机械结构减少间隙或软件上加入死区补偿球总是从平台边缘掉落1. 平台活动范围太小2. 外环控制响应太慢球速过快时来不及纠正3. 平台初始不平衡1. 测量平台最大倾斜角2. 观察球在偏离中心时平台是否及时反向倾斜3. 上电时校准平台水平零点1. 增大机械倾斜范围需考虑电机扭矩2. 提高外环P值或加入前馈控制预测球速3. 软件中增加零点校准功能摄像头识别不稳定坐标跳动1. 光照变化影响颜色阈值2. 小球反光或颜色不均匀3. 图像处理帧率低1. 在不同光线下测试观察阈值变化2. 更换小球材质或颜色3. 打印OpenMV的帧率1. 采用自适应阈值或HSV颜色空间更抗光照2. 使用哑光小球或增加多个颜色阈值3. 降低图像分辨率优化识别算法系统运行一段时间后失控1. 电源电压下降导致电机无力或单片机复位2. 传感器数据漂移如MPU6050温漂3. 软件内存泄漏或变量溢出1. 用万用表监测电池电压2. 观察角度数据长时间静置后的变化3. 检查堆栈使用是否有递归或大数组1. 使用电量充足的电池电源路径加粗2. 定期进行软件零漂校准如每10分钟一次3. 优化代码使用静态分配避免动态内存车体移动与平台控制互相干扰1. 车体加速/减速时惯性导致球在平台上滑动2. 控制耦合车体电机电流影响控制电路电源1. 观察车体启动瞬间球的状态2. 用示波器观察电源纹波1. 车体运动规划需平滑避免急起急停2. 加强电源隔离和滤波电机电源与控制电源分开8. 进阶优化与比赛加分项要想在比赛中脱颖而出满足基本功能后可以考虑以下优化状态估计与滤波对MPU6050的数据使用互补滤波或卡尔曼滤波能得到比官方DMP更稳定、延迟更低的姿态角。对摄像头获取的球坐标进行低通滤波或卡尔曼预测可以平滑数据甚至预测球未来位置实现更超前的控制。先进控制算法模糊PID根据球偏离中心的距离和速度动态调整PID参数在远处快速响应在中心附近精细调节。LQR线性二次型调节器如果能为系统建立精确的数学模型状态空间方程LQR能提供比PID更优的控制性能。这对理论扎实的队伍是很好的加分点。上位机监控与调试系统利用STM32的串口将关键数据球坐标、平台角度、PID输出、电机转速实时发送到电脑。使用Python的Matplotlib或SerialPlot等工具绘制实时曲线。这是调试的“神器”能让你直观看到系统内部状态。抗干扰与鲁棒性设计软件看门狗防止程序跑飞。传感器数据有效性检查例如如果摄像头连续多帧丢失目标系统应进入安全模式平台回平而不是失控。控制量平滑对PID输出进行斜坡处理避免电机突变。任务策略优化如果赛题包含多个子任务如稳球、运球过障、投篮设计一个状态机来清晰地在不同任务模式间切换。为车体移动规划最优路径节省时间。从系统架构设计到硬件选型从核心算法实现到细致入微的调试构建一个“车载平衡滚球运动控制系统”是一次对电子、控制、软件和机械知识的全面检验。它没有天书般的技术但每一个环节的疏忽都可能导致整体失败。建议队伍尽早确定方案留出至少三分之一的时间进行系统联调和稳定性测试。记住在比赛现场稳定压倒一切。一个能重复运行100次成功99次的系统远胜于一个性能惊艳但时好时坏的系统。希望这篇长文能为你提供一个坚实的起点祝你在2026年的全国大学生电子设计大赛中取得优异成绩。
返回列表