I've developed a basic navigation system, and implemented it on the MiG-29. Currently you can only display the navigation system on the console, by pressing the 'P' key, but I will eventually build a GUI to replace this, as well as integrate the system with the cockpit instruments of the MiG-29, including the HSI.

Compass Mode allows you to simply set the HSI Bearing Needle to a fixed direction.

Currently, in GPS mode, any user can enter a single Waypoint (latitude/longitude), or select Home mode by editing the variables at the top of the script, (Alt+E). If you select home mode, than the navigation system will set the waypoint to the initial location where the aircraft is spawned. I like to save a location at the threshold of a runway so I can easily load that location, spawn the aircraft and take-off. In Home mode, it is much easier to navigate back to the runway.

I also plan to write a string array function, so any user can easily enter a waypoint course, of an unlimited number of waypoints. There will be three added parameters for each waypoint besides lat/long, these are altitude, speed and approach bearing. When your GPS coordinates come within a specified radius of each waypoint, the navigation system will switch to the next waypoint, and display the bearing, distance, attitude, speed and approach to the next waypoint.

You can download the MiG-29 script here and replace it in: ./Anteworld/packages/outerra/mig29/mig29.js

**http://www.mediafire.com/view/b3fzr6d8ud93rhi/mig29.js**Best regards,

Uriah

These variables need to be added at the top of the script, allowing any user to select navigation and gps modes, and enter a GPS waypoint to navigate to.

`//GPS/COMPASS NAV MODE SWITCH`

nav_mode = 0; //GPS = 0, Compass = 1

//WAYPOINT MODE SWITCH

gps_mode = 0; //Home = 0, Waypoint = 1

//GPS Waypoint Navigation

var lat_gps_wp_deg = 48.1439; //Latitude Waypoint Degrees, N = 0 to +90, S = 0 to -90

var long_gps_wp_deg = 17.1097; //Longitude Waypoint Degrees, E = 0 to +180, W = 0 to -180

var lat_wp_deg; //Latitude Waypoint Degrees

var long_wp_deg; //Longitude Waypoint Degrees

var lat_deg; //Latitude Degrees

var long_deg; //Longitude Degrees

var lat_orig_deg; //Latitude Origin Degrees

var long_orig_deg; //Longitude Origin Degrees

//Compass Navigation

var compass_nav_deg = 180; // 0 = North, 45 = NE, 90 = East, 135 = SE, 180 = South,

// 125 = SW, 170 = West, 215 = NW

Next the Home waypoint code needs to be added somewhere in the initialize section below where you cache the jsb interface, like:

`function initialize(reload){`

geom = this.get_geomob(0); // get first geometry isntance

jsb = this.jsb(); // get JSBSim interface

snd = this.sound(); // get SoundMan interface

lat_orig_deg = jsb["position/vrp-gc-latitude_deg"]; //Latitude Origin Degrees

long_orig_deg = jsb["position/vrp-longitude_deg"]; //Longitude Origin Degrees

Next a few functions need to be added in-between the initialize section and the update section.

`function rad2deg(angle_rad){return angle_rad*180/PI;}`

function km2mile(kilometer){return kilometer*0.621371;}

Next the core of the navigation system is added to the update section, including the equation to calculate Bearing (forward azimuth) and distance to waypoint. I will eventually add this in as a function so it is more efficient, but I have to re-code some other interface first before I refactor the nav system to integrate the multiple waypoint system.

`//Waypoint Navigation System`

//GPS Sensor

lat_deg = jsb["position/vrp-gc-latitude_deg"]; //Latitude Origin Degrees

long_deg = jsb["position/vrp-longitude_deg"]; //Longitude Origin Degrees

var φ1 = deg2rad(lat_deg); //Latitude Origin Radians

var λ1 = deg2rad(long_deg); //Longitude Origin Radians

var φ2 = deg2rad(lat_wp_deg); //Latitude Waypoint Radians

var λ2 = deg2rad(long_wp_deg); //Longitude Waypoint Radians

//Distance to Waypoint

var R = 6371000; // metres

var Δφ = (φ2-φ1);

var Δλ = (λ2-λ1);

var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +

Math.cos(φ1) * Math.cos(φ2) *

Math.sin(Δλ/2) * Math.sin(Δλ/2);

var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

var waypoint_distance = R * c;

