1
0
Fork 0
flightgear/test_suite/unit_tests/AI/test_traffic.cxx

747 lines
32 KiB
C++
Raw Normal View History

/*
* Copyright (C) 2020 James Turner
*
* This file is part of the program FlightGear.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "test_traffic.hxx"
2021-03-27 08:00:22 +00:00
#include <math.h>
#include <cstring>
#include <memory>
#include "test_suite/FGTestApi/NavDataCache.hxx"
#include "test_suite/FGTestApi/TestDataLogger.hxx"
#include "test_suite/FGTestApi/testGlobals.hxx"
2021-02-16 20:22:08 +00:00
#include <simgear/math/sg_geodesy.hxx>
#include <AIModel/AIAircraft.hxx>
#include <AIModel/AIFlightPlan.hxx>
#include <AIModel/AIManager.hxx>
#include <AIModel/performancedb.hxx>
#include <Airports/airport.hxx>
#include <Airports/airportdynamicsmanager.hxx>
2021-03-08 20:57:58 +00:00
#include <Airports/groundnetwork.hxx>
#include <Scenery/scenery.hxx>
2021-02-13 08:27:56 +00:00
#include <Time/TimeManager.hxx>
2021-03-10 20:27:06 +00:00
#include <Traffic/TrafficMgr.hxx>
2021-05-24 14:50:37 +00:00
2021-03-10 20:27:06 +00:00
#include <simgear/math/sg_geodesy.hxx>
2021-05-24 14:50:37 +00:00
#include <simgear/debug/logstream.hxx>
2021-07-01 19:27:15 +00:00
#include <simgear/io/iostreams/sgstream.hxx>
2021-03-27 08:00:22 +00:00
#include <simgear/timing/sg_time.hxx>
#include <ATC/atc_mgr.hxx>
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
2021-05-24 14:50:37 +00:00
/////////////////////////////////////////////////////////////////////////////
// Set up function for each test.
void TrafficTests::setUp()
{
2021-05-24 14:50:37 +00:00
time_t t = time(0); // get time now
2021-02-16 20:22:08 +00:00
this->currentWorldTime = t - t%86400 + 86400 + 9 * 60;
2021-05-24 14:50:37 +00:00
FGTestApi::setUp::initTestGlobals("Traffic");
FGTestApi::setUp::initNavDataCache();
2021-03-10 20:27:06 +00:00
fgSetBool("sim/ai/enabled", true);
fgSetBool("sim/traffic-manager/enabled", true);
2021-03-20 12:19:16 +00:00
fgSetBool("sim/signals/fdm-initialized", true);
2021-03-10 20:27:06 +00:00
fgSetInt("/environment/visibility-m", 1000);
fgSetBool("/environment/realwx/enabled", false);
fgSetBool("/environment/metar/valid", false);
fgSetBool("/sim/terrasync/ai-data-update-now", false);
2021-03-20 12:19:16 +00:00
globals->append_data_path(SGPath::fromUtf8(FG_TEST_SUITE_DATA), false);
// ensure EDDF has a valid ground net for parking testing
FGAirport::clearAirportsCache();
FGAirportRef egph = FGAirport::getByIdent("EGPH");
egph->testSuiteInjectGroundnetXML(SGPath::fromUtf8(FG_TEST_SUITE_DATA) / "EGPH.groundnet.xml");
2021-02-20 07:22:56 +00:00
FGAirportRef yssy = FGAirport::getByIdent("YSSY");
yssy->testSuiteInjectGroundnetXML(SGPath::fromUtf8(FG_TEST_SUITE_DATA) / "YSSY.groundnet.xml");
2021-02-21 07:22:31 +00:00
FGAirportRef ybbn = FGAirport::getByIdent("YBBN");
ybbn->testSuiteInjectGroundnetXML(SGPath::fromUtf8(FG_TEST_SUITE_DATA) / "YBBN.groundnet.xml");
2021-04-25 17:57:36 +00:00
globals->add_new_subsystem<PerformanceDB>(SGSubsystemMgr::GENERAL);
globals->add_new_subsystem<FGATCManager>(SGSubsystemMgr::GENERAL);
globals->add_new_subsystem<FGAIManager>(SGSubsystemMgr::GENERAL);
globals->add_new_subsystem<flightgear::AirportDynamicsManager>(SGSubsystemMgr::GENERAL);
2021-02-21 07:22:31 +00:00
globals->add_new_subsystem<FGTrafficManager>(SGSubsystemMgr::GENERAL);
globals->get_subsystem_mgr()->bind();
globals->get_subsystem_mgr()->init();
globals->get_subsystem_mgr()->postinit();
2021-05-24 14:50:37 +00:00
// This means time is always 00:09
2021-02-16 20:22:08 +00:00
FGTestApi::adjustSimulationWorldTime(this->currentWorldTime);
}
// Clean up after each test.
void TrafficTests::tearDown()
{
FGTestApi::tearDown::shutdownTestGlobals();
}
void TrafficTests::testPushback()
{
2021-03-10 20:27:06 +00:00
FGAirportRef departureAirport = FGAirport::getByIdent("EGPH");
2021-03-10 20:27:06 +00:00
FGAirportRef arrivalAirport = FGAirport::getByIdent("EGPF");
2021-02-16 20:22:08 +00:00
2021-03-10 20:27:06 +00:00
fgSetString("/sim/presets/airport-id", departureAirport->getId());
2021-02-16 20:22:08 +00:00
fgSetInt("/environment/visibility-m", 1000);
fgSetInt("/environment/metar/base-wind-speed-kt", 10);
fgSetInt("/environment/metar/base-wind-dir-deg", 160);
2021-02-13 08:27:56 +00:00
2021-03-10 20:27:06 +00:00
// Time to depart
std::string dep = getTimeString(30);
// Time to arrive
std::string arr = getTimeString(320);
2021-02-13 08:27:56 +00:00
2021-03-10 20:27:06 +00:00
const int radius = 18.0;
const int cruiseAltFt = 32000;
const int cruiseSpeedKnots = 80;
const char* flighttype = "gate";
2021-02-13 08:27:56 +00:00
FGAISchedule* schedule = new FGAISchedule(
2021-03-10 20:27:06 +00:00
"B737", "KLM", departureAirport->getId(), "G-BLA", "ID", false, "B737", "KLM", "N", flighttype, radius, 8);
FGScheduledFlight* flight = new FGScheduledFlight("", "", departureAirport->getId(), arrivalAirport->getId(), 24, dep, arr, "WEEK", "HBR_BN_2");
2021-02-13 08:27:56 +00:00
schedule->assign(flight);
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
2021-03-10 20:27:06 +00:00
const SGGeod position = departureAirport->geod();
ParkingAssignment parking = departureAirport->getDynamics()->getParkingByName("north-cargo208");
FGTestApi::setPositionAndStabilise(departureAirport->getDynamics()->getParkingByName("ga206").parking()->geod());
aiAircraft->setPerformance("jet_transport", "");
aiAircraft->setCompany("KLM");
aiAircraft->setAcType("B737");
aiAircraft->setSpeed(0);
aiAircraft->setBank(0);
2021-03-10 20:27:06 +00:00
const string flightPlanName = departureAirport->getId() + "-" + arrivalAirport->getId() + ".xml";
2021-03-10 20:27:06 +00:00
const double crs = SGGeodesy::courseDeg(departureAirport->geod(), arrivalAirport->geod()); // direct course
2021-05-24 14:50:37 +00:00
time_t departureTime = globals->get_time_params()->get_cur_time();
departureTime = departureTime - 90;
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
flightPlanName, crs, departureTime,
2021-03-10 20:27:06 +00:00
departureAirport, arrivalAirport, true, radius,
cruiseAltFt, // cruise alt
position.getLatitudeDeg(),
position.getLongitudeDeg(),
cruiseSpeedKnots, "gate",
aiAircraft->getAcType(),
2021-03-10 20:27:06 +00:00
aiAircraft->getCompany()));
2021-02-13 08:27:56 +00:00
2021-03-10 20:27:06 +00:00
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
aiAircraft = flyAI(aiAircraft, "flight_EGPH_EGPF_" + std::to_string(departureTime));
2021-02-13 08:27:56 +00:00
}
2021-03-10 20:27:06 +00:00
void TrafficTests::testPushbackCargo()
2021-02-13 08:27:56 +00:00
{
FGAirportRef egph = FGAirport::getByIdent("EGPH");
2021-03-10 20:27:06 +00:00
2021-02-13 08:27:56 +00:00
FGAirportRef egpf = FGAirport::getByIdent("EGPF");
fgSetString("/sim/presets/airport-id", "EGPH");
2021-03-10 20:27:06 +00:00
// Time to depart
std::string dep = getTimeString(30);
// Time to arrive
std::string arr = getTimeString(320);
2021-02-13 08:27:56 +00:00
FGAISchedule* schedule = new FGAISchedule(
2021-02-20 07:22:56 +00:00
"B737", "KLM", "EGPH", "G-BLA", "ID", false, "B737", "KLM", "N", "cargo", 24, 8);
2021-02-13 08:27:56 +00:00
FGScheduledFlight* flight = new FGScheduledFlight("", "", "EGPH", "EGPF", 24, dep, arr, "WEEK", "HBR_BN_2");
schedule->assign(flight);
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
2021-03-10 20:27:06 +00:00
2021-02-13 08:27:56 +00:00
const SGGeod position = egph->geod();
2021-03-10 20:27:06 +00:00
ParkingAssignment parking = egph->getDynamics()->getParkingByName("north-cargo208");
2021-02-13 08:27:56 +00:00
FGTestApi::setPositionAndStabilise(egph->getDynamics()->getParkingByName("ga206").parking()->geod());
aiAircraft->setPerformance("jet_transport", "");
aiAircraft->setCompany("KLM");
aiAircraft->setAcType("B737");
aiAircraft->setSpeed(0);
aiAircraft->setBank(0);
const string flightPlanName = egph->getId() + "-" + egpf->getId() + ".xml";
2021-02-20 07:22:56 +00:00
const int radius = 16.0;
2021-02-13 08:27:56 +00:00
const int cruiseAltFt = 32000;
const int cruiseSpeedKnots = 80;
2021-02-13 08:27:56 +00:00
const double crs = SGGeodesy::courseDeg(egph->geod(), egpf->geod()); // direct course
2021-05-24 14:50:37 +00:00
time_t departureTime = globals->get_time_params()->get_cur_time();
departureTime = departureTime - 90;
2021-02-13 08:27:56 +00:00
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
flightPlanName, crs, departureTime,
egph, egpf, true, radius,
cruiseAltFt, // cruise alt
position.getLatitudeDeg(),
position.getLongitudeDeg(),
2021-02-20 07:22:56 +00:00
cruiseSpeedKnots, "cargo",
2021-02-13 08:27:56 +00:00
aiAircraft->getAcType(),
2021-03-10 20:27:06 +00:00
aiAircraft->getCompany()));
2021-02-13 08:27:56 +00:00
2021-03-10 20:27:06 +00:00
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
2021-02-13 08:27:56 +00:00
2021-03-27 08:00:22 +00:00
aiAircraft = flyAI(aiAircraft, "flight_cargo_EGPH_EGPF_" + std::to_string(departureTime));
2021-02-20 07:22:56 +00:00
}
void TrafficTests::testChangeRunway()
{
FGAirportRef departureAirport = FGAirport::getByIdent("EGPH");
2021-03-10 20:27:06 +00:00
2021-02-20 07:22:56 +00:00
FGAirportRef arrivalAirport = FGAirport::getByIdent("EGPF");
fgSetString("/sim/presets/airport-id", departureAirport->getId());
fgSetInt("/environment/visibility-m", 1000);
fgSetInt("/environment/metar/base-wind-speed-kt", 10);
fgSetInt("/environment/metar/base-wind-dir-deg", 160);
2021-02-13 08:27:56 +00:00
2021-03-10 20:27:06 +00:00
// Time to depart
std::string dep = getTimeString(60);
// Time to arrive
std::string arr = getTimeString(320);
2021-02-20 07:22:56 +00:00
const int radius = 24.0;
const int cruiseAltFt = 32000;
const int cruiseSpeedKnots = 80;
const char* flighttype = "gate";
FGAISchedule* schedule = new FGAISchedule(
"B737", "KLM", departureAirport->getId(), "G-BLA", "ID", false, "B737", "KLM", "N", flighttype, radius, 8);
FGScheduledFlight* flight = new FGScheduledFlight("", "", departureAirport->getId(), arrivalAirport->getId(), 24, dep, arr, "WEEK", "HBR_BN_2");
schedule->assign(flight);
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
2021-03-10 20:27:06 +00:00
2021-02-20 07:22:56 +00:00
const SGGeod position = departureAirport->geod();
FGTestApi::setPositionAndStabilise(position);
aiAircraft->setPerformance("jet_transport", "");
aiAircraft->setCompany("KLM");
aiAircraft->setAcType("B737");
aiAircraft->setSpeed(0);
aiAircraft->setBank(0);
const string flightPlanName = departureAirport->getId() + "-" + arrivalAirport->getId() + ".xml";
const double crs = SGGeodesy::courseDeg(departureAirport->geod(), arrivalAirport->geod()); // direct course
2021-05-24 14:50:37 +00:00
time_t departureTime = globals->get_time_params()->get_cur_time();
departureTime = departureTime - 90;
2021-02-20 07:22:56 +00:00
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
flightPlanName, crs, departureTime,
departureAirport, arrivalAirport, true, radius,
cruiseAltFt, // cruise alt
position.getLatitudeDeg(),
position.getLongitudeDeg(),
cruiseSpeedKnots, flighttype,
aiAircraft->getAcType(),
2021-03-10 20:27:06 +00:00
aiAircraft->getCompany()));
2021-02-20 07:22:56 +00:00
2021-03-10 20:27:06 +00:00
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
2021-02-20 07:22:56 +00:00
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
2021-03-27 08:00:22 +00:00
aiAircraft = flyAI(aiAircraft, "flight_runway_EGPH_EGPF_" + std::to_string(departureTime));
2021-02-20 07:22:56 +00:00
}
void TrafficTests::testPushforward()
{
FGAirportRef departureAirport = FGAirport::getByIdent("YSSY");
2021-03-10 20:27:06 +00:00
2021-02-21 07:22:31 +00:00
FGAirportRef arrivalAirport = FGAirport::getByIdent("YBBN");
2021-02-20 07:22:56 +00:00
fgSetString("/sim/presets/airport-id", departureAirport->getId());
2021-03-10 20:27:06 +00:00
// Time to depart
std::string dep = getTimeString(60);
// Time to arrive
std::string arr = getTimeString(320);
2021-02-20 07:22:56 +00:00
const int radius = 8.0;
const int cruiseAltFt = 32000;
const int cruiseSpeedKnots = 80;
const char* flighttype = "ga";
FGAISchedule* schedule = new FGAISchedule(
"B737", "KLM", departureAirport->getId(), "G-BLA", "ID", false, "B737", "KLM", "N", flighttype, radius, 8);
FGScheduledFlight* flight = new FGScheduledFlight("", "", departureAirport->getId(), arrivalAirport->getId(), 24, dep, arr, "WEEK", "HBR_BN_2");
schedule->assign(flight);
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
2021-03-10 20:27:06 +00:00
2021-02-20 07:22:56 +00:00
const SGGeod position = departureAirport->geod();
FGTestApi::setPositionAndStabilise(position);
aiAircraft->setPerformance("jet_transport", "");
aiAircraft->setCompany("KLM");
aiAircraft->setAcType("B737");
aiAircraft->setSpeed(0);
aiAircraft->setBank(0);
const string flightPlanName = departureAirport->getId() + "-" + arrivalAirport->getId() + ".xml";
const double crs = SGGeodesy::courseDeg(departureAirport->geod(), arrivalAirport->geod()); // direct course
2021-05-24 14:50:37 +00:00
time_t departureTime = globals->get_time_params()->get_cur_time();
departureTime = departureTime - 90;
2021-02-20 07:22:56 +00:00
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
flightPlanName, crs, departureTime,
departureAirport, arrivalAirport, true, radius,
cruiseAltFt, // cruise alt
position.getLatitudeDeg(),
position.getLongitudeDeg(),
cruiseSpeedKnots, flighttype,
aiAircraft->getAcType(),
2021-03-10 20:27:06 +00:00
aiAircraft->getCompany()));
2021-02-20 07:22:56 +00:00
2021-03-10 20:27:06 +00:00
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
2021-02-20 07:22:56 +00:00
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
2021-03-10 20:27:06 +00:00
aiAircraft = flyAI(aiAircraft, "flight_ga_YSSY_depart_" + std::to_string(departureTime));
2021-02-13 08:27:56 +00:00
}
2021-02-22 17:17:47 +00:00
void TrafficTests::testPushforwardSpeedy()
{
FGAirportRef departureAirport = FGAirport::getByIdent("YSSY");
2021-03-10 20:27:06 +00:00
2021-02-22 17:17:47 +00:00
FGAirportRef arrivalAirport = FGAirport::getByIdent("YBBN");
fgSetString("/sim/presets/airport-id", departureAirport->getId());
2021-03-10 20:27:06 +00:00
// Time to depart
std::string dep = getTimeString(60);
// Time to arrive
std::string arr = getTimeString(320);
2021-02-22 17:17:47 +00:00
const int radius = 8.0;
const int cruiseAltFt = 32000;
const int cruiseSpeedKnots = 80;
const char* flighttype = "ga";
FGAISchedule* schedule = new FGAISchedule(
"B737", "KLM", departureAirport->getId(), "G-BLA", "ID", false, "B737", "KLM", "N", flighttype, radius, 8);
FGScheduledFlight* flight = new FGScheduledFlight("", "", departureAirport->getId(), arrivalAirport->getId(), 24, dep, arr, "WEEK", "HBR_BN_2");
schedule->assign(flight);
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
2021-03-10 20:27:06 +00:00
2021-02-22 17:17:47 +00:00
const SGGeod position = departureAirport->geod();
FGTestApi::setPositionAndStabilise(position);
aiAircraft->setPerformance("NotValid", "jet_transport");
aiAircraft->setCompany("KLM");
aiAircraft->setAcType("B737");
aiAircraft->setSpeed(0);
aiAircraft->setBank(0);
const string flightPlanName = departureAirport->getId() + "-" + arrivalAirport->getId() + ".xml";
const double crs = SGGeodesy::courseDeg(departureAirport->geod(), arrivalAirport->geod()); // direct course
2021-05-24 14:50:37 +00:00
time_t departureTime = globals->get_time_params()->get_cur_time();
departureTime = departureTime - 90;
2021-02-22 17:17:47 +00:00
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
flightPlanName, crs, departureTime,
departureAirport, arrivalAirport, true, radius,
cruiseAltFt, // cruise alt
position.getLatitudeDeg(),
position.getLongitudeDeg(),
cruiseSpeedKnots, flighttype,
aiAircraft->getAcType(),
2021-03-10 20:27:06 +00:00
aiAircraft->getCompany()));
2021-02-22 17:17:47 +00:00
2021-03-10 20:27:06 +00:00
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
2021-02-22 17:17:47 +00:00
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
2021-03-10 20:27:06 +00:00
aiAircraft = flyAI(aiAircraft, "flight_ga_YSSY_fast_depart_" + std::to_string(departureTime));
2021-02-22 17:17:47 +00:00
}
2021-02-21 07:22:31 +00:00
void TrafficTests::testPushforwardParkYBBN()
{
FGAirportRef departureAirport = FGAirport::getByIdent("YBBN");
2021-03-10 20:27:06 +00:00
FGAirportRef arrivalAirport = FGAirport::getByIdent("YSSY");
2021-02-21 07:22:31 +00:00
2021-03-10 20:27:06 +00:00
fgSetString("/sim/presets/airport-id", arrivalAirport->getId());
2021-02-21 07:22:31 +00:00
2021-03-10 20:27:06 +00:00
// Time to depart
std::string dep = getTimeString(60);
// Time to arrive
std::string arr = getTimeString(3260);
2021-02-21 07:22:31 +00:00
const int radius = 8.0;
const int cruiseAltFt = 32000;
const int cruiseSpeedKnots = 80;
const char* flighttype = "ga";
FGAISchedule* schedule = new FGAISchedule(
"B737", "KLM", departureAirport->getId(), "G-BLA", "ID", false, "B737", "KLM", "N", flighttype, radius, 8);
FGScheduledFlight* flight = new FGScheduledFlight("gaParkYSSY", "", departureAirport->getId(), arrivalAirport->getId(), 24, dep, arr, "WEEK", "HBR_BN_2");
schedule->assign(flight);
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
2021-03-10 20:27:06 +00:00
2021-02-21 07:22:31 +00:00
const SGGeod position = departureAirport->geod();
FGTestApi::setPositionAndStabilise(position);
aiAircraft->setPerformance("ga", "");
aiAircraft->setCompany("KLM");
aiAircraft->setAcType("B737");
aiAircraft->setSpeed(0);
aiAircraft->setBank(0);
const string flightPlanName = departureAirport->getId() + "-" + arrivalAirport->getId() + ".xml";
const double crs = SGGeodesy::courseDeg(departureAirport->geod(), arrivalAirport->geod()); // direct course
2021-05-24 14:50:37 +00:00
time_t departureTime = globals->get_time_params()->get_cur_time();
departureTime = departureTime - 90;
2021-02-21 07:22:31 +00:00
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
flightPlanName, crs, departureTime,
departureAirport, arrivalAirport, true, radius,
cruiseAltFt, // cruise alt
position.getLatitudeDeg(),
position.getLongitudeDeg(),
cruiseSpeedKnots, flighttype,
aiAircraft->getAcType(),
2021-03-10 20:27:06 +00:00
aiAircraft->getCompany()));
2021-02-21 07:22:31 +00:00
2021-03-10 20:27:06 +00:00
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
2021-02-21 07:22:31 +00:00
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
2021-03-10 20:27:06 +00:00
aiAircraft = flyAI(aiAircraft, "flight_ga_YSSY_YBBN_park_" + std::to_string(departureTime));
2021-03-08 20:57:58 +00:00
int shortestDistance = 10000;
const FGParkingList& parkings(arrivalAirport->groundNetwork()->allParkings());
FGParkingList::const_iterator it;
FGParking* nearestParking = 0;
for (it = parkings.begin(); it != parkings.end(); ++it) {
2021-03-10 20:27:06 +00:00
int currentDistance = !nearestParking ? 9999 : SGGeodesy::distanceM(nearestParking->geod(), (*it)->geod());
if (currentDistance < shortestDistance) {
2021-03-08 20:57:58 +00:00
nearestParking = (*it);
shortestDistance = currentDistance;
2021-03-27 08:00:22 +00:00
/*
2021-03-10 20:27:06 +00:00
std::cout << (*it)->name() << "\t" << (*it)->getHeading()
<< "\t" << shortestDistance << "\t" << (*it)->geod() << "\n";
2021-03-27 08:00:22 +00:00
*/
2021-03-08 20:57:58 +00:00
}
}
2021-03-10 20:27:06 +00:00
CPPUNIT_ASSERT_EQUAL(true, aiAircraft->getDie());
2021-03-08 20:57:58 +00:00
}
2021-05-09 18:46:52 +00:00
void TrafficTests::testPushforwardParkYBBNRepeatGa()
2021-03-08 20:57:58 +00:00
{
FGAirportRef departureAirport = FGAirport::getByIdent("YBBN");
2021-03-10 20:27:06 +00:00
FGAirportRef arrivalAirport = FGAirport::getByIdent("YSSY");
2021-03-08 20:57:58 +00:00
2021-03-10 20:27:06 +00:00
fgSetString("/sim/presets/airport-id", arrivalAirport->getId());
2021-03-08 20:57:58 +00:00
2021-03-10 20:27:06 +00:00
// Time to depart
2021-05-24 14:50:37 +00:00
std::string dep = getTimeString(120);
2021-03-10 20:27:06 +00:00
// Time to arrive
std::string arr = getTimeString(3260);
// Time to arrive back
std::string ret = getTimeString(6460);
2021-03-08 20:57:58 +00:00
const int radius = 8.0;
const int cruiseAltFt = 32000;
const int cruiseSpeedKnots = 80;
const char* flighttype = "ga";
FGAISchedule* schedule = new FGAISchedule(
2021-05-24 14:50:37 +00:00
"B737", "KLM", departureAirport->getId(), "G-BLA", "TST_BN_1", false, "B737", "KLM", "N", flighttype, radius, 8);
FGScheduledFlight* flight = new FGScheduledFlight("gaParkYSSY", "VFR", departureAirport->getId(), arrivalAirport->getId(), 24, dep, arr, "WEEK", "TST_BN_1");
2021-03-08 20:57:58 +00:00
schedule->assign(flight);
2021-05-24 14:50:37 +00:00
FGScheduledFlight* returnFlight = new FGScheduledFlight("gaParkYSSY", "", arrivalAirport->getId(), departureAirport->getId(), 24, arr, ret, "WEEK", "TST_BN_1");
2021-03-10 20:27:06 +00:00
schedule->assign(returnFlight);
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
2021-03-10 20:27:06 +00:00
2021-03-08 20:57:58 +00:00
const SGGeod position = departureAirport->geod();
FGTestApi::setPositionAndStabilise(position);
aiAircraft->setPerformance("ga", "");
aiAircraft->setCompany("KLM");
aiAircraft->setAcType("B737");
aiAircraft->setSpeed(0);
aiAircraft->setBank(0);
const string flightPlanName = departureAirport->getId() + "-" + arrivalAirport->getId() + ".xml";
const double crs = SGGeodesy::courseDeg(departureAirport->geod(), arrivalAirport->geod()); // direct course
2021-05-24 14:50:37 +00:00
time_t departureTime = globals->get_time_params()->get_cur_time();
departureTime = departureTime - 90;
2021-03-08 20:57:58 +00:00
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
flightPlanName, crs, departureTime,
departureAirport, arrivalAirport, true, radius,
cruiseAltFt, // cruise alt
position.getLatitudeDeg(),
position.getLongitudeDeg(),
cruiseSpeedKnots, flighttype,
aiAircraft->getAcType(),
2021-03-10 20:27:06 +00:00
aiAircraft->getCompany()));
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
2021-03-08 20:57:58 +00:00
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
2021-03-10 20:27:06 +00:00
aiAircraft = flyAI(aiAircraft, "flight_ga_YSSY_YBBN_park_repeat" + std::to_string(departureTime));
int shortestDistance = 10000;
const FGParkingList& parkings(arrivalAirport->groundNetwork()->allParkings());
FGParkingList::const_iterator it;
FGParking* nearestParking = 0;
for (it = parkings.begin(); it != parkings.end(); ++it) {
int currentDistance = !nearestParking ? 9999 : SGGeodesy::distanceM(nearestParking->geod(), (*it)->geod());
if (currentDistance < shortestDistance) {
nearestParking = (*it);
shortestDistance = currentDistance;
}
}
2021-03-27 08:00:22 +00:00
CPPUNIT_ASSERT_EQUAL(true, (aiAircraft->getDie() || aiAircraft->GetFlightPlan()->getCurrentWaypoint()->getName() == "park"));
2021-03-10 20:27:06 +00:00
}
2021-05-09 18:46:52 +00:00
void TrafficTests::testPushforwardParkYBBNRepeatGate()
{
FGAirportRef departureAirport = FGAirport::getByIdent("YBBN");
FGAirportRef arrivalAirport = FGAirport::getByIdent("YSSY");
fgSetString("/sim/presets/airport-id", arrivalAirport->getId());
// Time to depart
2021-05-24 14:50:37 +00:00
std::string dep = getTimeString(10);
2021-05-09 18:46:52 +00:00
// Time to arrive
std::string arr = getTimeString(3260);
// Time to arrive back
std::string ret = getTimeString(6460);
const int radius = 20.0;
const int cruiseAltFt = 32000;
const int cruiseSpeedKnots = 80;
const char* flighttype = "gate";
FGAISchedule* schedule = new FGAISchedule(
"B737", "KLM", departureAirport->getId(), "G-BLA", "TST_BN_2", false, "B737", "KLM", "N", flighttype, radius, 8);
2021-05-24 14:50:37 +00:00
FGScheduledFlight* flight = new FGScheduledFlight("gateParkYSSY", "VFR", departureAirport->getId(), arrivalAirport->getId(), 24, dep, arr, "WEEK", "TST_BN_1");
2021-05-09 18:46:52 +00:00
schedule->assign(flight);
2021-05-24 14:50:37 +00:00
FGScheduledFlight* returnFlight = new FGScheduledFlight("gateParkYSSY", "", arrivalAirport->getId(), departureAirport->getId(), 24, arr, ret, "WEEK", "TST_BN_1");
2021-05-09 18:46:52 +00:00
schedule->assign(returnFlight);
const SGGeod position = departureAirport->geod();
FGTestApi::setPositionAndStabilise(position);
SGSharedPtr<FGAIAircraft> aiAircraft = new FGAIAircraft{schedule};
2021-05-24 14:50:37 +00:00
2021-05-09 18:46:52 +00:00
aiAircraft->setPerformance("gate", "");
aiAircraft->setCompany("KLM");
aiAircraft->setAcType("B737");
aiAircraft->setSpeed(0);
aiAircraft->setBank(0);
const string flightPlanName = departureAirport->getId() + "-" + arrivalAirport->getId() + ".xml";
const double crs = SGGeodesy::courseDeg(departureAirport->geod(), arrivalAirport->geod()); // direct course
2021-05-24 14:50:37 +00:00
time_t departureTime = globals->get_time_params()->get_cur_time();
departureTime = departureTime - 90;
2021-05-09 18:46:52 +00:00
std::unique_ptr<FGAIFlightPlan> fp(new FGAIFlightPlan(aiAircraft,
flightPlanName, crs, departureTime,
departureAirport, arrivalAirport, true, radius,
cruiseAltFt, // cruise alt
position.getLatitudeDeg(),
position.getLongitudeDeg(),
cruiseSpeedKnots, flighttype,
aiAircraft->getAcType(),
aiAircraft->getCompany()));
CPPUNIT_ASSERT_EQUAL(fp->isValidPlan(), true);
aiAircraft->FGAIBase::setFlightPlan(std::move(fp));
globals->get_subsystem<FGAIManager>()->attach(aiAircraft);
2021-05-24 14:50:37 +00:00
CPPUNIT_ASSERT_EQUAL(aiAircraft->GetFlightPlan()->isValidPlan(), true);
2021-05-09 18:46:52 +00:00
aiAircraft = flyAI(aiAircraft, "flight_gate_YSSY_YBBN_park_repeat" + std::to_string(departureTime));
int shortestDistance = 10000;
const FGParkingList& parkings(arrivalAirport->groundNetwork()->allParkings());
FGParkingList::const_iterator it;
FGParking* nearestParking = 0;
for (it = parkings.begin(); it != parkings.end(); ++it) {
int currentDistance = !nearestParking ? 9999 : SGGeodesy::distanceM(nearestParking->geod(), (*it)->geod());
if (currentDistance < shortestDistance) {
nearestParking = (*it);
shortestDistance = currentDistance;
}
}
CPPUNIT_ASSERT_EQUAL(true, (aiAircraft->getDie() || aiAircraft->GetFlightPlan()->getCurrentWaypoint()->getName() == "park"));
}
2021-03-27 08:00:22 +00:00
/**
*
*
*
*/
2021-07-01 19:27:15 +00:00
FGAIAircraft * TrafficTests::flyAI(SGSharedPtr<FGAIAircraft> aiAircraft, std::string testname) {
2021-03-27 08:00:22 +00:00
int lineIndex = 0;
2021-05-24 14:50:37 +00:00
CPPUNIT_ASSERT_EQUAL(aiAircraft->GetFlightPlan()->isValidPlan(), true);
2021-05-09 18:46:52 +00:00
2021-05-24 14:50:37 +00:00
time_t now = globals->get_time_params()->get_cur_time();
tm* startTime = localtime(&now);
time_t departureTime = aiAircraft->GetFlightPlan()->getStartTime();
2021-05-09 18:46:52 +00:00
2021-05-24 14:50:37 +00:00
char buffer[50];
char buffer2[50];
2021-05-09 18:46:52 +00:00
2021-05-24 14:50:37 +00:00
strftime (buffer,50,"%FT%TZ",startTime);
strftime (buffer2,50,"%FT%TZ", localtime(&departureTime));
SG_LOG(SG_AI, SG_DEBUG, "Start Time " << buffer << " First Departure " << buffer2);
2021-03-27 08:00:22 +00:00
char fname [160];
2021-05-24 14:50:37 +00:00
time_t t = time(0); // get time now
2021-07-01 19:27:15 +00:00
sprintf (fname, "%ld.csv", t);
SGPath p = SGPath::desktop() / (testname + fname);
sg_ofstream csvFile;
csvFile.open(p);
2021-03-27 08:00:22 +00:00
if(!csvFile.is_open()) {
2021-02-16 20:22:08 +00:00
SG_LOG(SG_AI, SG_DEBUG, "CSV File " << fname << " couldn't be opened");
2021-03-27 08:00:22 +00:00
}
2021-05-09 18:46:52 +00:00
if (sglog().get_log_priority() <= SG_DEBUG) {
2021-05-24 14:50:37 +00:00
aiAircraft->dumpCSVHeader(csvFile);
2021-07-01 19:27:15 +00:00
FGTestApi::setUp::logLinestringsToKML(testname);
2021-05-09 18:46:52 +00:00
}
2021-03-08 20:57:58 +00:00
flightgear::SGGeodVec geods = flightgear::SGGeodVec();
2021-03-20 12:19:16 +00:00
int iteration = 1;
2021-03-08 20:57:58 +00:00
int lastLeg = -1;
2021-03-27 08:00:22 +00:00
double lastHeading = -500;
double headingSum = 0;
2021-05-24 14:50:37 +00:00
int startSpeed = aiAircraft->GetFlightPlan()->getCurrentWaypoint()->getSpeed();
aiAircraft->AccelTo(startSpeed);
2021-03-10 20:27:06 +00:00
for (size_t i = 0; i < 12000000 && !(aiAircraft->getDie()) && aiAircraft->GetFlightPlan()->getLeg() < 10; i++) {
2021-05-24 14:50:37 +00:00
CPPUNIT_ASSERT_EQUAL(aiAircraft->GetFlightPlan()->isValidPlan(), true);
2021-03-10 20:27:06 +00:00
if (!aiAircraft->getDie()) {
2021-03-08 20:57:58 +00:00
// collect position
2021-03-10 20:27:06 +00:00
if (geods.empty() ||
2021-03-27 08:00:22 +00:00
SGGeodesy::distanceM(aiAircraft->getGeodPos(), geods.back()) > 0.05) {
2021-03-10 20:27:06 +00:00
geods.insert(geods.end(), aiAircraft->getGeodPos());
2021-03-08 20:57:58 +00:00
}
2021-03-27 08:00:22 +00:00
// follow aircraft
2021-03-10 20:27:06 +00:00
if (geods.empty() ||
(aiAircraft->getSpeed() > 0 &&
2021-05-09 18:46:52 +00:00
SGGeodesy::distanceM(aiAircraft->getGeodPos(), FGTestApi::getPosition()) > 10000 &&
2021-03-10 20:27:06 +00:00
/* stop following towards the end*/
aiAircraft->GetFlightPlan()->getLeg() < 8))
{
FGTestApi::setPosition(aiAircraft->getGeodPos());
2021-03-08 20:57:58 +00:00
}
}
2021-03-27 08:00:22 +00:00
// Leg has been incremented
if (aiAircraft->GetFlightPlan()->getLeg() != lastLeg ) {
// The current WP is really in our new leg
2021-05-09 18:46:52 +00:00
if (sglog().get_log_priority() <= SG_DEBUG) {
sprintf(buffer, "AI Leg %d Callsign %s Iteration %d", lastLeg, aiAircraft->getCallSign().c_str(), iteration);
FGTestApi::writeGeodsToKML(buffer, geods);
}
2021-03-20 12:19:16 +00:00
if (aiAircraft->GetFlightPlan()->getLeg() < lastLeg) {
iteration++;
}
2021-03-08 20:57:58 +00:00
lastLeg = aiAircraft->GetFlightPlan()->getLeg();
SGGeod last = geods.back();
geods.clear();
geods.insert(geods.end(), last);
}
2021-03-27 08:00:22 +00:00
if (lastHeading==-500) {
lastHeading = aiAircraft->getTrueHeadingDeg();
}
headingSum += (lastHeading-aiAircraft->getTrueHeadingDeg());
lastHeading = aiAircraft->getTrueHeadingDeg();
aiAircraft->dumpCSV(csvFile, lineIndex++);
// A flight without loops should never reach 400°
CPPUNIT_ASSERT_LESSEQUAL(400.0, headingSum);
2021-03-08 20:57:58 +00:00
CPPUNIT_ASSERT_LESSEQUAL(10, aiAircraft->GetFlightPlan()->getLeg());
2021-05-24 14:50:37 +00:00
CPPUNIT_ASSERT_MESSAGE( "Aircraft has not completed test in time.", i < 3000000);
2021-02-16 20:22:08 +00:00
// Arrived at a parking
int beforeNextDepTime = aiAircraft->getTrafficRef()->getDepartureTime() - 30;
2021-05-24 14:50:37 +00:00
if (iteration > 1
&& aiAircraft->GetFlightPlan()->getLeg() == 1
2021-02-16 20:22:08 +00:00
&& aiAircraft->getSpeed() == 0
&& this->currentWorldTime < beforeNextDepTime) {
FGTestApi::adjustSimulationWorldTime(beforeNextDepTime);
2021-02-16 20:22:08 +00:00
SG_LOG(SG_AI, SG_BULK, "Jumped time " << (beforeNextDepTime - this->currentWorldTime) );
this->currentWorldTime = beforeNextDepTime;
2021-05-24 14:50:37 +00:00
}
2021-03-27 08:00:22 +00:00
FGTestApi::runForTime(1);
2021-02-16 20:22:08 +00:00
FGTestApi::adjustSimulationWorldTime(++this->currentWorldTime);
2021-03-08 20:57:58 +00:00
}
lastLeg = aiAircraft->GetFlightPlan()->getLeg();
2021-03-20 12:19:16 +00:00
sprintf(buffer, "AI Leg %d Callsign %s Iteration %d", lastLeg, aiAircraft->getCallSign().c_str(), iteration);
2021-05-09 18:46:52 +00:00
if (sglog().get_log_priority() <= SG_DEBUG) {
FGTestApi::writeGeodsToKML(buffer, geods);
}
2021-02-21 07:22:31 +00:00
geods.clear();
2021-03-27 08:00:22 +00:00
csvFile.close();
2021-03-10 20:27:06 +00:00
return aiAircraft;
2021-02-21 07:22:31 +00:00
}
2021-03-10 20:27:06 +00:00
std::string TrafficTests::getTimeString(int timeOffset)
{
char ret[11];
2021-05-24 14:50:37 +00:00
time_t rawtime = globals->get_time_params()->get_cur_time();
2021-03-10 20:27:06 +00:00
rawtime = rawtime + timeOffset;
tm* timeinfo = gmtime(&rawtime);
strftime(ret, 11, "%w/%H:%M:%S", timeinfo);
return ret;
}