Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

How do the PID controllers for altitude, roll and position work?

A topic by ashtorak created Dec 14, 2021 Views: 327 Replies: 1
Viewing posts 1 to 3
(1 edit)

It's based on the algorithms from Chapter 6 of "Control System Design" by Karl Joahn Åström, 2002.

I need to find some time to actually explain it, but it works basically as in the kOS KSP mod (which unfortunately I only found afterwards).

So, normally you only adjust K, Ti and Td. But there are also some more options, which I haven't really made use of. The default settings, which I found to somewhat work, are also not really the best. So you are invited to find better settings and share them with us.

This implementation uses the time constant notation for Ti and Td. So, if you want to remove the I and D parts from the controller you have to set Ti very large and Td (and N) very low.

Note, that when you change Ti and already have a somewhat large integral part, it might take some time until it adjusts and the new Ti takes effect. This depends on Tt. If this is around 1 or a bit lower it should wind back the integral part pretty fast.

Here are details from the actual implementation in the C# file, which I use and which mostly follows the design by Åström:

    float K = 0.2f; // K - proportional gain

    float Ti = 11.0f; // Ti - integral time

    float Td = 1.0f; // Td - derivative time

    float b = 0.1f; // b - additional parameter for set point weighting

    float Tt = 1.0f; // Tt - tracking time constant (integrator reset time for anti wind up)

    float N = 11.0f;

 //Compute controller coefficients

        h = Time.fixedDeltaTime;

        bi=K*h/Ti; // integral gain

        ad=(2*Td-N*h)/(2*Td+N*h);

        bd=2*K*N*Td/(2*Td+N*h); //derivative gain

        a0=h/Tt;

// compute output

        y = processVariable;

        ysp = setPoint;

        // controller algorithm

        P = K*(b*ysp-y); // compute proportional part

        D = ad*D-bd*(y-yold); // update derivative part

        v = P+I+D; // compute temporary output

        if(manipulateVariableMin!=0) output = Mathf.Clamp(v, manipulateVariableMin, manipulateVariableMax);

        else output = v;

        I = I+bi*(ysp-y)+a0*(output-v); // update integral

        I = Mathf.Clamp(I, -1000000, 1000000); // prevent unreasonably large values for I, which can result from extreme parameter settings

        yold = y; // update old process output

        return output;

(2 edits)

There are 6 PID controllers currently:

- Altitude by Throttle

- Orientation/Position by gimballing engines with controllers GimbalX/GimbalY and GimbalXSP/GimbalYSP

-  Roll by adding a rotation to the gimbal action

More explanation from in-game:

When "Automatic Control" is toggled on, and nothing else, it just tries to keep the orientation upwards by gimballing the engines. The controllers "GimbalX" and "GimbalY" are used for this.

Altitude control throttles the engines to reach the given set point. It doesn't switch off single engines. You have to do this manually, if you have too much thrust.

Roll is for orienting the mounting points towards the tower. This is tricky. Use it only when the rocket is relatively steady and not gimballing much.

For position, target coordinates in North and East directions can be given. The launch mount is the origin.

The position controller provides a set point to the gimbal controllers to tilt the rocket into the direction of the target. Therefore they are called "GimbalXSP" and "GimbalYSP".

For the landing phase, the control depends on the object:

For the booster it is as follows: Before starting the raptors, a landing trajectory is calculated using the landing target position and current booster position and velocity. After the raptors are started the trajectory is fixed and used as reference for automatic control. The controller takes the closest point on the trajectory curve as target for the position control and the tangent at this point as target vector for the orientation.

Starship: As the flip is usually initiated relatively close to the target, the controller always uses the set target coordinates and altitude setpoint as reference. So the orientation target is always the world up axis. That makes it easier for the controller as the ship typically comes in with horizontal orientation or might even be pitching downwards (even though optimal pitch would be slightly upwards to maximize drag).

When the ship is in landing phase and the raptors are started, the front flaps are automatically opened, while the AFT flaps are folded. For the prototypes SpaceX also folded the front flaps after the flip. I don't think it does much, so it's up to you. If you want you can do it manually.

There is some sort of mass distribution with the current ship implementation. But it is not very realistic. If you increase the propellant mass, the center of mass is shifted to the AFT somewhat. For small changes of mass the controllers should be able to still work properly. But for larger changes it might become difficult, for example at some point the flaps just don't generate enough torque anymore to keep the pitch stable. 

moved this topic to UNITY version: Info