Nexus2004_1 2023-04-19 13:36 采纳率: 100%
浏览 84
已结题

gd32芯片循迹小车

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);
    }
                  
}


  • 写回答

4条回答 默认 最新

  • 关注

    根据你的代码和描述,问题可能出在电机驱动和传感器采集上。具体地说,当电机转速达到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()函数计算得到的调整值来设置电机转速。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 4月27日
  • 已采纳回答 4月19日
  • 赞助了问题酬金20元 4月19日
  • 修改了问题 4月19日
  • 展开全部

悬赏问题

  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解