I’m building a flight tracker that plots live flight data (gps points) using cesiumjs and I wrote a function that moves the aircraft along at the current speed and heading. Although the aircraft provides it’s heading, I’ve opted to calculate the heading with a function that uses the last two reported positions. My issue is that the aircraft position is drifting away from the reported track. I calculated the heading between the last two interpolated positions and compared that to the calculated heading from the two previously reported gps points and from a brief observation it appears that the interpolated movements are off by 13 degrees consistently. A little research led me to magnetic declination and when consulting a chart it appears the magnetic declination in the area of the aircrafts movements are right around 13 degrees. I’m confused about why this is happening however. I never use a magnetic compass heading (even the one provided by the aircraft is true north I believe). Shouldn’t a heading calculated from two gps points give a true north heading? Is this just a coincidence? Here’s some code
static calcNewPoint(lat,lon,bearing,distance){
const bearing_rad = (bearing*Math.PI)/180;
const EARTH_RADIUS =6371000;
const initial_position = {
"latitude": lat,
"longitude": lon
};
const init_lat = (initial_position.latitude*Math.PI)/180;
const init_lon = (initial_position.longitude*Math.PI)/180;
const final_lat = (180/Math.PI)*(Math.asin( Math.sin(init_lat)*Math.cos(distance/EARTH_RADIUS) + Math.cos(init_lat)*Math.sin(distance/EARTH_RADIUS)*Math.cos(bearing_rad)));
const final_lon = (180/Math.PI)*(init_lon + Math.atan2(Math.sin(bearing_rad)*Math.sin(distance/EARTH_RADIUS)*Math.cos(init_lat), Math.cos(distance/EARTH_RADIUS)-Math.sin(init_lat)*Math.sin(final_lat)));
return[final_lat, final_lon];
}
static calculateBearing(lat1, lon1, lat2, lon2) {
const lat1Rad = (Math.PI / 180) * (lat1);
const lat2Rad = (Math.PI / 180) * (lat2);
const deltaLon = (Math.PI / 180) * (lon2 - lon1);
const y = Math.sin(deltaLon) * Math.cos(lat2Rad);
const x =
Math.cos(lat1Rad) * Math.sin(lat2Rad) -
Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLon);
let bearing = Math.atan2(y, x);
bearing = (180 / Math.PI) * (bearing);
bearing = (bearing + 360) % 360; // Normalize to 0-360 degrees
return bearing;
}
You can see the error here. The red sphere indicates the calculated lat/lon on a bearing (calculated from the previous two points) at a distance of 500 meters. Its position should be at the end of a theoretical line projecting from the second to last point, through the last point but it’s off by several degrees. Could this be a floating point error?