本人使用的设备/驱动:
使用stm32f103rct6,实现pid算法控制电机的转角
本文直接从项目中加入相关功能说起,环境以及其他外设配置:
使用ST-LINK utility将单片机中的程序下载下来
CubeMX配合PlatformIO开发STM32,配置环境,点亮LED灯
CubeMX配合PlatformIO开发STM32,配置usart实现串口通讯
CubeMX配合PlatformIO开发STM32,配置ADC实现电池电压检测
CubeMX配合PlatformIO开发STM32,配置MPU6050(I2C)
CubeMX配合PlatformIO开发STM32,配置双MPU6050(板载与外置),并使用gui显示数据
CubeMX配合PlatformIO开发STM32,通过系统时钟(systick)中断让不同功能代码以不同频率执行,计算计算所花时间
CubeMX配合PlatformIO开发STM32,实现pid算法控制电机的转角
CubeMX配合PlatformIO开发STM32,配置定时器,实现SPWM算法控制电机
CubeMX配合PlatformIO开发STM32,配置uart中断,配合python的gui在线调参
耳熟能详pid:
设计方便
不需要知道被控对象的传递函数
只需要调整参数,可以很好的控制很多的系统
在控制系统中,pid作为控制器,根据需求角度和实际角度的角度差,控制过程电机以一定速度转动,来跟随需求角度。
控制系统中其他部分:电机驱动SPWM(执行器),MPU6050获取实际角度(反馈)
因为main算法以200Hz的频率刷新,所以delta_t可以求出,I和D直接整合进I和D进行调整即可
#define cutoff_coefficent ((float)1/(2*MATH_PI*30.0f))
#define delta_t ((float)SYSTEM_PERIOD*0.001)
static float pitchPPara = 130.0;
static float pitchIPara = 1.0;
static float pitchDPara = 10.0;
static float rollPPara = 130.0;
static float rollIPara = 1.0;
static float rollDPara = 10.0;
static float yawPPara = 80.0;
static float yawIPara = 0.0;
static float yawDPara = 8.0;
float PID_Motor1(float actAngle, float expAngle) // return electric angular speed
{
static float expAngle_old = 0.0, et = 0.0, et_pre = 0.0, et_sum = 0.0, et_diff = 0.0,et_diff_last =0, dpid = 0.0;
static float dP = 0.0, dI = 0.0, dD = 0.0;
et = actAngle - expAngle; //error
dP = rollPPara * et; //
et_sum += et;
dI = rollIPara * et_sum;
et_diff_last=et_diff;
et_diff = et - et_pre;
// low-pass filter
et_diff = cutoff_coefficent / (cutoff_coefficent + delta_t) * et_diff_last + delta_t / (cutoff_coefficent + delta_t) * et_diff;
et_pre = et;
dD = rollDPara * et_diff;
dpid = dP + dI + dD;
return dpid;
}
在实验中发现信号的噪声会使D参数的波动较大,影响控制的性能,所以增加了一个低通滤波器。
其中,截止频率选择为30rad/s,因为通过建模,得出系统的wn大约是22rad/s