swift-project / pilotclient

Cross-platform cross-simulator pilot client for virtual air traffic networks
https://swift-project.org
GNU General Public License v3.0
94 stars 27 forks source link

Adjust true altitude to compensate for MSFS/XP12 realistic altimetry model #169

Closed oktal3700 closed 1 year ago

oktal3700 commented 2 years ago

MSFS 2020 has an altimetry model that is more accurate/realistic than that of other sims, in that it simulates the effect of temperature on the pressure lapse rate in the atmosphere. Because of this, the indicated altitude that the pilot sees may be different from the true altitude of the aircraft. Since ATC clients show the reported true altitude in the data block when the aircraft is below the transition level, and since pilot clients render other aircraft at their reported true altitude, this creates an obvious problem. The more the temperature differs from a standard atmosphere, the greater the error.

And when X-Plane 12 is released, it will include a similar feature.

See the proposed solution by Ross.

oktal3700 commented 1 year ago

The importance of this issue continues to grow as X-Plane 12 is now available to buy in early access.

oktal3700 commented 1 year ago

Description from Ross of what vPilot is doing:

MSFS has a new simvar called INDICATED ALTITUDE CALIBRATED which is essentially "what the indicated altitude would be if the pilot set the kohlsman window setting to local sea level pressure" ... so it's a perfect value to use for sending the true altitude to the network

so what I'm doing is reading that value and sending it as the true altitude value in the @ packet, and I'm also using it to "correct" altitudes received from other pilots ... I get the difference between that value and the true altitude (PLANE ALTITUDE simvar) and apply that offset to incoming altitudes

I only apply that offset if the other aircraft is within 3000 feet of the user's aircraft, and I interpolate that offset down to zero if the other aircraft is between 3000 and 6000 feet of the user's aircraft, vertically

private double AdjustIncomingAltitude(double altitude)
{
    if (mActiveSimulatorType != ModelMatching.SimulatorType.Msfs) {
        return altitude;
    }

    double verticalDistance = Maths.Abs(mCurrentUserAircraftData.CalibratedIndicatedAltitude - altitude);
    if (verticalDistance > 6000.0) {
        return altitude;
    }

    double weight = 1.0;
    if (verticalDistance > 3000.0) {
        weight = 1.0 - ((verticalDistance - 3000.0) / 3000.0);
    }

    double offset = mCurrentUserAircraftData.CalibratedIndicatedAltitude - mCurrentUserAircraftData.TrueAltitude;
    return altitude - (offset * weight);
}
oktal3700 commented 1 year ago

There is a new dataref in XP12 sim/flightmodel2/position/pressure_altitude to expose the pressure altitude including temperature calculation.

Remember though, we still need to support XP11.

oktal3700 commented 1 year ago

Conceptual solution:

jonaseberle commented 1 year ago

Thank you for working on it. I can't comment on the changes needed in Swift. These were the changes in xPiIot so they got away with just using the new DataRef sim/flightmodel2/position/pressure_altitude.

ltoenning commented 1 year ago

Fixed with b3e312e1d35d714d1207b078e68c759cad92987e and 1e2910010273020332945b55595c9a81053f098c. Released with version 0.12.72.