PID运算过程中出现的问题:
①6拨叉的拨弹电机旋转时,前5次顺时针转,第6次快速逆时针旋转
假设:fed = 0.9pi, set = rad_format(fed + pi/6) = rad_format(1.066666pi) = -0.93333pi,此时pid会计算出负值,反方向旋转
解决方法: pid->error[0] = rad_format(set - ref);
将err限制在-pi~pi,可避免第6次快速逆时针旋转的情况。
②robomaster的C板例程里面云台pid计算代码就是这样的逻辑,此时即可实现yaw轴360°旋转。
static fp32 gimbal_PID_calc(gimbal_PID_t *pid, fp32 get, fp32 set, fp32 error_delta) { fp32 err; if (pid == NULL) { return 0.0f; } pid->get = get; pid->set = set; err = set - get; pid->err = rad_format(err);//此处将err限制在-pi~pi pid->Pout = pid->kp * pid->err; pid->Iout += pid->ki * pid->err; pid->Dout = pid->kd * error_delta; abs_limit(&pid->Iout, pid->max_iout); pid->out = pid->Pout + pid->Iout + pid->Dout; abs_limit(&pid->out, pid->max_out); return pid->out; }
感触:①在完成shoot.c文件时,想出来将err限制的想法。
②在调试gimbal时,将max_relative_angle设置得很大,此时可以实现yaw轴360°旋转,且remote操纵下,正常运行。但没有注意是为什么
③而在寒假回家后看代码,发现如果set值++,会使set超出pi,而feedback一直在-pi~pi,此时应该会暴走。
④和刘老板讨论后,打算设置一个新变量 delta_angle,为实现一直旋转,让delta_angle作为pid计算的输入值,delta_angle=0.2,则每运行一次,即可增加0.2rad,避免了set值不停变大的情况。
如何改变代码:设置一个新变量 delta_angle;初始化该变量;设置控制值delta_angle=0.2;修改pid计算的代码。
唉,这个问题困扰了我好久啊!一直让我不想去调试。自己看代码不够仔细,当时没想明白为什么遥控器可以正常控制,导致之后走了这么多弯路,纠结了这么久。
都忘记当时shoot里面解决的经验了,还是对这个不敏感。
因为想不出来怎么解决,一直没有去解决,甚至没有去debug,今晚上看了一下,才发现问题这么简单,下次不能这么拖延症了!