稳定性 - 通过最大加速度,最大减速度和最大速度减少位置误差

时间:2017-10-26 12:23:42

标签: c++ simulation velocity pid acceleration

我正在努力解决问题,我需要一些帮助。我会尽力解释一下。

我正在研究坦克的模拟。坦克是这样组成的:我有底盘。底盘上是炮塔,只能在方位角上旋转。在炮塔上还有其他几个东西,如枪管(可以在高度上旋转),炮手瞄准系统(GSS)方位角部分和指挥官瞄准系统(CSS)方位角部分。在GSS方位角部分是GSS高程部分,在CSS方位角部分是CSS高程部分。当然,GSS和CSS的方位角部分只能在方位角上旋转,对于只能在高程中旋转的高程部分也是如此。当然,由于GSS在炮塔上,如果炮塔旋转,它也会使GSS旋转。

所以,让我们回顾一下:

Chassis <- Turret (AZ) <- Barrel (EL).
Chassis <- Turret (AZ) <- GSS (AZ) <- GSS (EL).
Chassis <- Turret (AZ) <- CSS (AZ) <- CSS (EL).

每个部分都可以被视为仅在一个轴上锁定的DOF(自由域)(方位角或仰角)。

现在,每个部分都有一些移动限制:

炮塔可以在[-360°,+ 360°]的范围内旋转(因此没有限制)。

枪管相对于其母体可以在[-10°,+ 50°]的范围内旋转 炮塔。

GSS AZ可以在[-5°,+ 5°]的范围内旋转。

GSS EL可以在[-10°,+ 50°]的范围内旋转。

CSS AZ可以在[-360°,+ 360°]的范围内旋转。

CSS EL可以在[-10°,+ 50°]的范围内旋转。

每个部分也有一些物理限制:

GSS AZ,GSS EL,CSS AZ和CSS EL的最大加速度为570°/s²,最大减速度为570°/s²,最大速度为57°/ s。

炮塔的最大加速度为32°/s²,最大减速度为160°/s²,最大速度为40°/ s。

枪管的最大加速度为57°/s²,最大减速度为114°s²,最大速度为34°/ s。

现在,问题如下。对于GSS,我有两个代表世界方向的固定值。一个是方位角,另一个是海拔。我们假设它是25°(AZ)和3°(EL)。这意味着GSS部分必须在世界参考的那个方向。这些值可以实时更新(例如,我们可以使用操纵杆控制这些值,以移动相机)。我想要的是GSS始终与这些值对齐(我只能忍受5 * 10 ^( - 5)弧度的小误差),即使我们正在驾驶并且底盘正在移动(位置和方向) 。当然,因为GSS有一些限制,所以它不能总是与方向一致。要解决这个问题,炮塔也必须与这些值对齐(因此,当炮塔旋转以便在方位角上对齐时,它会使GSS更接近想要的方向。)

在任何时候,我都可以访问一个物体相对于其父物体的位置(方位角或仰角)(因此我可以将其方向指向世界参考物)以及相对于其父物体的旋转速度。

我可以用来控制每个部分的唯一参数是部件相对于其父部件的速度。

我所做的是在其父母的指称中转换所有世界方向。从这里开始,我只是计算所需的速度,同时考虑到我所拥有的不同约束(加速度,减速度和速度)。这是我用来计算速度的代码:

double desiredVelocity = (wrappedDesiredPosition - wrappedCurrentPosition) / deltaTime;
if (std::abs(desiredVelocity) > object.maximumVelocity)
  desiredVelocity *= object.maximumVelocity / std::abs(desiredVelocity);
const double maximumForce = (std::abs(desiredVelocity) < std::abs(object.velocity) || Sign(desiredVelocity) == -Sign(object.velocity)) ? object.maximumDeceleration : object.maximumAcceleration;
double requiredForce = (desiredVelocity - object.velocity) / deltaTime;
if (std::abs(requiredForce) > maximumForce)
{
  requiredForce *= maximumForce / std::abs(requiredForce);
  desiredVelocity = object.velocity + requiredForce * deltaTime;
  if (std::abs(desiredVelocity) > object.maximumVelocity)
    desiredVelocity *= object.maximumVelocity / std::abs(desiredVelocity);
}

这里已经处理了限制位置(wrappedDesiredPosition已被限制)。

这确实有效,但是,我绝对不够精确。在相机正确稳定之前,相机有时会略微振动(不过很多)。我进行了一些测量,当底盘移动时,我的稳定性大约为3.5*10^(-3)弧度(以16km / h的速度进行一些颠簸)。这绝对不够好,因为我想要精确地达到5.0*10^(-5)弧度。

我可以做些什么来改善我的稳定性?我需要将它提高~70,这似乎是巨大的。我知道PID控制器,这可能有所帮助,但我不知道如何在这里正确应用它,我不确定它可以帮助我实现我的目标。

如果有人提出如何改进的建议,我很乐意听到。

0 个答案:

没有答案