小车编码电机PID速度环位置式和增量式调试总结

目录

一、位置式PID和增量式PID

二、问题分析

三、参数调节


小车由于在自身重力或摩擦力等因素影响下,实际转速会小于输入转速,导致里程计误差较大。在较小速度情况下可能会出现堵转情况,导致小车在导航过程中输入小幅度角度转动的时候,无法及时调整进而撞到障碍物,因此需要给电机加PID速度环闭环控制。

一、位置式PID和增量式PID

        PID有位置式和增量式,两者各有优缺点。

        位置式PID的输出直接对应系统输出,响应速度快,适用于需要快速响应的系统,但缺点是容易出现积分饱和:当惯性系统达到最大输出值时,由于系统还未达到目标位置,error一直存在,如果没有积分限幅积分项会不断累加,一旦开始反向变化,系统需要一定时间从饱和区退出,会导致系统超调或震荡。

        增量式PID不需要做累加,控制量增量的确定仅与最近三次偏差采样值有关,计算误差对控制量计算的影响较小,当输出达到最大值时,增量自动归零,避免持续饱和,适用于需要平滑控制的系统,如步进电机。缺点是由于输出的是控制量的增量,响应不如位置式PID,更难直接用于控制一些需要精确位置调整的系统

二、问题分析

        我们先采用位置式PID来进行调试,下面给出代码

double PID::compute_positional(double setpoint, double measured_value, short outLimit, short IntegralLimit) {
    outLimit = config_outLimit;
    IntegralLimit = config_IntegralLimit;

    double error = setpoint - measured_value;

    // 当目标值为零时,重置积分项
    if (setpoint == 0.0) {
        integral_pos = 0.0;
    }

    double proportional = kp * error;
    integral_pos += ki * error;
    double derivative = kd * (error - prev_error_pos);

    // 积分限幅
    if (integral_pos > IntegralLimit)
        integral_pos = IntegralLimit;
    else if (integral_pos < -IntegralLimit)
        integral_pos = -IntegralLimit;

    double output_unclamped = proportional + integral_pos - derivative;
    double output = output_unclamped;
    // ROS_INFO("integral_pos=%.1f,output=%.1f",integral_pos,output);

    // 输出限幅
    if (output > outLimit)          output = outLimit;
    else if (output < -outLimit)    output = -outLimit;

    // 抗积分饱和:输出被限幅时调整积分项
    if (output_unclamped != output) {
        integral_pos = output - proportional - derivative;
    }

    prev_error_pos = error;
    return output;
}

小车最大pwm为900,最大线速度0.3m/s,先给小车一个KP=2000,KI和KP都为0,输出限幅和积分限幅为900,目标速度为0.2,输出左右两轮速度波形图如下:

小车速度始终达不到0.2,这里有个矛盾的地方:如果小车速度达到0.2了,则偏差值error为0,那么KP*error为0,output也为0,那么速度为0,速度为0那么error值又不为0,就会有速度输出,形成矛盾,为此我记录了几组数据,得出以下公式:实际速度=f+(目标速度-f)/2,f为小车克服摩擦力的速度,当f为0时,小车实际速度为目标速度一半,此时加入KI,先给个较小值20

可以看到小车速度逐渐到达0.2,分析后得知:小车电机速度环的KP可以帮助小车预先接近目标速度,再此基础上,KI开始进行积分,从积分开始到目标速度的那块红色阴影面积即为最终的pwm值,如下图,当达到目标速度时KP和KI稳定在目标速度进行调节使小车稳定在目标速度

三、参数调节

        个人调参经验:KP<=最大output/最大误差。KI影响增长到目标转速的快慢,但太快会过冲,我对小车的要求使快速到达目标转速,建议大家对着波形调试,将KI调到速度波形可快速到达目标转速,或稍微过冲。KD我个人不建议加,因为小车电机要快速达到目标转速,但KD会抑制速度过快增长,所以KD给0。

KP=2000,KI=200效果:

位置式和增量式效果对比,上面是位置式,下面是增量式,相同参数情况下:

个人觉得差别不大,但增量式在参数较小的情况下变化更平滑,KP=200,KI=20:

增量式PID代码:

double PID::compute_incremental(double setpoint, double measured_value, short outLimit) {
    // 当目标速度为0时,重置历史值
    if (setpoint == 0.0) {
        prev_output_inc = 0.0;
        prev_error_inc1 = 0.0;
        prev_error_inc2 = 0.0;
    }

    double error = setpoint - measured_value;
    double output = prev_output_inc + kp * (error - prev_error_inc1) +
                    ki * error + kd * (error - 2 * prev_error_inc1 + prev_error_inc2);

    prev_error_inc2 = prev_error_inc1;
    prev_error_inc1 = error;
    prev_output_inc = output;

    // 输出限幅
    if (output > outLimit)          output = outLimit;
    else if (output < -outLimit)    output = -outLimit;


    return output;
}

### PID控制器在平衡小车速度环中的实现方法 PID控制器是一种广泛应用于工业自动化机器人技术的经典控制算法。对于平衡小车而言,其核心目标是在保持车身直立的同时实现稳定的速度控制。以下是关于如何通过PID控制器实现平衡小车速度环的具体方法: #### 1. **理解速度环的作用** 速度环的主要功能是对平衡小车的目标速度进行精确跟踪。它接收来自上层控制系统设定的目标速度值,并将其与实际测量到的小车当前速度进行比较,计算误差并利用该误差调整电机驱动信号[^2]。 #### 2. **构建速度环的输入输出关系** - 输入:目标速度 \(v_{\text{target}}\) 实际速度 \(v_{\text{actual}}\)。 - 输出:经过PID调节后的PWM信号用于驱动直流电机。 速度误差定义为: \[ e_v = v_{\text{target}} - v_{\text{actual}} \] 其中,\(e_v\) 是速度误差,表示期望速度与实际速度之间的偏差[^3]。 #### 3. **设计PID参数 (Kp, Ki, Kd)** PID控制器由比例项(P)、积分项(I)微分项(D)组成,具体表达式如下: \[ u(t) = K_p e_v + K_i \int_0^t e_v(\tau)d\tau + K_d \frac{de_v}{dt} \] - 比例增益 (\(K_p\)):直接影响系统的响应速度。较大的 \(K_p\) 值可以加快系统反应,但也可能导致振荡。 - 积分时间常数 (\(K_i\)):消除稳态误差,使系统更接近目标值。然而,过高的 \(K_i\) 可能引起累积效应导致不稳定。 - 微分时间常数 (\(K_d\)):抑制快速变化带来的波动,提高抗干扰能力[^1]。 #### 4. **调试过程** 为了获得最佳性能,在实际应用中需要不断调整三个参数直到满足需求为止。通常采用逐步逼近法或者Ziegler-Nichols法则来进行初步设置后再细调优化。 ```python def pid_speed_control(target_velocity, current_velocity, kp, ki, kd, dt): error = target_velocity - current_velocity # 初始化累计误差变量 integral += error * dt derivative = (error - previous_error) / dt output_pwm_signal = kp * error + ki * integral + kd * derivative # 更新前一次误差以便下次循环使用 previous_error = error return max(min(output_pwm_signal, MAX_PWM), MIN_PWM) ``` 上述代码片段展示了基于Python语言编写的一个简单版本的速度环PID控制器函数实现方式。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值