PID控制两轮fishbot检测速度与实际速度不一样
-
使用pid控制轮子速度时,设置的值一致,检测的当前速度值一致,但是输出的pid值差了30左右,导致两个轮子的实际转速左轮比右轮慢
以下为main文件代码,头文件与小鱼老师的一致。// 引入必要的库文件 #include <Arduino.h> // Arduino核心库 #include <Esp32McpwmMotor.h> // ESP32电机控制库 #include <Esp32PcntEncoder.h> // ESP32编码器库 #include <PIDController.h> // PID控制算法库 // 创建电机控制对象 Esp32McpwmMotor motor; // 创建编码器对象数组(左右轮) Esp32PcntEncoder encoders[2]; // 创建PID控制器数组(左右轮) PIDController pid_controller[2]; // 定义电机数据结构体 typedef struct { int64_t current; // 当前编码器计数值 int64_t last; // 上一次编码器计数值 int16_t delta; // 两次采样间的计数值变化 float speed; // 计算得到的轮速(mm/s) float pid_out; // PID控制器输出值 } MotorData; MotorData wheels[2]; // 左右轮数据存储 float last_update_time = 0; // 上次更新时间戳 const char* LABELS[] = {"Left", "Right"}; // 左右轮标签 const float Single_Pulse_Distance = 0.10342f; // 单个脉冲距离(单位:mm) // 打印电机数据函数 void printMotorData(uint8_t i) { Serial.printf("%s Wheel:\n", LABELS[i]); Serial.printf("Current: %d\n", wheels[i].current); Serial.printf("Last: %d\n", wheels[i].last); Serial.printf("Delta: %d\n", wheels[i].delta); // 脉冲计数值变化量(当前-上次) Serial.printf("Speed: %.2fmm/s\n", wheels[i].speed); // 速度(mm/s) Serial.printf("PID Out: %.2f\n\n", wheels[i].pid_out); // PID输出值 } // 更新电机控制函数 void updateMotorControl() { float dt = millis() - last_update_time; // 计算时间差(ms) for(uint8_t i = 0; i < 2; i++) { // 获取当前编码器值 wheels[i].current = encoders[i].getTicks(); // 计算计数值变化量 wheels[i].delta = wheels[i].current - wheels[i].last; // 计算轮速(cm/s): (脉冲数*单个脉冲距离)mm*1000/时间差ms,1000mm/ms 精度 100mm/1m = 0.1m/s wheels[i].speed = (wheels[i].delta * Single_Pulse_Distance * 1000)/dt; // 更新PID控制器并获取输出 wheels[i].pid_out = pid_controller[i].update(wheels[i].speed); Serial.printf("dt: %fms\n", dt); printMotorData(i); // 打印数据 // 更新电机速度 motor.updateMotorSpeed(i, wheels[i].pid_out); // 更新上一次编码器值 wheels[i].last = encoders[i].getTicks(); } last_update_time = millis(); // 更新时间戳 } // 初始化函数 void setup() { Serial.begin(115200); // 初始化串口 // 连接电机引脚(电机编号, 引脚A, 引脚B) motor.attachMotor(0, 22, 23); // 左轮 motor.attachMotor(1, 12, 13); // 右轮 // 初始化编码器(编码器编号, 引脚A, 引脚B) encoders[0].init(0, 32, 33); // 左轮编码器 encoders[1].init(1, 26, 25); // 右轮编码器 // 配置PID参数 for(uint8_t i = 0; i < 2; i++) { pid_controller[i].update_pid(0.30, 0.10, 0.045); // P,I,D参数 pid_controller[i].out_limit(-99, 99); // 输出限幅--占空比 } // 设置目标速度(左轮正向400,右轮正向400) pid_controller[0].update_target(400); //目标速度--mm/s pid_controller[1].update_target(400); } // 主循环 void loop() { delay(10); // 10ms控制周期 updateMotorControl(); // 更新电机控制 }
以下为部分串口数据
dt: 10.000000ms
Left Wheel:
Current: 22567
Last: 22528
Delta: 39
Speed: 403.34mm/s
PID Out: 54.30dt: 10.000000ms
Right Wheel:
Current: 44701
Last: 44662
Delta: 39
Speed: 403.34mm/s
PID Out: 88.05dt: 10.000000ms
Left Wheel:
Current: 22606
Last: 22568
Delta: 38
Speed: 393.00mm/s
PID Out: 58.57dt: 10.000000ms
Right Wheel:
Current: 44779
Last: 44740
Delta: 39
Speed: 403.34mm/s
PID Out: 87.72dt: 10.000000ms
Left Wheel:
Current: 22646
Last: 22607
Delta: 39
Speed: 403.34mm/s
PID Out: 54.20dt: 10.000000ms
Right Wheel:
Current: 44857
Last: 44818
Delta: 39
Speed: 403.34mm/s
PID Out: 87.38 -
此回复已被删除!