//HSI Bearing to GPS Waypoint (Forward Azimuth)

var y = Math.sin(λ2-λ1) * Math.cos(φ2);

var x = Math.cos(φ1)*Math.sin(φ2) - Math.sin(φ1)*Math.cos(φ2)*Math.cos(λ2-λ1);

var fwd_azimuth = Math.atan2(y, x);

var compass_nav_rad = deg2rad(compass_nav_deg);

//Waypoint Mode

if (gps_mode==0){lat_wp_deg = lat_orig_deg;}

else if (gps_mode==1){lat_wp_deg = lat_gps_wp_deg;}

else {lat_wp_deg = lat_orig_deg;}

if (gps_mode==0){long_wp_deg = long_orig_deg;}

else if (gps_mode==1){long_wp_deg = long_gps_wp_deg;}

else {long_wp_deg = long_orig_deg;}

//HSI Navigation Mode

var hsi_bearing;

if (nav_mode==1){hsi_bearing=compass_nav_rad;}

else if (nav_mode==0){hsi_bearing=fwd_azimuth;}

else {hsi_bearing=fwd_azimuth;}

Next, log the navigation system data to the console at the end of the update section.

` this.log_inf("Fuel Tanks (%): " + (Math.round(jsb['propulsion/tank[0]/pct-full']*100)/100)+" - "`

+ (Math.round(jsb['propulsion/tank[1]/pct-full']*100)/100)+" - "

+ (Math.round(jsb['propulsion/tank[2]/pct-full']*100)/100)+" - "

+ (Math.round(jsb['propulsion/tank[3]/pct-full']*100)/100)

);

this.log_inf("Fuel (lbs): " + (Math.round(jsb['propulsion/tank[0]/contents-lbs']*100)/100)+" - "

+ (Math.round(jsb['propulsion/tank[1]/contents-lbs']*100)/100)+" - "

+ (Math.round(jsb['propulsion/tank[2]/contents-lbs']*100)/100)+" - "

+ (Math.round(jsb['propulsion/tank[3]/contents-lbs']*100)/100)

);

this.log_inf("Mach: " + (Math.round(jsb['velocities/mach']*100)/100));

this.log_inf("Heading (deg): " + (Math.round(rad2deg(jsb['attitude/psi-rad'])*100)/100));

this.log_inf("HSI Bearing (deg): " + rad2deg(hsi_bearing));

if(gps_mode===0){

this.log_inf("Distance Home (miles): " + (Math.round(km2mile(waypoint_distance/1000)*1000)/1000));

}

else if(gps_mode===1){

this.log_inf("Distance to Waypoint (miles): " + (Math.round(km2mile(waypoint_distance/1000)*1000)/1000));

}

else{this.log_inf("Distance Home (miles): " + (Math.round(km2mile(waypoint_distance/1000)*1000)/1000));}

this.log_inf("Latitude: " + lat_deg + ", Longitude: " + long_deg);

this.log_inf("Lat Orig: " + lat_orig_deg + ", Long Orig: " + long_orig_deg);

I've also included the code I used to animate a 3-axis attitude indicator (aka navball) and the HSI. Note: For the HSI, there are two animated BONE joints, the Compass Card and the Bearing Needle. For the HSI to work correctly, the compass card needs to be initially facing 0 degrees due North, and will be rotated to the correct heading. The Bearing Needle takes the forward azimuth angle from the navigation system mode selected, and adds that to the heading, so that the bearing needle is aligned to the compass card. The navball also needs to be initially aligned to 0 degrees due north, and 0 degrees pitch/roll.

` var roll = jsb['attitude/phi-rad'];`

var pitch = jsb['attitude/theta-rad'];

var heading = jsb['attitude/heading-true-rad'];

//HSI Bearing to Waypoint

this.geom.rotate_joint_orig(hsi_heading_line_1, heading-hsi_bearing, {x:1,y:0,z:0});

//HSI Compass

this.geom.rotate_joint_orig(hsi_compass_1, heading, {x:1,y:0,z:0});

//Navball

this.geom.rotate_joint_orig(navball_1, heading, {x:0,y:0,z:-1});

this.geom.rotate_joint_orig(navball_roll_1, roll, {x:0,y:-1,z:0});

this.geom.rotate_joint_orig(navball_pitch_1, pitch, {x:1,y:0,z:0});