Aircraft Receivers

Signals from radio-navigation stations are received by specialised radio receivers on-board the aircraft as follows:

The RxData Structure

struct RxData     //DATA STRUCTURE FOR A RECEIVER
{
  int Syn;          //current position of tuning synchro
  int SynHi[3];     //synchro position for highest frequency in each band
  int SynLo[3];     //synchro position for lowest frequency in each band
  int WB;           //currently selected waveband
  int Sig;          //signal strength delivered by receiver's IF amp
  int Tone[3];      //tone levels delivered to receiver's AF stage input
  int Valid;        //NAV data validation bits
  long Frq;         //frequency to which receiver is currently tuned
  double ISR;       //selected inbound VOR radial or ILS runway heading
  double OSR;       //selected outbound VOR radial
  double Brg;       //bearing of tuned station from receiver
  double RadDev;    //deviation of aircraft from selected radial
  double StrOff;    //required steering offset from station
  double ReqHdg;    //heading the aircraft must fly
  double DistTD;    //ILS distance to touch-down
  double PrvDst;    //dist to/from stn at previous program pass
  double HdgErr;    //horizontal (VOR/ILS) deviation correction command
  double GsErr;     //aircraft's ILS glideslope deviation
  double DesErr;    //difference between required and actual angle of descent
  double Atten;     //signal attenuation divisor due to receiver being off-tune
  BOOL dFrq;        //set TRUE by Receivers() when receiver is re-tuned
  BOOL capture;     //indicates a selected radial has been captured
  BOOL OnOff;       //receiver's on/off switch
  BOOL CctBrk;      //receiver's d/c power supply circuit breaker
  BOOL SynBrk;      //receiver's synchro a/c power supply circuit breaker
  struct TxData *t; //pointer to the TxData structure of the
}                   //dominant currently on-tune station.
  *Rx[10];          //Array of pointers to NumRx receiver data structures 
To access the Rx[ ] pointer-array efficiently within for() loops we use a secondary array of pointers pRx[ ] which contains pointers to the elements of the Rx[ ] array:

pRx[ ] is declared inside the RxSig() function where it is used exclusively.

The following function determines the signal strength for all receivers of the type which receives the type of station whose TxData is pointed to by 't'. It also calculates the possible separate audio tone levels for each of the three possible pitches of 1020Hz, 1300Hz and 3000Hz.

int RxSig(t) {
  int RxType [] = {  //Type of Stn received by Type of Rx
    0,               //0       NDB              0      ADF
    0,               //1       RRG              0      ADF
    1,               //2       VOR              1      NAV
    1,               //3     VOR/DME            1      NAV
    1,               //4       ILS              1      NAV
    1,               //5     ILS/DME            1      NAV
    1,               //6       DME              1      NAV
    2,               //7       AMK              2      MKR
    2,               //8       BMK              2      MKR
    2,               //9       OMK              2      MKR
    2,               //10      MMK              2      MKR
    2                //11      IMK              2      MKR
  };

  //An array of pointers to pointers to RxData structures
  struct RxData **pRx[] = {
    Rx,     //points to Rx[] element ptg to RxData for ADF1
    Rx + 4, //points to Rx[] element ptg to RxData for NAV1
    Rx + 8, //points to Rx[] element ptg to RxData for MKR1
    Rx + 10 //points to the element beyond end of Rx array
  },
    *r,     //points to RxData struct of rx being dealt with
    **rx,   //points to element of Rx[] containing 'r'

    /*The following pointer points to the element of Rx[] 
      after the one containing the pointer to last RxData 
      structure for the type of receiver concerned */
    **RX,

    /*The following pointer points to the element within pRx[]
      (above) which points to the element within Rx[ ] which 
      points to the RxData structure of the first receiver of 
      the type which receives the type of station whose TxData 
      structure is pointed to by 't'. */

    ***prx = pRx + *( RxType + t->StnType );

for(rx = *prx, RX = *(prx + 1); rx < RX; rx++) {  //FOR EACH RECEIVER OF THIS TYPE...
    if((r = *rx) > NULL) {                        //If Rx[rx] contains a ptr to an existing RxData structure..
      if(r->dFrq == TRUE) {                       //If this rx has been re-tuned since the last station scan...
        r->dFrq = FALSE;                          //Cancel 'frequency changed' flag
        r->Atten = DeTune(t->Frq, r-Frq);         //Get its detuning attenuation divisor 
      } 

  /* Get the signal strength of this station at the aircraft 
     and divide it by the de-tuning attenuation of receiver's 
     passband. Rescale it from a floating point double to an 
     interger ranging from 0 to 255. If the resulting signal 
     is the strongest so far encountered during this station 
     scan THEN set it as receiver's current signal strength,
     and set this station as dominant on-tune station. */

      if((Sig = (int)(255 * TxSig(t)/r->Atten)) > r->Sig) {	
        r->Sig = Sig; r->t = t;

        /*If the station's Morse key is down, and this is the 
        strongest station keying at this pitch, make this the 
        sound level for this pitch of tone. */

        if((t->MorseKey == TRUE)&&(r->Tone[t->pitch] < Sig))
          r->Tone[t->pitch] = Sig;
      }
    }
  }
}
This function checks each receiver's on/off switch and dc power circuit breaker and then determines the frequency to which it is currently tuned. If the receiver has been retuned since the last pass, the new frequency is stored and a 'frequency changed' flag is set in the receiver's RxData structure. If the receiver is switched off or its circuit breaker is out, its frequency is set to zero. The signal and tone levels of all receivers are reset to zero ready for the next station scan.
RxInput() {
  long(*GetFrq[])(struct RxData *) = {
    ADFfrq, ADFfrq,                     //function returning ADF rx frequency
    ADFfrq, ADFfrq,
    NAVfrq, NAVfrq,                     //function returning NAV rx frequency
    NAVfrq, NAVfrq,
    MKRfrq,MKRfrq                       //function returning Marker frequency
  };
  struct RxData *r;                     //points to RxData of current rx
    **rx;                               //ptr to Rx[] element holding 'r'
    **RX = Rx + 10;
  static int r = 0;                     //element number of Rx[] range 0 to 9
  long frq;                             //current receiver frequency
  register n = 0;                       //element number of Rx[]

  for(rx = Rx; rx <= RX; rx++, n++)     //for all receivers
  {
    if((r = *rx) > NULL)                //if an rx installed in this 'position'
    {

      if(r->CctBrk == TRUE && r->OnOff == TRUE) {    //if rx's dc circuit breaker closed and rx is switched on
         if((frq = (*(GetFrq + rx))(r)) != r->Frq) { //if receiver has been retuned
            r->Frq = frq;                            //store new frequency
            r->dFrq = TRUE;                          //indicate that it has changed
        }
      }
      else r->Frq = 0;	                //frequency = 0 means rx inoperative
    }
    r->Sig = 0;		                //clear the dominant signal strength

    for(register x = 0; x < 3; x++)
      r->Tone[x] = 0;                   //clear the Morse tone levels
  }
}

