我有一个差动驱动机器人,可以说1 m / s正常运行(良好的PD参数)。现在,如果速度加快(达到1.2 m / s),它将再次开始摆动。对于能够应付整个速度范围0-4 m / s的控制器,什么是好的策略?

编辑4月14日:

是线跟随机器人,但我看不到这与我的问题有什么关系,因为跟随轨迹的机器人也有同样的问题。

我最近与差动驱动机器人的其他开发人员进行了交谈,他们也面临着类似的问题,例如他们告诉我说,一旦电池没有充满电,他们就需要调整PID参数,因此机器人以不同的速度行驶。对我的机器人感兴趣,此链接会有所帮助:https://www.youtube.com/watch?v=vMedNPhXlEo

PID参数为:P 0.31,D 0.59,I 0.00

使用C编程的PID控制器:

  // note: the inner wheel turns backwards for narrow curves
  // cte is -128..128 depending on the robots position
  // relative to a trajectory / black line 
  /** Execute the PID controller and update motor speeds */
  void PID()
  {
    int32_t steer;
    int32_t cte;
    cte = 128 - get_segment_center(0);
    // Compute PID equation
    steer = (int)(
      -P * (float)cte 
      -D * (float)(cte - diff_cte) / (float)PERIOD_MS
      -I * (float)int_cte
    );
    if (steer < -5)
    {
      // turn left
      turn = -1;
      uXbot_move(MAX_SPEED + steer, MAX_SPEED);
    } 
    else if (steer > 5)
    {
      // turn right
      turn = 1;
      uXbot_move(MAX_SPEED, MAX_SPEED - steer);
    }
    else
    {
      // go straight
      turn = 0;
      uXbot_move(MAX_SPEED, MAX_SPEED);
    }
    diff_cte = cte;
    int_cte += cte;
  }


评论

为什么+ 5 / -5阈值?如果删除该怎么办?您不需要引入这种非线性。尝试D = 0,I = 0,然后逐渐提高P。

+ 5 / -5来自另一个功能。要禁用该功能,我可以将其设置为0,我已经尝试过了。最近两天我尝试了不同的PID值(为此我有一个模拟器,过去几周累了成千上万个不同的值)。

#1 楼

您没有将您的转向值正确映射到车轮速度。实际上,我认为您根本没有正确应用PID。

从您的代码中,我猜测您正在使用get_segment_center来确定需要进行的调整。我的假设是,这描述了线传感器离线中心有多远的距离测量。如果是这种情况,则您缺少必要的计算。

PID的输出会产生错误并为您提供校正,因此,如果您的错误以英寸为单位,则校正将以英寸为单位;如果误差以度为单位,则校正将以度为单位,依此类推。您需要选择其中一个并坚持使用。如所写,您正在获取距离误差并将其直接插入速度校正中-难怪它只能以一种速度起作用!

我的建议是将转向误差计算为一个角度,您可以通过测量(1)传感器可以拾取线的距离和(2)轴与传感器之间的距离来获得。使用切线功能,您可以将传感器读数映射到角度误差。然后,您可以实现我在本文中介绍的功能,以将转向角转换为车轮速度。

评论


$ \ begingroup $
太好了!这是一个非常有趣的观察。我的代码中采用的方法与我在其他人的线性追随者中研究的代码相似,但我从未像您一样真正质疑过它。我认为P因子可以解决转换问题。但这仅在线性转换时有效。我将在复活节假期期间进一步研究此问题并向您报告。如果您不介意,在此之前我将一直保持开放状态。
$ \ endgroup $
–tired_of_nitpickers
2014年4月14日19:20在

$ \ begingroup $
我按照您的建议考虑了(1)和(2)cte = 104.0 * atan((float)(128-get_segment_center(0))* 0.003);对另一篇文章的引用(很好的可视化)并不是很有帮助,因为它具有一些我不需要的功能(当场打开等)。它也不适用于所宣传的速度。我的新PID(使用上述公式)效果更好,但仍不能解决问题。我目前无法发送机器人遥测(我想念一个小的sprintf库)。但是,一旦解决,我将提供一些数据和图表。
$ \ endgroup $
–tired_of_nitpickers
2014年4月21日在7:21

$ \ begingroup $
如何将所需的车辆转向角(+速度)映射到各个车轮速度?当您说另一个算法“不适用于广告宣传的速度”时,您遇到了什么问题?
$ \ endgroup $
–伊恩
2014年4月21日在15:38

