The calculations behind the plane's behaviour on the ground
Not surprisingly, most of Aviator's flight model is dedicated to calculating the aerodynamics of the plane when it's in the air (see the deep dive on the flight model for details). However, the plane's behaviour on the ground is also simulated, where most of the usual aerodynamic forces still apply, and so do various ground-specific calculations. We take a look at these extra calculations here.
Most of the on-ground calculations described below are applied in part 5 of the ApplyFlightModel routine, after the flight forces have been calculated but before they are applied to the plane. That's because being on the ground cancels out some of the forces (such as roll and pitch), so the following can be thought of as an extra step inserted into the flight model calculations between calculation 5 and calculation 6.
Note that this deep dive looks at the ground-specific parts of the flight model. There is also a totally separate section of the code that deals with the question of whether we are landing, touching down or taxiing, which isn't a part of the flight model as such, but is very relevant to the calculations discussed here. In particular, a key value in the on-ground calculations is the onGround flag, which is 0 if we are not on the ground, and 1 if we are on the ground, with the latter effectively meaning "we have landed", as opposed to "we are touching the ground". The onGround variable is updated by the ProcessLanding routine, and is described in the deep dive on take-offs and landings. For our purposes, the calculations in this deep dive only apply when onGround is 1.
Pitching moment from the undercarriage
--------------------------------------
The first difference made by being on the ground is in the calculation of the gravity vector in part 1 of the ApplyFlightModel routine. This vector is used to calculate the pitching moment due to the centre of gravity, which takes the gravitational force in yGravity and applies it as an angular force around the x-axis, giving us our pitching moment (see calculation 4 in the flight model for details).
When the plane is in the air, the gravity vector is set like this:
[ xGravity ] [ 0 ] [ yGravity ] = matrix4 x [ -512 ] [ zGravity ] [ 0 ]
but if we are on the ground, with the undercarriage down and a negative value in dyVelocity, then it set like this:
[ xGravity ] [ 0 ] [ yGravity ] = matrix4 x [ -512 - (dyVelocity / 2 + 1) ] [ zGravity ] [ 0 ]
At this point the value of dyVelocity is the one that's left over from the previous iteration of the main loop, and it represents the current vertical acceleration (i.e. the change in vertical velocity). So if it is negative, it means the plane is accelerating downwards, but we find ourselves on the ground with the undercarriage down. The undercarriage therefore pushes back, so this calculation simulates the springs in the undercarriage, making sure their push-back effect is incorporated when calculating the pitching moment due to the centre of gravity later on.
Ground steering
---------------
Next up, the ApplyFlightControl routine gets called from part 2 of ApplyFlightModel, and it calculates the forces from the three flight controls: elevators, rudder and aileron. The same routine is called when the plane is on the ground, but there is one difference: on the ground, the rudder controls are used to control ground steering via the wheel brakes, rather than controlling the rudder.
Luckily for the flight model, the linear forces applied by the rudder and ground steering are the same - both of them apply yaw to the plane - but the difference is that the "instant centre" feature that the aileron controls enjoy in the air is also applied to the rudder when ground steering (but it isn't applied to the rudder when in the air). The "instant centre" feature is for keyboard users only, and instantly centres the control when you press the key for the opposite direction.
So if we're in the air and we press "S" to roll left using the ailerons, then pressing "D" will instantly centre the joystick before rolling to the right. The same is true for ground steering: if we are on the ground and press "A" to steer left, then pressing "+" to steer right will instantly start steering us in that direction.
The actual effect of the ground steering is applied in part 5 of the ApplyFlightModel routine, where we calculate the force of the steering as follows:
- 0 if the forward airspeed is negative or < 20
- rudderPosition otherwise
If we call this figure groundSteering, then we turn the plane with the rudder controls as follows:
yTurn = groundSteering * 4
This simulates using the plane's left and right brakes to steer the plane, which is why we can only steer when moving forwards above a minimum speed.
Taxiing
-------
The next batch of code in part 5 of the ApplyFlightModel routine looks at the effect of the ground surface on the plane.
First, the roll rate in dzTurn is set to 0, so if the flight model has calculated a change to the roll rate, it gets cancelled, as the plane can't roll when it's on the ground.
Next, if the undercarriage is up, we prevent the plane from pitching forward below the level of the ground by setting dxTurn to 0. So if the flight model has calculated a change to the pitch rate, it gets cancelled, as the plane can't pitch when its belly is flat on the ground.
We now calculate the effect of being on the ground on the calculated linear forces in (xLinear yLinear zLinear).
- If the plane is stationary, set landingStatus = %01000000 and skip to the next section without changing the linear forces.
- If the plane is travelling forwards at a speed of 10 or less, set zLinear = -256 to simulate the friction of the wheels and slow the plane down gently, set landingStatus = %01000000 and skip to the next section.
- If the plane is on the runway, the undercarriage is down and the brakes are off, set landingStatus = 0 and skip to the next section without changing the linear forces.
- Otherwise, set landingStatus = 0 and subtract the following from zLinearHi (from the least slowdown to the biggest slowdown):
- 7 if the plane is not on the runway and:
- The undercarriage is down and the brakes are off
- 11 if the plane is on the runway and:
- The undercarriage is up
- Or the undercarriage is down and the brakes are on
- 50 if the plane is not on the runway and:
- The undercarriage is up
- Or the undercarriage is down and the brakes are on
- 248 if the plane is going backwards (zVelocityP < 0)
- 7 if the plane is not on the runway and:
In other words, the following factors slow us down when travelling forwards along the ground:
- Having the brakes on
- Having the undercarriage up
- Not being on the runway
All of which is pretty logical.
Sideways frictional forces of wheels
------------------------------------
The final calculation for when the plane is on the ground is also performed by part 5 of the ApplyFlightModel routine. This applies a sideways force due to the friction of the wheels. When the wheels are on the ground, the plane can move forwards and backwards without extra friction, but trying to move the plane sideways is much harder, and it's this frictional force that is modelled here.
The sideways friction is calculated as follows:
xLinear = -xVelocityPLo * 128
So the friction is proportional to the sideways speed, as you would expect.