9.33pid控制电机出现震荡,跟鱼哥的kp差挺多
- 背景:代码都校对过了是一样的,小车是鱼哥的两轮小车,硬件都一样,kp跟鱼哥一样是0.625,ki0.125,kd0.0,但就会震荡,具体表现为轮子快速正转后反转,始终无法自调到100,kp降到0.4,就好了,求解决
- 调试: 自己调pid 亲测只有<0.45左右才不会出现震荡的情况,且没报错,只要kp<0.45,pid就能很快调到100
- 疑问:怀疑是否虽然是同一个硬件,但是硬件有微小差异,导致0.625用不了,虽然同一小车,但是具体kp 多少还得自己调出来
- 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);
}