Почему мой ПИД-регулятор выводит мой космический корабль из-под контроля? - PullRequest
0 голосов
/ 17 февраля 2020

Я работаю в Unity, пробую свои силы в простой космической игре. Я пытался контролировать шаг и рыскание с помощью одного джойстика. Поэтому я беру ввод оси x или y на джойстике и использую его в качестве моего заданного значения для скорости angular. Тогда у меня есть маленький контроллер 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 градусов, теперь, когда я наклоняю нос, он не будет опускаться, он сделает бочку. Я еще не понимаю, что я делаю неправильно. Любой совет приветствуется!

...