1
0
Fork 0
This commit is contained in:
Torsten Dreyer 2011-01-05 09:16:12 +01:00
commit ecdc811a5b
18 changed files with 520 additions and 147 deletions

View file

@ -8,7 +8,9 @@ include (CPack)
project(FlightGear) project(FlightGear)
file(READ version FLIGHTGEAR_VERSION) # read 'version' file into a variable (stripping any newlines or spaces)
file(READ version versionFile)
string(STRIP ${versionFile} FLIGHTGEAR_VERSION)
#packaging #packaging
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING") SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
@ -20,6 +22,25 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}")
# autoconf compatibility # autoconf compatibility
set(PKGLIBDIR "foo") set(PKGLIBDIR "foo")
if($ENV{BUILD_ID})
set(HUDSON_BUILD_ID $ENV{BUILD_ID})
set(HUDSON_BUILD_NUMBER $ENV{BUILD_NUMBER})
message(STATUS "running under Hudson, build-number is ${HUDSON_BUILD_NUMBER}")
else()
set(HUDSON_BUILD_NUMBER 0)
set(HUDSON_BUILD_ID "none")
endif()
find_package(Git)
if (GIT_FOUND)
execute_process(COMMAND git --git-dir ${PROJECT_SOURCE_DIR}/.git rev-parse HEAD
OUTPUT_VARIABLE REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Git revision is ${REVISION}")
else()
set(REVISION "none")
endif()
option(LOGGING "Set to OFF to build FlightGear without logging" ON) option(LOGGING "Set to OFF to build FlightGear without logging" ON)
option(SP_FDMS "Set to ON to build FlightGear with special-purpose FDMs" OFF) option(SP_FDMS "Set to ON to build FlightGear with special-purpose FDMs" OFF)
@ -28,6 +49,7 @@ 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(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)
set(MSVC_3RDPARTY_DIR NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
if(LOGGING) if(LOGGING)
# nothing # nothing
@ -52,29 +74,32 @@ else(EVENT_INPUT)
set(ENABLE_PLIB_JOYSTICK 1) set(ENABLE_PLIB_JOYSTICK 1)
endif(EVENT_INPUT) endif(EVENT_INPUT)
# check required dependencies if (MSVC_3RDPARTY_DIR)
if (MSVC) message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_DIR}")
# on MSVC, Olaf reports that the serialization library is required at set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_DIR}/3rdParty/lib ${MSVC_3RDPARTY_DIR}/install/msvc90/OpenScenegraph/lib ${MSVC_3RDPARTY_DIR}/install/msvc90/SimGear/lib )
# link time. No one has you explained why, unfortunately. set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_DIR}/3rdParty/include ${MSVC_3RDPARTY_DIR}/install/msvc90/OpenScenegraph/include ${MSVC_3RDPARTY_DIR}/install/msvc90/SimGear/include)
set(Boost_USE_STATIC_LIBS ON) set (BOOST_ROOT ${MSVC_3RDPARTY_DIR}/boost_1_44_0)
set(Boost_USE_MULTITHREADED ON) set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_DIR}/3rdParty/include)
set(Boost_USE_STATIC_RUNTIME OFF) set (ALUT_INCLUDE_DIR ${MSVC_3RDPARTY_DIR}/3rdParty/include)
find_package(Boost REQUIRED COMPONENTS serialization) set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_DIR}/3rdParty/lib)
else (MSVC) endif (MSVC_3RDPARTY_DIR)
find_package(Boost REQUIRED)
endif (MSVC)
# check required dependencies
find_package(Boost REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
find_package(OpenAL REQUIRED) find_package(OpenAL REQUIRED)
find_package(ALUT REQUIRED) find_package(ALUT REQUIRED)
find_package(OpenSceneGraph 2.8.2 REQUIRED osgText osgSim osgDB osgParticle osgFX osgUtil osgViewer osgGA) find_package(OpenSceneGraph 2.8.2 REQUIRED osgText osgSim osgDB osgParticle osgFX osgUtil osgViewer osgGA)
find_package(PLIB REQUIRED puaux pu js fnt) find_package(PLIB REQUIRED puaux pu js fnt)
find_package(SimGear 2.0.0 REQUIRED) find_package(SimGear 2.0.0 REQUIRED)
check_include_file(unistd.h HAVE_UNISTD_H) check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H) check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(windows.h HAVE_WINDOWS_H)
# definition depends on OSG version # definition depends on OSG version
set(CMAKE_REQUIRED_INCLUDES ${OPENSCENEGRAPH_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES ${OPENSCENEGRAPH_INCLUDE_DIRS})
@ -128,7 +153,7 @@ if(WIN32)
# SET(WARNING_FLAGS "${WARNING_FLAGS} /wd${warning}") # SET(WARNING_FLAGS "${WARNING_FLAGS} /wd${warning}")
# endforeach(warning) # endforeach(warning)
set(MSVC_FLAGS "-DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS") set(MSVC_FLAGS "-DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS")
endif(MSVC) endif(MSVC)
set(NOMINMAX 1) set(NOMINMAX 1)
@ -146,6 +171,10 @@ include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
${PLIB_INCLUDE_DIR} ) ${PLIB_INCLUDE_DIR} )
include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_SOURCE_DIR}/src)
# following is needed, because config.h is include 'bare', whereas
# version.h is included as <Include/version.h> - this should be cleaned up
include_directories(${PROJECT_BINARY_DIR}/src)
include_directories(${PROJECT_BINARY_DIR}/src/Include) include_directories(${PROJECT_BINARY_DIR}/src/Include)
add_definitions(-DHAVE_CONFIG_H) add_definitions(-DHAVE_CONFIG_H)
@ -157,6 +186,12 @@ configure_file (
"${PROJECT_BINARY_DIR}/src/Include/config.h" "${PROJECT_BINARY_DIR}/src/Include/config.h"
) )
#and the same for the version header
configure_file (
"${PROJECT_SOURCE_DIR}/src/Include/version.h.cmake-in"
"${PROJECT_BINARY_DIR}/src/Include/version.h"
)
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(utils) add_subdirectory(utils)

