This class creates hold and manages flights along 3 predetermined routes. These routes have been chosen to exercise the flight guidance software's ability to fly the aircraft in different directions along both short-legged circuitous and long-legged great-circle routes.
This class facilitates the creation of, and holds, an ordered list of the waypoints for each route. Necessarily, it also holds a list of routes. There are only 3 routes in this demonstration applet, all of which are pre-determined. They cannot be altered by the user. However, the class has been designed to provide a future external client class with the means to enable users to build their own routes.
Whenever a new route is selected by the user, the init() method steps along the route - waypoint-by-waypoint - placing in each one's object data the distances and bearings of its next and previous neighbours in the route. This information is used by WpEnc.class during its management of the aircraft's encounter with each waypoint.
A flight along a route is managed by the advance() method. A flight starts with the aircraft leaving (receding from) its airport of origin. This is regarded as the first waypoint. The aircraft therefore starts off in an encounter with its point of origin. When the aircraft has travelled half way to the next waypoint, the advance() method steps to the next waypoint along the route. This next waypoint thus now becomes the current waypoint being encountered. This stepping process continues until the aircraft reaches its destination (which is also regarded as a waypoint).
/**
* Route Manager for my Moving Map package
* @author Robert J Morton
* @version 18 December 1997 */
class route implements navconst {
private static route CR; //reference to current route object
private static int NR = 3; //number of possible routes
private static int nr = 0; //number of routes built (so far)
private static route[] Routes = new route[NR]; //references to all route objects
private aircraft ac; //reference to current aircraft object
private waypnt WR[]; //array of references to waypoints in route
private int NWR; //total number of waypoints in this route
private int nwr; //number of waypoints so far installed
private int CWN; //number of last waypoint in route
private int cwn; //current waypoint number
private wpenc we; //reference to a waypoint encounter event object
private waypnt pw; //reference to previous waypoint
private waypnt cw; //reference to 'current' waypoint
route(int x) { //CONSTRUCT A NEW ROUTE
NWR = x; //set total number of waypoints in new route
WR = new waypnt[NWR]; //array for the references to the waypoints in new route
nwr = 0; //no waypoints installed yet
Routes[nr++] = this; //add this routes reference to array of references
}
void AddWayPnt(int w) { //ADD A GIVEN WAYPOINT TO A GIVEN ROUTE
if(nwr < NWR) //Provided there's still room,
WR[nwr++] = waypnt.getRef(w); // put new waypoint's object reference
} // in next route array element.
void init() { //INITIALISE THE CURRENTLY-SELECTED ROUTE
if(nwr < 3) return; //not enough waypoints to make a route
CWN = nwr - 1; //index number of the last waypoint in the route
ac = aircraft.getCurrent(); //reference to current aircraft object
double R = ac.getTCR(); //radius of turning circle
for(cwn = CWN ; cwn > 0 ; cwn--) { //for each waypoint in the route except the last
cw = WR[cwn]; //object reference to current waypoint
pw = WR[cwn - 1]; //object reference to 'previous' waypoint
pw.setNext(cw); //current waypoint is previous waypoint's next waypoint
cw.setPrev(pw); //previous waypoint is current waypoint's previous waypoint
ac.reset(pw); //set 'aircraft' to previous waypoint
we = new wpenc(cw); //create an encounter between 'aircraft' and current waypoint
double InRad = cw.gettBrg(); //bearing of previous waypoint ('aircraft') from current one
double D = cw.getDst(); //distance of current waypoint from previous waypoint ('aircraft')
boolean isDestination = false; //indicates current waypoint is not destination
if(cwn == CWN) { //if doing the last waypoint in the route
cw.setNext(cw); //say that this waypoint's next waypoint is itself
cw.setDST(4 * R); //dist to run after final waypoint = 2 * turning circle diameter
cw.setOutRad(cw.getRunHdg()); //'outbound direction = runway heading of destination waypoint
isDestination = true; //current waypoint is the destination
}
cw.setDest(isDestination); //current waypoint is/is not the destination
cw.setInRad(InRad); //set for drawing the approach corridor
cw.setPWD(D); //tell current waypoint distance from previous waypoint
pw.setDST(D); //tell previous waypoint distance to current waypoint
double OutRad = cw.getrBrg(); //Outbound radial to next waypoint
if(D < cw.getRange()) //if close enough for Cartesian approach & turn geometry
OutRad += we.getStrOff(InRad); //subtract the steering offset from the inbound radial
pw.setOutRad(OutRad); //set previous waypoint's outbound radial
double a = ac.BipAng(InRad - cw.getOutRad() + Pi);
double b = R * (1 - Math.cos(a)); //half the width of this waypoint's approach corridor
if(a < 0) b = -b; //make it the same sign as 'a'
cw.setDL(b); //store it as the width for the approach corridor
if(cwn == 1) { //if current waypoint is the second waypoint in route
pw.setPrev(pw); //previous waypoint is the first: its previous is itself
pw.setInRad(ac.getHdg()); //previous waypoint's InRad is its take-off runway heading
}
}
}
boolean advance() { //ADVANCE THE AIRCRAFT ALONG THE CURRENTLY SELECTED ROUTE
if(we.enRoute()) return true; //exit if current waypoint encounter still in progress
if(cwn < CWN) { //if this is not the last waypoint in the route
we = new wpenc(WR[++cwn]); //set up the next waypoint encounter event
return true; //indicate flight still in progress
}
butpanel.getCurrent().stop(); //hit the stop button
return false; //and signal termination of flight
}
void reset() {setAircraftAt(cwn = 0);} //reset aircraft to start of currently selected route
void setNext() { //set aircraft to next waypoint en-route
if(cwn < CWN) setAircraftAt(++cwn);
}
void setPrev() { //set aircraft to previous waypoint en-route
if(cwn > 0) setAircraftAt(--cwn);
}
private void setAircraftAt(int x) { //REPOSITION AIRCRAFT TO GIVEN WAYPOINT IN CURRENT ROUTE
ac = aircraft.getCurrent(); //get reference to current aircraft object
ac.reset(cw = WR[x]); //set aircraft to given waypoint
if(x > 0) //if not at start of route
ac.setHdg(cw.getOutRad()); //set aircraft heading to next waypoint
we = new wpenc(cw); //set up the [next] waypoint encounter event
}
static void setCurrent(int rn) { //set object reference to currently selected route
if(rn >= 0 && rn < NR) { //if the current route number is within bounds
CR = Routes[rn]; //set the corresponding route reference
} else { //else if given route number is out of bounds
CR = Routes[0]; //and set its corresponding reference
} if(CR != null) CR.init(); //initialise the newly-selected route
}
static route getCurrent() {return CR;} //get object reference of currently selected route
static void purge() {nr = 0;} //reset number of routes to zero
}
/* Robert J Morton, the author of this program,
is a poor but Right Honourable Member of the
Ancient and Noble Order of the Long-term Unemployed.
Offers of work please to: robmorton@clara.net */