$ \ begingroup $
您的帖子使用“操纵杆位置”而不是速度。我看不到您在说的车轮速度:(
$ \ endgroup $
–tired_of_nitpickers
2014年4月22日下午5:25

$ \ begingroup $
Aah,在那篇文章中,假设左右操纵杆位置将用于指示所需的转向角(-90至+90),上下操纵杆位置将指示所需的车速( -100%到+ 100%)。您的缩写“ cte”代表什么?
$ \ endgroup $
–伊恩
2014年4月22日在13:12

#2 楼

我看到他的问题来自很久以前,但是,以防万一它仍然受到关注,以下是基于运行小型追随者的一些想法:

首先解决电池问题:uXbot_move(MAX_SPEED + steer, MAX_SPEED);具有映射到PWM值的参数-可能是通过一定的比例因子。

固定的PWM值会随着电池电压下降而产生不同的驱动电压。在电动机驱动器中,使用ADC输入测量电池电压。使用该值调整实际的PWM占空比,以使平均电压保持恒定。更改uxBot()以接受电压而不是PWM。现在,您可以向电动机发出3伏的指令,并确信无论实际电池电压如何(在限制范围内),电动机都能得到3伏的电压。如果您具有8位的PWM分辨率,则可能会得到如下代码片段:

void setLeftMotorVolts(float volts) {
  int motorPWM = (255 * volts) / batteryVolts;
  setLeftMotorPWM(motorPWM);
}

void setRightMotorVolts(float volts) {
  // reverse the right motor
  int motorPWM = (-255 * volts) / batteryVolts;
  setRightMotorPWM(motorPWM);
}


如何通过速度进行性能调整:

    if (steer < -5)
    {
      // turn left
      turn = -1;
      uXbot_move(MAX_SPEED + steer, MAX_SPEED);
    } else if (steer > 5)
    {
      // turn right
      turn = 1;
      uXbot_move(MAX_SPEED, MAX_SPEED - steer);
    } else {
      // go straight
      turn = 0;
      uXbot_move(MAX_SPEED, MAX_SPEED);
    }


这里的部分问题是机器人的前进速度会随着旋转而改变。任何转动都会降低前进速度。在您链接到的视频中,效果清晰可见。虽然这可以帮助导航急转弯,但在某种程度上会干扰动态。

相反,如果同时更改两个车轮的速度,则前进速度将保持恒定。显然,外轮必须留有一定的净空空间才能提高速度。在两个轮子都改变速度的情况下,上面的代码片段将减少为:

uXbot_move(MAX_SPEED + steer, MAX_SPEED - steer);


这将使响应一致,但是控制器可能仍难以适应不同的速度。要解决此问题,请考虑使用当前速度调整转向校正。即,在较高速度下校正将更大。

关于控制器,我有三个观察结果。

首先,重要的是,必须定期且恒定地调用PID函数。除非那是真的,否则它不会很好地工作。您的代码未指定,因此可能已经成立。实际上,除以PERIOD_MS的存在表明您已经意识到这一点。

其次,对于您描述的任务后面的特定行,控制器中不需要I项。实际上,由于您没有采取任何措施来限制积分缠绕,因此弊大于利。

最后,除非您受到处理器能力的严重限制,否则请尽可能在浮点中进行计算。仅当您实际计算定时器寄存器的PWM占空比时,才减小为int。

#3 楼

不错的机器人。

代码中的+/- 5阈值对我来说是一个危险信号。这就引入了非线性/不连续性,这是不必要的。

如果您有足够的内存来捕获一些实时数据,请尝试记录ctesteer,然后在调优时对其进行检查。

速度将受到影响,因为您设置转向的方式和车辆动力学。随着速度的增加,您的转向命令将导致不同的转弯半径。而且,随着速度增加,转向车辆也变得困难。这不是一个琐碎的系统。当电池电压下降并且假设电压是电动机功率的尾巴并且您实际上没有关闭速度环时,较低电压的影响将是较低的速度,因此,PID系数的影响将线性降低至。请注意,电池电量充足时以较低的速度行驶,而电池电量较低则以低速行驶(其转向命令的影响会有所不同)。

我的建议是首先:


摆脱+ 5 / -5阈值。
添加一些登录数据并在调整时查看。
以I =开头0,D = 0并选择一个固定速度。从慢端开始。
将P斜升,不断加倍直到系统变得不稳定。退缩(例如,获取不稳定P的一半或1/4)。
通过添加一点I或D来进行实验,看看它们是否可以提高性能。如果不保留为0。
以一些速度重复进行调谐,并绘制调整后的变量与速度的关系。 br />

评论


$ \ begingroup $
我可以解释什么是“差动驱动”机器人,但我认为这里的人会知道。我认为我的问题对于这类机器人非常普遍,例如电池电量下降时需要更改PID参数...
$ \ endgroup $
–tired_of_nitpickers
2014年4月14日下午5:36

$ \ begingroup $
@mark:在您的问题中,您谈论的是速度,在此注释中,您谈论的是电池电量。我们看不懂你的想法。如果您花时间提供所有必要的信息,则可以获得更多更好的答案。由你决定。您无需解释什么是差分驱动器,但需要提供有关特定设置的详细信息,该特定设置存在特定问题。
$ \ endgroup $
– Guy Sirton
14-4-14在6:15



#4 楼

在考虑了这个问题之后,我有了一个重要的认识:

为了使机器人差动驱动PID控制器以不同的速度运行,用于转向的转向角R必须在整个速度上保持一致范围。

这篇文章激发了我的思考,并解释了差动驱动机器人的转向角度:
计算差动驱动机器人的位置

感谢Guy Sirton和Ian讨论我的PID控制器并提供有用的调试技巧。