Transmitter Simulation

The function below simulates the activity of all active stations by controlling the keying of their callsigns and computing their strength strengths and audio tone levels presented to each receiver.

Whenever a station's Morse tone duration timer expires, the Transmitters() function reloads the station's Morse tone duration timer with the duration of the next dot, dash, inter-element, inter-letter or delay specified in its callsign string and flips the state of the Morse key from tone-on to tone-off or vice versa. This function should be called roughly every 200 milliseconds.


TxScan() {                         //NAVIGATION STATION SCANNER
  static double Sigma, InvDst;     //For computing height of 
  static int N;                    //ground under aircraft.
  static struct TxData **tx;       //Pointer to an element in 
                                   //Tx[ ] pointer array.
  struct TxData *t;                //Pointer to a TxData (ie a 
                                   //station data) structure.
  for(tx = Tx; tx <= TxHi; tx++) { //for each element in the Tx[] pointer array

    /*If it contains a pointer to a TxData structure
      and if it is the end of current Morse element
      then first reverse the state of the Morse key. */

    if(((t = *tx) > NULL) && (--(t->MorseTimer) < 0)) {
      t->MorseKey = !(t->MorseKey);

      /*if we've reached the end of the current sequence of
        dots and dashes then first reset the pointer to the 
        start of the Morse Code buffer. */

      if(*(t->pMorse) == '\0') {                       
        t->pMorse = t->Morse;

        /*If the station has a multiple and if it has been 
          repeated the required number of times, then get
          the next part of the call sign. */

        if(t->Single == FALSE) && ((--(t->Repeat) < 0))
          SetUpCallSign(t);
      }
      //Set timer to the duration of the next dash or dot
      t->MorseTimer = *(t->pMorse)++;
    }
    RxSig(t); //compute the station's signal for each receiver

    /*If the station is an ILS or an ILS/DME then add in the
      inverse of the station's distance from the aircraft and
      the inverse of their height differences divided by the
      distance between them. Note: (--(t->Repeat) < 0) above 
      avoids the possibility of a division by zero error. */

    if((t->StnType == 4 || t->StnType == 5) && (t->Dst > 0)) {
      InvDst += 1 / t->Dst;       //add inverse dist
      Sigma += t->Ht / t->Dst;    //add dist/height
    }
  }
  //Compute estimated height of ground beneath aircraft
  Air.GndHt = Sigma / (N * InvDst); 
}

This page's parent within this Web Site. About this Web Site. Its home page. Email its Author.