由于双电机的PID上升曲线难以完全重合,造成左右电机速度不一致。本文为了解决该问题设计了一种方法。
主要思想是将不同速度对应的PWM占空比曲线拟合出来,减1000(总10000)占空比后作为预设值给PID,然后在预设值的基础上调左右电机的PID。这样控制的时候,左右电机在不同速度下都只需要PID控制1000的区域。具体步骤分为三步:
第二步:将拟合后的曲线插入模型中,在预设值基础上调前进后退的PID
1. 在simulink中插入拟合后的曲线;
2. 在拟合曲线的基础上调PID参数,让两条曲线尽量靠近。(上图是累积误差,下图是两个电机的速度曲线)
3. 在simulink中调试成功后,将需要代码的内容,放在一个模块中,打包代码,生成.c文件。
(1)模型中将所有需要打包的部分,放在Motor的模块(自己起任意的名字)中。
(2)点击打包代码
(3)一路next,下面两页需要配置
System页中,需要选择Subsystem,如果你有多个模块,需要自己选择。
Word Size页中,需要选择自己单片机的型号,我的是STM32
(4)获取生成的代码,融入keil工程中。
生成的代码一般在matlab根目录下,xxx_ert_rtw的文件夹中,需要xxx.c、xxx.h、rtwtypes.h。
第三步:将打包的算法融入到keil工程中
(1)将xxx.c导入到工程中,头文件包含进来。
(2) 将参数输入,运行算法,获取输出结果。
// PID control
rtU.In1 = enc0_signed; // 左电机速度(100ms内编码器感应次数)
rtU.In2 = enc1_signed; // 右电机速度
rtU.In3 = pwr0; // 左电机目标速度
rtU.In4 = pwr1; // 右电机目标速度
rtU.In5 = servo_duty; // 舵机旋转角度
rtU.In6 = TIME_INTERVAL; // 运行间隔,100ms/20ms,自己定义
Motor_step(); // PID调整
pwr0 = rtY.Out1; // 输出左电机PWM
pwr1 = rtY.Out2; // 输出右电机PWM
servo_pwm = rtY.Out3; // 输出舵机PWM