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.jsBest 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});