gd32f303的芯片,写寻迹小车,当转速给1000还有2000的时候小车可以正常循迹,但是当转速到3000的时候,无论如何改动pid的三个参数都无法使之循迹,好像是电感突然不检测了,卡死了。这是为什么?
#include "main.h"
#include "headfile.h"
typedef struct
{
float kp;
float ki;
float kd;
float er;
float erl;
float ers;
float erd;
}tpid;
tpid speed;
void inint()
{
speed.kp=200;
speed.ki=0.2;
speed.kd=0.2;
speed.er=0;
speed.erl=0;
speed.ers=0;
speed.erd=0;
}
float ut(tpid *pid ,float er)
{
pid->er=er;
pid->erd=(pid->er)-(pid->erl);
pid->ers+=pid->er;
float ut=(pid->er*pid->kp)+(pid->ers*pid->ki)+(pid->erd*pid->kd);
pid->erl=pid->er;
return ut;
}
int main(void)
{
car_init();
inint();
oled_init();
oled_display_on();
unsigned int adc_value[5];
unsigned int d=1;
while(1)
{
adc_value[1] = adc_get(ADC0, ADC_CH_11);
adc_value[3] = adc_get(ADC0, ADC_CH_13);
int a=(adc_value[1]-adc_value[3]);
if(a<0)
{
a=-a;
d=0;
}
else
{
d=1;
}
float b=(&speed,a);
if(d)
{
motor_forward(left, 5000-b);
motor_forward(right, 5000+b);
}
else
{
motor_forward(left, 5000+b);
motor_forward(right, 5000-b);
}
oled_show_number(48,2,a,7,16);
}
}
根据你的代码和描述,问题可能出在电机驱动和传感器采集上。具体地说,当电机转速达到3000时,电机可能会对传感器的采样产生干扰,从而导致传感器输出的值变得不稳定。这种干扰可能会导致你的小车失去循迹能力。
要解决这个问题,你可以尝试以下几个方法:
使用更好的电机驱动器,以减少电机对传感器的干扰。
在代码中添加传感器采样值的平滑滤波器,以减少传感器输出值的波动。
调整PID参数以提高循迹的稳定性和减少对传感器输出的依赖。
总的来说,你需要在电机驱动和传感器采样方面进行更多的调试和优化,以使小车能够在更高的转速下保持稳定的循迹能力。
且代码我觉得有些问题,以下是我的一些建议:
1.在函数ut()中,您应该传递指向结构体的指针类型,而不是整数类型的指针。另外,在函数内部,您应该先初始化结构体的所有成员变量,再计算输出值。修复后的代码应该如下所示:
float ut(tpid *pid ,float er)
{
pid->er=er;
pid->erd=(pid->er)-(pid->erl);
pid->ers+=pid->er;
float ut=(pid->er*pid->kp)+(pid->ers*pid->ki)+(pid->erd*pid->kd);
pid->erl=pid->er;
return ut;
}
// 在main()函数中
tpid speed = {0.2, 0.2, 0.2, 0, 0, 0, 0}; // 初始化结构体成员变量
float b = ut(&speed, a); // 传递指向结构体的指针类型
2.在main()函数中,您应该对ADC进行初始化,并检查ADC采样是否成功。此外,您可以使用平滑滤波器来处理采样值的噪声,例如使用移动平均或低通滤波器。修复后的代码应该如下所示:
// 在main()函数中
adc_init(); // 初始化ADC
unsigned int adc_value[5];
float filtered_value = 0; // 初始化平滑滤波器
while(1)
{
adc_value[1] = adc_get(ADC0, ADC_CH_11);
adc_value[3] = adc_get(ADC0, ADC_CH_13);
// 检查ADC采样是否成功
if (adc_value[1] == 0 || adc_value[3] == 0) {
// 处理错误值
continue;
}
// 平滑滤波器处理采样值
filtered_value = 0.9 * filtered_value + 0.1 * (adc_value[1] - adc_value[3]);
// 进行循迹控制
int d = (filtered_value >= 0) ? 1 : 0;
float b = ut(&speed, filtered_value);
if(d) {
motor_forward(left, 5000 - b);
motor_forward(right, 5000 + b);
} else {
motor_forward(left, 5000 + b);
motor_forward(right, 5000 - b);
}
oled_show_number(48, 2, filtered_value, 7, 16); // 显示平滑后的采样值
}
3.在函数motor_forward()中,您应该使用ut()函数计算得到的调整值来设置电机转速。
这个问题可能是因为在转速达到3000的时候,小车的电机运动速度增加,导致电感检测距离变短,可能电感检测范围不够用,同时也可能会因为小车速度过快导致电感检测误差增加,从而导致小车无法很好地循迹。
建议对电感检测的距离进行调整,根据实际情况进行改变,使得能够慢慢加快小车的运行速度,同时也可以考虑加入超声波测距等其他传感器辅助电感进行循迹,并且优化PID参数使得小车能够更好地适应不同速度下的循迹。
引用chatGPT作答,根据你提供的代码和描述,可能是由于电机在高转速下造成的机械震动,导致光电传感器的接触不稳定,从而导致无法很好地检测到轨迹。解决方法可以尝试以下几种方式:
1.检查电机是否安装正确,并确保它们的振动不会影响传感器的稳定性。
2.尝试添加额外的低通滤波器以平滑传感器输出,从而减少振动的影响。
3.尝试使用更高质量的光电传感器,这些传感器具有更好的稳定性和抗振性。
4.调整PID参数以适应更高的转速。
希望这些建议对你有所帮助。