1
0
Fork 0

Move the user aircraft proxy into the AIManger

This should ensure there is always a proxy for the user in the AI
world for parking and ATC purposes.
This commit is contained in:
James Turner 2017-09-24 18:13:15 +02:00
parent 561e39e94f
commit a8e1fd4fd0
6 changed files with 77 additions and 79 deletions

View file

@ -951,3 +951,8 @@ SGGeod FGAIBase::getGeodPos() const
return pos;
}
void FGAIBase::setGeodPos(const SGGeod& geod)
{
pos = geod;
}

View file

@ -113,7 +113,8 @@ public:
void setFlightPlan(std::unique_ptr<FGAIFlightPlan> f);
SGGeod getGeodPos() const;
void setGeodPos(const SGGeod& pos);
SGVec3d getCartPosAt(const SGVec3d& off) const;
SGVec3d getCartPos() const;

View file

@ -133,6 +133,16 @@ FGAIManager::init() {
globals->get_commands()->addCommand("load-scenario", this, &FGAIManager::loadScenarioCommand);
globals->get_commands()->addCommand("unload-scenario", this, &FGAIManager::unloadScenarioCommand);
_environmentVisiblity = fgGetNode("/environment/visibility-m");
// Create an (invisible) AIAircraft representation of the current
// users's aircraft, that mimicks the user aircraft's behavior.
_userAircraft = new FGAIAircraft;
_userAircraft->setCallSign ( fgGetString("/sim/multiplay/callsign") );
_userAircraft->setGeodPos(globals->get_aircraft_position());
_userAircraft->setPerformance("", "jet_transport");
_userAircraft->setHeading(fgGetDouble("/orientation/heading-deg"));
_userAircraft->setSpeed(fgGetDouble("/velocities/groundspeed-kt"));
}
void
@ -187,6 +197,7 @@ FGAIManager::shutdown()
ai_list.clear();
_environmentVisiblity.clear();
_userAircraft.clear();
globals->get_commands()->removeCommand("load-scenario");
globals->get_commands()->removeCommand("unload-scenario");
@ -220,7 +231,8 @@ void FGAIManager::removeDeadItem(FGAIBase* base)
}
void
FGAIManager::update(double dt) {
FGAIManager::update(double dt)
{
// initialize these for finding nearest thermals
range_nearest = 10000.0;
strength = 0.0;
@ -228,7 +240,7 @@ FGAIManager::update(double dt) {
if (!enabled->getBoolValue())
return;
fetchUserState();
fetchUserState(dt);
// partition the list into dead followed by alive
auto firstAlive =
@ -314,14 +326,19 @@ FGAIManager::getNumAiObjects() const
}
void
FGAIManager::fetchUserState( void ) {
FGAIManager::fetchUserState( double dt )
{
globals->get_aircraft_orientation(user_heading, user_pitch, user_roll);
user_speed = user_speed_node->getDoubleValue() * 0.592484;
wind_from_east = wind_from_east_node->getDoubleValue();
wind_from_north = wind_from_north_node->getDoubleValue();
user_altitude_agl = user_altitude_agl_node->getDoubleValue();
_userAircraft->setGeodPos(globals->get_aircraft_position());
_userAircraft->setHeading(user_heading);
_userAircraft->setSpeed(fgGetDouble("/velocities/groundspeed-kt"));
_userAircraft->update(dt);
}
// only keep the results from the nearest thermal
@ -579,4 +596,9 @@ FGAIManager::calcRangeFt(const SGVec3d& aCartPos, const FGAIBase* aObject) const
return distM * SG_METER_TO_FEET;
}
FGAIAircraft* FGAIManager::getUserAircraft() const
{
return _userAircraft.get();
}
//end AIManager.cxx

View file

@ -31,6 +31,7 @@
class FGAIBase;
class FGAIThermal;
class FGAIAircraft;
typedef SGSharedPtr<FGAIBase> FGAIBasePtr;
@ -82,6 +83,14 @@ public:
double calcRangeFt(const SGVec3d& aCartPos, const FGAIBase* aObject) const;
static const char* subsystemName() { return "ai-model"; }
/**
* @brief Retrieve the representation of the user's aircraft in the AI manager
* the position and velocity of this object are slaved to the user's aircraft,
* so that AI systems such as parking and ATC can see the user and process /
* avoid correctly.
*/
FGAIAircraft* getUserAircraft() const;
private:
// FGSubmodelMgr is a friend for access to the AI_list
friend class FGSubmodelMgr;
@ -122,7 +131,7 @@ private:
double wind_from_east;
double wind_from_north;
void fetchUserState( void );
void fetchUserState( double dt );
// used by thermals
double range_nearest;
@ -135,6 +144,8 @@ private:
class Scenario;
typedef std::map<std::string, Scenario*> ScenarioDict;
ScenarioDict _scenarios;
SGSharedPtr<FGAIAircraft> _userAircraft;
};
#endif // _FG_AIMANAGER_HXX

View file

@ -33,6 +33,7 @@
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <AIModel/AIAircraft.hxx>
#include <AIModel/AIManager.hxx>
#include <Traffic/Schedule.hxx>
#include <Traffic/SchedFlight.hxx>
#include <AIModel/AIFlightPlan.hxx>
@ -53,9 +54,8 @@ FGATCManager::FGATCManager() :
FGATCManager::~FGATCManager() {
}
void FGATCManager::init() {
SGSubsystem::init();
void FGATCManager::postinit()
{
int leg = 0;
trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
@ -70,24 +70,11 @@ void FGATCManager::init() {
string airport = fgGetString("/sim/presets/airport-id");
string parking = fgGetString("/sim/presets/parkpos");
FGAIManager* aiManager = globals->get_subsystem<FGAIManager>();
FGAIAircraft* userAircraft = aiManager->getUserAircraft();
// Create an (invisible) AIAircraft represenation of the current
// Users, aircraft, that mimicks the user aircraft's behavior.
string callsign= fgGetString("/sim/multiplay/callsign");
double longitude = fgGetDouble("/position/longitude-deg");
double latitude = fgGetDouble("/position/latitude-deg");
double altitude = fgGetDouble("/position/altitude-ft");
double heading = fgGetDouble("/orientation/heading-deg");
double speed = fgGetDouble("/velocities/groundspeed-kt");
double aircraftRadius = 40; // note that this is currently hardcoded to a one-size-fits all JumboJet value. Should change later;
ai_ac = new FGAIAircraft;
ai_ac->setCallSign ( callsign );
ai_ac->setLongitude( longitude );
ai_ac->setLatitude ( latitude );
ai_ac->setAltitude ( altitude );
ai_ac->setPerformance("", "jet_transport");
// NEXT UP: Create a traffic Schedule and fill that with appropriate information. This we can use to flight planning.
// Note that these are currently only defaults.
FGAISchedule *trafficRef = new FGAISchedule;
@ -98,11 +85,11 @@ void FGATCManager::init() {
flight->setArrivalAirport(airport);
flight->initializeAirports();
flight->setFlightRules("IFR");
flight->setCallSign(callsign);
flight->setCallSign(userAircraft->getCallSign());
trafficRef->assign(flight);
std::unique_ptr<FGAIFlightPlan> fp ;
ai_ac->setTrafficRef(trafficRef);
userAircraft->setTrafficRef(trafficRef);
string flightPlanName = airport + "-" + airport + ".xml";
//double cruiseAlt = 100; // Doesn't really matter right now.
@ -115,7 +102,6 @@ void FGATCManager::init() {
ParkingAssignment pk(dcs->getParkingByName(parking));
// No valid parking location, so either at the runway or at a random location.
if (pk.isValid()) {
dcs->setParkingAvailable(pk.parking(), false);
fp.reset(new FGAIFlightPlan);
@ -134,7 +120,7 @@ void FGATCManager::init() {
string aircraftType; // Unused.
string airline; // Currently used for gate selection, but a fallback mechanism will apply when not specified.
fp->setGate(pk);
if (!(fp->createPushBack(ai_ac,
if (!(fp->createPushBack(userAircraft,
false,
dcs->parent(),
aircraftRadius,
@ -148,6 +134,8 @@ void FGATCManager::init() {
} else if (!runway.empty()) {
// on a runway
controller = dcs->getTowerController();
int stationFreq = dcs->getTowerFrequency(2);
if (stationFreq > 0)
@ -159,10 +147,10 @@ void FGATCManager::init() {
leg = 3;
string fltType = "ga";
fp->setRunway(runway);
fp->createTakeOff(ai_ac, false, dcs->parent(), 0, fltType);
ai_ac->setTakeOffStatus(2);
fp->createTakeOff(userAircraft, false, dcs->parent(), 0, fltType);
userAircraft->setTakeOffStatus(2);
} else {
// We're on the ground somewhere. Handle this case later.
// We're on the ground somewhere. Handle this case later.
}
if (fp) {
@ -177,20 +165,23 @@ void FGATCManager::init() {
if (fp) {
fp->restart();
fp->setLeg(leg);
ai_ac->FGAIBase::setFlightPlan(std::move(fp));
userAircraft->FGAIBase::setFlightPlan(std::move(fp));
}
if (controller) {
FGAIFlightPlan* plan = ai_ac->GetFlightPlan();
controller->announcePosition(ai_ac->getID(), plan, plan->getCurrentWaypoint()->getRouteIndex(),
ai_ac->_getLatitude(), ai_ac->_getLongitude(), heading, speed, altitude,
aircraftRadius, leg, ai_ac);
FGAIFlightPlan* plan = userAircraft->GetFlightPlan();
controller->announcePosition(userAircraft->getID(), plan, plan->getCurrentWaypoint()->getRouteIndex(),
userAircraft->_getLatitude(),
userAircraft->_getLongitude(),
userAircraft->_getHeading(),
userAircraft->getSpeed(),
userAircraft->getAltitude(),
aircraftRadius, leg, userAircraft);
}
initSucceeded = true;
}
void FGATCManager::shutdown()
{
ai_ac.clear();
activeStations.clear();
}
@ -211,8 +202,8 @@ void FGATCManager::update ( double time ) {
//cerr << "ATC update code is running at time: " << time << endl;
// Test code: let my virtual co-pilot handle ATC:
FGAIManager* aiManager = globals->get_subsystem<FGAIManager>();
FGAIAircraft* ai_ac = aiManager->getUserAircraft();
FGAIFlightPlan *fp = ai_ac->GetFlightPlan();
/* test code : find out how the routing develops */
@ -244,35 +235,7 @@ void FGATCManager::update ( double time ) {
if (fp) {
//cerr << "Currently at leg : " << fp->getLeg() << endl;
}
double longitude = fgGetDouble("/position/longitude-deg");
double latitude = fgGetDouble("/position/latitude-deg");
double heading = fgGetDouble("/orientation/heading-deg");
double speed = fgGetDouble("/velocities/groundspeed-kt");
double altitude = fgGetDouble("/position/altitude-ft");
/*
SGGeod me(SGGeod::fromDegM(longitude,
latitude,
altitude));
SGGeod wpt1(SGGeod::fromDegM(fp->getWayPoint(1)->getLongitude(),
fp->getWayPoint(1)->getLatitude(),
fp->getWayPoint(1)->getAltitude()));
SGGeod wpt2(SGGeod::fromDegM(fp->getWayPoint(1)->getLongitude(),
fp->getWayPoint(1)->getLatitude(),
fp->getWayPoint(1)->getAltitude()));
double course1, az1, dist1;
double course2, az2, dist2;
SGGeodesy::inverse(me, wpt1, course1, az1, dist1);
cerr << "Bearing to nearest waypoint : " << course1 << " " << dist1 << ". (course " << course2 << ")." << endl;
*/
ai_ac->setLatitude(latitude);
ai_ac->setLongitude(longitude);
ai_ac->setAltitude(altitude);
ai_ac->setHeading(heading);
ai_ac->setSpeed(speed);
ai_ac->update(time);
controller = ai_ac->getATCController();
FGATCDialogNew::instance()->update(time);
if (controller) {
@ -281,11 +244,11 @@ void FGATCManager::update ( double time ) {
//cerr << "Running FGATCManager::update()" << endl;
//cerr << "Currently under control of " << controller->getName() << endl;
controller->updateAircraftInformation(ai_ac->getID(),
latitude,
longitude,
heading,
speed,
altitude, time);
ai_ac->_getLatitude(),
ai_ac->_getLongitude(),
ai_ac->_getHeading(),
ai_ac->getSpeed(),
ai_ac->getAltitude(), time);
//string airport = fgGetString("/sim/presets/airport-id");
//FGAirport *apt = FGAirport::findByIdent(airport);
// AT this stage we should update the flightplan, so that waypoint incrementing is conducted as well as leg loading.

View file

@ -36,9 +36,6 @@
#include <ATC/trafficcontrol.hxx>
#include <ATC/atcdialog.hxx>
class FGAIAircraft;
typedef std::vector<FGATCController*> AtcVec;
typedef std::vector<FGATCController*>::iterator AtcVecIterator;
@ -46,8 +43,7 @@ class FGATCManager : public SGSubsystem
{
private:
AtcVec activeStations;
SGSharedPtr<FGAIAircraft> ai_ac;
FGATCController *controller, *prevController; // The ATC controller that is responsible for the user's aircraft.
FGATCController *controller, *prevController; // The ATC controller that is responsible for the user's aircraft.
bool networkVisible;
bool initSucceeded;
SGPropertyNode_ptr trans_num;
@ -55,8 +51,8 @@ private:
public:
FGATCManager();
~FGATCManager();
void init();
virtual void shutdown();
void postinit() override;
void shutdown() override;
void addController(FGATCController *controller);
void removeController(FGATCController* controller);