完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
官方提供的ROS_arduino_bridge是利用两个PID控制两个马达,但由于马达问题,机器人走直线,因此需要一个马达进行单独的PID控制,本文修改ROS_Arduino_bridge以实现两路PID控制 1.首先修改arduino代码 a.修改diff_controller.h文件 增加左右两个马达的PID控制变量: /* PID 参数 */INT Kp = 20;整数 Kd = 12;INT KI = 0;INT KO = 50;int left_Kp=Kp;int left_Kd=Kd;int left_Ki=Ki;int left_Ko=Ko;int right_Kp=Kp;int right_Kd=Kd;int right_Ki=Ki;int right_Ko=Ko;123456789101112131415分别定义左右两个马达的dorightPID()和doleftPID()函数 /* PID 程序来计算下一个电机命令 */void dorightID(SetPointInfo * p) { 长 Perror; 长输出; 整数输入; //Perror = p->TargetTicksPerFrame - (p->Encoder - p->PrevEnc); 输入 = p->编码器 - p->PrevEnc; Perror = p->TargetTicksPerFrame - 输入; /* * 避免导数踢并允许调整调整, * 见 http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-derivative-kick/ * 见 http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-tuning-changes/ */ //输出 = (Kp * Perror + Kd * (Perror - p->PrevErr) + Ki * p->Ierror) / Ko; // p->PrevErr = Perror; 输出 = (right_Kp * Perror - right_Kd * (input - p->PrevInput) + p->ITerm) / right_Ko; p->PrevEnc = p->编码器; 输出 += p-> 输出; // 累积积分误差 * 或 * 限制输出。 // 当输出饱和时停止累积 如果(输出 >= MAX_PWM) 输出 = MAX_PWM; 否则如果(输出<= -MAX_PWM) 输出 = -MAX_PWM; 别的 /* * 允许转向更改,参见 http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-tuning-changes/ */ p->ITerm += Ki * Perror; p-> 输出 = 输出; p->PrevInput = input;}/* PID 程序来计算下一个电机命令 */void doleftPID(SetPointInfo * p) { 长 Perror; 长输出; 整数输入; //Perror = p->TargetTicksPerFrame - (p->Encoder - p->PrevEnc); 输入 = p->编码器 - p->PrevEnc; Perror =p->TargetTicksPerFrame + 输入; /* * 避免导数踢并允许调整调整, * 见 http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-derivative-kick/ * 见 http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-tuning-changes/ */ //输出 = (Kp * Perror + Kd * (Perror - p->PrevErr) + Ki * p->Ierror) / Ko; // p->PrevErr = Perror; 输出 = (left_Kp * Perror - left_Kd * (input - p->PrevInput) + p->ITerm) / left_Ko; p->PrevEnc = p->编码器; 输出 += p-> 输出; // 累积积分误差 * 或 * 限制输出。 // 当输出饱和时停止累积 如果(输出 >= MAX_PWM) 输出 = MAX_PWM; 否则如果(输出<= -MAX_PWM) 输出 = -MAX_PWM; 别的 /* * 允许转向更改,参见 http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-tuning-changes/ */ p->ITerm += Ki * Perror; p-> 输出 = 输出; P-> PrevInput =输入;} 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374修改updatePID()函数 无效更新PID(){ /* 读取编码器 */ leftPID.Encoder =readEncoder(LEFT); rightPID.Encoder = readEncoder(RIGHT); /* 如果我们不移动,就没有什么可做的 */ 如果(!移动){ /* * 重置 PID 一次,以防止启动尖峰, * 见 http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-initialization/ * PrevInput 被认为是一个很好的检测代理 * 重置是否已经发生 */ if (leftPID.PrevInput != 0 || rightPID.PrevInput != 0) resetPID(); 返回; } /* 计算每个电机的 PID 更新 */ dorightID(&rightPID);//执行右马达PID doleftPID(&leftPID);//执行左马达PID /* 相应地设置电机速度 */ setMotorSpeeds(leftPID.output, rightPID.output);}12345678910111213141516171819202122223242526b.修改ROSArduinoBridge.ino文件 修改argv1和argv2的数组长度 字符 argv1[32];字符 argv2[32];12修改pid_args的声明为如下代码 int pid_args[8];1修改runCommand(),修改case UPDATE_PID,把原来的Kp,K,Ki,Ko为调用函数的代码注释掉,修改如下的代码、 案例 UPDATE_PID: while ((str = strtok_r(p, ":", &p)) != ' |