Merge branch 'next' of gitorious.org:fg/flightgear into next
This commit is contained in:
commit
70a525d47c
32 changed files with 284 additions and 1976 deletions
|
@ -27,8 +27,6 @@ option(ENABLE_UIUC_MODEL "Set to ON to build FlightGear with UIUCModel FDM" ON)
|
||||||
option(ENABLE_LARCSIM "Set to ON to build FlightGear with LaRCsim FDM" ON)
|
option(ENABLE_LARCSIM "Set to ON to build FlightGear with LaRCsim FDM" ON)
|
||||||
option(ENABLE_YASIM "Set to ON to build FlightGear with YASIM FDM" ON)
|
option(ENABLE_YASIM "Set to ON to build FlightGear with YASIM FDM" ON)
|
||||||
option(ENABLE_JSBSIM "Set to ON to build FlightGear with JSBSim FDM" ON)
|
option(ENABLE_JSBSIM "Set to ON to build FlightGear with JSBSim FDM" ON)
|
||||||
|
|
||||||
option(ATCDCL "Set to ON to build FlightGear with Dave Luff's ATC code" OFF)
|
|
||||||
option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support" OFF)
|
option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support" OFF)
|
||||||
|
|
||||||
if(LOGGING)
|
if(LOGGING)
|
||||||
|
@ -41,10 +39,6 @@ if(${SP_FDMS})
|
||||||
set(ENABLE_SP_FDM 1)
|
set(ENABLE_SP_FDM 1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ATCDCL)
|
|
||||||
set(ENABLE_ATCDCL 1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(EVENT_INPUT)
|
if(EVENT_INPUT)
|
||||||
message(STATUS "checking event-based Input")
|
message(STATUS "checking event-based Input")
|
||||||
IF(APPLE)
|
IF(APPLE)
|
||||||
|
@ -165,3 +159,14 @@ configure_file (
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
### uninstall target
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
CONFIGURE_FILE(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/cmake_uninstall.cmake.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||||
|
IMMEDIATE @ONLY)
|
||||||
|
ADD_CUSTOM_TARGET(uninstall
|
||||||
|
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
|
|
||||||
|
|
22
CMakeModules/cmake_uninstall.cmake.in
Normal file
22
CMakeModules/cmake_uninstall.cmake.in
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||||
|
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||||
|
STRING(REGEX REPLACE "\n" ";" files "${files}")
|
||||||
|
|
||||||
|
FOREACH(file ${files})
|
||||||
|
MESSAGE(STATUS "Uninstalling \"${file}\"")
|
||||||
|
IF(EXISTS "${file}")
|
||||||
|
EXEC_PROGRAM(
|
||||||
|
"@CMAKE_COMMAND@" ARGS "-E remove \"${file}\""
|
||||||
|
OUTPUT_VARIABLE rm_out
|
||||||
|
RETURN_VALUE rm_retval
|
||||||
|
)
|
||||||
|
IF(NOT "${rm_retval}" STREQUAL 0)
|
||||||
|
MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"")
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS "File \"${file}\" does not exist.")
|
||||||
|
ENDIF()
|
||||||
|
ENDFOREACH()
|
17
configure.ac
17
configure.ac
|
@ -209,16 +209,6 @@ else
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(ENABLE_SP_FDM, test "x$enable_sp_fdms" != "xno")
|
AM_CONDITIONAL(ENABLE_SP_FDM, test "x$enable_sp_fdms" != "xno")
|
||||||
|
|
||||||
# Specify whether we want to compile ATCDCL.
|
|
||||||
# default to with_atcdcl=yes
|
|
||||||
AC_ARG_ENABLE(atcdcl, [ --enable-atcdcl Compile and link the deprecated atc/ai module], [], [enable_atcdcl="$enableval"] )
|
|
||||||
if test "x$enable_atcdcl" = "xyes"; then
|
|
||||||
AC_DEFINE([ENABLE_ATCDCL], 1, [Define to include old ATC/AI module])
|
|
||||||
else
|
|
||||||
AC_DEFINE([ENABLE_ATCDCL], 0, [Define to include old ATC/AI module])
|
|
||||||
fi
|
|
||||||
AM_CONDITIONAL(ENABLE_ATCDCL, test "x$enable_atcdcl" = "xyes")
|
|
||||||
|
|
||||||
dnl EXPERIMENTAL generic event driven input device
|
dnl EXPERIMENTAL generic event driven input device
|
||||||
# defaults to no
|
# defaults to no
|
||||||
AC_ARG_WITH(eventinput, [ --with-eventinput Include event driven input (EXPERIMENTAL) [default=no]], [], [with_eventinput=no])
|
AC_ARG_WITH(eventinput, [ --with-eventinput Include event driven input (EXPERIMENTAL) [default=no]], [], [with_eventinput=no])
|
||||||
|
@ -945,10 +935,3 @@ if test "x$enable_sp_fdms" != "xno"; then
|
||||||
else
|
else
|
||||||
echo "Include special purpose flight models: no"
|
echo "Include special purpose flight models: no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$enable_atcdcl" = "xyes"; then
|
|
||||||
echo "Build deprecated ATC/AI module: yes"
|
|
||||||
else
|
|
||||||
echo "Build deprecated ATC/AI module: no"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -611,7 +611,7 @@ double FGAIBase::_getRdot() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
double FGAIBase::_getVS_fps() const {
|
double FGAIBase::_getVS_fps() const {
|
||||||
return vs*60.0;
|
return vs/60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double FGAIBase::_get_speed_east_fps() const {
|
double FGAIBase::_get_speed_east_fps() const {
|
||||||
|
@ -623,7 +623,7 @@ double FGAIBase::_get_speed_north_fps() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAIBase::_setVS_fps( double _vs ) {
|
void FGAIBase::_setVS_fps( double _vs ) {
|
||||||
vs = _vs/60.0;
|
vs = _vs*60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double FGAIBase::_getAltitude() const {
|
double FGAIBase::_getAltitude() const {
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
include(FlightGearComponent)
|
include(FlightGearComponent)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
atcutils.cxx
|
atis_mgr.cxx
|
||||||
atis.cxx
|
|
||||||
trafficcontrol.cxx
|
trafficcontrol.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
flightgear_component(ATC "${SOURCES}")
|
flightgear_component(ATC "${SOURCES}")
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
noinst_LIBRARIES = libATC.a
|
noinst_LIBRARIES = libATC.a
|
||||||
|
|
||||||
libATC_a_SOURCES = \
|
libATC_a_SOURCES = \
|
||||||
atcutils.cxx atcutils.hxx \
|
atis_mgr.cxx atis_mgr.hxx \
|
||||||
atis.cxx atis.hxx \
|
|
||||||
trafficcontrol.cxx trafficcontrol.hxx
|
trafficcontrol.cxx trafficcontrol.hxx
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
|
||||||
|
|
|
@ -1,373 +0,0 @@
|
||||||
// commlist.cxx -- comm frequency lookup class
|
|
||||||
//
|
|
||||||
// Written by David Luff and Alexander Kappes, started Jan 2003.
|
|
||||||
// Based on navlist.cxx by Curtis Olson, started April 2000.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
|
|
||||||
//
|
|
||||||
// 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, write to the Free Software
|
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
|
||||||
#include <simgear/misc/sgstream.hxx>
|
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
|
||||||
#include <simgear/math/sg_random.h>
|
|
||||||
#include <simgear/bucket/newbucket.hxx>
|
|
||||||
#include <Airports/simple.hxx>
|
|
||||||
|
|
||||||
#include "atcutils.hxx"
|
|
||||||
|
|
||||||
#if !ENABLE_ATCDCL
|
|
||||||
|
|
||||||
|
|
||||||
FGCommList *current_commlist;
|
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
FGCommList::FGCommList( void ) {
|
|
||||||
sg_srandom_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
FGCommList::~FGCommList( void ) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// load the navaids and build the map
|
|
||||||
bool FGCommList::init( const SGPath& path ) {
|
|
||||||
/*
|
|
||||||
SGPath temp = path;
|
|
||||||
commlist_freq.erase(commlist_freq.begin(), commlist_freq.end());
|
|
||||||
commlist_bck.erase(commlist_bck.begin(), commlist_bck.end());
|
|
||||||
temp.append( "ATC/default.atis" );
|
|
||||||
LoadComms(temp);
|
|
||||||
temp = path;
|
|
||||||
temp.append( "ATC/default.tower" );
|
|
||||||
LoadComms(temp);
|
|
||||||
temp = path;
|
|
||||||
temp.append( "ATC/default.ground" );
|
|
||||||
LoadComms(temp);
|
|
||||||
temp = path;
|
|
||||||
temp.append( "ATC/default.approach" );
|
|
||||||
LoadComms(temp);*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool FGCommList::LoadComms(const SGPath& path) {
|
|
||||||
/*
|
|
||||||
sg_gzifstream fin( path.str() );
|
|
||||||
if ( !fin.is_open() ) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// read in each line of the file
|
|
||||||
fin >> skipcomment;
|
|
||||||
|
|
||||||
while ( !fin.eof() ) {
|
|
||||||
ATCData a;
|
|
||||||
fin >> a;
|
|
||||||
if(a.type == INVALID) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "WARNING - INVALID type found in " << path.str() << '\n');
|
|
||||||
} else {
|
|
||||||
// Push all stations onto frequency map
|
|
||||||
commlist_freq[a.freq].push_back(a);
|
|
||||||
|
|
||||||
// Push non-atis stations onto bucket map as well
|
|
||||||
// In fact, push all stations onto bucket map for now so FGATCMgr::GetFrequency() works.
|
|
||||||
//if(a.type != ATIS and/or AWOS?) {
|
|
||||||
// get bucket number
|
|
||||||
SGBucket bucket(a.geod);
|
|
||||||
int bucknum = bucket.gen_index();
|
|
||||||
commlist_bck[bucknum].push_back(a);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
fin >> skipcomment;
|
|
||||||
}
|
|
||||||
|
|
||||||
fin.close();*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// query the database for the specified frequency, lon and lat are in
|
|
||||||
// degrees, elev is in meters
|
|
||||||
// If no atc_type is specified, it returns true if any non-invalid type is found
|
|
||||||
// If atc_type is specifed, returns true only if the specified type is found
|
|
||||||
bool FGCommList::FindByFreq(const SGGeod& aPos, double freq,
|
|
||||||
ATCData* ad, atc_type tp )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
comm_list_type stations;
|
|
||||||
stations = commlist_freq[kHz10(freq)];
|
|
||||||
comm_list_iterator current = stations.begin();
|
|
||||||
comm_list_iterator last = stations.end();
|
|
||||||
|
|
||||||
// double az1, az2, s;
|
|
||||||
SGVec3d aircraft = SGVec3d::fromGeod(aPos);
|
|
||||||
const double orig_max_d = 1e100;
|
|
||||||
double max_d = orig_max_d;
|
|
||||||
double d;
|
|
||||||
// TODO - at the moment this loop returns the first match found in range
|
|
||||||
// We want to return the closest match in the event of a frequency conflict
|
|
||||||
for ( ; current != last ; ++current ) {
|
|
||||||
d = distSqr(aircraft, current->cart);
|
|
||||||
|
|
||||||
//cout << " dist = " << sqrt(d)
|
|
||||||
// << " range = " << current->range * SG_NM_TO_METER << endl;
|
|
||||||
|
|
||||||
// TODO - match up to twice the published range so we can model
|
|
||||||
// reduced signal strength
|
|
||||||
// NOTE The below is squared since we match to distance3Dsquared (above) to avoid a sqrt.
|
|
||||||
if ( d < (current->range * SG_NM_TO_METER
|
|
||||||
* current->range * SG_NM_TO_METER ) ) {
|
|
||||||
//cout << "matched = " << current->ident << endl;
|
|
||||||
if((tp == INVALID) || (tp == (*current).type)) {
|
|
||||||
if(d < max_d) {
|
|
||||||
max_d = d;
|
|
||||||
*ad = *current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(max_d < orig_max_d) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FGCommList::FindByPos(const SGGeod& aPos, double range, comm_list_type* stations, atc_type tp)
|
|
||||||
{
|
|
||||||
// number of relevant stations found within range
|
|
||||||
int found = 0;
|
|
||||||
/*
|
|
||||||
stations->erase(stations->begin(), stations->end());
|
|
||||||
|
|
||||||
// get bucket number for plane position
|
|
||||||
SGBucket buck(aPos);
|
|
||||||
|
|
||||||
// get neigboring buckets
|
|
||||||
int bx = (int)( range*SG_NM_TO_METER / buck.get_width_m() / 2) + 1;
|
|
||||||
int by = (int)( range*SG_NM_TO_METER / buck.get_height_m() / 2 ) + 1;
|
|
||||||
|
|
||||||
// loop over bucket range
|
|
||||||
for ( int i=-bx; i<=bx; i++) {
|
|
||||||
for ( int j=-by; j<=by; j++) {
|
|
||||||
buck = sgBucketOffset(aPos.getLongitudeDeg(), aPos.getLatitudeDeg(), i, j);
|
|
||||||
long int bucket = buck.gen_index();
|
|
||||||
comm_map_const_iterator Fstations = commlist_bck.find(bucket);
|
|
||||||
if (Fstations == commlist_bck.end()) continue;
|
|
||||||
comm_list_const_iterator current = Fstations->second.begin();
|
|
||||||
comm_list_const_iterator last = Fstations->second.end();
|
|
||||||
|
|
||||||
|
|
||||||
// double az1, az2, s;
|
|
||||||
SGVec3d aircraft = SGVec3d::fromGeod(aPos);
|
|
||||||
double d;
|
|
||||||
for(; current != last; ++current) {
|
|
||||||
if((current->type == tp) || (tp == INVALID)) {
|
|
||||||
d = distSqr(aircraft, current->cart);
|
|
||||||
// NOTE The below is squared since we match to distance3Dsquared (above) to avoid a sqrt.
|
|
||||||
if ( d < (current->range * SG_NM_TO_METER
|
|
||||||
* current->range * SG_NM_TO_METER ) ) {
|
|
||||||
stations->push_back(*current);
|
|
||||||
++found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the distance in meters to the closest station of a given type,
|
|
||||||
// with the details written into ATCData& ad. If no type is specifed simply
|
|
||||||
// returns the distance to the closest station of any type.
|
|
||||||
// Returns -9999 if no stations found within max_range in nautical miles (default 100 miles).
|
|
||||||
// Note that the search algorithm starts at 10 miles and multiplies by 10 thereafter, so if
|
|
||||||
// say 300 miles is specifed 10, then 100, then 1000 will be searched, breaking at first result
|
|
||||||
// and giving up after 1000.
|
|
||||||
double FGCommList::FindClosest(const SGGeod& aPos, ATCData& ad, atc_type tp, double max_range) {
|
|
||||||
/*
|
|
||||||
int num_stations = 0;
|
|
||||||
int range = 10;
|
|
||||||
comm_list_type stations;
|
|
||||||
comm_list_iterator itr;
|
|
||||||
double distance = -9999.0;
|
|
||||||
|
|
||||||
while(num_stations == 0) {
|
|
||||||
num_stations = FindByPos(aPos, range, &stations, tp);
|
|
||||||
if(num_stations) {
|
|
||||||
double closest = max_range * SG_NM_TO_METER;
|
|
||||||
double tmp;
|
|
||||||
for(itr = stations.begin(); itr != stations.end(); ++itr) {
|
|
||||||
ATCData ad2 = *itr;
|
|
||||||
const FGAirport *a = fgFindAirportID(ad2.ident);
|
|
||||||
if (a) {
|
|
||||||
tmp = dclGetHorizontalSeparation(ad2.geod, aPos);
|
|
||||||
if(tmp <= closest) {
|
|
||||||
closest = tmp;
|
|
||||||
distance = tmp;
|
|
||||||
ad = *itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//cout << "Closest station is " << ad.ident << " at a range of " << distance << " meters\n";
|
|
||||||
return(distance);
|
|
||||||
}
|
|
||||||
if(range > max_range) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
range *= 10;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return(-9999.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Find by Airport code.
|
|
||||||
// This is basically a wrapper for a call to the airport database to get the airport
|
|
||||||
// position followed by a call to FindByPos(...)
|
|
||||||
bool FGCommList::FindByCode( const std::string& ICAO, ATCData& ad, atc_type tp ) {
|
|
||||||
/*
|
|
||||||
const FGAirport *a = fgFindAirportID( ICAO);
|
|
||||||
if ( a) {
|
|
||||||
comm_list_type stations;
|
|
||||||
int found = FindByPos(a->geod(), 10.0, &stations, tp);
|
|
||||||
if(found) {
|
|
||||||
comm_list_iterator itr = stations.begin();
|
|
||||||
while(itr != stations.end()) {
|
|
||||||
if(((*itr).ident == ICAO) && ((*itr).type == tp)) {
|
|
||||||
ad = *itr;
|
|
||||||
//cout << "FindByCode returns " << ICAO
|
|
||||||
// << " type: " << tp
|
|
||||||
// << " freq: " << itr->freq
|
|
||||||
// << endl;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO - this function should move somewhere else eventually!
|
|
||||||
// Return an appropriate sequence number for an ATIS transmission.
|
|
||||||
// Return sequence number + 2600 if sequence is unchanged since
|
|
||||||
// last time.
|
|
||||||
int FGCommList::GetAtisSequence( const std::string& apt_id,
|
|
||||||
const double tstamp, const int interval, const int special)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
atis_transmission_type tran;
|
|
||||||
|
|
||||||
if(atislog.find(apt_id) == atislog.end()) { // New station
|
|
||||||
tran.tstamp = tstamp - interval;
|
|
||||||
// Random number between 0 and 25 inclusive, i.e. 26 equiprobable outcomes:
|
|
||||||
tran.sequence = int(sg_random() * LTRS);
|
|
||||||
atislog[apt_id] = tran;
|
|
||||||
//cout << "New ATIS station: " << apt_id << " seq-1: "
|
|
||||||
// << tran.sequence << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate the appropriate identifier and update the log
|
|
||||||
tran = atislog[apt_id];
|
|
||||||
|
|
||||||
int delta = int((tstamp - tran.tstamp) / interval);
|
|
||||||
tran.tstamp += delta * interval;
|
|
||||||
if (special && !delta) delta++; // a "special" ATIS update is required
|
|
||||||
tran.sequence = (tran.sequence + delta) % LTRS;
|
|
||||||
atislog[apt_id] = tran;
|
|
||||||
//if (delta) cout << "New ATIS sequence: " << tran.sequence
|
|
||||||
// << " Delta: " << delta << endl;
|
|
||||||
return(tran.sequence + (delta ? 0 : LTRS*1000));
|
|
||||||
*/
|
|
||||||
return 2600;
|
|
||||||
}
|
|
||||||
/*****************************************************************************
|
|
||||||
* FGKln89AlignedProjection
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
FGKln89AlignedProjection::FGKln89AlignedProjection() {
|
|
||||||
_origin.setLatitudeRad(0);
|
|
||||||
_origin.setLongitudeRad(0);
|
|
||||||
_origin.setElevationM(0);
|
|
||||||
_correction_factor = cos(_origin.getLatitudeRad());
|
|
||||||
}
|
|
||||||
|
|
||||||
FGKln89AlignedProjection::FGKln89AlignedProjection(const SGGeod& centre, double heading) {
|
|
||||||
_origin = centre;
|
|
||||||
_theta = heading * SG_DEGREES_TO_RADIANS;
|
|
||||||
_correction_factor = cos(_origin.getLatitudeRad());
|
|
||||||
}
|
|
||||||
|
|
||||||
FGKln89AlignedProjection::~FGKln89AlignedProjection() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGKln89AlignedProjection::Init(const SGGeod& centre, double heading) {
|
|
||||||
_origin = centre;
|
|
||||||
_theta = heading * SG_DEGREES_TO_RADIANS;
|
|
||||||
_correction_factor = cos(_origin.getLatitudeRad());
|
|
||||||
}
|
|
||||||
|
|
||||||
SGVec3d FGKln89AlignedProjection::ConvertToLocal(const SGGeod& pt) {
|
|
||||||
// convert from lat/lon to orthogonal
|
|
||||||
double delta_lat = pt.getLatitudeRad() - _origin.getLatitudeRad();
|
|
||||||
double delta_lon = pt.getLongitudeRad() - _origin.getLongitudeRad();
|
|
||||||
double y = sin(delta_lat) * SG_EQUATORIAL_RADIUS_M;
|
|
||||||
double x = sin(delta_lon) * SG_EQUATORIAL_RADIUS_M * _correction_factor;
|
|
||||||
|
|
||||||
// Align
|
|
||||||
if(_theta != 0.0) {
|
|
||||||
double xbar = x;
|
|
||||||
x = x*cos(_theta) - y*sin(_theta);
|
|
||||||
y = (xbar*sin(_theta)) + (y*cos(_theta));
|
|
||||||
}
|
|
||||||
|
|
||||||
return SGVec3d(x, y, pt.getElevationM());
|
|
||||||
}
|
|
||||||
|
|
||||||
SGGeod FGKln89AlignedProjection::ConvertFromLocal(const SGVec3d& pt) {
|
|
||||||
// de-align
|
|
||||||
double thi = _theta * -1.0;
|
|
||||||
double x = pt.x()*cos(thi) - pt.y()*sin(thi);
|
|
||||||
double y = (pt.x()*sin(thi)) + (pt.y()*cos(thi));
|
|
||||||
|
|
||||||
// convert from orthogonal to lat/lon
|
|
||||||
double delta_lat = asin(y / SG_EQUATORIAL_RADIUS_M);
|
|
||||||
double delta_lon = asin(x / SG_EQUATORIAL_RADIUS_M) / _correction_factor;
|
|
||||||
|
|
||||||
return SGGeod::fromRadM(_origin.getLongitudeRad()+delta_lon, _origin.getLatitudeRad()+delta_lat, pt.z());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // #ENABLE_ATCDCL
|
|
|
@ -1,198 +0,0 @@
|
||||||
// atcutils.hxx
|
|
||||||
//
|
|
||||||
// This file contains a collection of classes from David Luff's
|
|
||||||
// AI/ATC code that are shared by non-AI parts of FlightGear.
|
|
||||||
// more specifcially, it contains implementations of FGCommList and
|
|
||||||
// FGATCAlign
|
|
||||||
//
|
|
||||||
// Written by David Luff and Alexander Kappes, started Jan 2003.
|
|
||||||
// Based on navlist.hxx by Curtis Olson, started April 2000.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
|
|
||||||
//
|
|
||||||
// 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, write to the Free Software
|
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
/*****************************************************************
|
|
||||||
*
|
|
||||||
* FGCommList is used to store communication frequency information
|
|
||||||
* for the ATC and AI subsystems. Two maps are maintained - one
|
|
||||||
* searchable by location and one searchable by frequency. The
|
|
||||||
* data structure returned from the search is the ATCData struct
|
|
||||||
* defined in ATC.hxx, containing location, frequency, name, range
|
|
||||||
* and type of the returned station.
|
|
||||||
*
|
|
||||||
******************************************************************/
|
|
||||||
|
|
||||||
#ifndef _FG_ATCUTILS_HXX
|
|
||||||
#define _FG_ATCUTILS_HXX
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
//#include "ATC.hxx"
|
|
||||||
//#include "atis.hxx"
|
|
||||||
|
|
||||||
#if !ENABLE_ATCDCL
|
|
||||||
|
|
||||||
class SGPath;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Possible types of ATC type that the radios may be tuned to.
|
|
||||||
// INVALID implies not tuned in to anything.
|
|
||||||
enum atc_type {
|
|
||||||
AWOS,
|
|
||||||
ATIS,
|
|
||||||
GROUND,
|
|
||||||
TOWER,
|
|
||||||
APPROACH,
|
|
||||||
DEPARTURE,
|
|
||||||
ENROUTE,
|
|
||||||
INVALID /* must be last element; see ATC_NUM_TYPES */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ATCData {
|
|
||||||
ATCData() : type(INVALID), cart(0, 0, 0), freq(0), range(0) {}
|
|
||||||
atc_type type;
|
|
||||||
SGGeod geod;
|
|
||||||
SGVec3d cart;
|
|
||||||
unsigned short int freq;
|
|
||||||
unsigned short int range;
|
|
||||||
std::string ident;
|
|
||||||
std::string name;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// A list of ATC stations
|
|
||||||
typedef std::list < ATCData > comm_list_type;
|
|
||||||
typedef comm_list_type::iterator comm_list_iterator;
|
|
||||||
typedef comm_list_type::const_iterator comm_list_const_iterator;
|
|
||||||
|
|
||||||
// A map of ATC station lists
|
|
||||||
typedef std::map < int, comm_list_type > comm_map_type;
|
|
||||||
typedef comm_map_type::iterator comm_map_iterator;
|
|
||||||
typedef comm_map_type::const_iterator comm_map_const_iterator;
|
|
||||||
|
|
||||||
|
|
||||||
class FGCommList {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
FGCommList();
|
|
||||||
~FGCommList();
|
|
||||||
|
|
||||||
// load all comm frequencies and build the map
|
|
||||||
bool init( const SGPath& path );
|
|
||||||
|
|
||||||
// query the database for the specified frequency, lon and lat are
|
|
||||||
// If no atc_type is specified, it returns true if any non-invalid type is found.
|
|
||||||
// If atc_type is specifed, returns true only if the specified type is found.
|
|
||||||
// Returns the station closest to the supplied position.
|
|
||||||
// The data found is written into the passed-in ATCData structure.
|
|
||||||
bool FindByFreq(const SGGeod& aPos, double freq, ATCData* ad, atc_type tp = INVALID );
|
|
||||||
|
|
||||||
// query the database by location, lon and lat are in degrees, elev is in meters, range is in nautical miles.
|
|
||||||
// Returns the number of stations of the specified atc_type tp that are in range of the position defined by
|
|
||||||
// lon, lat and elev, and pushes them into stations.
|
|
||||||
// If no atc_type is specifed, returns the number of all stations in range, and pushes them into stations
|
|
||||||
// ** stations is erased before use **
|
|
||||||
int FindByPos(const SGGeod& aPos, double range, comm_list_type* stations, atc_type tp = INVALID );
|
|
||||||
|
|
||||||
// Returns the distance in meters to the closest station of a given type,
|
|
||||||
// with the details written into ATCData& ad. If no type is specifed simply
|
|
||||||
// returns the distance to the closest station of any type.
|
|
||||||
// Returns -9999 if no stations found within max_range in nautical miles (default 100 miles).
|
|
||||||
// Note that the search algorithm starts at 10 miles and multiplies by 10 thereafter, so if
|
|
||||||
// say 300 miles is specifed 10, then 100, then 1000 will be searched, breaking at first result
|
|
||||||
// and giving up after 1000.
|
|
||||||
// !!!Be warned that searching anything over 100 miles will pause the sim unacceptably!!!
|
|
||||||
// (The ability to search longer ranges should be used during init only).
|
|
||||||
double FindClosest(const SGGeod& aPos, ATCData& ad, atc_type tp = INVALID, double max_range = 100.0 );
|
|
||||||
|
|
||||||
// Find by Airport code.
|
|
||||||
bool FindByCode( const std::string& ICAO, ATCData& ad, atc_type tp = INVALID );
|
|
||||||
|
|
||||||
// Return the sequence letter for an ATIS transmission given transmission time and airport id
|
|
||||||
// This maybe should get moved somewhere else!!
|
|
||||||
int GetAtisSequence( const std::string& apt_id, const double tstamp,
|
|
||||||
const int interval, const int flush=0);
|
|
||||||
|
|
||||||
// Comm stations mapped by frequency
|
|
||||||
//comm_map_type commlist_freq;
|
|
||||||
|
|
||||||
// Comm stations mapped by bucket
|
|
||||||
//comm_map_type commlist_bck;
|
|
||||||
|
|
||||||
// Load comms from a specified path (which must include the filename)
|
|
||||||
private:
|
|
||||||
|
|
||||||
bool LoadComms(const SGPath& path);
|
|
||||||
|
|
||||||
//----------- This stuff is left over from atislist.[ch]xx and maybe should move somewhere else
|
|
||||||
// Add structure and map for storing a log of atis transmissions
|
|
||||||
// made in this session of FlightGear. This allows the callsign
|
|
||||||
// to be allocated correctly wrt time.
|
|
||||||
//typedef struct {
|
|
||||||
// double tstamp;
|
|
||||||
// int sequence;
|
|
||||||
//} atis_transmission_type;
|
|
||||||
|
|
||||||
//typedef std::map < std::string, atis_transmission_type > atis_log_type;
|
|
||||||
//typedef atis_log_type::iterator atis_log_iterator;
|
|
||||||
//typedef atis_log_type::const_iterator atis_log_const_iterator;
|
|
||||||
|
|
||||||
//atis_log_type atislog;
|
|
||||||
//-----------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
extern FGCommList *current_commlist;
|
|
||||||
|
|
||||||
// FGATCAlignedProjection - a class to project an area local to a runway onto an orthogonal co-ordinate system
|
|
||||||
// with the origin at the threshold and the runway aligned with the y axis.
|
|
||||||
class FGKln89AlignedProjection {
|
|
||||||
|
|
||||||
public:
|
|
||||||
FGKln89AlignedProjection();
|
|
||||||
FGKln89AlignedProjection(const SGGeod& centre, double heading);
|
|
||||||
~FGKln89AlignedProjection();
|
|
||||||
|
|
||||||
void Init(const SGGeod& centre, double heading);
|
|
||||||
|
|
||||||
// Convert a lat/lon co-ordinate (degrees) to the local projection (meters)
|
|
||||||
SGVec3d ConvertToLocal(const SGGeod& pt);
|
|
||||||
|
|
||||||
// Convert a local projection co-ordinate (meters) to lat/lon (degrees)
|
|
||||||
SGGeod ConvertFromLocal(const SGVec3d& pt);
|
|
||||||
|
|
||||||
private:
|
|
||||||
SGGeod _origin; // lat/lon of local area origin (the threshold)
|
|
||||||
double _theta; // the rotation angle for alignment in radians
|
|
||||||
double _correction_factor; // Reduction in surface distance per degree of longitude due to latitude. Saves having to do a cos() every call.
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // #if ENABLE_ATCDCL
|
|
||||||
|
|
||||||
#endif // _FG_ATCUTILS_HXX
|
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <simgear/math/SGMath.hxx>
|
#include <simgear/math/SGMath.hxx>
|
||||||
#include "atis.hxx"
|
#include "atis_mgr.hxx"
|
||||||
|
|
||||||
FGAtisManager::FGAtisManager() {
|
FGAtisManager::FGAtisManager() {
|
||||||
|
|
|
@ -52,13 +52,12 @@ FGATCMgr::FGATCMgr() :
|
||||||
initDone(false),
|
initDone(false),
|
||||||
atc_list(new atc_list_type),
|
atc_list(new atc_list_type),
|
||||||
#ifdef ENABLE_AUDIO_SUPPORT
|
#ifdef ENABLE_AUDIO_SUPPORT
|
||||||
voiceOK(false),
|
|
||||||
voice(true),
|
voice(true),
|
||||||
|
voiceOK(false),
|
||||||
|
v1(0)
|
||||||
#else
|
#else
|
||||||
voice(false),
|
voice(false),
|
||||||
#endif
|
#endif
|
||||||
last_in_range(false),
|
|
||||||
v1(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,9 +85,6 @@ private:
|
||||||
SGPropertyNode_ptr lat_node;
|
SGPropertyNode_ptr lat_node;
|
||||||
SGPropertyNode_ptr elev_node;
|
SGPropertyNode_ptr elev_node;
|
||||||
|
|
||||||
//string approach_ident;
|
|
||||||
bool last_in_range;
|
|
||||||
|
|
||||||
//FGATIS atis;
|
//FGATIS atis;
|
||||||
|
|
||||||
// Voice related stuff
|
// Voice related stuff
|
||||||
|
|
|
@ -268,4 +268,4 @@ bool OnRunway(const SGGeod& pt, const FGRunwayBase* rwy) {
|
||||||
|
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/ATCDCL/CMakeLists.txt
Normal file
14
src/ATCDCL/CMakeLists.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
include(FlightGearComponent)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
ATC.cxx
|
||||||
|
atis.cxx
|
||||||
|
commlist.cxx
|
||||||
|
ATCDialog.cxx
|
||||||
|
ATCVoice.cxx
|
||||||
|
ATCmgr.cxx
|
||||||
|
ATCutils.cxx
|
||||||
|
ATCProjection.cxx
|
||||||
|
)
|
||||||
|
|
||||||
|
flightgear_component(ATCDCL "${SOURCES}")
|
|
@ -31,6 +31,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "atis.hxx"
|
#include "atis.hxx"
|
||||||
|
#include "atis_lexicon.hxx"
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
@ -39,8 +40,10 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/algorithm/string/case_conv.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
|
||||||
|
@ -63,6 +66,8 @@ using boost::ref;
|
||||||
using boost::tie;
|
using boost::tie;
|
||||||
|
|
||||||
FGATIS::FGATIS() :
|
FGATIS::FGATIS() :
|
||||||
|
transmission(""),
|
||||||
|
trans_ident(""),
|
||||||
old_volume(0),
|
old_volume(0),
|
||||||
atis_failed(false),
|
atis_failed(false),
|
||||||
msg_OK(0),
|
msg_OK(0),
|
||||||
|
@ -76,6 +81,23 @@ FGATIS::FGATIS() :
|
||||||
SG_LOG(SG_ATC, SG_ALERT, "ERROR - _type not ATIS or AWOS in atis.cxx");
|
SG_LOG(SG_ATC, SG_ALERT, "ERROR - _type not ATIS or AWOS in atis.cxx");
|
||||||
}
|
}
|
||||||
fgTie("/environment/attention", this, (int_getter)0, &FGATIS::attend);
|
fgTie("/environment/attention", this, (int_getter)0, &FGATIS::attend);
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// FIXME: This would be more flexible and more extensible
|
||||||
|
// if the mappings were taken from an XML file, not hard-coded ...
|
||||||
|
// ... although having it in a .hxx file is better than nothing.
|
||||||
|
//
|
||||||
|
// Load the remap list from the .hxx file:
|
||||||
|
using namespace lex;
|
||||||
|
# define NIL ""
|
||||||
|
# define REMAP(from,to) _remap[#from] = to;
|
||||||
|
# include "atis_remap.hxx"
|
||||||
|
# undef REMAP
|
||||||
|
# undef NIL
|
||||||
|
|
||||||
|
#ifdef ATIS_TEST
|
||||||
|
SG_LOG(SG_ATC, SG_ALERT, "ATIS initialized");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hint:
|
// Hint:
|
||||||
|
@ -107,7 +129,7 @@ FGATIS::attend (int attn)
|
||||||
void FGATIS::Update(double dt) {
|
void FGATIS::Update(double dt) {
|
||||||
cur_time = globals->get_time_params()->get_cur_time();
|
cur_time = globals->get_time_params()->get_cur_time();
|
||||||
msg_OK = (msg_time < cur_time);
|
msg_OK = (msg_time < cur_time);
|
||||||
#if 0
|
#ifdef ATIS_TEST
|
||||||
if (msg_OK || _display != _prev_display) {
|
if (msg_OK || _display != _prev_display) {
|
||||||
cout << "ATIS Update: " << _display << " " << _prev_display
|
cout << "ATIS Update: " << _display << " " << _prev_display
|
||||||
<< " len: " << transmission.length()
|
<< " len: " << transmission.length()
|
||||||
|
@ -191,6 +213,7 @@ const int minute(60); // measured in seconds
|
||||||
// Returns 1 if we actually generated something.
|
// Returns 1 if we actually generated something.
|
||||||
int FGATIS::GenTransmission(const int regen, const int special) {
|
int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
using namespace atmodel;
|
using namespace atmodel;
|
||||||
|
using namespace lex;
|
||||||
|
|
||||||
string BRK = ".\n";
|
string BRK = ".\n";
|
||||||
|
|
||||||
|
@ -212,53 +235,59 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
|
|
||||||
transmission = "";
|
transmission = "";
|
||||||
|
|
||||||
// UK CAA radiotelephony manual indicated ATIS transmissions start
|
if (ident.substr(0,2) == "EG") {
|
||||||
|
// UK CAA radiotelephony manual indicates ATIS transmissions start
|
||||||
// with "This is ..."
|
// with "This is ..."
|
||||||
// In the US they just start with the airport name.
|
transmission += This_is + " ";
|
||||||
// transmission += "This_is ";
|
} else {
|
||||||
|
// In the US they just start with the airport name.
|
||||||
|
}
|
||||||
|
|
||||||
// SG_LOG(SG_ATC, SG_ALERT, "ATIS: facility name: " << name);
|
// SG_LOG(SG_ATC, SG_ALERT, "ATIS: facility name: " << name);
|
||||||
|
|
||||||
// Note that at this point, multi-word facility names
|
// Note that at this point, multi-word facility names
|
||||||
// will sometimes contain hyphens, not spaces.
|
// will sometimes contain hyphens, not spaces.
|
||||||
// Force the issue, just to be safe:
|
|
||||||
|
vector<string> name_words;
|
||||||
string name2 = name;
|
boost::split(name_words, name, boost::is_any_of(" -"));
|
||||||
for(string::iterator p = name2.begin(); p != name2.end(); p++){
|
|
||||||
if (*p == ' ') *p = '-';
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////
|
|
||||||
// FIXME: This would be more flexible and more extensible
|
|
||||||
// if the mappings were taken from an XML file, not hard-coded.
|
|
||||||
///////////////
|
|
||||||
|
|
||||||
|
for (vector<string>::const_iterator wordp = name_words.begin();
|
||||||
|
wordp != name_words.end(); wordp++) {
|
||||||
|
string word(*wordp);
|
||||||
// Remap some abbreviations that occur in apt.dat, to
|
// Remap some abbreviations that occur in apt.dat, to
|
||||||
// make things nicer for the text-to-speech system:
|
// make things nicer for the text-to-speech system:
|
||||||
name2 = replace_word(name2, "Intl", "International");
|
for (MSS::const_iterator replace = _remap.begin();
|
||||||
name2 = replace_word(name2, "Rgnl", "Regional");
|
replace != _remap.end(); replace++) {
|
||||||
name2 = replace_word(name2, "Co", "County");
|
// Due to inconsistent capitalisation in the apt.dat file, we need
|
||||||
name2 = replace_word(name2, "Muni", "Municipal");
|
// to do a case-insensitive comparison here.
|
||||||
name2 = replace_word(name2, "Mem", "Memorial");
|
string tmp1 = word, tmp2 = replace->first;
|
||||||
name2 = replace_word(name2, "Fld", "Field");
|
boost::algorithm::to_lower(tmp1);
|
||||||
name2 = replace_word(name2, "AFB", "Air-Force-Base");
|
boost::algorithm::to_lower(tmp2);
|
||||||
name2 = replace_word(name2, "AAF", "Army-Air-Field");
|
if (tmp1 == tmp2) {
|
||||||
name2 = replace_word(name2, "MCAS", "Marine-Corps-Air-Station");
|
word = replace->second;
|
||||||
transmission += name2 + " ";
|
break;
|
||||||
if (_type == ATIS /* as opposed to AWOS */) {
|
}
|
||||||
transmission += "airport_information ";
|
}
|
||||||
phonetic_seq_string = GetPhoneticLetter(sequence); // Add the sequence letter
|
transmission += word + " ";
|
||||||
transmission += phonetic_seq_string + BRK;
|
|
||||||
}
|
}
|
||||||
transmission += "Automated_weather_observation ";
|
|
||||||
|
if (_type == ATIS /* as opposed to AWOS */) {
|
||||||
|
transmission += airport_information + " ";
|
||||||
|
} else {
|
||||||
|
transmission += Automated_weather_observation + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
phonetic_seq_string = GetPhoneticLetter(sequence); // Add the sequence letter
|
||||||
|
transmission += phonetic_seq_string + BRK;
|
||||||
|
|
||||||
// Warning - this is fragile if the time string format changes
|
// Warning - this is fragile if the time string format changes
|
||||||
hours = time_str.substr(0,2).c_str();
|
hours = time_str.substr(0,2).c_str();
|
||||||
mins = time_str.substr(3,2).c_str();
|
mins = time_str.substr(3,2).c_str();
|
||||||
// speak each digit separately:
|
// speak each digit separately:
|
||||||
transmission += ConvertNumToSpokenDigits(hours + mins);
|
transmission += ConvertNumToSpokenDigits(hours + mins);
|
||||||
transmission += " zulu weather" + BRK;
|
transmission += " " + zulu + " " + weather + BRK;
|
||||||
|
|
||||||
transmission += "Wind: ";
|
transmission += wind + ": ";
|
||||||
|
|
||||||
double wind_speed = fgGetDouble("/environment/config/boundary/entry[0]/wind-speed-kt");
|
double wind_speed = fgGetDouble("/environment/config/boundary/entry[0]/wind-speed-kt");
|
||||||
double wind_dir = fgGetDouble("/environment/config/boundary/entry[0]/wind-from-heading-deg");
|
double wind_dir = fgGetDouble("/environment/config/boundary/entry[0]/wind-from-heading-deg");
|
||||||
|
@ -281,14 +310,14 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
// Force west-facing rwys to be used in no-wind situations
|
// Force west-facing rwys to be used in no-wind situations
|
||||||
// which is consistent with Flightgear's initial setup:
|
// which is consistent with Flightgear's initial setup:
|
||||||
wind_dir = 270;
|
wind_dir = 270;
|
||||||
transmission += " light_and_variable";
|
transmission += " " + light_and_variable;
|
||||||
} else {
|
} else {
|
||||||
// FIXME: get gust factor in somehow
|
// FIXME: get gust factor in somehow
|
||||||
snprintf(buf, bs, "%03.0f", 5*SGMiscd::round(wind_dir/5));
|
snprintf(buf, bs, "%03.0f", 5*SGMiscd::round(wind_dir/5));
|
||||||
transmission += ConvertNumToSpokenDigits(buf);
|
transmission += ConvertNumToSpokenDigits(buf);
|
||||||
|
|
||||||
snprintf(buf, bs, "%1.0f", wind_speed);
|
snprintf(buf, bs, "%1.0f", wind_speed);
|
||||||
transmission += " at " + ConvertNumToSpokenDigits(buf) + BRK;
|
transmission += " " + at + " " + ConvertNumToSpokenDigits(buf) + BRK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int did_some(0);
|
int did_some(0);
|
||||||
|
@ -297,17 +326,17 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
for (int layer = 0; layer <= 4; layer++) {
|
for (int layer = 0; layer <= 4; layer++) {
|
||||||
snprintf(buf, bs, "/environment/clouds/layer[%i]/coverage", layer);
|
snprintf(buf, bs, "/environment/clouds/layer[%i]/coverage", layer);
|
||||||
string coverage = fgGetString(buf);
|
string coverage = fgGetString(buf);
|
||||||
if (coverage == "clear") continue;
|
if (coverage == clear) continue;
|
||||||
snprintf(buf, bs, "/environment/clouds/layer[%i]/thickness-ft", layer);
|
snprintf(buf, bs, "/environment/clouds/layer[%i]/thickness-ft", layer);
|
||||||
if (fgGetDouble(buf) == 0) continue;
|
if (fgGetDouble(buf) == 0) continue;
|
||||||
snprintf(buf, bs, "/environment/clouds/layer[%i]/elevation-ft", layer);
|
snprintf(buf, bs, "/environment/clouds/layer[%i]/elevation-ft", layer);
|
||||||
double ceiling = int(fgGetDouble(buf) - _geod.getElevationFt());
|
double ceiling = int(fgGetDouble(buf) - _geod.getElevationFt());
|
||||||
if (ceiling > 12000) continue;
|
if (ceiling > 12000) continue;
|
||||||
if (coverage == "scattered") {
|
if (coverage == scattered) {
|
||||||
if (!did_some) transmission += " Sky_condition: ";
|
if (!did_some) transmission += " " + Sky_condition + ": ";
|
||||||
did_some++;
|
did_some++;
|
||||||
} else /* must be a ceiling */ if (!did_ceiling) {
|
} else /* must be a ceiling */ if (!did_ceiling) {
|
||||||
transmission += " Ceiling: ";
|
transmission += " " + Ceiling + ": ";
|
||||||
did_ceiling++;
|
did_ceiling++;
|
||||||
did_some++;
|
did_some++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -320,51 +349,52 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
if (cig000) {
|
if (cig000) {
|
||||||
snprintf(buf, bs, "%i", cig000);
|
snprintf(buf, bs, "%i", cig000);
|
||||||
transmission += ConvertNumToSpokenDigits(buf);
|
transmission += ConvertNumToSpokenDigits(buf);
|
||||||
transmission += " thousand ";
|
transmission += " " + thousand + " ";
|
||||||
}
|
}
|
||||||
if (cig00) {
|
if (cig00) {
|
||||||
snprintf(buf, bs, "%i", cig00);
|
snprintf(buf, bs, "%i", cig00);
|
||||||
transmission += ConvertNumToSpokenDigits(buf);
|
transmission += ConvertNumToSpokenDigits(buf);
|
||||||
transmission += " hundred ";
|
transmission += " " + hundred + " ";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Should this be "sky obscured?"
|
// Should this be "sky obscured?"
|
||||||
transmission += " zero "; // not "zero hundred"
|
transmission += " " + zero + " "; // not "zero hundred"
|
||||||
}
|
}
|
||||||
transmission += coverage + BRK;
|
transmission += coverage + BRK;
|
||||||
}
|
}
|
||||||
|
|
||||||
transmission += "Temperature: ";
|
transmission += Temperature + ": ";
|
||||||
double Tsl = fgGetDouble("/environment/temperature-sea-level-degc");
|
double Tsl = fgGetDouble("/environment/temperature-sea-level-degc");
|
||||||
int temp = int(SGMiscd::round(FGAtmo().fake_T_vs_a_us(_geod.getElevationFt(), Tsl)));
|
int temp = int(SGMiscd::round(FGAtmo().fake_T_vs_a_us(_geod.getElevationFt(), Tsl)));
|
||||||
if(temp < 0) {
|
if(temp < 0) {
|
||||||
transmission += "minus ";
|
transmission += lex::minus + " ";
|
||||||
}
|
}
|
||||||
snprintf(buf, bs, "%i", abs(temp));
|
snprintf(buf, bs, "%i", abs(temp));
|
||||||
transmission += ConvertNumToSpokenDigits(buf);
|
transmission += ConvertNumToSpokenDigits(buf);
|
||||||
transmission += " dewpoint ";
|
transmission += " " + Celsius;
|
||||||
|
transmission += " " + dewpoint + " ";
|
||||||
double dpsl = fgGetDouble("/environment/dewpoint-sea-level-degc");
|
double dpsl = fgGetDouble("/environment/dewpoint-sea-level-degc");
|
||||||
temp = int(SGMiscd::round(FGAtmo().fake_dp_vs_a_us(dpsl, _geod.getElevationFt())));
|
temp = int(SGMiscd::round(FGAtmo().fake_dp_vs_a_us(dpsl, _geod.getElevationFt())));
|
||||||
if(temp < 0) {
|
if(temp < 0) {
|
||||||
transmission += "minus ";
|
transmission += lex::minus + " ";
|
||||||
}
|
}
|
||||||
snprintf(buf, bs, "%i", abs(temp));
|
snprintf(buf, bs, "%i", abs(temp));
|
||||||
transmission += ConvertNumToSpokenDigits(buf) + BRK;
|
transmission += ConvertNumToSpokenDigits(buf);
|
||||||
|
transmission += " " + Celsius + BRK;
|
||||||
|
|
||||||
|
transmission += Visibility + ": ";
|
||||||
transmission += "Visibility: ";
|
|
||||||
double visibility = fgGetDouble("/environment/config/boundary/entry[0]/visibility-m");
|
double visibility = fgGetDouble("/environment/config/boundary/entry[0]/visibility-m");
|
||||||
visibility /= atmodel::sm; // convert to statute miles
|
visibility /= atmodel::sm; // convert to statute miles
|
||||||
if (visibility < 0.25) {
|
if (visibility < 0.25) {
|
||||||
transmission += "less than one quarter";
|
transmission += less_than_one_quarter;
|
||||||
} else if (visibility < 0.5) {
|
} else if (visibility < 0.5) {
|
||||||
transmission += "one quarter";
|
transmission += one_quarter;
|
||||||
} else if (visibility < 0.75) {
|
} else if (visibility < 0.75) {
|
||||||
transmission += "one half";
|
transmission += one_half;
|
||||||
} else if (visibility < 1.0) {
|
} else if (visibility < 1.0) {
|
||||||
transmission += "three quarters";
|
transmission += three_quarters;
|
||||||
} else if (visibility >= 1.5 && visibility < 2.0) {
|
} else if (visibility >= 1.5 && visibility < 2.0) {
|
||||||
transmission += "one and one half";
|
transmission += one_and_one_half;
|
||||||
} else {
|
} else {
|
||||||
// integer miles
|
// integer miles
|
||||||
if (visibility > 10) visibility = 10;
|
if (visibility > 10) visibility = 10;
|
||||||
|
@ -373,7 +403,7 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
}
|
}
|
||||||
transmission += BRK;
|
transmission += BRK;
|
||||||
|
|
||||||
transmission += "Altimeter: ";
|
transmission += Altimeter + ": ";
|
||||||
double myQNH;
|
double myQNH;
|
||||||
double Psl = fgGetDouble("/environment/pressure-sea-level-inhg");
|
double Psl = fgGetDouble("/environment/pressure-sea-level-inhg");
|
||||||
{
|
{
|
||||||
|
@ -405,7 +435,7 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
assert(apt);
|
assert(apt);
|
||||||
string rwy_no = apt->getActiveRunwayForUsage()->ident();
|
string rwy_no = apt->getActiveRunwayForUsage()->ident();
|
||||||
if(rwy_no != "NN") {
|
if(rwy_no != "NN") {
|
||||||
transmission += "Landing_and_departing_runway ";
|
transmission += Landing_and_departing_runway + " ";
|
||||||
transmission += ConvertRwyNumToSpokenString(rwy_no) + BRK;
|
transmission += ConvertRwyNumToSpokenString(rwy_no) + BRK;
|
||||||
if (msg_OK) {
|
if (msg_OK) {
|
||||||
msg_time = cur_time;
|
msg_time = cur_time;
|
||||||
|
@ -413,7 +443,7 @@ int FGATIS::GenTransmission(const int regen, const int special) {
|
||||||
// << " wind_dir: " << wind_dir << endl;
|
// << " wind_dir: " << wind_dir << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transmission += "On_initial_contact_advise_you_have_information ";
|
transmission += On_initial_contact_advise_you_have_information + " ";
|
||||||
transmission += phonetic_seq_string;
|
transmission += phonetic_seq_string;
|
||||||
transmission += "... " + BRK;
|
transmission += "... " + BRK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
//DCL - a complete guess for now.
|
//DCL - a complete guess for now.
|
||||||
#define FG_ATIS_DEFAULT_RANGE 30
|
#define FG_ATIS_DEFAULT_RANGE 30
|
||||||
|
|
||||||
|
typedef std::map<std::string,std::string> MSS;
|
||||||
|
|
||||||
class FGATIS : public FGATC {
|
class FGATIS : public FGATC {
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ class FGATIS : public FGATC {
|
||||||
int attention;
|
int attention;
|
||||||
|
|
||||||
bool _prev_display; // Previous value of _display flag
|
bool _prev_display; // Previous value of _display flag
|
||||||
|
MSS _remap; // abbreviations to be expanded
|
||||||
|
|
||||||
// Aircraft position
|
// Aircraft position
|
||||||
// ATIS is actually a special case in that unlike other ATC eg.tower it doesn't actually know about
|
// ATIS is actually a special case in that unlike other ATC eg.tower it doesn't actually know about
|
||||||
|
|
60
src/ATCDCL/atis_lexicon.hxx
Normal file
60
src/ATCDCL/atis_lexicon.hxx
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef _FG_ATIS_LEXICON_HXX
|
||||||
|
#define _FG_ATIS_LEXICON_HXX
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
#define Q(word) const std::string word(#word);
|
||||||
|
|
||||||
|
namespace lex {
|
||||||
|
Q(Airport)
|
||||||
|
Q(Airfield)
|
||||||
|
Q(Airbase)
|
||||||
|
Q(Junior)
|
||||||
|
Q(Celsius)
|
||||||
|
Q(wind)
|
||||||
|
Q(zulu)
|
||||||
|
Q(zulu_weather)
|
||||||
|
Q(Automated_weather_observation)
|
||||||
|
Q(weather)
|
||||||
|
Q(airport_information)
|
||||||
|
Q(International)
|
||||||
|
Q(Regional)
|
||||||
|
Q(County)
|
||||||
|
Q(Municipal)
|
||||||
|
Q(Memorial)
|
||||||
|
Q(Field)
|
||||||
|
Q(Air_Force_Base)
|
||||||
|
Q(Army_Air_Field)
|
||||||
|
Q(Marine_Corps_Air_Station)
|
||||||
|
Q(light_and_variable)
|
||||||
|
Q(at)
|
||||||
|
Q(thousand)
|
||||||
|
Q(hundred)
|
||||||
|
Q(zero)
|
||||||
|
Q(Temperature)
|
||||||
|
Q(clear)
|
||||||
|
Q(scattered)
|
||||||
|
Q(broken)
|
||||||
|
Q(overcast)
|
||||||
|
Q(Sky_condition)
|
||||||
|
Q(Ceiling)
|
||||||
|
Q(minus)
|
||||||
|
Q(dewpoint)
|
||||||
|
Q(Visibility)
|
||||||
|
Q(less_than_one_quarter)
|
||||||
|
Q(one_quarter)
|
||||||
|
Q(one_half)
|
||||||
|
Q(three_quarters)
|
||||||
|
Q(one_and_one_half)
|
||||||
|
Q(Altimeter)
|
||||||
|
Q(Landing_and_departing_runway)
|
||||||
|
Q(On_initial_contact_advise_you_have_information)
|
||||||
|
Q(This_is)
|
||||||
|
Q(left)
|
||||||
|
Q(right)
|
||||||
|
Q(center)
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef Q
|
||||||
|
#endif // _FG_ATIS_LEXICON_HXX
|
15
src/ATCDCL/atis_remap.hxx
Normal file
15
src/ATCDCL/atis_remap.hxx
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
REMAP(Intl, International)
|
||||||
|
REMAP(Rgnl, Regional)
|
||||||
|
REMAP(Co, County)
|
||||||
|
REMAP(Muni, Municipal)
|
||||||
|
REMAP(Mem, Memorial)
|
||||||
|
REMAP(Apt, Airport)
|
||||||
|
REMAP(Arpt, Airport)
|
||||||
|
REMAP(Fld, Field)
|
||||||
|
REMAP(AFLD, Airfield)
|
||||||
|
REMAP(AFB, Air_Force_Base)
|
||||||
|
REMAP(AB, Airbase)
|
||||||
|
REMAP(AAF, Army_Air_Field)
|
||||||
|
REMAP(MCAS, Marine_Corps_Air_Station)
|
||||||
|
REMAP(JR, Junior)
|
||||||
|
REMAP(GKI, NIL)
|
|
@ -46,11 +46,7 @@
|
||||||
#include "simple.hxx"
|
#include "simple.hxx"
|
||||||
#include "runways.hxx"
|
#include "runways.hxx"
|
||||||
#include "pavement.hxx"
|
#include "pavement.hxx"
|
||||||
#if ENABLE_ATCDCL
|
#include <ATCDCL/commlist.hxx>
|
||||||
# include <ATCDCL/commlist.hxx>
|
|
||||||
#else
|
|
||||||
#include <ATC/atcutils.hxx>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -486,7 +482,6 @@ private:
|
||||||
// 50 11770 AWOS 3
|
// 50 11770 AWOS 3
|
||||||
// This code parallels code found in "operator>>" in ATC.hxx;
|
// This code parallels code found in "operator>>" in ATC.hxx;
|
||||||
// FIXME: unify the code.
|
// FIXME: unify the code.
|
||||||
#if ENABLE_ATCDCL
|
|
||||||
ATCData a;
|
ATCData a;
|
||||||
a.geod = SGGeod::fromDegFt(rwy_lon_accum / (double)rwy_count,
|
a.geod = SGGeod::fromDegFt(rwy_lon_accum / (double)rwy_count,
|
||||||
rwy_lat_accum / (double)rwy_count, last_apt_elev);
|
rwy_lat_accum / (double)rwy_count, last_apt_elev);
|
||||||
|
@ -505,8 +500,6 @@ private:
|
||||||
SGBucket bucket(a.geod);
|
SGBucket bucket(a.geod);
|
||||||
int bucknum = bucket.gen_index();
|
int bucknum = bucket.gen_index();
|
||||||
comm_list->commlist_bck[bucknum].push_back(a);
|
comm_list->commlist_bck[bucknum].push_back(a);
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
#if 0
|
#if 0
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
"Loaded ATIS/AWOS for airport: " << a.ident
|
"Loaded ATIS/AWOS for airport: " << a.ident
|
||||||
|
|
|
@ -7,6 +7,7 @@ foreach( mylibfolder
|
||||||
Airports
|
Airports
|
||||||
Aircraft
|
Aircraft
|
||||||
ATC
|
ATC
|
||||||
|
ATCDCL
|
||||||
Autopilot
|
Autopilot
|
||||||
Cockpit
|
Cockpit
|
||||||
Environment
|
Environment
|
||||||
|
|
|
@ -298,6 +298,13 @@ FGJSBsim::FGJSBsim( double dt )
|
||||||
FGJSBsim::~FGJSBsim(void)
|
FGJSBsim::~FGJSBsim(void)
|
||||||
{
|
{
|
||||||
delete fdmex;
|
delete fdmex;
|
||||||
|
|
||||||
|
SGPropertyNode_ptr jsbsimRoot = fgGetNode("/fdm/jsbsim");
|
||||||
|
if (jsbsimRoot) {
|
||||||
|
SGPropertyNode* fdm = jsbsimRoot->getParent();
|
||||||
|
fdm->removeChild("jsbsim", 0, false);
|
||||||
|
}
|
||||||
|
// properties are deleted when the sharedPtr above goes away
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
#cmakedefine FG_NDEBUG
|
#cmakedefine FG_NDEBUG
|
||||||
#cmakedefine ENABLE_ATCDCL
|
|
||||||
#cmakedefine ENABLE_SP_FDM
|
#cmakedefine ENABLE_SP_FDM
|
||||||
|
|
||||||
// JSBSim needs this, to switch from standalone to in-FG mode
|
// JSBSim needs this, to switch from standalone to in-FG mode
|
||||||
|
|
|
@ -44,11 +44,7 @@
|
||||||
#include "kln89_symbols.hxx"
|
#include "kln89_symbols.hxx"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if ENABLE_ATCDCL
|
|
||||||
#include <ATCDCL/ATCProjection.hxx>
|
#include <ATCDCL/ATCProjection.hxx>
|
||||||
#else
|
|
||||||
#include <ATC/atcutils.hxx>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
#include <simgear/math/SGMath.hxx>
|
#include <simgear/math/SGMath.hxx>
|
||||||
|
@ -763,11 +759,7 @@ void KLN89::DrawMap(bool draw_avs) {
|
||||||
double mapScaleMeters = _mapScale * (_mapScaleUnits == 0 ? SG_NM_TO_METER : 1000);
|
double mapScaleMeters = _mapScale * (_mapScaleUnits == 0 ? SG_NM_TO_METER : 1000);
|
||||||
|
|
||||||
// TODO - use an aligned projection when either DTK or TK up!
|
// TODO - use an aligned projection when either DTK or TK up!
|
||||||
#if ENABLE_ATCDCL
|
|
||||||
FGATCAlignedProjection mapProj(SGGeod::fromRad(_gpsLon, _gpsLat), _mapHeading);
|
FGATCAlignedProjection mapProj(SGGeod::fromRad(_gpsLon, _gpsLat), _mapHeading);
|
||||||
#else
|
|
||||||
FGKln89AlignedProjection mapProj(SGGeod::fromRad(_gpsLon, _gpsLat), _mapHeading);
|
|
||||||
#endif
|
|
||||||
double meter_per_pix = (_mapOrientation == 0 ? mapScaleMeters / 20.0f : mapScaleMeters / 29.0f);
|
double meter_per_pix = (_mapOrientation == 0 ? mapScaleMeters / 20.0f : mapScaleMeters / 29.0f);
|
||||||
SGGeod bottomLeft = mapProj.ConvertFromLocal(SGVec3d(gps_max(-57.0 * meter_per_pix, -50000), gps_max((_mapOrientation == 0 ? -20.0 * meter_per_pix : -11.0 * meter_per_pix), -25000), 0.0));
|
SGGeod bottomLeft = mapProj.ConvertFromLocal(SGVec3d(gps_max(-57.0 * meter_per_pix, -50000), gps_max((_mapOrientation == 0 ? -20.0 * meter_per_pix : -11.0 * meter_per_pix), -25000), 0.0));
|
||||||
SGGeod topRight = mapProj.ConvertFromLocal(SGVec3d(gps_min(54.0 * meter_per_pix, 50000), gps_min((_mapOrientation == 0 ? 20.0 * meter_per_pix : 29.0 * meter_per_pix), 25000), 0.0));
|
SGGeod topRight = mapProj.ConvertFromLocal(SGVec3d(gps_min(54.0 * meter_per_pix, 50000), gps_min((_mapOrientation == 0 ? 20.0 * meter_per_pix : 29.0 * meter_per_pix), 25000), 0.0));
|
||||||
|
|
|
@ -29,11 +29,7 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#if ENABLE_ATCDCL
|
#include <ATCDCL/commlist.hxx>
|
||||||
# include <ATCDCL/commlist.hxx>
|
|
||||||
#else
|
|
||||||
#include <ATC/atcutils.hxx>
|
|
||||||
#endif
|
|
||||||
#include <Main/globals.hxx>
|
#include <Main/globals.hxx>
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
#include <Airports/simple.hxx>
|
#include <Airports/simple.hxx>
|
||||||
|
|
|
@ -9,13 +9,6 @@ else
|
||||||
SP_FDM_LIBS =
|
SP_FDM_LIBS =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ENABLE_ATCDCL
|
|
||||||
ATCDCL_LIBS = $(top_builddir)/src/ATCDCL/libATCDCL.a
|
|
||||||
else
|
|
||||||
ATCDCL_LIBS =
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
if WITH_EVENTINPUT
|
if WITH_EVENTINPUT
|
||||||
EVENT_LIBS = $(eventinput_LIBS)
|
EVENT_LIBS = $(eventinput_LIBS)
|
||||||
else
|
else
|
||||||
|
@ -81,7 +74,7 @@ fgfs_SOURCES = bootstrap.cxx
|
||||||
fgfs_LDADD = \
|
fgfs_LDADD = \
|
||||||
libMain.a \
|
libMain.a \
|
||||||
$(top_builddir)/src/Aircraft/libAircraft.a \
|
$(top_builddir)/src/Aircraft/libAircraft.a \
|
||||||
$(ATCDCL_LIBS) \
|
$(top_builddir)/src/ATCDCL/libATCDCL.a \
|
||||||
$(top_builddir)/src/Cockpit/libCockpit.a \
|
$(top_builddir)/src/Cockpit/libCockpit.a \
|
||||||
$(top_builddir)/src/Cockpit/built_in/libBuilt_in.a \
|
$(top_builddir)/src/Cockpit/built_in/libBuilt_in.a \
|
||||||
$(top_builddir)/src/Network/libNetwork.a \
|
$(top_builddir)/src/Network/libNetwork.a \
|
||||||
|
|
|
@ -74,13 +74,9 @@
|
||||||
|
|
||||||
#include <AIModel/AIManager.hxx>
|
#include <AIModel/AIManager.hxx>
|
||||||
|
|
||||||
#if ENABLE_ATCDCL
|
#include <ATCDCL/ATCmgr.hxx>
|
||||||
# include <ATCDCL/ATCmgr.hxx>
|
#include <ATCDCL/commlist.hxx>
|
||||||
# include "ATCDCL/commlist.hxx"
|
#include <ATC/atis_mgr.hxx>
|
||||||
#else
|
|
||||||
# include "ATC/atis.hxx"
|
|
||||||
# include "ATC/atcutils.hxx"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <Autopilot/route_mgr.hxx>
|
#include <Autopilot/route_mgr.hxx>
|
||||||
#include <Autopilot/autopilotgroup.hxx>
|
#include <Autopilot/autopilotgroup.hxx>
|
||||||
|
@ -1387,19 +1383,17 @@ bool fgInitSubsystems() {
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Initialise the ATC Manager
|
// Initialise the ATC Manager
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if ENABLE_ATCDCL
|
|
||||||
SG_LOG(SG_GENERAL, SG_INFO, " ATC Manager");
|
SG_LOG(SG_GENERAL, SG_INFO, " ATC Manager");
|
||||||
globals->set_ATC_mgr(new FGATCMgr);
|
globals->set_ATC_mgr(new FGATCMgr);
|
||||||
globals->get_ATC_mgr()->init();
|
globals->get_ATC_mgr()->init();
|
||||||
#else
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Initialise the ATIS Manager
|
// Initialise the ATIS Manager
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
globals->add_subsystem("atis", new FGAtisManager, SGSubsystemMgr::POST_FDM);
|
globals->add_subsystem("atis", new FGAtisManager, SGSubsystemMgr::POST_FDM);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -83,7 +83,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.exists()) {
|
if (r.exists()) {
|
||||||
SG_LOG(SG_IO, SG_INFO, "found path:" << aResource << " via /sim/aircraft-dir: " << r.str());
|
SG_LOG(SG_IO, SG_DEBUG, "found path:" << aResource << " via /sim/aircraft-dir: " << r.str());
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public:
|
||||||
for (; it != dirs.end(); ++it) {
|
for (; it != dirs.end(); ++it) {
|
||||||
SGPath p(*it, res);
|
SGPath p(*it, res);
|
||||||
if (p.exists()) {
|
if (p.exists()) {
|
||||||
SG_LOG(SG_IO, SG_INFO, "found path:" << aResource << " in aircraft dir: " << *it);
|
SG_LOG(SG_IO, SG_DEBUG, "found path:" << aResource << " in aircraft dir: " << *it);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
} // of aircraft path iteration
|
} // of aircraft path iteration
|
||||||
|
|
|
@ -63,9 +63,7 @@
|
||||||
#include <Sound/beacon.hxx>
|
#include <Sound/beacon.hxx>
|
||||||
#include <Sound/morse.hxx>
|
#include <Sound/morse.hxx>
|
||||||
#include <Sound/fg_fx.hxx>
|
#include <Sound/fg_fx.hxx>
|
||||||
#if ENABLE_ATCDCL
|
|
||||||
#include <ATCDCL/ATCmgr.hxx>
|
#include <ATCDCL/ATCmgr.hxx>
|
||||||
#endif
|
|
||||||
#include <Time/TimeManager.hxx>
|
#include <Time/TimeManager.hxx>
|
||||||
#include <Environment/environment_mgr.hxx>
|
#include <Environment/environment_mgr.hxx>
|
||||||
#include <Environment/ephemeris.hxx>
|
#include <Environment/ephemeris.hxx>
|
||||||
|
@ -145,11 +143,8 @@ static void fgMainLoop( void ) {
|
||||||
altitude->getDoubleValue() * SG_FEET_TO_METER,
|
altitude->getDoubleValue() * SG_FEET_TO_METER,
|
||||||
globals->get_time_params()->getJD() );
|
globals->get_time_params()->getJD() );
|
||||||
|
|
||||||
#if ENABLE_ATCDCL
|
|
||||||
// Run ATC subsystem
|
// Run ATC subsystem
|
||||||
if (fgGetBool("/sim/atc/enabled"))
|
globals->get_ATC_mgr()->update(sim_dt);
|
||||||
globals->get_ATC_mgr()->update(sim_dt);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
globals->get_subsystem_mgr()->update(sim_dt);
|
globals->get_subsystem_mgr()->update(sim_dt);
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
if ENABLE_ATCDCL
|
|
||||||
ATCDCL_DIR = ATCDCL
|
|
||||||
else
|
|
||||||
ATCDCL_DIR =
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
Include \
|
Include \
|
||||||
Aircraft \
|
Aircraft \
|
||||||
Airports \
|
Airports \
|
||||||
ATC \
|
ATC \
|
||||||
$(ATCDCL_DIR) \
|
ATCDCL \
|
||||||
Autopilot \
|
Autopilot \
|
||||||
Cockpit \
|
Cockpit \
|
||||||
Environment \
|
Environment \
|
||||||
|
|
|
@ -186,8 +186,16 @@ static naRef f_getprop(naContext c, naRef me, int argc, naRef* args)
|
||||||
case props::BOOL: case props::INT:
|
case props::BOOL: case props::INT:
|
||||||
case props::LONG: case props::FLOAT:
|
case props::LONG: case props::FLOAT:
|
||||||
case props::DOUBLE:
|
case props::DOUBLE:
|
||||||
return naNum(p->getDoubleValue());
|
{
|
||||||
|
double dv = p->getDoubleValue();
|
||||||
|
if (osg::isNaN(dv)) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Nasal getprop: property " << p->getPath() << " is NaN");
|
||||||
|
naRuntimeError(c, "getprop() would have read NaN");
|
||||||
|
}
|
||||||
|
|
||||||
|
return naNum(dv);
|
||||||
|
}
|
||||||
|
|
||||||
case props::STRING:
|
case props::STRING:
|
||||||
case props::UNSPECIFIED:
|
case props::UNSPECIFIED:
|
||||||
{
|
{
|
||||||
|
@ -234,6 +242,11 @@ static naRef f_setprop(naContext c, naRef me, int argc, naRef* args)
|
||||||
naRef n = naNumValue(val);
|
naRef n = naNumValue(val);
|
||||||
if(naIsNil(n))
|
if(naIsNil(n))
|
||||||
naRuntimeError(c, "setprop() value is not string or number");
|
naRuntimeError(c, "setprop() value is not string or number");
|
||||||
|
|
||||||
|
if (osg::isNaN(n.num)) {
|
||||||
|
naRuntimeError(c, "setprop() passed a NaN");
|
||||||
|
}
|
||||||
|
|
||||||
result = props->setDoubleValue(buf, n.num);
|
result = props->setDoubleValue(buf, n.num);
|
||||||
}
|
}
|
||||||
} catch (const string& err) {
|
} catch (const string& err) {
|
||||||
|
|
|
@ -169,7 +169,16 @@ static naRef f_getValue(naContext c, naRef me, int argc, naRef* args)
|
||||||
case props::BOOL: case props::INT:
|
case props::BOOL: case props::INT:
|
||||||
case props::LONG: case props::FLOAT:
|
case props::LONG: case props::FLOAT:
|
||||||
case props::DOUBLE:
|
case props::DOUBLE:
|
||||||
return naNum((*node)->getDoubleValue());
|
{
|
||||||
|
double dv = (*node)->getDoubleValue();
|
||||||
|
if (osg::isNaN(dv)) {
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT, "Nasal getValue: property " << (*node)->getPath() << " is NaN");
|
||||||
|
naRuntimeError(c, "props.getValue() would have read NaN");
|
||||||
|
}
|
||||||
|
|
||||||
|
return naNum(dv);
|
||||||
|
}
|
||||||
|
|
||||||
case props::STRING:
|
case props::STRING:
|
||||||
case props::UNSPECIFIED:
|
case props::UNSPECIFIED:
|
||||||
return NASTR((*node)->getStringValue());
|
return NASTR((*node)->getStringValue());
|
||||||
|
@ -217,7 +226,13 @@ static naRef f_setValue(naContext c, naRef me, int argc, naRef* args)
|
||||||
naRef n = naNumValue(val);
|
naRef n = naNumValue(val);
|
||||||
if(naIsNil(n))
|
if(naIsNil(n))
|
||||||
naRuntimeError(c, "props.setValue() with non-number");
|
naRuntimeError(c, "props.setValue() with non-number");
|
||||||
result = (*node)->setDoubleValue(naNumValue(val).num);
|
|
||||||
|
double d = naNumValue(val).num;
|
||||||
|
if (osg::isNaN(d)) {
|
||||||
|
naRuntimeError(c, "props.setValue() passed a NaN");
|
||||||
|
}
|
||||||
|
|
||||||
|
result = (*node)->setDoubleValue(d);
|
||||||
}
|
}
|
||||||
return naNum(result);
|
return naNum(result);
|
||||||
}
|
}
|
||||||
|
@ -250,8 +265,13 @@ static naRef f_setDoubleValue(naContext c, naRef me, int argc, naRef* args)
|
||||||
{
|
{
|
||||||
NODEARG();
|
NODEARG();
|
||||||
naRef r = naNumValue(naVec_get(argv, 0));
|
naRef r = naNumValue(naVec_get(argv, 0));
|
||||||
if(naIsNil(r))
|
if (naIsNil(r))
|
||||||
naRuntimeError(c, "props.setDoubleValue() with non-number");
|
naRuntimeError(c, "props.setDoubleValue() with non-number");
|
||||||
|
|
||||||
|
if (osg::isNaN(r.num)) {
|
||||||
|
naRuntimeError(c, "props.setDoubleValue() passed a NaN");
|
||||||
|
}
|
||||||
|
|
||||||
return naNum((*node)->setDoubleValue(r.num));
|
return naNum((*node)->setDoubleValue(r.num));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue