The Route Management Class

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.

Route Creation

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.

Initialisation

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.

Management

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  */