View file

@ -67,76 +67,92 @@ FIND_LIBRARY(PLIB_LIBRARIES
/Library/Frameworks /Library/Frameworks
) )
if (MSVC)
set (PUNAME "pui")
else (MSVC)
set (PUNAME "pu")
endif (MSVC)
macro(find_static_component comp libs) macro(find_static_component comp libs)
set(compLib "plib${comp}") # account for alternative Windows PLIB distribution naming
string(TOUPPER "PLIB_${comp}_LIBRARY" compLibName) if(MSVC)
set(compLib "${comp}")
else(MSVC)
set(compLib "plib${comp}")
endif(MSVC)
FIND_LIBRARY(${compLibName} string(TOUPPER "PLIB_${comp}_LIBRARY" compLibName)
NAMES ${compLib}
HINTS $ENV{PLIBDIR}
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
PATHS
/usr/local
/usr
/opt
)
set(componentLib ${${compLibName}}) FIND_LIBRARY(${compLibName}
if (NOT ${componentLib} STREQUAL "componentLib-NOTFOUND") NAMES ${compLib}
#message(STATUS "found ${componentLib}") HINTS $ENV{PLIBDIR}
list(APPEND ${libs} ${componentLib}) PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
#set(PLIB_LIBRARIES "${PLIB_LIBRARIES} ${componentLib}" PARENT_SCOPE) PATHS
endif() /usr/local
/usr
/opt
)
set(componentLib ${${compLibName}})
if (NOT ${componentLib} STREQUAL "componentLib-NOTFOUND")
list(APPEND ${libs} ${componentLib})
endif()
endmacro() endmacro()
if(${PLIB_LIBRARIES} STREQUAL "PLIB_LIBRARIES-NOTFOUND") if(${PLIB_LIBRARIES} STREQUAL "PLIB_LIBRARIES-NOTFOUND")
set(PLIB_LIBRARIES "") # clear value set(PLIB_LIBRARIES "") # clear value
# based on the contents of deps, add other required PLIB # based on the contents of deps, add other required PLIB
# static library dependencies. Eg PUI requires SSG and FNT # static library dependencies. Eg PUI requires SSG and FNT
set(outDeps ${PLIB_FIND_COMPONENTS}) set(outDeps ${PLIB_FIND_COMPONENTS})
foreach(c ${PLIB_FIND_COMPONENTS}) foreach(c ${PLIB_FIND_COMPONENTS})
if (${c} STREQUAL "pu") if (${c} STREQUAL "pu")
list(APPEND outDeps "fnt" "ssg" "sg") # handle MSVC confusion over pu/pui naming, by removing
elseif (${c} STREQUAL "puaux") # 'pu' and then adding it back
list(APPEND outDeps "pu" "fnt" "ssg" "sg") list(REMOVE_ITEM outDeps "pu")
elseif (${c} STREQUAL "ssg") list(APPEND outDeps ${PUNAME} "fnt" "ssg" "sg")
list(APPEND outDeps "sg") elseif (${c} STREQUAL "puaux")
endif() list(APPEND outDeps ${PUNAME} "fnt" "ssg" "sg")
endforeach() elseif (${c} STREQUAL "ssg")
list(APPEND outDeps "sg")
endif()
endforeach()
list(APPEND outDeps "ul") # everything needs ul list(APPEND outDeps "ul") # everything needs ul
list(REMOVE_DUPLICATES outDeps) # clean up list(REMOVE_DUPLICATES outDeps) # clean up
# look for traditional static libraries
foreach(component ${outDeps})
find_static_component(${component} PLIB_LIBRARIES) # look for traditional static libraries
endforeach() foreach(component ${outDeps})
find_static_component(${component} PLIB_LIBRARIES)
endforeach()
endif() endif()
list(FIND outDeps "js" haveJs) list(FIND outDeps "js" haveJs)
if(${haveJs} GREATER -1) if(${haveJs} GREATER -1)
message(STATUS "adding runtime JS dependencies") message(STATUS "adding runtime JS dependencies")
if(APPLE) if(APPLE)
# resolve frameworks to full paths # resolve frameworks to full paths
find_library(IOKIT_LIBRARY IOKit) find_library(IOKIT_LIBRARY IOKit)
find_library(CF_LIBRARY CoreFoundation) find_library(CF_LIBRARY CoreFoundation)
set(JS_LIBS ${IOKIT_LIBRARY} ${CF_LIBRARY}) set(JS_LIBS ${IOKIT_LIBRARY} ${CF_LIBRARY})
elseif(WIN32) elseif(WIN32)
find_library(WINMM_LIBRARY winmm) find_library(WINMM_LIBRARY winmm)
set(JS_LIBS ${WINMM_LIBRARY}) set(JS_LIBS ${WINMM_LIBRARY})
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
# anything needed here? # anything needed here?
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
find_library(USBHID_LIBRARY usbhid) find_library(USBHID_LIBRARY usbhid)
# check_function_exists(hidinit) # check_function_exists(hidinit)
set(JS_LIBS ${USBHID_LIBRARY}) set(JS_LIBS ${USBHID_LIBRARY})
else() else()
message(WARNING "Unsupported platform for PLIB JS libs") message(WARNING "Unsupported platform for PLIB JS libs")
endif() endif()
list(APPEND PLIB_LIBRARIES ${JS_LIBS}) list(APPEND PLIB_LIBRARIES ${JS_LIBS})
endif() endif()
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)

