四轮电磁------速度环增量式PID
这是我的第一次书写博客,仅代表我个人看法,若有问题希望各位大佬不吝赐教!!!
我们最近正在准备智能车四轮电磁的校内赛,我采用的是英飞凌的TC264
单片机,使用的软件是AURIXTM Development Studio
。以下是我在近日对速度环的一些学习。
例程学习+硬件测试
正式开始做一个项目,首先,我们学会使用这个软件和例程。例程是商家提供给我们学习测试硬件的一个代码,我们需要的是学会看,并且可以举一反三;与此同时,我们需要使用例程测试我们的硬件是否完好。在完全掌握和硬件测试之后,我们才能正式开始写代码。
速度环增量式PID
在博客里,介绍增量式的已经很多了,作为一只小菜熊,我就浅浅的把我的代码放出来请各位大佬指正指正。
PID
结构体
typedef struct
{
float actualValue;//真实值
float set_point;//期望值
float K_p;
float K_i;
float K_d;
float sum_error;//本次error
float last_error;//上一次error
float last_2_error;//上两次error
}Pid;
设置PID
参数
void setPIDParam(Pid* pid,float set_point,float p,float i,float d)//设置PID参数,
{
pid->set_point=set_point;
pid->K_p = p;
pid->K_i = i;
pid->K_d = d;
}
速度环PID
/****************************
* 增量式pid
* 控制电机
* {
* 本次误差 = 目标值-实际值
* P输出 =Kp (本次误差-上次误差)
* I输出 = Ki本次误差
* D输出 =Kd (本次误差-2*上次误差+上上次误差)
* ID输出 += P输出+I输出+D输出
* 上上次误差=上次误差
* 上次误差 = 本次误差
* }
***************************/
int32 speed_pid_ctrl(Pid *PID,int value)
{
if(value<0)
{
value=-value;
i=0;
}
else i=1;
PID->sum_error=PID->set_point-value; /*本次误差*/
PID->actualValue += (PID->K_p * (PID->sum_error - PID->last_error)) /* 比例*/
+ (PID->K_i * PID->sum_error) /* 积分 */
+ (PID->K_d * (PID->sum_error - 2 * PID->last_error + PID->last_2_error)); /* 微分 */
PID->last_2_error = PID->last_error; /*储存偏差 */
PID->last_error = PID->sum_error;
if(PID->actualValue<2000)
PID->actualValue=2000;
if(PID->actualValue>6000)
PID->actualValue=6000;
if(i==1)
return ((int32)(PID->actualValue)); /* 返回数值 */
else
return ((int32)(-PID->actualValue));
}
PID
在主函数的设置
setPIDParam(&speed_left_pid,230,13,1.4,0);//左轮pid
setPIDParam(&speed_right_pid,230,13,1.4,0);//右轮pid
以上,便是我在写pid的一个简单过程,希望能够对初学者有一点帮助。
当然,如果有遗漏的地方,欢迎各位大佬指正。
过程中的简单问题
1.AURIXTM Development Studio这个软件对代码的要求很高:变量定义类型不同,会产生warning;全局若出现两个相同的变量名词,会产生error等等,遇到了很多不同的代码问题(这里想说一下,并不是所以的软件都需要之这样的要求,还是因软件而异)。
2.在这个过程中,我还遇到了一个硬件问题:我们对电机的控制是通过两个引脚(DIR和PWM)加上GND控制。
其中:
21.2 21.4 控制PWM
21.3 21.5 控制DIR
但是,控制方向的21.5引脚口,不能使用我在长达4个小时的寻找问题和思考如何解决问题后,我使用了如下代码来控制电机转动。
#define MOTOR1_A ATOM0_CH0_P21_2 //定义1电机正转PWM引脚
#define MOTOR1_B ATOM0_CH1_P21_3 //控制电机方向DIR引脚
#define MOTOR2_A ATOM0_CH2_P21_4 //定义2电机正转PWM引脚
/************************
* Motor_Ctrl(pwm1,pwm2)
* pwm1:控制左电机(pwm1>0,向前;pwm1<0,向后)
* pwm2:控制右电机(pwm2>0,向前;pwm2<0,向后)
* *********************/
*
void Motor_Ctrl(sint32 pwm1,sint32 pwm2)
{
if (pwm1 > 0)
{
pwm_duty(MOTOR1_A,pwm1);
gpio_init(MOTOR1_B, GPO, 0, PUSHPULL);
}
else
{
pwm_duty(MOTOR1_A,0-pwm1);
gpio_init(MOTOR1_B, GPO, 1, PUSHPULL);
}
if (pwm2 > 0)
{
pwm_duty(MOTOR2_A,pwm2);
gpio_init(MOTOR1_B, GPO, 0, PUSHPULL);
}
else
{
pwm_duty(MOTOR2_A,0-pwm2);
gpio_init(MOTOR1_B, GPO, 1, PUSHPULL);
}
}
在这几个小时中,我排除掉了一下几个问题:
- 驱动模块出现故障。排除方法:测试了那三根导线,发现了导出后并不是正确的电流,因此不能判断为电机驱动的问题。
- 母板电路故障。排除方法:测试核心板上的引脚电流,依旧不是正确的电流,因此不能判断为母板发生故障。
- 核心板出现故障。排除方法:我换了三块核心板,都是同样的电流,因此不能判断为核心板出现故障。
最后我也没能确定是那个部分的问题,但是我考虑到我是做的电磁四轮,后面的两个轮子也不会一个正转一个反转,于是,我使用了21.3这个引脚同时控制两个电机的正反转。最后,暴力解决了这个问题。
我寻找问题的方法可能不是那么的专业,而且最后也没能找出问题出在哪里。我的第一篇博客到这里就要结束了,可能会有许多问题,希望各位大佬多多指教!!
评论(0)
您还未登录,请登录后发表或查看评论