鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    9.33pid控制电机,kp跟鱼哥一样是0.625,但是就会震荡,求解决

    已定时 已固定 已锁定 已移动
    FishBot二驱机器人
    pid控制 fishbot双驱版
    1
    1
    57
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • Y
      yinyinyinmusic
      最后由 yinyinyinmusic 编辑

      9.33pid控制电机出现震荡,跟鱼哥的kp差挺多

      1. 背景:代码都校对过了是一样的,小车是鱼哥的两轮小车,硬件都一样,kp跟鱼哥一样是0.625,ki0.125,kd0.0,但就会震荡,具体表现为轮子快速正转后反转,始终无法自调到100,kp降到0.4,就好了,求解决
      2. 调试: 自己调pid 亲测只有<0.45左右才不会出现震荡的情况,且没报错,只要kp<0.45,pid就能很快调到100
      3. 疑问:怀疑是否虽然是同一个硬件,但是硬件有微小差异,导致0.625用不了,虽然同一小车,但是具体kp 多少还得自己调出来
      4. ros2新人,以下为代码求解答
      #include <Arduino.h>
      #include <Esp32PcntEncoder.h>
      #include <Esp32McpwmMotor.h>
      #include <PidController.h>
      
      Esp32PcntEncoder encoders[2]; // 创建一个数组用于存储两个编码器
      Esp32McpwmMotor motors;
      PidController pid_controller[2];
      
      int32_t last_tick[2] = {0, 0};
      int32_t delta_tick[2] = {0, 0};
      uint32_t last_update_time = 0;
      
      float current_speed[2] = {0, 0};
      
      void setup()
      {
          // 1.初始化串口
          Serial.begin(115200); // 初始化串口通信,设置通信速率为115200
      
          motors.attachMotor(0, 22, 23); // 将电机0连接到引脚
          motors.attachMotor(1, 12, 13); // 将电机1连接到引脚
      
          // 2.设置编码器
          encoders[0].init(0, 32, 33); // 初始化第一个编码器,使用GPIO 32和33连接
          encoders[1].init(1, 26, 25); // 初始化第二个编码器,使用GPIO 26和25连接
      
          // motors.updateMotorSpeed(0,50); //设置两个电机pwm占空比
          // motors.updateMotorSpeed(1,50);
      
          // piccontroller参数 初始化
          pid_controller[0].update_pid(0.425, 0.125, 0.0); // 设置PID参数 kp ki kd
          pid_controller[1].update_pid(0.425, 0.125, 0.0); //
      
          pid_controller[0].out_limit(-100, 100);
          pid_controller[1].out_limit(-100, 100);
      
          pid_controller[0].update_target(100); // 使用mm/s为单位,为了提高精度
          pid_controller[1].update_target(100); //
      }
      
      // 用于控制电机的速度/闭环控制pid
      void motorSpeedControl()
      {
      
          // 计算tick差
          delta_tick[0] = encoders[0].getTicks() - last_tick[0];
          delta_tick[1] = encoders[1].getTicks() - last_tick[1];
      
          // 计算速度  dt为毫秒 毫米/毫秒 -> 毫米/秒
          int16_t dt = millis() - last_update_time;
      
          current_speed[0] = (delta_tick[0] * 0.105805) * 1000 / dt; //mm/s
          current_speed[1] = (delta_tick[1] * 0.105805) * 1000 / dt; //mm/s
          
          // 调用pid,获取动态的输出值
          motors.updateMotorSpeed(0, pid_controller[0].update(current_speed[0]));
          motors.updateMotorSpeed(1, pid_controller[1].update(current_speed[1]));
      
          // // 打印距离
          // Serial.printf("左轮已行驶路程距离=%f cm ", (encoders[0].getTicks()) * 0.105849 / 10);
          // delay(100);
          // Serial.printf("右轮已行驶路程距离=%f cm     ", (encoders[1].getTicks()) * 0.105849 / 10);
          // delay(100);
          // 打印速度
      
          last_tick[0] = encoders[0].getTicks();
          last_tick[1] = encoders[1].getTicks();
          last_update_time = millis();
      }
      
      void loop()
      {
          delay(10); // 等待10毫秒
      
          motorSpeedControl();
      
          Serial.printf("左轮实时速度=%f m/s", current_speed[0]/1000);//mm/s->m/s
          delay(100);
          Serial.printf("右轮实时速度=%f m/s\n", current_speed[1]/1000);
          delay(100);
      }
      
      
      1 条回复 最后回复 回复 引用 0
      • 第一个帖子
        最后一个帖子
      皖ICP备16016415号-7
      Powered by NodeBB | 鱼香ROS