用STM32F411和CLion从零搭建三轮全向小车:PID调参、VOFA+上位机调试全记录
用STM32F411和CLion从零搭建三轮全向小车PID调参、VOFA上位机调试全记录第一次接触全向轮机器人时我被它灵活的运动方式深深吸引——不同于传统轮式机器人它能实现任意方向的平移和旋转。这种独特的移动能力在狭小空间作业、仓储物流等领域有着巨大潜力。本文将详细记录我使用STM32F411CEU6开发板、CLion开发环境和VOFA调试工具从零构建三轮全向小车的完整过程。1. 硬件选型与基础环境搭建选择STM32F411CEU6作为主控芯片主要基于三点考虑首先它具备足够的定时器资源共11个定时器来同时控制三个电机其次72MHz的主频完全能满足实时控制需求最重要的是它支持硬件浮点运算单元FPU这对PID算法的实时计算至关重要。核心硬件清单电机带编码器的直流减速电机360线编码器减速比1:74.8驱动模块TB6612四路电机驱动全向轮直径70mm的塑料材质麦克纳姆轮姿态传感器IM600用于获取小车航向角电源3S锂电池11.1V2200mAh开发环境采用CLionSTM32CubeMX的组合。CLion提供了优秀的代码导航和自动补全功能而CubeMX则极大简化了外设配置过程。特别提醒在CubeMX中配置定时器时务必注意以下几点// PWM输出配置示例TIM2 Channel2 htim2.Instance TIM2; htim2.Init.Prescaler 71; // 72MHz/(711)1MHz htim2.Init.CounterMode TIM_COUNTERMODE_UP; htim2.Init.Period 9; // 1MHz/(91)100kHz htim2.Init.ClockDivision TIM_CLOCKDIVISION_DIV1;编码器接口配置更为关键需要设置为编码器模式// 编码器模式配置TIM1 sEncoderConfig.EncoderMode TIM_ENCODERMODE_TI12; sEncoderConfig.IC1Polarity TIM_ICPOLARITY_RISING; sEncoderConfig.IC1Selection TIM_ICSELECTION_DIRECTTI; sEncoderConfig.IC1Prescaler TIM_ICPSC_DIV1; sEncoderConfig.IC1Filter 0; // Channel2配置同理2. 电机速度环PID控制实战速度控制是底盘运动的基础。我采用增量式PID算法主要考虑到它对计算资源的占用较少且不易产生积分饱和问题。实际调试中发现几个关键点采样周期选择通过实验对比1ms的速度采样周期编码器读数配合10ms的控制周期取得了最佳效果。过短的采样周期会导致噪声放大而过长则会影响响应速度。死区处理当误差小于0.1rpm时直接归零避免电机抖动if(pid-err 0.1 pid-err -0.1) pid-err 0;积分限幅这是防止windup现象的关键if(pid-ki * pid-integral -pid-maxIntegral) pid-integral -pid-maxIntegral / pid-ki; else if(pid-ki * pid-integral pid-maxIntegral) pid-integral pid-maxIntegral / pid-ki;使用VOFA进行实时波形监控极大提升了调试效率。通过串口以FireWater协议发送数据printf(MOTOR:%.2f,%.2f,%d,%d\n, Target_Speed, motorA.speed, (short)(__HAL_TIM_GET_COUNTER(ENCODER1)), motorA.totalCount);PID参数调试经验先单独调P值直到出现明显振荡加入D项抑制振荡最后尝试加入少量I项消除静差实际测试发现本系统中I项会引入超调最终采用了PD控制3. 位置环与角度环的串级控制位置环作为外环输出作为速度环的目标值。这里采用全量式PID因为它能更好地处理阶跃响应。位置计算的关键是将编码器脉冲转换为角度angle_now motorA.totalCount / (4.0 * 74.8 * 360) * 360.0;角度环的实现有几个特殊处理角度归一化处理-180°到180°的跳变if(target-feedback 180){ feedback 360; }else if(target-feedback -180){ feedback - 360; }串级控制结构角度环输出 → 速度环目标值 → PWM输出航向角修正在小车移动过程中角度环的输出作为底盘解算的旋转分量输入实现运动过程中的航向保持。4. 三轮全向底盘运动学解算三轮全向底盘的运动学模型是项目中最精妙的部分。三个电机呈120°分布通过速度矢量合成实现全向移动。运动解算的核心公式void Kinematic_Analysis(float Vx, float Vy, float V_angle) { Target_Speed_C Vx L_PARAMETER*V_angle/(2*PI)*60; Target_Speed_A -0.5f*Vx 0.866f*Vy L_PARAMETER*V_angle/(2*PI)*60; Target_Speed_B -0.5f*Vx - 0.866f*Vy L_PARAMETER*V_angle/(2*PI)*60; }其中L_PARAMETER是轮子中心到机器人中心的距离0.117m。通过PS2手柄控制时将摇杆输入分解为X/Y方向速度case FORWARD: Kinematic_Analysis(0, Target_Speed, pid_angle.output); break; case LEFT: Kinematic_Analysis(-Target_Speed, 0, pid_angle.output); break;实际测试中发现当三个电机特性不一致时会出现运动偏差。解决方法是在代码中加入电机输出补偿系数// 在PWM输出函数中加入补偿 void MotorA_Run(float output) { __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_2, fabs(output) * 0.97); // A电机补偿系数 }5. 系统集成与调试技巧整个系统的定时器中断处理流程如下1ms读取三个编码器值并清零计数器计算各电机转速RPM每10ms执行一次PID计算根据控制模式旋转/移动选择控制策略输出PWM到电机驱动VOFA的高级用法使用控件发送PID参数进行实时调整创建多个波形窗口同时监控速度、位置、角度保存数据日志供后期分析一个特别实用的调试技巧当出现异常振动时可以先固定两个电机单独调试第三个电机的PID参数然后再进行整体调试。电源管理也是实战中的重要课题。发现当电池电压低于10V时电机控制会出现异常。最终解决方案是添加电压检测电路在代码中实现低压保护if(ADC_Value 2500) { // 约10V MotorA_Run(0); MotorB_Run(0); MotorC_Run(0); }6. 性能优化与扩展思考经过两周的调试小车最终实现了以下性能指标直线运动误差2cm/m旋转定位精度3°最大运动速度0.8m/s几个可能的改进方向加入运动轨迹规划实现平滑加减速添加红外或超声波传感器实现避障移植到ROS系统实现SLAM功能在底盘机械结构方面发现全向轮在粗糙地面表现不佳。后续考虑使用更大直径的轮子90mm并采用金属轮毂提高耐用性。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2465329.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!