View file

@ -134,7 +134,7 @@ SET(CMAKE_REQUIRED_INCLUDES ${SIMGEAR_INCLUDE_DIR})
check_cxx_source_runs( check_cxx_source_runs(
"#include <cstdio> "#include <cstdio>
#include <simgear/version.h> #include \"simgear/version.h\"
#define xstr(s) str(s) #define xstr(s) str(s)
#define str(s) #s #define str(s) #s

View file

@ -530,7 +530,7 @@ if test "x$ac_cv_header_simgear_version_h" != "xyes"; then
exit exit
fi fi
AC_MSG_CHECKING([for SimGear 2.0.0 or newer]) AC_MSG_CHECKING([for SimGear 2.2.0 or newer])
AC_TRY_RUN([ AC_TRY_RUN([
#include <stdio.h> #include <stdio.h>
@ -540,7 +540,7 @@ AC_TRY_RUN([
#define XSTRINGIFY(X) #X #define XSTRINGIFY(X) #X
#define MIN_MAJOR 2 #define MIN_MAJOR 2
#define MIN_MINOR 0 #define MIN_MINOR 2
#define MIN_MICRO 0 #define MIN_MICRO 0
int main() { int main() {
@ -837,6 +837,7 @@ AC_CONFIG_FILES([ \
scripts/debug/Makefile \ scripts/debug/Makefile \
scripts/perl/Makefile \ scripts/perl/Makefile \
scripts/perl/examples/Makefile \ scripts/perl/examples/Makefile \
scripts/perl/traffic/Makefile \
scripts/python/Makefile \ scripts/python/Makefile \
src/Makefile \ src/Makefile \
src/Include/Makefile \ src/Include/Makefile \

View file

@ -1 +1,2 @@
SUBDIRS = examples SUBDIRS = examples \
traffic

View file

@ -0,0 +1,3 @@
EXTRA_DIST = \
conf2xml.pl \
xml2conf.pl

117
scripts/perl/traffic/conf2xml.pl Executable file
View file

@ -0,0 +1,117 @@
#!/usr/bin/perl -w
sub parseTime {
# print "Parsing time @_\n";
#die;
my $timeStr = $_[0];
@timeArray = split(":", $timeStr);
# print STDERR "TimeArray: @timeArray\n";
return ($timeArray[0] + $timeArray[1]/60.0);
}
sub writeFlight {
print XMLFILE " <flight>\n";
print XMLFILE " <callsign>$_[0]</callsign>\n";
print XMLFILE " <required-aircraft>$_[1]</required-aircraft>\n";
print XMLFILE " <fltrules>$_[2]</fltrules>\n";
print XMLFILE " <departure>\n";
print XMLFILE " <port>$_[3]</port>\n";
if ($_[4] =~ /[0-6]/) { print XMLFILE " <time>$_[4]/$_[5]:00</time>\n" }
else { print XMLFILE " <time>$_[5]:00</time>\n" };
print XMLFILE " </departure>\n";
print XMLFILE " <cruise-alt>$_[6]</cruise-alt>\n";
print XMLFILE " <arrival>\n";
print XMLFILE " <port>$_[7]</port>\n";
if ($_[8] =~ /[0-6]/) { print XMLFILE " <time>$_[8]/$_[9]:00</time>\n" }
else { print XMLFILE " <time>$_[9]:00</time>\n" };
print XMLFILE " </arrival>\n";
if (($_[4] =~ /[0-6]/) && ($_[8] =~ /[0-6]/)) { print XMLFILE " <repeat>WEEK</repeat>\n" }
else { print XMLFILE " <repeat>24Hr</repeat>\n" };
print XMLFILE " </flight>\n";
return;
}
@inputfiles = glob("???.conf");
while ($infile = shift(@inputfiles)) {
open (CONF, $infile) or die "Unable to open input configuration file";
($outname = $infile) =~ s/conf/xml/;
print "Opening $outname\n";
open XMLFILE, ">$outname";
while ($buf = readline(CONF)) {
push @DataList, $buf;
}
close (CONF);
print XMLFILE "<?xml version=\"1.0\"?>\n";
print XMLFILE "<trafficlist>\n";
while ($dataline = shift(@DataList)) {
# print STDERR "Dataline: $dataline\n";
@token = split(" ", $dataline);
if (scalar(@token) > 0) {
# print STDERR "Token: @token\n";
if ($token[0] eq "AC")
{
print XMLFILE " <aircraft>\n";
print XMLFILE " <model>$token[12]</model>\n";
print XMLFILE " <livery>$token[6]</livery>\n";
print XMLFILE " <airline>$token[5]</airline>\n";
print XMLFILE " <home-port>$token[1]</home-port>\n";
print XMLFILE " <required-aircraft>$token[3]$token[5]</required-aircraft>\n";
print XMLFILE " <actype>$token[4]</actype>\n";
print XMLFILE " <offset>$token[7]</offset>\n";
print XMLFILE " <radius>$token[8]</radius>\n";
print XMLFILE " <flighttype>$token[9]</flighttype>\n";
print XMLFILE " <performance-class>$token[10]</performance-class>\n";
print XMLFILE " <registration>$token[2]</registration>\n";
print XMLFILE " <heavy>$token[11]</heavy>\n";
print XMLFILE " </aircraft>\n";
}
if ($token[0] eq "FLIGHT") {
$weekdays = $token[3];
if (!(($weekdays =~ /^(0|\.)?(1|\.)?(2|\.)?(3|\.)?(4|\.)?(5|\.)?(6|\.)?$/) || ($weekdays eq "DAILY"))) {
die "Syntax Error! Check days $weekdays for flight no. $token[1]!\n";
}
if ($token[4] !~ /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])$/) {
die "Syntax Error! Check departure time $token[4] for flight no. $token[1]!\n"
}
if ($token[6] !~ /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])$/) {
die "Syntax Error! Check arrival time $token[6] for flight no. $token[1]!\n"
}
# print STDERR "Weekdays: $weekdays\n";
if ($weekdays =~ /^(0|\.)?(1|\.)?(2|\.)?(3|\.)?(4|\.)?(5|\.)?(6|\.)?$/) {
# print STDERR "Weekly for flight no. $token[1]\n";
# print STDERR "Day: $_\n";
@day = split(//, $weekdays);
foreach (@day) {
if ($_ eq "\.") {
next;
} else {
$depTime = parseTime($token[4]);
# print STDERR "depTime: $depTime\n";
$arrTime = parseTime($token[6]);
# print STDERR "arrTime: $arrTime\n";
$depDay = $_ + 1;
if ($depDay > 6) { $depDay = 0 };
$arrDay = $depDay;
if ($depTime > $arrTime) { $arrDay++ };
if ($arrDay > 6) { $arrDay = 0 };
# print STDERR "depDay: $depDay, arrDay: $arrDay\n";
writeFlight ($token[1], $token[9], $token[2], $token[5], $depDay, $token[4], $token[8], $token[7], $arrDay, $token[6]);
}
}
}
elsif ($weekdays eq "DAILY") {
# print STDERR "Daily flights for flight no. $token[1]\n";
$depTime = parseTime($token[4]);
$arrTime = parseTime($token[6]);
writeFlight ($token[1], $token[9], $token[2], $token[5], 7, $token[4], $token[8], $token[7], 7, $token[6]);
}
else {
die "System Error! Can't find days to place a flight!\n";
}
}
}
}
print XMLFILE "</trafficlist>\n";
close XMLFILE;
# print "Closing $outname\n";
}

View file

@ -0,0 +1,99 @@
#!/usr/bin/perl -w
#use strict;
#use warnings;
# DEBUG
# use Data::Dumper;
# print Dumper($data) . "\n";
# END
if (scalar (@ARGV) == 1) {
@files = glob("$ARGV[0]");
print "Processing : ", @files, "\n";
} else {
die "Usage : conf2xml.pl <inputfile> [ > outputfile ]\n";
}
$file = shift(@files);
use Switch;
use XML::LibXML;
my $parser = XML::LibXML->new();
my $doc = $parser->load_xml(location => $file);
my $data;
# reformatting days
# According to http://wiki.flightgear.org/index.php/Interactive_Traffic
# 0 = Sunday and 6 = saturday
# For convenience we switch here to "classical" numbering
# where 0 = Monday and 6 = sunday
sub parseDay {
my $day;
$day = substr($_[0],0,1);
switch ($day) {
case 0 {$day="......6"} # Sunday
case 1 {$day="0......"} # Monday
case 2 {$day=".1....."} # Tuesday
case 3 {$day="..2...."} # Wednesday
case 4 {$day="...3..."} # Thrusday
case 5 {$day="....4.."} # Friday
case 6 {$day=".....5."} # Saturday
else {$day="0123456"} # Daily
};
return $day;
}
# reformatting times
sub parseTime {
return substr($_[0],2,5);
}
print "# AC Homeport Registration RequiredAC AcTyp Airline Livery Offset Radius Flighttype PerfClass Heavy Model\n";
# get aircraft data
foreach $data ($doc->findnodes('/trafficlist/aircraft')) {
my $AcMdl = $data->findnodes('./model');
my $AcLvy = $data->findnodes('./livery');
my $AcAln = $data->findnodes('./airline');
my $AcHp = $data->findnodes('./home-port');
my $AcReq = $data->findnodes('./required-aircraft');
my $AcTyp = $data->findnodes('./actype');
my $AcO = $data->findnodes('./offset');
my $AcRad = $data->findnodes('./radius');
my $AcFt = $data->findnodes('./flighttype');
my $AcPrf = $data->findnodes('./performance-class');
my $AcReg = $data->findnodes('./registration');
my $AcHvy = $data->findnodes('./heavy');
print "AC $AcHp $AcReg $AcReq $AcTyp $AcAln $AcLvy $AcO $AcRad $AcFt $AcPrf $AcHvy $AcMdl\n";
}
print "\n# FLIGHT Callsign Flightrule Days DeparTime DepartPort ArrivalTime ArrivalPort Altitude RequiredAc\n# 0 = Monday, 6 = Sunday\n";
# get flight data
foreach $data ($doc->findnodes('/trafficlist/flight')) {
my $FlRep = $data->findnodes('repeat');
my $FlDepPrt = $data->findnodes('departure/port');
my $FlArrPrt = $data->findnodes('arrival/port');
my $FlCs = $data->findnodes('callsign');
my $FlFr = $data->findnodes('fltrules');
my $FlCa = $data->findnodes('cruise-alt');
my $FlReq = $data->findnodes('required-aircraft');
my $FlDepDay = $data->findnodes('departure/time');
my $FlDepTime = $data->findnodes('departure/time');
my $FlArrDay = $data->findnodes('arrival/time');
my $FlArrTime = $data->findnodes('arrival/time');
my $FlDays = ".......";
# handle flights depending on weekly or daily schedule
if (lc($FlRep) eq "week") {
$FlDays = parseDay($FlDepTime);
$FlDepTime = parseTime($FlDepTime);
$FlArrTime = parseTime($FlArrTime);
} elsif (lc($FlRep) eq "24hr") {
$FlDepDay = $data->findnodes('departure/time');
$FlDepTime = substr($data->findnodes('departure/time'),0,5);
$FlArrDay = $data->findnodes('arrival/time');
$FlArrTime = substr($data->findnodes('arrival/time'),0,5);
$FlDays = "0123456";
} else {
die "Error! No proper repetition found in XML!\n";
}
# output data
print "FLIGHT $FlCs $FlFr $FlDays $FlDepTime $FlDepPrt $FlArrTime $FlArrPrt $FlCa $FlReq\n";
}

View file

@ -151,6 +151,7 @@ void FGATIS::Update(double dt) {
// If !_prev_display, the radio had been detuned for a while and our // If !_prev_display, the radio had been detuned for a while and our
// "transmission" variable was lost when we were de-instantiated. // "transmission" variable was lost when we were de-instantiated.
int rslt = GenTransmission(!_prev_display, attention); int rslt = GenTransmission(!_prev_display, attention);
TreeOut(msg_OK);
if (rslt || volume != old_volume) { if (rslt || volume != old_volume) {
//cout << "ATIS calling ATC::render volume: " << volume << endl; //cout << "ATIS calling ATC::render volume: " << volume << endl;
Render(transmission, volume, refname, true); Render(transmission, volume, refname, true);
@ -207,6 +208,28 @@ const int minute(60); // measured in seconds
const int ATIS_interval(60*minute); const int ATIS_interval(60*minute);
#endif #endif
// FIXME: This is heuristic. It gets the right answer for
// more than 90% of the world's airports, which is a lot
// better than nothing ... but it's not 100%.
// We know "most" of the world uses millibars,
// but the US, Canada and *some* other places use inches of mercury,
// but (a) we have not implemented a reliable method of
// ascertaining which airports are in the US, let alone
// (b) ascertaining which other places use inches.
//
int Apt_US_CA(const string id) {
// Assume all IDs have length 3 or 4.
// No counterexamples have been seen.
if (id.length() == 4) {
if (id.substr(0,1) == "K") return 1;
if (id.substr(0,2) == "CY") return 1;
}
for (string::const_iterator ptr = id.begin(); ptr != id.end(); ptr++) {
if (isdigit(*ptr)) return 1;
}
return 0;
}
// Generate the actual broadcast ATIS transmission. // Generate the actual broadcast ATIS transmission.
// Regen means regenerate the /current/ transmission. // Regen means regenerate the /current/ transmission.
// Special means generate a new transmission, with a new sequence. // Special means generate a new transmission, with a new sequence.
@ -216,9 +239,12 @@ int FGATIS::GenTransmission(const int regen, const int special) {
using namespace lex; using namespace lex;
string BRK = ".\n"; string BRK = ".\n";
string PAUSE = " / ";
double tstamp = atof(fgGetString("sim/time/elapsed-sec")); double tstamp = atof(fgGetString("sim/time/elapsed-sec"));
int interval = ATIS ? ATIS_interval : 2*minute; // AWOS updated frequently int interval = _type == ATIS ?
ATIS_interval // ATIS updated hourly
: 2*minute; // AWOS updated more frequently
int sequence = current_commlist->GetAtisSequence(ident, int sequence = current_commlist->GetAtisSequence(ident,
tstamp, interval, special); tstamp, interval, special);
if (!regen && sequence > LTRS) { if (!regen && sequence > LTRS) {
@ -235,7 +261,9 @@ int FGATIS::GenTransmission(const int regen, const int special) {
transmission = ""; transmission = "";
if (ident.substr(0,2) == "EG") { int US_CA = Apt_US_CA(ident);
if (!US_CA) {
// UK CAA radiotelephony manual indicates ATIS transmissions start // UK CAA radiotelephony manual indicates ATIS transmissions start
// with "This is ..." // with "This is ..."
transmission += This_is + " "; transmission += This_is + " ";
@ -320,6 +348,9 @@ int FGATIS::GenTransmission(const int regen, const int special) {
transmission += " " + at + " " + ConvertNumToSpokenDigits(buf) + BRK; transmission += " " + at + " " + ConvertNumToSpokenDigits(buf) + BRK;
} }
// Sounds better with a pause in there:
transmission += PAUSE;
int did_some(0); int did_some(0);
int did_ceiling(0); int did_ceiling(0);
@ -332,29 +363,39 @@ int FGATIS::GenTransmission(const int regen, const int special) {
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 (!did_some) transmission += " " + Sky_condition + ": "; // BEWARE: At the present time, the environment system has no
did_some++; // way (so far as I know) to represent a "thin broken" or
// "thin overcast" layer. If/when such things are implemented
// in the environment system, code will have to be written here
// to handle them.
// First, do the prefix if any:
if (coverage == scattered || coverage == few) {
if (!did_some) {
transmission += " " + Sky_condition + ": ";
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 {
transmission += " "; transmission += " "; // no prefix required
} }
int cig00 = int(SGMiscd::round(ceiling/100)); // hundreds of feet int cig00 = int(SGMiscd::round(ceiling/100)); // hundreds of feet
if (cig00) { if (cig00) {
int cig000 = cig00/10; int cig000 = cig00/10;
cig00 -= cig000*10; // just the hundreds digit cig00 -= cig000*10; // just the hundreds digit
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?"
@ -362,6 +403,7 @@ int FGATIS::GenTransmission(const int regen, const int special) {
} }
transmission += coverage + BRK; transmission += coverage + BRK;
} }
if (!did_some) transmission += " " + Sky + " " + clear + BRK;
transmission += Temperature + ": "; transmission += Temperature + ": ";
double Tsl = fgGetDouble("/environment/temperature-sea-level-degc"); double Tsl = fgGetDouble("/environment/temperature-sea-level-degc");
@ -371,7 +413,7 @@ int FGATIS::GenTransmission(const int regen, const int special) {
} }
snprintf(buf, bs, "%i", abs(temp)); snprintf(buf, bs, "%i", abs(temp));
transmission += ConvertNumToSpokenDigits(buf); transmission += ConvertNumToSpokenDigits(buf);
transmission += " " + Celsius; if (US_CA) transmission += " " + Celsius;
transmission += " " + dewpoint + " "; 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())));
@ -380,7 +422,8 @@ int FGATIS::GenTransmission(const int regen, const int special) {
} }
snprintf(buf, bs, "%i", abs(temp)); snprintf(buf, bs, "%i", abs(temp));
transmission += ConvertNumToSpokenDigits(buf); transmission += ConvertNumToSpokenDigits(buf);
transmission += " " + Celsius + BRK; if (US_CA) transmission += " " + Celsius;
transmission += 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");
@ -403,7 +446,6 @@ int FGATIS::GenTransmission(const int regen, const int special) {
} }
transmission += BRK; transmission += BRK;
transmission += Altimeter + ": ";
double myQNH; double myQNH;
double Psl = fgGetDouble("/environment/pressure-sea-level-inhg"); double Psl = fgGetDouble("/environment/pressure-sea-level-inhg");
{ {
@ -418,63 +460,75 @@ int FGATIS::GenTransmission(const int regen, const int special) {
#endif #endif
myQNH = FGAtmo().QNH(_geod.getElevationM(), press); myQNH = FGAtmo().QNH(_geod.getElevationM(), press);
} }
if(ident.substr(0,2) == "EG" && fgGetBool("/sim/atc/use-millibars")) {
// Convert to millibars for the UK! // Convert to millibars for most of the world (not US, not CA)
if((!US_CA) || fgGetBool("/sim/atc/use-millibars")) {
transmission += QNH + ": ";
myQNH /= mbar; myQNH /= mbar;
if (myQNH > 1000) myQNH -= 1000; // drop high digit if (myQNH > 1000) myQNH -= 1000; // drop high digit
snprintf(buf, bs, "%03.0f", myQNH); snprintf(buf, bs, "%03.0f", myQNH);
transmission += ConvertNumToSpokenDigits(buf) + " " + millibars + BRK;
} else { } else {
myQNH /= inHg; transmission += Altimeter + ": ";
myQNH *= 100.; // shift two decimal places double asetting = myQNH / inHg; // use inches of mercury
snprintf(buf, bs, "%04.0f", myQNH); asetting *= 100.; // shift two decimal places
snprintf(buf, bs, "%04.0f", asetting);
transmission += ConvertNumToSpokenDigits(buf) + BRK;
} }
transmission += ConvertNumToSpokenDigits(buf) + BRK;
if (_type == ATIS /* as opposed to AWOS */) { if (_type == ATIS /* as opposed to AWOS */) {
const FGAirport* apt = fgFindAirportID(ident); const FGAirport* apt = fgFindAirportID(ident);
assert(apt); if (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;
#ifdef ATIS_TEST
if (msg_OK) { if (msg_OK) {
msg_time = cur_time; msg_time = cur_time;
//cout << "In atis.cxx, r.rwy_no: " << rwy_no cout << "In atis.cxx, r.rwy_no: " << rwy_no
// << " wind_dir: " << wind_dir << endl; << " wind_dir: " << wind_dir << endl;
} }
#endif
}
} }
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 + PAUSE + PAUSE;
} }
#ifdef ATIS_TEST transmission_readable = transmission;
cout << "**** ATIS active on:"; // Take the previous readable string and munge it to
#endif
for (map<string,int>::iterator act = active_on.begin(); act != active_on.end(); act++){
string prop = "/instrumentation/" + act->first + "/atis";
globals->get_props()->setStringValue(prop.c_str(),
("<pre>\n" + transmission + "</pre>\n").c_str());
#ifdef ATIS_TEST
cout << " " << prop;
#endif
}
#ifdef ATIS_TEST
cout << " ****" << endl;
cout << transmission << endl;
// Note that even if we aren't outputting the transmission
// on stdout, you can still see it by pointing a web browser
// at the property tree. The second comm radio is:
// http://localhost:5400/instrumentation/comm[1]
#endif
// Take the previous English-looking string and munge it to
// be relatively-more acceptable to the primitive tts system. // be relatively-more acceptable to the primitive tts system.
// Note that : ; and . are among the token-delimeters recognized // Note that : ; and . are among the token-delimeters recognized
// by the tts system. // by the tts system.
for (size_t where;;) { for (size_t where;;) {
where = transmission.find_first_of(":."); where = transmission.find_first_of(":.");
if (where == string::npos) break; if (where == string::npos) break;
transmission.replace(where, 1, " /_ "); transmission.replace(where, 1, PAUSE);
} }
return 1; return 1;
} }
// Put the transmission into the property tree,
// possibly in multiple places if multiple radios
// are tuned to the same ATIS.
// You can see it by pointing a web browser
// at the property tree. The second comm radio is:
// http://localhost:5400/instrumentation/comm[1]
//
// (Also, if in debug mode, dump it to the console.)
void FGATIS::TreeOut(int msg_OK){
for (map<string,int>::iterator act = active_on.begin();
act != active_on.end();
act++){
string prop = "/instrumentation/" + act->first + "/atis";
globals->get_props()->setStringValue(prop.c_str(),
("<pre>\n" + transmission_readable + "</pre>\n").c_str());
#ifdef ATIS_TEST
if (msg_OK) cout << "**** ATIS active on: " << prop << endl;
#endif
}
#ifdef ATIS_TEST
if (msg_OK) cout << transmission_readable << endl;
#endif
}

View file

@ -39,9 +39,14 @@ typedef std::map<std::string,std::string> MSS;
class FGATIS : public FGATC { class FGATIS : public FGATC {
//atc_type type; //atc_type type;
std::string transmission; // The actual ATIS transmission
// This is not stored in default.atis but is generated // The actual ATIS transmission
// from the prevailing conditions when required. // This is generated from the prevailing conditions when required.
// This is the version with markup, suitable for voice synthesis:
std::string transmission;
// Same as above, but in a form more readable as text.
std::string transmission_readable;
// for failure modeling // for failure modeling
std::string trans_ident; // transmitted ident std::string trans_ident; // transmitted ident
@ -82,8 +87,12 @@ class FGATIS : public FGATC {
std::string refname; // Holds the refname of a transmission in progress std::string refname; // Holds the refname of a transmission in progress
int GenTransmission(const int regen, // Generate the ATIS transmission text:
const int special); // Generate the transmission string int GenTransmission(const int regen, const int special);
// Put the text into the property tree
// (and in debug mode, print it on the console):
void TreeOut(int msgOK);
friend std::istream& operator>> ( std::istream&, FGATIS& ); friend std::istream& operator>> ( std::istream&, FGATIS& );
}; };

View file

@ -3,6 +3,9 @@
#include <string> #include <string>
// NOTE: This file serves as a database.
// It is read by some utility programs that synthesize
// the library of spoken words.
#define Q(word) const std::string word(#word); #define Q(word) const std::string word(#word);
@ -34,10 +37,14 @@ Q(hundred)
Q(zero) Q(zero)
Q(Temperature) Q(Temperature)
Q(clear) Q(clear)
Q(isolated)
Q(few)
Q(scattered) Q(scattered)
Q(broken) Q(broken)
Q(overcast) Q(overcast)
Q(thin)
Q(Sky_condition) Q(Sky_condition)
Q(Sky)
Q(Ceiling) Q(Ceiling)
Q(minus) Q(minus)
Q(dewpoint) Q(dewpoint)
@ -48,6 +55,8 @@ Q(one_half)
Q(three_quarters) Q(three_quarters)
Q(one_and_one_half) Q(one_and_one_half)
Q(Altimeter) Q(Altimeter)
Q(QNH)
Q(millibars)
Q(Landing_and_departing_runway) Q(Landing_and_departing_runway)
Q(On_initial_contact_advise_you_have_information) Q(On_initial_contact_advise_you_have_information)
Q(This_is) Q(This_is)

View file

@ -1,8 +1,13 @@
// NOTE: This file serves as a database.
// It is read by some utility programs that synthesize
// the library of spoken words.
REMAP(Intl, International) REMAP(Intl, International)
REMAP(Rgnl, Regional) REMAP(Rgnl, Regional)
REMAP(Co, County) REMAP(Co, County)
REMAP(Muni, Municipal) REMAP(Muni, Municipal)
REMAP(Mem, Memorial) REMAP(Mem, Memorial)
REMAP(Meml, Memorial)
REMAP(Apt, Airport) REMAP(Apt, Airport)
REMAP(Arpt, Airport) REMAP(Arpt, Airport)
REMAP(Fld, Field) REMAP(Fld, Field)

View file

@ -457,8 +457,12 @@ void FGAirport::readTowerData(SGPropertyNode* aRoot)
double lat = twrNode->getDoubleValue("lat"), double lat = twrNode->getDoubleValue("lat"),
lon = twrNode->getDoubleValue("lon"), lon = twrNode->getDoubleValue("lon"),
elevM = twrNode->getDoubleValue("elev-m"); elevM = twrNode->getDoubleValue("elev-m");
// tower elevation is AGL, not AMSL. Since we don't want to depend on the
// scenery for a precise terrain elevation, we use the field elevation
// (this is also what the apt.dat code does)
double fieldElevationM = geod().getElevationM();
_tower_location = SGGeod::fromDegM(lon, lat, elevM); _tower_location = SGGeod::fromDegM(lon, lat, fieldElevationM + elevM);
} }
bool FGAirport::buildApproach(Waypt* aEnroute, STAR* aSTAR, FGRunway* aRwy, WayptVec& aRoute) bool FGAirport::buildApproach(Waypt* aEnroute, STAR* aSTAR, FGRunway* aRwy, WayptVec& aRoute)

View file

@ -1285,6 +1285,22 @@ void MapWidget::drawILS(bool tuned, FGRunway* rwy)
glVertex2dv(endCentre.data()); glVertex2dv(endCentre.data());
glVertex2dv(endR.data()); glVertex2dv(endR.data());
glEnd(); glEnd();
if (validDataForKey(loc)) {
setAnchorForKey(loc, endR);
return;
}
char buffer[1024];
::snprintf(buffer, 1024, "%s\n%s\n%3.2fMHz",
loc->name().c_str(), loc->ident().c_str(),loc->get_freq()/100.0);
MapData* d = createDataForKey(loc);
d->setPriority(40);
d->setLabel(loc->ident());
d->setText(buffer);
d->setOffset(MapData::HALIGN_CENTER | MapData::VALIGN_BOTTOM, 10);
d->setAnchor(endR);
} }
void MapWidget::drawTraffic() void MapWidget::drawTraffic()

View file

@ -17,9 +17,12 @@
#define ENABLE_AUDIO_SUPPORT 1 #define ENABLE_AUDIO_SUPPORT 1
#cmakedefine HAVE_SYS_TIME_H #cmakedefine HAVE_SYS_TIME_H
#cmakedefine HAVE_WINDOWS_H
#cmakedefine HAVE_CULLSETTINGS_CLEAR_MASK #cmakedefine HAVE_CULLSETTINGS_CLEAR_MASK
#define VERSION "@FLIGHTGEAR_VERSION" #define VERSION "@FLIGHTGEAR_VERSION@"
#define HAVE_VERSION_H 1 // version.h is assumed for CMake builds
#cmakedefine ENABLE_UIUC_MODEL #cmakedefine ENABLE_UIUC_MODEL
#cmakedefine ENABLE_LARCSIM #cmakedefine ENABLE_LARCSIM

View file

@ -0,0 +1,10 @@
#define FLIGHTGEAR_VERSION "@FLIGHTGEAR_VERSION@"
#define HUDSON_BUILD_NUMBER @HUDSON_BUILD_NUMBER@
#define HUDSON_BUILD_ID "@HUDSON_BUILD_ID@"
#define REVISION "@REVISION@"

View file

@ -39,7 +39,6 @@ target_link_libraries(fgfs
${ALUT_LIBRARY} ${ALUT_LIBRARY}
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
${PLIB_LIBRARIES} ${PLIB_LIBRARIES}
${RT_LIBRARY} ${RT_LIBRARY})
${Boost_SERIALIZATION_LIBRARY})
install(TARGETS fgfs RUNTIME DESTINATION bin) install(TARGETS fgfs RUNTIME DESTINATION bin)

View file

@ -33,14 +33,6 @@
#define FG_DME_DEFAULT_RANGE 50 // nm #define FG_DME_DEFAULT_RANGE 50 // nm
#define FG_NAV_MAX_RANGE 300 // nm #define FG_NAV_MAX_RANGE 300 // nm
// FIXME - get rid of these, and use the real enum directly
#define FG_NAV_VOR FGPositioned::VOR
#define FG_NAV_NDB FGPositioned::NDB
#define FG_NAV_ILS FGPositioned::ILS
#define FG_NAV_ANY FGPositioned::INVALID
typedef FGPositioned::Type fg_nav_types;
// forward decls // forward decls
class FGRunway; class FGRunway;
class SGPropertyNode; class SGPropertyNode;