SG_USING_STD(string);
#include "ATC.hxx"
+#include "transmission.hxx"
//DCL - a complete guess for now.
#define FG_APPROACH_DEFAULT_RANGE 100
-// Contains all information about a plane that the approach control needs
-const int max_planes = 20; // max number of planes on the stack
-const int max_wp = 10; // max number of waypoints for approach phase
+// Contains all the information about a plane that the approach control needs
+const int max_planes = 20; // max number of planes on the stack
+const int max_wp = 10; // max number of waypoints for approach phase
+const double max_ta = 130; // max turning angle for plane during approach
+const double tbm = 20000.0; // min time (in ms) between two messages
+const double lfl = 10.0; // length of final leg
+
struct PlaneApp {
// variables for plane if it's on the radar
// 0 = no contact yet
// 1 = in contact
// 2 = handed off to tower
+ double turn_rate; // standard turning rate of the plane in seconds per degree
+ double desc_rate; // standard descent rate of the plane in feets per minute
+ double clmb_rate; // standard climb rate of the plane in feets per minute
// additional variables if contact has been established
int wpn; // number of waypoints
// first wp in list is airport
// last waypoint point at which contact was established
// second index: 0 = bearing to airport
- // second index: 1 = distance to aiport
+ // second index: 1 = distance to airport
// second index: 2 = alt
// second index: 3 = ETA
// second index: 4 = heading to next waypoint
double dnwp; // distance to next waypoint
double dcc; // closest distance to current assigned course
double dnc; // closest distance to course from next to next to next wp
- double aalt; // assigned alt at next waypoint
+ double aalt; // assigned altitude
double ahdg; // assigned heading
bool on_crs; // is the plane on course?
+ bool wp_change; // way point has changed
double tlm; // time when last message was sent
+ TransCode lmc; // code of last message
};
class FGApproach : public FGATC {
- char type;
- double lon, lat;
- double elev;
- double x, y, z;
- int freq;
int bucket;
- double range;
string active_runway;
double active_rw_hdg;
+ double active_rw_lon;
+ double active_rw_lat;
+ double active_rw_len;
- bool display; // Flag to indicate whether we should be outputting to the display.
- bool displaying; // Flag to indicate whether we are outputting to the display.
- string ident; // Code of the airport its at.
- string name; // Name transmitted in the broadcast.
int num_planes; // number of planes on the stack
PlaneApp planes[max_planes]; // Array of planes
string transmission;
SGPropertyNode *comm1_node;
SGPropertyNode *comm2_node;
+ SGPropertyNode *atcmenu_node;
+ SGPropertyNode *atcopt0_node;
+ SGPropertyNode *atcopt1_node;
+ SGPropertyNode *atcopt2_node;
+ SGPropertyNode *atcopt3_node;
+ SGPropertyNode *atcopt4_node;
+ SGPropertyNode *atcopt5_node;
+ SGPropertyNode *atcopt6_node;
+ SGPropertyNode *atcopt7_node;
+ SGPropertyNode *atcopt8_node;
+ SGPropertyNode *atcopt9_node;
+
// for failure modeling
string trans_ident; // transmitted ident
bool approach_failed; // approach failed?
void Init();
- void Update();
+ void Update(double dt);
// Add new plane to stack if not already registered
// Input: pid - id of plane (name)
// Remove plane from stack if out of range
int RemovePlane();
- //Indicate that this instance should be outputting to the ATC display
- inline void SetDisplay(void) {display = true;}
-
- //Indicate that this instance should not be outputting to the ATC display
- inline void SetNoDisplay(void) {display = false;}
-
- inline char get_type() const { return type; }
- inline double get_lon() const { return lon; }
- inline double get_lat() const { return lat; }
- inline double get_elev() const { return elev; }
- inline double get_x() const { return x; }
- inline double get_y() const { return y; }
- inline double get_z() const { return z; }
inline double get_bucket() const { return bucket; }
- inline int get_freq() const { return freq; }
- inline double get_range() const { return range; }
inline int get_pnum() const { return num_planes; }
- inline const char* GetIdent() { return ident.c_str(); }
inline string get_trans_ident() { return trans_ident; }
- inline string get_name() { return name; }
- inline atc_type GetType() { return APPROACH; }
private:
+ void calc_wp( const int &i);
+
void update_plane_dat();
void get_active_runway();
+ void update_param(const int &i);
+
+ double round_alt( bool hl, double alt );
+
+ double angle_diff_deg( const double &a1, const double &a2);
+
+// ========================================================================
+// get point2 given starting point1 and course and distance
+// input: point1 = heading in degrees, distance
+// input: course in degrees, distance
+// output: point2 = heading in degrees, distance
+// ========================================================================
+ void calc_cd_head_dist(const double &h1, const double &d1,
+ const double &course, const double &dist,
+ double *h2, double *d2);
+
+
// ========================================================================
// get heading and distance between two points; point2 ---> point1
-// input: point1 = heading in degrees, distance
-// input: point2 = heading in degrees, distance
-// ouput: course in degrees, distance
+// input: point1 = heading in degrees, distance
+// input: point2 = heading in degrees, distance
+// output: course in degrees, distance
// ========================================================================
void calc_hd_course_dist(const double &h1, const double &d1,
const double &h2, const double &d2,
double *course, double *dist);
+
+
// ========================================================================
// closest distance between a point and a straigt line in 2 dim.
// the input variables are given in (heading, distance)
SGPropertyNode *lon_node;
SGPropertyNode *lat_node;
SGPropertyNode *elev_node;
+ SGPropertyNode *hdg_node;
+ SGPropertyNode *speed_node;
+ SGPropertyNode *etime_node;
//Update the transmission string
void UpdateTransmission(void);
friend istream& operator>> ( istream&, FGApproach& );
};
-
-inline istream&
-operator >> ( istream& in, FGApproach& a )
-{
- double f;
- char ch;
-
- static bool first_time = true;
- static double julian_date = 0;
- static const double MJD0 = 2415020.0;
- if ( first_time ) {
- julian_date = sgTimeCurrentMJD(0, 0) + MJD0;
- first_time = false;
- }
-
- in >> a.type;
-
- if ( a.type == '[' )
- return in >> skipeol;
-
- in >> a.lat >> a.lon >> a.elev >> f >> a.range
- >> a.ident;
-
- a.name = "";
- in >> ch;
- a.name += ch;
- while(1) {
- //in >> noskipws
- in.unsetf(ios::skipws);
- in >> ch;
- a.name += ch;
- if((ch == '"') || (ch == 0x0A)) {
- break;
- } // we shouldn't need the 0x0A but it makes a nice safely in case someone leaves off the "
- }
- in.setf(ios::skipws);
- //cout << "approach.name = " << a.name << '\n';
-
- a.freq = (int)(f*100.0 + 0.5);
-
- // generate cartesian coordinates
- Point3D geod( a.lon * SGD_DEGREES_TO_RADIANS , a.lat * SGD_DEGREES_TO_RADIANS,
- a.elev * SG_FEET_TO_METER );
- Point3D cart = sgGeodToCart( geod );
- a.x = cart.x();
- a.y = cart.y();
- a.z = cart.z();
-
- // get bucket number
- SGBucket buck(a.lon, a.lat);
- a.bucket = buck.gen_index();
-
- a.trans_ident = a.ident;
- a.approach_failed = false;
-
- return in >> skipeol;
-}
-
#endif // _FG_APPROACH_HXX