用stm32+超声波通过pid控制小车与墙保持15cm距离,打开开关后,就一上来,会来回撞墙,过一会就要么一直向后,要么一直向前了,是什么原因?
main.c
#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
#include "string.h"
#include "OLED.h"
#include "HSC4.h"
#include "PWM.h"
#include "PID.h"
void main(void)
{
// Time_init();
OLED_Init();
Hcsr04Init();
Pid_init();
OLED_ShowString(1,1,"distance:");
while (1)
{
OLED_ShowNum(1,11,Hcsr04GetLength(),3);
Pid_op();
Pidto_pwm();
}
}
PID.c
#include "PID.h"
#include "HSC4.h"
#include "PWM.h"
#include "Motor.h"
struct Pid
{
float distance;//当前距离
float targetdistance;//目标距离
float err; //误差
float last_err;//上次的误差
float kp;
float ki;
float kd;
float count_err;//累积误差
float pout;
}pid;
void Pid_init(){
pid.kp = 300;
pid.ki = 100;
pid.kd = 1000;
pid.targetdistance = 15;
}
void Pid_op(){
pid.distance = Hcsr04GetLength();
pid.err = pid.distance - pid.targetdistance;//计算误差
pid.count_err += pid.err;
pid.pout = pid.kp*pid.err + pid.ki*pid.count_err+pid.kd*(pid.err - pid.last_err);
pid.last_err = pid.err;
}
void Pidto_pwm(){
Motor_Init();
if(pid.pout>0){
if(pid.pout>500){//前进
pid.pout = 500;
go_forward(pid.pout);
} else if(pid.pout<300){
pid.pout = 150;//转换成输出
go_forward(pid.pout);
}
} else if(pid.pout<0){//后退
if(pid.pout<-500){
pid.pout = 500;
go_back(pid.pout);//转换输出
} else if(pid.pout<-300){
pid.pout = 150;
go_back(pid.pout);//转换输出
}
} else if(pid.pout == 0)
{
pid.pout = 0;
}
}