X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=inline;f=src%2FATCDCL%2FAILocalTraffic.cxx;h=0e81570aeb5b9f1c7137ab19b3a777556f3609c0;hb=a99ea1c7b5fb0ba69810bbad9b6aca8b4cdc116b;hp=bcaab722e3ae18386c0da2f43ea79a3b3d90fdb1;hpb=2b0588d170418f842a4191c5af3dae3a975c7cae;p=flightgear.git diff --git a/src/ATCDCL/AILocalTraffic.cxx b/src/ATCDCL/AILocalTraffic.cxx index bcaab722e..0e81570ae 100644 --- a/src/ATCDCL/AILocalTraffic.cxx +++ b/src/ATCDCL/AILocalTraffic.cxx @@ -34,15 +34,12 @@ during descent to avoid occasionally landing short or long. # include #endif -#include - #include #include
#include
#include #include -#include -#include +#include #include #include #include @@ -55,16 +52,6 @@ using std::string; #include "AIMgr.hxx" FGAILocalTraffic::FGAILocalTraffic() { - /*ssgBranch *model = sgLoad3DModel( globals->get_fg_root(), - planepath.c_str(), - globals->get_props(), - globals->get_sim_time_sec() ); - *//* - _model = model; - _aip.init(_model); - */ - //SetModel(model); - ATC = globals->get_ATC_mgr(); // TODO - unhardwire this @@ -167,9 +154,9 @@ void FGAILocalTraffic::GetRwyDetails(const string& id) { const FGAirport* apt = fgFindAirportID(id); assert(apt); - FGRunway runway(apt->getActiveRunwayForUsage()); + FGRunway* runway(apt->getActiveRunwayForUsage()); - double hdg = runway._heading; + double hdg = runway->headingDeg(); double other_way = hdg - 180.0; while(other_way <= 0.0) { other_way += 360.0; @@ -177,20 +164,18 @@ void FGAILocalTraffic::GetRwyDetails(const string& id) { // move to the +l end/center of the runway //cout << "Runway center is at " << runway._lon << ", " << runway._lat << '\n'; - Point3D origin = Point3D(runway._lon, runway._lat, aptElev); - Point3D ref = origin; double tshlon, tshlat, tshr; double tolon, tolat, tor; - rwy.length = runway._length * SG_FEET_TO_METER; - rwy.width = runway._width * SG_FEET_TO_METER; - geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), other_way, + rwy.length = runway->lengthM(); + rwy.width = runway->widthM(); + geo_direct_wgs_84 ( aptElev, runway->latitude(), runway->longitude(), other_way, rwy.length / 2.0 - 25.0, &tshlat, &tshlon, &tshr ); - geo_direct_wgs_84 ( aptElev, ref.lat(), ref.lon(), hdg, + geo_direct_wgs_84 ( aptElev, runway->latitude(), runway->longitude(), hdg, rwy.length / 2.0 - 25.0, &tolat, &tolon, &tor ); // Note - 25 meters in from the runway end is a bit of a hack to put the plane ahead of the user. // now copy what we need out of runway into rwy - rwy.threshold_pos = Point3D(tshlon, tshlat, aptElev); - Point3D takeoff_end = Point3D(tolon, tolat, aptElev); + rwy.threshold_pos = SGGeod::fromDegM(tshlon, tshlat, aptElev); + SGGeod takeoff_end = SGGeod::fromDegM(tolon, tolat, aptElev); //cout << "Threshold position = " << tshlon << ", " << tshlat << ", " << aptElev << '\n'; //cout << "Takeoff position = " << tolon << ", " << tolat << ", " << aptElev << '\n'; rwy.hdg = hdg; @@ -248,7 +233,7 @@ bool FGAILocalTraffic::Init(const string& callsign, const string& ICAO, Operatin //cout << "In Init(), initialState = " << initialState << endl; operatingState = initialState; - Point3D orthopos; + SGVec3d orthopos; switch(operatingState) { case PARKED: tuned_station = ground; @@ -264,7 +249,7 @@ bool FGAILocalTraffic::Init(const string& callsign, const string& ICAO, Operatin vel = 0.0; slope = 0.0; _pos = ourGate->pos; - _pos.setelev(aptElev); + _pos.setElevationM(aptElev); _hdg = ourGate->heading; Transform(); @@ -287,10 +272,10 @@ bool FGAILocalTraffic::Init(const string& callsign, const string& ICAO, Operatin freeTaxi = true; // Set a position and orientation in an approximate place for hold short. //cout << "rwy.width = " << rwy.width << '\n'; - orthopos = Point3D((rwy.width / 2.0 + 10.0) * -1.0, 0.0, 0.0); + orthopos = SGVec3d((rwy.width / 2.0 + 10.0) * -1.0, 0.0, 0.0); // TODO - set the x pos to be +ve if a RH parallel rwy. _pos = ortho.ConvertFromLocal(orthopos); - _pos.setelev(aptElev); + _pos.setElevationM(aptElev); _hdg = rwy.hdg + 90.0; // TODO - reset the heading if RH rwy. _pitch = 0.0; @@ -330,8 +315,8 @@ bool FGAILocalTraffic::Init(const string& callsign, const string& ICAO, Operatin touchAndGo = false; if(initialLeg == DOWNWIND) { - _pos = ortho.ConvertFromLocal(Point3D(1000*patternDirection, 800, 0.0)); - _pos.setelev(rwy.threshold_pos.elev() + 1000 * SG_FEET_TO_METER); + _pos = ortho.ConvertFromLocal(SGVec3d(1000*patternDirection, 800, 0.0)); + _pos.setElevationM(rwy.threshold_pos.getElevationM() + 1000 * SG_FEET_TO_METER); _hdg = rwy.hdg + 180.0; leg = DOWNWIND; elevInitGood = false; @@ -349,9 +334,7 @@ bool FGAILocalTraffic::Init(const string& callsign, const string& ICAO, Operatin Transform(); } else { // Default to initial position on threshold for now - _pos.setlat(rwy.threshold_pos.lat()); - _pos.setlon(rwy.threshold_pos.lon()); - _pos.setelev(rwy.threshold_pos.elev()); + _pos = rwy.threshold_pos; _hdg = rwy.hdg; // Now we've set the position we can do the ground elev @@ -462,7 +445,7 @@ void FGAILocalTraffic::Update(double dt) { // we shouldn't really need this since there's a LOD of 10K on the whole plane anyway I think. // At the moment though I need to to avoid DList overflows - the whole plane LOD obviously isn't getting picked up. if(!_invisible) { - if(dclGetHorizontalSeparation(_pos, Point3D(fgGetDouble("/position/longitude-deg"), fgGetDouble("/position/latitude-deg"), 0.0)) > 8000) _aip.setVisible(false); + if(dclGetHorizontalSeparation(_pos, SGGeod::fromDegM(fgGetDouble("/position/longitude-deg"), fgGetDouble("/position/latitude-deg"), 0.0)) > 8000) _aip.setVisible(false); else _aip.setVisible(true); } else { _aip.setVisible(false); @@ -578,8 +561,8 @@ void FGAILocalTraffic::Update(double dt) { if(!inAir) { DoGroundElev(); if(!elevInitGood) { - if(_aip.getSGLocation()->get_cur_elev_m() > -9990.0) { - _pos.setelev(_aip.getSGLocation()->get_cur_elev_m() + wheelOffset); + if(_ground_elevation_m > -9990.0) { + _pos.setElevationM(_ground_elevation_m + wheelOffset); //cout << "TAKEOFF_ROLL, POS = " << pos.lon() << ", " << pos.lat() << ", " << pos.elev() << '\n'; //Transform(); _aip.setVisible(true); @@ -596,8 +579,8 @@ void FGAILocalTraffic::Update(double dt) { //cout << "*" << flush; if(!elevInitGood) { //DoGroundElev(); - if(_aip.getSGLocation()->get_cur_elev_m() > -9990.0) { - _pos.setelev(_aip.getSGLocation()->get_cur_elev_m() + wheelOffset); + if(_ground_elevation_m > -9990.0) { + _pos.setElevationM(_ground_elevation_m + wheelOffset); //Transform(); _aip.setVisible(true); //Transform(); @@ -623,7 +606,7 @@ void FGAILocalTraffic::Update(double dt) { //cout << "C" << endl; node* np = new node; np->struct_type = NODE; - np->pos = ortho.ConvertFromLocal(Point3D(0.0, 10.0, 0.0)); + np->pos = ortho.ConvertFromLocal(SGVec3d(0.0, 10.0, 0.0)); path.push_back(np); } else { //cout << "D" << endl; @@ -656,8 +639,8 @@ void FGAILocalTraffic::Update(double dt) { //cout << "In PARKED\n"; if(!elevInitGood) { DoGroundElev(); - if(_aip.getSGLocation()->get_cur_elev_m() > -9990.0) { - _pos.setelev(_aip.getSGLocation()->get_cur_elev_m() + wheelOffset); + if(_ground_elevation_m > -9990.0) { + _pos.setElevationM(_ground_elevation_m + wheelOffset); //Transform(); _aip.setVisible(true); //Transform(); @@ -812,8 +795,8 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { double turn_time = 60.0; // seconds - TODO - check this guess double turn_circumference; double turn_radius; - Point3D orthopos = ortho.ConvertToLocal(_pos); // ortho position of the plane - //cout << "runway elev = " << rwy.threshold_pos.elev() << ' ' << rwy.threshold_pos.elev() * SG_METER_TO_FEET << '\n'; + SGVec3d orthopos = ortho.ConvertToLocal(_pos); // ortho position of the plane + //cout << "runway elev = " << rwy.threshold_pos.getElevationM() << ' ' << rwy.threshold_pos.getElevationM() * SG_METER_TO_FEET << '\n'; //cout << "elev = " << _pos.elev() << ' ' << _pos.elev() * SG_METER_TO_FEET << '\n'; // HACK FOR TESTING - REMOVE @@ -836,8 +819,8 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { double dveldt = 5.0; vel += dveldt * dt; } - if(_aip.getSGLocation()->get_cur_elev_m() > -9990.0) { - _pos.setelev(_aip.getSGLocation()->get_cur_elev_m() + wheelOffset); + if(_ground_elevation_m > -9990.0) { + _pos.setElevationM(_ground_elevation_m + wheelOffset); } IAS = vel + (cos((_hdg - wind_from) * DCL_DEGREES_TO_RADIANS) * wind_speed); if(IAS >= 70) { @@ -855,7 +838,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { // (decided in FGTower and accessed through GetCrosswindConstraint(...)). // According to AIM, traffic should climb to within 300ft of pattern altitude before commencing crosswind turn. // TODO - At hot 'n high airports this may be 500ft AGL though - need to make this a variable. - if((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET > 700) { + if((_pos.getElevationM() - rwy.threshold_pos.getElevationM()) * SG_METER_TO_FEET > 700) { double cc = 0.0; if(tower->GetCrosswindConstraint(cc)) { if(orthopos.y() > cc) { @@ -870,7 +853,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { } // Need to check for levelling off in case we can't turn crosswind as soon // as we would like due to other traffic. - if((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET > 1000) { + if((_pos.getElevationM() - rwy.threshold_pos.getElevationM()) * SG_METER_TO_FEET > 1000) { slope = 0.0; _pitch = 0.0; IAS = 80.0; // FIXME - use smooth transistion to new speed and attitude. @@ -892,7 +875,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { break; case CROSSWIND: goAround = false; - if((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET > 1000) { + if((_pos.getElevationM() - rwy.threshold_pos.getElevationM()) * SG_METER_TO_FEET > 1000) { slope = 0.0; _pitch = 0.0; IAS = 80.0; // FIXME - use smooth transistion to new speed @@ -914,7 +897,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { case TURN2: SetTrack(rwy.hdg - (180 * patternDirection)); // just in case we didn't make height on crosswind - if((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET > 1000) { + if((_pos.getElevationM() - rwy.threshold_pos.getElevationM()) * SG_METER_TO_FEET > 1000) { slope = 0.0; _pitch = 0.0; IAS = 80.0; // FIXME - use smooth transistion to new speed @@ -926,12 +909,12 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { break; case DOWNWIND: // just in case we didn't make height on crosswind - if(((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET > 995) && ((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET < 1015)) { + if(((_pos.getElevationM() - rwy.threshold_pos.getElevationM()) * SG_METER_TO_FEET > 995) && ((_pos.getElevationM() - rwy.threshold_pos.getElevationM()) * SG_METER_TO_FEET < 1015)) { slope = 0.0; _pitch = 0.0; IAS = 90.0; // FIXME - use smooth transistion to new speed } - if((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET >= 1015) { + if((_pos.getElevationM() - rwy.threshold_pos.getElevationM()) * SG_METER_TO_FEET >= 1015) { slope = -1.0; _pitch = -1.0; IAS = 90.0; // FIXME - use smooth transistion to new speed @@ -1056,20 +1039,20 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { if(descending) { if(orthopos.y() < -50.0) { double thesh_offset = 30.0; - slope = atan((_pos.elev() - fgGetAirportElev(airportID)) / (orthopos.y() - thesh_offset)) * DCL_RADIANS_TO_DEGREES; + slope = atan((_pos.getElevationM() - fgGetAirportElev(airportID)) / (orthopos.y() - thesh_offset)) * DCL_RADIANS_TO_DEGREES; //cout << "slope = " << slope << ", elev = " << _pos.elev() << ", apt_elev = " << fgGetAirportElev(airportID) << ", op.y = " << orthopos.y() << '\n'; if(slope < -10.0) slope = -10.0; _savedSlope = slope; _pitch = -4.0; IAS = 70.0; } else { - if(_pos.elev() < (rwy.threshold_pos.elev()+10.0+wheelOffset)) { - if(_aip.getSGLocation()->get_cur_elev_m() > -9990.0) { - if(_pos.elev() < (_aip.getSGLocation()->get_cur_elev_m() + wheelOffset + 1.0)) { + if(_pos.getElevationM() < (rwy.threshold_pos.getElevationM()+10.0+wheelOffset)) { + if(_ground_elevation_m > -9990.0) { + if(_pos.getElevationM() < (_ground_elevation_m + wheelOffset + 1.0)) { slope = -2.0; _pitch = 1.0; IAS = 55.0; - } else if(_pos.elev() < (_aip.getSGLocation()->get_cur_elev_m() + wheelOffset + 5.0)) { + } else if(_pos.getElevationM() < (_ground_elevation_m + wheelOffset + 5.0)) { slope = -4.0; _pitch = -2.0; IAS = 60.0; @@ -1094,15 +1077,15 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { // Try and track the extended centreline SetTrack(rwy.hdg - (0.2 * orthopos.x())); //cout << "orthopos.x() = " << orthopos.x() << " hdg = " << hdg << '\n'; - if(_pos.elev() < (rwy.threshold_pos.elev()+20.0+wheelOffset)) { + if(_pos.getElevationM() < (rwy.threshold_pos.getElevationM()+20.0+wheelOffset)) { DoGroundElev(); // Need to call it here expicitly on final since it's only called // for us in update(...) when the inAir flag is false. } - if(_pos.elev() < (rwy.threshold_pos.elev()+10.0+wheelOffset)) { + if(_pos.getElevationM() < (rwy.threshold_pos.getElevationM()+10.0+wheelOffset)) { //slope = -1.0; //_pitch = 1.0; - if(_aip.getSGLocation()->get_cur_elev_m() > -9990.0) { - if((_aip.getSGLocation()->get_cur_elev_m() + wheelOffset) > _pos.elev()) { + if(_ground_elevation_m > -9990.0) { + if((_ground_elevation_m + wheelOffset) > _pos.getElevationM()) { slope = 0.0; _pitch = 0.0; leg = LANDING_ROLL; @@ -1118,8 +1101,8 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) { case LANDING_ROLL: //inAir = false; descending = false; - if(_aip.getSGLocation()->get_cur_elev_m() > -9990.0) { - _pos.setelev(_aip.getSGLocation()->get_cur_elev_m() + wheelOffset); + if(_ground_elevation_m > -9990.0) { + _pos.setElevationM(_ground_elevation_m + wheelOffset); } track = rwy.hdg; dveldt = -5.0; @@ -1301,7 +1284,7 @@ void FGAILocalTraffic::ProcessCallback(int code) { } } -void FGAILocalTraffic::ExitRunway(const Point3D& orthopos) { +void FGAILocalTraffic::ExitRunway(const SGVec3d& orthopos) { //cout << "In ExitRunway" << endl; //cout << "Runway ID is " << rwy.ID << endl; @@ -1324,7 +1307,7 @@ void FGAILocalTraffic::ExitRunway(const Point3D& orthopos) { node* rwyExit = *(exitNodes.begin()); //int gateID; //This might want to be more persistant at some point while(nItr != exitNodes.end()) { - d = ortho.ConvertToLocal((*nItr)->pos).y() - ortho.ConvertToLocal(_pos).y(); //FIXME - consider making orthopos a class variable + d = ortho.ConvertToLocal((*nItr)->pos).y() - ortho.ConvertToLocal(_pos).y(); //FIXME - consider making orthopos a class variable if(d > 0.0) { if(d < dist) { dist = d; @@ -1472,8 +1455,7 @@ void FGAILocalTraffic::Taxi(double dt) { // If we have reached turning point then get next point and turn onto that heading // Look out for the finish!! - //Point3D orthopos = ortho.ConvertToLocal(pos); // ortho position of the plane - desiredTaxiHeading = GetHeadingFromTo(_pos, nextTaxiNode->pos); + desiredTaxiHeading = GetHeadingFromTo(_pos, nextTaxiNode->pos); bool lastNode = (taxiPathPos == path.size() ? true : false); if(lastNode) { @@ -1505,8 +1487,8 @@ void FGAILocalTraffic::Taxi(double dt) { double slope = 0.0; _pos = dclUpdatePosition(_pos, track, slope, dist); //cout << "Updated position...\n"; - if(_aip.getSGLocation()->get_cur_elev_m() > -9990) { - _pos.setelev(_aip.getSGLocation()->get_cur_elev_m() + wheelOffset); + if(_ground_elevation_m > -9990) { + _pos.setElevationM(_ground_elevation_m + wheelOffset); } // else don't change the elev until we get a valid ground elev again! } else if(lastNode) { if(taxiState == TD_LINING_UP) { @@ -1524,8 +1506,8 @@ void FGAILocalTraffic::Taxi(double dt) { double slope = 0.0; _pos = dclUpdatePosition(_pos, track, slope, dist); //cout << "Updated position...\n"; - if(_aip.getSGLocation()->get_cur_elev_m() > -9990) { - _pos.setelev(_aip.getSGLocation()->get_cur_elev_m() + wheelOffset); + if(_ground_elevation_m > -9990) { + _pos.setElevationM(_ground_elevation_m + wheelOffset); } // else don't change the elev until we get a valid ground elev again! if(fabs(_hdg - rwy.hdg) <= 1.0) { operatingState = IN_PATTERN; @@ -1554,32 +1536,24 @@ void FGAILocalTraffic::Taxi(double dt) { // Either this function or the logic of how often it is called // will almost certainly change. void FGAILocalTraffic::DoGroundElev() { - // It would be nice if we could set the correct tile center here in order to get a correct - // answer with one call to the function, but what I tried in the two commented-out lines - // below only intermittently worked, and I haven't quite groked why yet. - //SGBucket buck(pos.lon(), pos.lat()); - //aip.getSGLocation()->set_tile_center(Point3D(buck.get_center_lon(), buck.get_center_lat(), 0.0)); - // Only do the proper hitlist stuff if we are within visible range of the viewer. double visibility_meters = fgGetDouble("/environment/visibility-m"); FGViewer* vw = globals->get_current_view(); - if(dclGetHorizontalSeparation(_pos, Point3D(vw->getLongitude_deg(), vw->getLatitude_deg(), 0.0)) > visibility_meters) { - _aip.getSGLocation()->set_cur_elev_m(aptElev); + if(dclGetHorizontalSeparation(_pos, SGGeod::fromDegM(vw->getLongitude_deg(), vw->getLatitude_deg(), 0.0)) > visibility_meters) { + _ground_elevation_m = aptElev; return; } // FIXME: make shure the pos.lat/pos.lon values are in degrees ... double range = 500.0; - double lat = _aip.getSGLocation()->getLatitude_deg(); - double lon = _aip.getSGLocation()->getLongitude_deg(); - if (!globals->get_tile_mgr()->scenery_available(lat, lon, range)) { + if (!globals->get_tile_mgr()->scenery_available(_aip.getPosition(), range)) { // Try to shedule tiles for that position. - globals->get_tile_mgr()->update( _aip.getSGLocation(), range ); + globals->get_tile_mgr()->update( _aip.getPosition(), range ); } // FIXME: make shure the pos.lat/pos.lon values are in degrees ... double alt; - if (globals->get_scenery()->get_elevation_m(lat, lon, 20000.0, alt, 0)) - _aip.getSGLocation()->set_cur_elev_m(alt); + if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(_aip.getPosition(), 20000), alt, 0)) + _ground_elevation_m = alt; }