30#include <osg/Geometry>
31#include <osg/MatrixTransform>
34#include <simgear/scene/material/EffectGeode.hxx>
35#include <simgear/scene/material/matlib.hxx>
36#include <simgear/scene/material/mat.hxx>
37#include <simgear/scene/util/OsgMath.hxx>
38#include <simgear/timing/sg_time.hxx>
80 int currentPosition,
double lat,
81 double lon,
double heading,
82 double speed,
double alt,
83 double radius,
int leg,
96 rec->setPositionAndHeading(lat, lon, heading, speed, alt, leg);
100 rec->setRadius(radius);
101 rec->setAircraft(ref);
107 time_t now =
globals->get_time_params()->get_cur_time();
123 SG_LOG(SG_ATC, SG_ALERT,
124 "Not moved " << (*i)->getCallsign() <<
"(" << (*i)->getId() <<
")" << *
i);
128 (*i)->setPositionAndHeading(lat, lon, heading, speed, alt, leg);
129 (*i)->setRunway(intendedRoute->
getRunway());
132 if (blocker!=
nullptr) {
133 (*i)->setWaitsForId(blocker->getId());
134 double distM = SGGeodesy::distanceM((*i)->getPos(), blocker->getPos());
135 int newSpeed = blocker->getSpeed() * (distM / 100);
136 SG_LOG(SG_ATC, SG_DEBUG,
137 (*i)->getCallsign() <<
"(" << (*i)->getId() <<
") is blocked for takeoff by " << blocker->getCallsign() <<
"(" << blocker->getId() <<
") new speed " << newSpeed <<
" dist " << distM);
138 (*i)->setSpeedAdjustment(newSpeed);
140 int oldWaitsForId = (*i)->getWaitsForId();
141 if (oldWaitsForId>0) {
142 SG_LOG(SG_ATC, SG_DEBUG,
143 (*i)->getCallsign() <<
"(" << (*i)->getId() <<
") cleared of blocker " << oldWaitsForId);
144 (*i)->setResumeTaxi(
true);
146 (*i)->clearSpeedAdjustment();
147 (*i)->setWaitingSince(0);
148 (*i)->setWaitsForId(0);
155 double heading,
double speed,
double alt,
163 time_t now =
globals->get_time_params()->get_cur_time();
165 SG_LOG(SG_ATC, SG_ALERT,
166 "AI error: updating aircraft without traffic record at " <<
172 (*i)->setPositionAndHeading(geod.getLatitudeDeg(), geod.getLongitudeDeg(), heading, speed, alt,
AILeg::UNKNOWN);
210 SG_LOG(SG_ATC, SG_ALERT,
211 "FGApproachController updating aircraft without traffic record at " << SG_ORIGIN);
220 (*i)->getRunwaySlot() < now) {
221 (*i)->setHoldPosition(
false);
226 (*i)->setHoldPosition(
true);
227 SG_LOG(SG_ATC, SG_BULK,
228 (*i)->getCallsign() <<
"(" << (*i)->getId() <<
") Waiting for " << ((*i)->getRunwaySlot() - now) <<
" seconds");
232 if (
id == clearanceId) {
233 if ((*i)->hasHoldPosition()) {
234 SG_LOG(SG_ATC, SG_BULK, (*i)->getCallsign() <<
"(" << (*i)->getId() <<
") Unset Hold " << clearanceId <<
" for rwy " << rwy->
getRunwayName());
236 (*i)->setHoldPosition(
false);
238 SG_LOG(SG_ATC, SG_BULK, (*i)->getCallsign() <<
"(" << (*i)->getId() <<
") Not cleared " <<
id <<
" Currently cleared " << clearanceId);
242 SG_LOG(SG_ATC, SG_BULK,
243 (*i)->getCallsign() <<
"(" << (*i)->getId() <<
") Cleared for runway " <<
getName() <<
" " << rwy->
getRunwayName() <<
" Id " <<
id);
245 if (blocker==
nullptr) {
254 (*i)->setWaitsForId(blocker->getId());
255 double distM = SGGeodesy::distanceM((*i)->getPos(), blocker->getPos());
256 int newSpeed = blocker->getSpeed() * (distM / 100);
257 SG_LOG(SG_ATC, SG_DEBUG,
258 (*i)->getCallsign() <<
"(" << (*i)->getId() <<
") is blocked for takeoff by " << blocker->getCallsign() <<
"(" << blocker->getId() <<
") new speed " << newSpeed);
259 (*i)->setSpeedAdjustment(newSpeed);
263 SG_LOG(SG_ATC, SG_BULK,
282 SG_LOG(SG_ATC, SG_ALERT,
283 "AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN);
286 SG_LOG(SG_ATC, SG_BULK,
"Signing off " << (*i)->getCallsign() <<
"(" <<
id <<
") from " <<
getName() <<
" Leg : " << (*i)->getLeg() );
289 const auto trafficRunway = (*i)->getRunway();
292 SG_LOG(SG_ATC, SG_BULK, (*i)->getCallsign() <<
"(" << (*i)->getId() <<
") Cleared " <<
id <<
" from " << runwayIt->
getRunwayName() <<
" cleared " << runwayIt->
getCleared() );
295 (*i)->resetTakeOffStatus();
297 time_t now =
globals->get_time_params()->get_cur_time();
318 SG_LOG(SG_ATC, SG_ALERT,
319 "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
321 return (*i)->hasInstruction();
333 SG_LOG(SG_ATC, SG_ALERT,
334 "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
336 return (*i)->getInstruction();
343 SG_LOG(SG_ATC, SG_BULK,
"FGTowerController::render function not yet implemented");
347 return string(
parent->parent()->getName() +
"-tower");
356int FGTowerController::getFrequency() {
void setCleared(int number)
void requestTimeSlot(SGSharedPtr< FGTrafficRecord > eta)
Fetch next slot for the active runway.
const std::string & getRunwayName() const
const SGSharedPtr< FGTrafficRecord > getFirstAircraftInDepartureQueue() const
int getCleared() const
Get id of cleared AI Aircraft.
const SGSharedPtr< FGTrafficRecord > getFirstOfStatus(int stat) const
Fetch the first aircraft in the departure queue with a certain status.
void removeFromQueue(int id)
FGAISchedule * getTrafficRef()
const std::string & getCallSign() const
const std::string & getRunway() const
FGAirportRef departureAirport() const
FGAirportRef arrivalAirport() const
std::string getCallSign()
TrafficVectorIterator searchActiveTraffic(int id) const
Search activeTraffic vector to find matching id.
virtual void signOff(int id)
Sign off the aircraft with the id from this controller.
FGAirportDynamics * parent
SGSharedPtr< AirportGroundRadar > airportGroundRadar
TrafficVector activeTraffic
void transmit(FGTrafficRecord *rec, FGAirportDynamics *parent, AtcMsgId msgId, AtcMsgDir msgDir, bool audible)
@ MSG_ACKNOWLEDGE_CLEARED_FOR_TAKEOFF
@ MSG_CLEARED_FOR_TAKEOFF
bool checkTransmissionState(int minState, int MaxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId, AtcMsgDir msgDir)
int getTowerFrequency(unsigned nr)
virtual void render(bool)
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute, double lat, double lon, double hdg, double spd, double alt, double radius, int leg, FGAIAircraft *aircraft)
FGATCInstruction getInstruction(int id)
virtual void update(double dt)
bool hasInstruction(int id)
virtual std::string getName() const
virtual void updateAircraftInformation(int id, SGGeod geod, double heading, double speed, double alt, double dt)
FGTowerController(FGAirportDynamics *parent)
virtual ~FGTowerController()
void signOff(int id)
Sign off the aircraft with the id from this controller.
std::list< SGSharedPtr< FGTrafficRecord > >::const_iterator TrafficVectorIterator