首页 > 解决方案 > 为什么我的 PID 控制器会使我的飞船失控?

问题描述

我在 Unity 中工作,正在尝试一个简单的宇宙飞船游戏。我试图用一个操纵杆控制来控制俯仰和偏航。所以我在操纵杆上输入 x 或 y 轴并将其用作角速度的设定点。然后我有一个小 pid 控制器,它试图控制一切。如果我使用一个轴,它会很好用,但是当我同时使用两个轴时,它会疯狂地旋转失控。

这是 pid 控制器,非常简单:

public class pid : MonoBehaviour
{
public float pFactor, iFactor, dFactor;

float integral;
float lastError;


public pid(float pFactor, float iFactor, float dFactor)
{
    this.pFactor = pFactor;
    this.iFactor = iFactor;
    this.dFactor = dFactor;
}


public float Update(float setpoint, float actual, float timeFrame)
{
    float present = setpoint - actual;
    integral += present * timeFrame;
    float deriv = (present - lastError) / timeFrame;
    lastError = present;
    return present * pFactor + integral * iFactor + deriv * dFactor;
}
}

这是我的扭矩更新代码,我将扭矩应用于船舶(在固定更新内)。

float yawUpdate = mYawPid.Update(move.x*5, mRigidbody.angularVelocity.y, Time.deltaTime);
Debug.Log("setpoint " + move.x + "actual " + mRigidbody.angularVelocity.y + " yawupdate " +  yawUpdate.ToString());
mRigidbody.AddRelativeTorque(Vector3.up * yawUpdate);

float pitchUpdate = mPitchPid.Update(move.y*5, mRigidbody.angularVelocity.x, Time.deltaTime);
Debug.Log("setpoint " + move.y + "actual " + mRigidbody.angularVelocity.x + " pitchupdate " + pitchUpdate.ToString());
mRigidbody.AddRelativeTorque(Vector3.right * pitchUpdate);


float rollUpdate = mPitchPid.Update(0, mRigidbody.angularVelocity.z, Time.deltaTime);
//Debug.Log("setpoint " + move.y + "actual " + mRigidbody.angularVelocity.x + " pitchupdate " + pitchUpdate.ToString());
mRigidbody.AddRelativeTorque(Vector3.forward * rollUpdate);

现在我也尝试了 AddTorque 而不是 AddRelativeTorque,它很稳定,没有疯狂的旋转。但是现在我的船会根据面对摄像机的任何东西进行俯仰。因此,如果我将它向右旋转 90 度,现在当我俯仰鼻子不会下垂时,它会做一个桶形滚动。我不明白我做错了什么。任何建议表示赞赏!

标签: c#unity3dgame-physics

解决方案


推荐阅读