Merge branch 'next' into comm-subsystem
This commit is contained in:
commit
c6062ad93c
191 changed files with 3293 additions and 1681 deletions
CMakeLists.txtREADME.cmake
docs-mini
projects/VC90/metar
src
AIModel
AIAircraft.cxxAIAircraft.hxxAIBallistic.cxxAIBase.cxxAIBase.hxxAICarrier.cxxAIEscort.cxxAIFlightPlan.cxxAIFlightPlan.hxxAIFlightPlanCreate.cxxAIFlightPlanCreateCruise.cxxAIFlightPlanCreatePushBack.cxxAIGroundVehicle.cxxAIMultiplayer.cxxAIShip.cxxAIWingman.cxxperformancedata.cxxperformancedata.hxx
ATC
ATCDCL
Aircraft
Airports
Autopilot
analogcomponent.cxxautopilot.cxxautopilot.hxxautopilotgroup.cxxautopilotgroup.hxxcomponent.cxxdigitalcomponent.cxxdigitalcomponent.hxxdigitalfilter.cxxflipflop.cxxfunctor.hxxpidcontroller.cxxpisimplecontroller.cxxpredictor.cxx
Cockpit
Environment
FDM
GUI
Input
FGCommonInput.cxxFGEventInput.cxxFGEventInput.hxxFGJoystickInput.cxxFGMacOSXEventInput.cxxFGMacOSXEventInput.hxxFGMouseInput.cxx
Instrumentation
HUD
KLN89
kln89.cxxkln89.hxxkln89_page.cxxkln89_page.hxxkln89_page_alt.cxxkln89_page_apt.hxxkln89_page_cal.cxxkln89_page_dir.cxxkln89_page_dir.hxxkln89_page_fpl.hxxkln89_page_int.cxxkln89_page_int.hxxkln89_page_nav.cxxkln89_page_nav.hxxkln89_page_ndb.cxxkln89_page_ndb.hxxkln89_page_oth.cxxkln89_page_vor.cxxkln89_page_vor.hxx
NavDisplay.cxxNavDisplay.hxx
|
@ -4,7 +4,7 @@ include (CheckFunctionExists)
|
|||
include (CheckCSourceCompiles)
|
||||
include (CheckCXXSourceCompiles)
|
||||
include (CheckIncludeFile)
|
||||
include (CPack)
|
||||
|
||||
|
||||
project(FlightGear)
|
||||
|
||||
|
@ -27,6 +27,13 @@ set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
|
|||
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
|
||||
SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
|
||||
|
||||
set(CPACK_SOURCE_GENERATOR TBZ2 ZIP)
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "flightgear-${FLIGHTGEAR_VERSION}" CACHE INTERNAL "tarball basename")
|
||||
set(CPACK_SOURCE_IGNORE_FILES
|
||||
"^${PROJECT_SOURCE_DIR}/.git;\\\\.gitignore;Makefile.am;~$;${CPACK_SOURCE_IGNORE_FILES}")
|
||||
|
||||
include (CPack)
|
||||
|
||||
# We have some custom .cmake scripts not in the official distribution.
|
||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}")
|
||||
|
||||
|
@ -51,6 +58,10 @@ endif()
|
|||
|
||||
IF(APPLE)
|
||||
set(EVENT_INPUT_DEFAULT 1)
|
||||
|
||||
find_library(CORESERVICES_LIBRARY CoreServices)
|
||||
list(APPEND PLATFORM_LIBS ${CORESERVICES_LIBRARY})
|
||||
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# disabled while DBus / HAL / udev issues are decided
|
||||
#set(EVENT_INPUT_DEFAULT 1)
|
||||
|
@ -92,6 +103,7 @@ if (MSVC)
|
|||
else (EXISTS ${TEST_3RDPARTY_DIR})
|
||||
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
|
||||
endif (EXISTS ${TEST_3RDPARTY_DIR})
|
||||
list(APPEND PLATFORM_LIBS "winmm.lib")
|
||||
else (MSVC)
|
||||
set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted")
|
||||
endif (MSVC)
|
||||
|
@ -258,6 +270,15 @@ configure_file (
|
|||
add_subdirectory(src)
|
||||
add_subdirectory(utils)
|
||||
|
||||
set (INSTALL_DOCS
|
||||
README
|
||||
README.OpenAL
|
||||
README.plib
|
||||
README.OSG
|
||||
README.SimGear)
|
||||
|
||||
INSTALL(FILES ${INSTALL_DOCS} DESTINATION doc OPTIONAL)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
### uninstall target
|
||||
#-----------------------------------------------------------------------------
|
||||
|
|
155
README.cmake
Normal file
155
README.cmake
Normal file
|
@ -0,0 +1,155 @@
|
|||
Getting started with CMake
|
||||
|
||||
(These instructions apply to Unix-like systems, including Cygwin and Mac. To
|
||||
build using Visual Studio or some other IDE supported by CMake, most of the
|
||||
information below still applies)
|
||||
|
||||
Always compile in a separate directory to the code. For example, if the
|
||||
code (eg, from Git) is at /home/curt/projects/flightgear, you might create
|
||||
/home/curt/projects/fgbuild. Change into the new directory, and run
|
||||
|
||||
cmake ../flightger
|
||||
|
||||
To generate standard Unix Makefiles in fgbuild.
|
||||
|
||||
Probably you want to specify an install prefix:
|
||||
|
||||
cmake ../flightgear -DCMAKE_INSTALL_PREFIX=/usr
|
||||
|
||||
Note the install prefix is automatically searched for required libraries
|
||||
and header files, so if you install PLIB, OpenSceneGraph and SimGear to the
|
||||
same prefix, most configuration options are unnecessary.
|
||||
|
||||
If for some reason you have a dependency (or several) at a different prefix,
|
||||
you can specify one or more via CMAKE_PREFIX_PATH:
|
||||
|
||||
cmake ../flightgear -DCMAKE_PREFIX_PATH="/opt/local;/opt/fgfs"
|
||||
|
||||
(note the use of semi-colons to specify multiple prefix paths)
|
||||
|
||||
Standard prefixes are searched automatically (/usr, /usr/local, /opt/local)
|
||||
|
||||
Most dependencies also expose an environment variable to specify their
|
||||
installation directory explicitly eg OSG_DIR or PLIBDIR. Any of the methods
|
||||
described above will work, but specifying an INSTALL_PREFIX or PREFIX_PATH is
|
||||
usually simpler.
|
||||
|
||||
By default, we select a release build. To create a debug build, use
|
||||
|
||||
cmake ../flightgear -DCMAKE_BUILD_TYPE=Debug
|
||||
|
||||
(or MinSizeRel, or RelWithDbg)
|
||||
|
||||
Debug builds will automatically use corresponding debug builds of required
|
||||
libraries, if they are available. For example you can install debug builds of
|
||||
SimGear and OpenSceneGraph, and a debug FlightGear build will use them.
|
||||
|
||||
(Debug builds of libraries have the 'd' suffix by default - Release builds
|
||||
have no additional suffix)
|
||||
|
||||
Note most IDE projects (eg Xcode and Visual Studio) support building all the
|
||||
build types from the same project, so you can omit the CMAKE_BUILD_TYPE option
|
||||
when running cmake, and simply pick the build configuration as normal in the
|
||||
IDE.
|
||||
|
||||
It's common to have several build directories with different build
|
||||
configurations, eg
|
||||
|
||||
/home/curt/projects/flightgear (the git clone)
|
||||
/home/curt/projects/fgdebug
|
||||
/home/curt/projects/fgrelease
|
||||
/home/curt/projects/fg-with-svn-osg
|
||||
|
||||
To set an optional feature, do
|
||||
|
||||
cmake ../flightgear -DFEATURE_NAME=ON
|
||||
|
||||
(or 'OFF' to disable )
|
||||
|
||||
To see the variables that can be configured / are currently defined, you can
|
||||
run one of the GUI front ends, or the following command:
|
||||
|
||||
cmake ../flighgear -L
|
||||
|
||||
Add 'A' to see all the options (including advanced options), or 'H' to see
|
||||
the help for each option (similar to running configure --help under autoconf):
|
||||
|
||||
cmake ../flightgear -LH
|
||||
|
||||
Build Targets
|
||||
|
||||
For a Unix makefile build, 'make dist', 'make uninstall' and 'make test' are
|
||||
all available and should work as expected. 'make clean' is also as normal,
|
||||
but there is *no* 'make distclean' target. The equivalent is to completely
|
||||
remove your build directory, and start with a fresh one.
|
||||
|
||||
Adding new files to the build
|
||||
|
||||
Add source files to the SOURCES list, and headers to the HEADERS list. Note
|
||||
technically you only need to add source files, but omitting headers confuses
|
||||
project generation and distribution / packaging targets.
|
||||
|
||||
For target conditional files, you can append to the SOURCES or HEADERS lists
|
||||
inside an if() test, for example:
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND SOURCES extraFile1.cxx extraFile2.cxx)
|
||||
endif()
|
||||
|
||||
Setting include directories
|
||||
|
||||
In any CMakeList.txt, you can do the following:
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/some/path)
|
||||
|
||||
For example, this can be done in particular subdirectory, or at the project
|
||||
root, or an intermediate level.
|
||||
|
||||
Setting target specific compile flags, includes or defines
|
||||
|
||||
Use set_target_property(), for example
|
||||
|
||||
set_target_property(fgfs PROPERTIES
|
||||
COMPILE_DEFINITIONS FOO BAR=1)
|
||||
|
||||
You can set a property on an individual source file:
|
||||
|
||||
set_property(SOURCE myfile.cxx PROPERTY COMPILE_FLAGS "-Wno-unsigned-compare")
|
||||
|
||||
Detecting Features / Libraries
|
||||
|
||||
For most standard libraries (Gtk, wxWidget, Python, GDAL, Qt, libXml, Boost),
|
||||
cmake provides a standard helper. To see the available modules, run:
|
||||
|
||||
cmake --help-module-list
|
||||
|
||||
In the root CMakeLists file, use a statement like:
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
Each package helper sets various variables such aaa_FOUND, aaa_INCLUDE_DIR,
|
||||
and aaa_LIBRARY. Depending on the complexity of the package, these variables
|
||||
might have different names (eg, OPENSCENEGRAPH_LIBRARIES).
|
||||
|
||||
If there's no standard helper for a library you need, find a similar one, copy
|
||||
it to CMakeModules/FindABC.cmake, and modify the code to fit. Generally this
|
||||
is pretty straightforward. The built-in modules reside in the Cmake 'share'
|
||||
directory, eg /usr/share/cmake/modules on Unix systems.
|
||||
|
||||
Note libraries support by pkg-config can be handled directly, with no need
|
||||
to create a custom FindABC helper.
|
||||
|
||||
Adding a new executable target
|
||||
|
||||
add_executable(myexecutable ${SOURCES} ${HEADERS})
|
||||
target_link_libraries(myexecutable .... libraries ... )
|
||||
install(TARGETS myexecutable RUNTIME DESTINATION bin)
|
||||
|
||||
(If the executable should not be installed, omit the final line above)
|
||||
|
||||
If you add an additional line
|
||||
|
||||
add_test(testname ${EXECUTABLE_OUTPUT_PATH}/myexecutable)
|
||||
|
||||
Then running 'make test' will run your executable as a unit test. The
|
||||
executable should return either a success or failure result code.
|
|
@ -81,6 +81,31 @@ window, camera, or gui tags.
|
|||
width, height - int
|
||||
The dimensions of the viewport
|
||||
|
||||
physical-dimensions
|
||||
The physical dimension of the projection surface.
|
||||
Use this together with the master-perspective, right-of-perspective
|
||||
left-of-perspective, above-perspective, below-perspective or
|
||||
reference-points-perspective
|
||||
|
||||
width, height - double
|
||||
The dimensions of the projection plane, if unset the veiwport values
|
||||
are taken as default.
|
||||
|
||||
bezel
|
||||
Gives informantion about the bezel of monitors for a seamless view.
|
||||
|
||||
right
|
||||
right bezel with in the same units than with and height above
|
||||
|
||||
left
|
||||
left bezel with in the same units than with and height above
|
||||
|
||||
top
|
||||
top bezel with in the same units than with and height above
|
||||
|
||||
bottom
|
||||
bottom bezel with in the same units than with and height above
|
||||
|
||||
view
|
||||
The view node specifies the origin and direction of the camera in
|
||||
relation to the whole camera group. The coordinate system is +y up,
|
||||
|
@ -113,6 +138,11 @@ window, camera, or gui tags.
|
|||
and other background elements may not be drawn if the view plane is
|
||||
closer than 120km.
|
||||
|
||||
fixed-near-far - bool
|
||||
If true the near and far values are taken from above, if false
|
||||
near and far are adapted from the scene and visibility.
|
||||
Defaults to true.
|
||||
|
||||
offset-x, offset-y - double
|
||||
Offsets of the viewing volume specified by the other parameters in
|
||||
the near plane, in meters.
|
||||
|
@ -129,10 +159,77 @@ window, camera, or gui tags.
|
|||
near, far - double
|
||||
The near and far planes, in meters from the camera eye point.
|
||||
|
||||
fixed-near-far - bool
|
||||
If true the near and far values are taken from above, if false
|
||||
near and far are adapted from the scene and visibility.
|
||||
Defaults to true.
|
||||
|
||||
ortho
|
||||
This specifies an orthographic view. The parameters are the sames as
|
||||
the frustum node's.
|
||||
|
||||
fixed-near-far - bool
|
||||
If true the near and far values are taken from above, if false
|
||||
near and far are adapted from the scene and visibility.
|
||||
Defaults to true.
|
||||
|
||||
master-perspective
|
||||
Defines a persective projection matrix for use as the leading display
|
||||
in a seamless multiscreen configuration. This kind of perspective
|
||||
projection is zoomable.
|
||||
|
||||
eye-distance - double
|
||||
The distance of the eyepoint from the projection surface in units of
|
||||
the physical-dimensions values above.
|
||||
|
||||
x-offset, y-offset - double
|
||||
Offset of the eyelpint from the center of the screen in units of
|
||||
the physical-dimensions values above.
|
||||
|
||||
left-of-perspective, right-of-perspective, above-perspective,
|
||||
below-perspective
|
||||
Defines a perspective projection matrix for use as derived display
|
||||
in a seamless multiscreen configuration. The projection matrix
|
||||
is computed so that the respective edge of this display matches the
|
||||
assiciated other edge of the other display. For example the right edge
|
||||
of a left-of-perspective display matches the left edge of the parent
|
||||
display. This also works with different zoom levels, leading to distorted
|
||||
but still seamless multiview configurations.
|
||||
The bezel with configured in the physical dimensions of this screen and
|
||||
the parent screen are taken into account for this type of projection.
|
||||
|
||||
parent-camera - string
|
||||
Name of the parent camera.
|
||||
|
||||
reference-points-perspective
|
||||
Defines a perspective projection matrix for use as derived display
|
||||
in a seamless multiscreen configuration. This type is very similar to
|
||||
left-of-perspective and friends. It is just a more flexible but less
|
||||
convenient way to get the same effect. A child display is configured
|
||||
by 2 sets of reference points one in this current camera and one in
|
||||
the parrent camera which should match in the final view.
|
||||
|
||||
parent-camera - string
|
||||
Name of the parent camera.
|
||||
|
||||
this
|
||||
reference points for this projection.
|
||||
|
||||
point - array of two points
|
||||
|
||||
x, y - double
|
||||
x and y coodinates of the reference points in units of this
|
||||
physical-dimensions.
|
||||
|
||||
parent
|
||||
reference points for the parent projection.
|
||||
|
||||
point - array of two points
|
||||
|
||||
x, y - double
|
||||
x and y coodinates of the reference points in units of the
|
||||
parents physical-dimensions.
|
||||
|
||||
texture
|
||||
This tag indicates that the camera renders to a texture instead of the
|
||||
framebuffer. For now the following tags are supported, but obviously
|
||||
|
@ -395,3 +492,170 @@ This example renders the scene for projection onto a spherical screen.
|
|||
</sim>
|
||||
</PropertyList>
|
||||
|
||||
Here is an example for a 3 screen seamless zoomable multiscreen
|
||||
configuration using 3 533mmx300mm displays each with a 23mm bezel.
|
||||
The side views are angled with 45 deg.
|
||||
The commented out reference-points-perspective shows the
|
||||
aequivalent configuration than the active right-of-perspective.
|
||||
This is done by just using two reference points at the outer
|
||||
edge of the bezel of the respective display.
|
||||
|
||||
<PropertyList>
|
||||
<sim>
|
||||
<view n="0">
|
||||
<config>
|
||||
<pitch-offset-deg>0.0</pitch-offset-deg>
|
||||
</config>
|
||||
</view>
|
||||
|
||||
<rendering>
|
||||
<camera-group>
|
||||
<window>
|
||||
<name type="string">0.0</name>
|
||||
<host-name type="string"></host-name>
|
||||
<display>0</display>
|
||||
<screen>0</screen>
|
||||
<fullscreen type="bool">true</fullscreen>
|
||||
</window>
|
||||
|
||||
<window>
|
||||
<name type="string">0.1</name>
|
||||
<host-name type="string"></host-name>
|
||||
<display>0</display>
|
||||
<screen>1</screen>
|
||||
<fullscreen type="bool">true</fullscreen>
|
||||
</window>
|
||||
|
||||
<camera>
|
||||
<name type="string">CenterCamera</name>
|
||||
<window>
|
||||
<name>0.0</name>
|
||||
</window>
|
||||
<viewport>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
</viewport>
|
||||
<view>
|
||||
<heading-deg type="double">0.0</heading-deg>
|
||||
<roll-deg type="double">0.0</roll-deg>
|
||||
<pitch-deg type="double">0.0</pitch-deg>
|
||||
</view>
|
||||
<physical-dimensions>
|
||||
<!-- The size of the projection plane: 533mm 300mm -->
|
||||
<width>533</width>
|
||||
<height>300</height>
|
||||
<bezel>
|
||||
<right>23</right>
|
||||
<left>23</left>
|
||||
<top>23</top>
|
||||
<bottom>23</bottom>
|
||||
</bezel>
|
||||
</physical-dimensions>
|
||||
<master-perspective>
|
||||
<!-- Cheating, the real distance is about 800mm.
|
||||
But then the screen does not show what is needed to fly.
|
||||
By shortening this pictures get bigger but the view also gets
|
||||
less realistic.
|
||||
-->
|
||||
<eye-distance>450</eye-distance>
|
||||
<x-offset>0</x-offset>
|
||||
<y-offset>130</y-offset>
|
||||
</master-perspective>
|
||||
</camera>
|
||||
<camera>
|
||||
<name type="string">RightCamera</name>
|
||||
<window>
|
||||
<name>0.0</name>
|
||||
</window>
|
||||
<viewport>
|
||||
<x>1920</x>
|
||||
<y>0</y>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
</viewport>
|
||||
<view>
|
||||
<heading-deg type="double">-45</heading-deg>
|
||||
<roll-deg type="double">0</roll-deg>
|
||||
<pitch-deg type="double">0</pitch-deg>
|
||||
</view>
|
||||
<physical-dimensions>
|
||||
<!-- The size of the projection plane: 533mm 300mm -->
|
||||
<width>533</width>
|
||||
<height>300</height>
|
||||
<bezel>
|
||||
<right>23</right>
|
||||
<left>23</left>
|
||||
<top>23</top>
|
||||
<bottom>23</bottom>
|
||||
</bezel>
|
||||
</physical-dimensions>
|
||||
<right-of-perspective>
|
||||
<parent-camera type="string">CenterCamera</parent-camera>
|
||||
</right-of-perspective>
|
||||
<!-- <reference-points-perspective> -->
|
||||
<!-- <parent-camera type="string">CenterCamera</parent-camera> -->
|
||||
<!-- <parent> -->
|
||||
<!-- <point n="0"> -->
|
||||
<!-- <x>289.5</x> -->
|
||||
<!-- <y>100</y> -->
|
||||
<!-- </point> -->
|
||||
<!-- <point n="1"> -->
|
||||
<!-- <x>289.5</x> -->
|
||||
<!-- <y>-100</y> -->
|
||||
<!-- </point> -->
|
||||
<!-- </parent> -->
|
||||
<!-- <this> -->
|
||||
<!-- <point n="0"> -->
|
||||
<!-- <x>-289.5</x> -->
|
||||
<!-- <y>100</y> -->
|
||||
<!-- </point> -->
|
||||
<!-- <point n="1"> -->
|
||||
<!-- <x>-289.5</x> -->
|
||||
<!-- <y>-100</y> -->
|
||||
<!-- </point> -->
|
||||
<!-- </this> -->
|
||||
<!-- </reference-points-perspective> -->
|
||||
</camera>
|
||||
|
||||
<camera>
|
||||
<name type="string">LeftCamera</name>
|
||||
<window>
|
||||
<name>0.1</name>
|
||||
</window>
|
||||
<viewport>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
</viewport>
|
||||
<view>
|
||||
<heading-deg type="double">45</heading-deg>
|
||||
<roll-deg type="double">0</roll-deg>
|
||||
<pitch-deg type="double">0</pitch-deg>
|
||||
</view>
|
||||
<physical-dimensions>
|
||||
<!-- The size of the projection plane: 533mm 300mm -->
|
||||
<width>533</width>
|
||||
<height>300</height>
|
||||
<bezel>
|
||||
<right>23</right>
|
||||
<left>23</left>
|
||||
<top>23</top>
|
||||
<bottom>23</bottom>
|
||||
</bezel>
|
||||
</physical-dimensions>
|
||||
<left-of-perspective>
|
||||
<parent-camera type="string">CenterCamera</parent-camera>
|
||||
</left-of-perspective>
|
||||
</camera>
|
||||
<gui>
|
||||
<window>
|
||||
<name type="string">0.0</name>
|
||||
</window>
|
||||
</gui>
|
||||
</camera-group>
|
||||
</rendering>
|
||||
</sim>
|
||||
</PropertyList>
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="sg_d.lib ul_d.lib net_d.lib ws2_32.lib"
|
||||
AdditionalDependencies="sg_d.lib ul_d.lib net_d.lib ws2_32.lib winmm.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\..\..\..\3rdParty\lib"
|
||||
GenerateDebugInformation="true"
|
||||
|
@ -145,7 +145,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="sg_d.lib ul_d.lib net_d.lib ws2_32.lib"
|
||||
AdditionalDependencies="sg_d.lib ul_d.lib net_d.lib ws2_32.lib winmm.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\..\..\..\3rdParty.x64\lib"
|
||||
GenerateDebugInformation="true"
|
||||
|
@ -221,7 +221,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="sg.lib ul.lib net.lib ws2_32.lib"
|
||||
AdditionalDependencies="sg.lib ul.lib net.lib ws2_32.lib winmm.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\..\3rdParty\lib"
|
||||
GenerateDebugInformation="true"
|
||||
|
@ -299,7 +299,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="sg.lib ul.lib net.lib ws2_32.lib"
|
||||
AdditionalDependencies="sg.lib ul.lib net.lib ws2_32.lib winmm.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\..\..\3rdParty.x64\lib"
|
||||
GenerateDebugInformation="true"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// // FGAIAircraft - FGAIBase-derived class creates an AI airplane
|
||||
// FGAIAircraft - FGAIBase-derived class creates an AI airplane
|
||||
//
|
||||
// Written by David Culp, started October 2003.
|
||||
//
|
||||
|
@ -47,11 +47,10 @@ using std::string;
|
|||
#include "AIAircraft.hxx"
|
||||
#include "performancedata.hxx"
|
||||
#include "performancedb.hxx"
|
||||
#include <signal.h>
|
||||
|
||||
//#include <Airports/trafficcontroller.hxx>
|
||||
|
||||
static string tempReg;
|
||||
|
||||
FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
|
||||
/* HOT must be disabled for AI Aircraft,
|
||||
* otherwise traffic detection isn't working as expected.*/
|
||||
|
@ -191,6 +190,7 @@ void FGAIAircraft::checkVisibility()
|
|||
|
||||
void FGAIAircraft::AccelTo(double speed) {
|
||||
tgt_speed = speed;
|
||||
//assertSpeed(speed);
|
||||
if (!isStationary())
|
||||
_needsGroundElevation = true;
|
||||
}
|
||||
|
@ -287,6 +287,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
|||
if (! leadPointReached(curr)) {
|
||||
controlHeading(curr);
|
||||
controlSpeed(curr, next);
|
||||
|
||||
/*
|
||||
if (speed < 0) {
|
||||
cerr << getCallSign()
|
||||
|
@ -350,13 +351,18 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
|||
fp->setLeadDistance(tgt_speed, tgt_heading, curr, next);
|
||||
}
|
||||
|
||||
|
||||
if (!(prev->getOn_ground())) // only update the tgt altitude from flightplan if not on the ground
|
||||
{
|
||||
tgt_altitude_ft = prev->getAltitude();
|
||||
if (curr->getCrossat() > -1000.0) {
|
||||
use_perf_vs = false;
|
||||
tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
|
||||
/ 6076.0 / speed*60.0);
|
||||
// Distance to go in meters
|
||||
double vert_dist_ft = curr->getCrossat() - altitude_ft;
|
||||
double err_dist = prev->getCrossat() - altitude_ft;
|
||||
double dist_m = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||
tgt_vs = calcVerticalSpeed(vert_dist_ft, dist_m, speed, err_dist);
|
||||
|
||||
checkTcas();
|
||||
tgt_altitude_ft = curr->getCrossat();
|
||||
} else {
|
||||
|
@ -369,6 +375,49 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
|
|||
}
|
||||
}
|
||||
|
||||
double FGAIAircraft::calcVerticalSpeed(double vert_ft, double dist_m, double speed, double err)
|
||||
{
|
||||
// err is negative when we passed too high
|
||||
double vert_m = vert_ft * SG_FEET_TO_METER;
|
||||
double err_m = err * SG_FEET_TO_METER;
|
||||
//double angle = atan2(vert_m, dist_m);
|
||||
double speedMs = (speed * SG_NM_TO_METER) / 3600;
|
||||
//double vs = cos(angle) * speedMs; // Now in m/s
|
||||
double vs = 0;
|
||||
//cerr << "Error term = " << err_m << endl;
|
||||
if (dist_m) {
|
||||
vs = ((vert_m) / dist_m) * speedMs;
|
||||
}
|
||||
// Convert to feet per minute
|
||||
vs *= (SG_METER_TO_FEET * 60);
|
||||
//if (getCallSign() == "LUFTHANSA2002")
|
||||
//if (fabs(vs) > 100000) {
|
||||
// if (getCallSign() == "LUFTHANSA2057") {
|
||||
// cerr << getCallSign() << " " << fp->getPreviousWaypoint()->getName() << ". Alt = " << altitude_ft << " vertical dist = " << vert_m << " horiz dist = " << dist_m << " << angle = " << angle * SG_RADIANS_TO_DEGREES << " vs " << vs << " horizontal speed " << speed << "Previous crossAT " << fp->getPreviousWaypoint()->getCrossat() << endl;
|
||||
// //= (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
|
||||
// // / 6076.0 / speed*60.0);
|
||||
// //raise(SIGSEGV);
|
||||
// }
|
||||
return vs;
|
||||
}
|
||||
|
||||
void FGAIAircraft::assertSpeed(double speed)
|
||||
{
|
||||
if ((speed < -50) || (speed > 1000)) {
|
||||
cerr << getCallSign() << " "
|
||||
<< "Previous waypoint " << fp->getPreviousWaypoint()->getName() << " "
|
||||
<< "Departure airport " << trafficRef->getDepartureAirport() << " "
|
||||
<< "Leg " << fp->getLeg() << " "
|
||||
<< "target_speed << " << tgt_speed << " "
|
||||
<< "speedFraction << " << speedFraction << " "
|
||||
<< "Currecnt speed << " << speed << " "
|
||||
<< endl;
|
||||
//raise(SIGSEGV);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGAIAircraft::checkTcas(void)
|
||||
{
|
||||
if (props->getIntValue("tcas/threat-level",0)==3)
|
||||
|
@ -497,6 +546,9 @@ void FGAIAircraft::getGroundElev(double dt) {
|
|||
|
||||
|
||||
void FGAIAircraft::doGroundAltitude() {
|
||||
if ((fp->getLeg() == 7) && ((altitude_ft - tgt_altitude_ft) > 5)) {
|
||||
tgt_vs = -500;
|
||||
} else {
|
||||
if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
|
||||
(isStationary()))
|
||||
altitude_ft = (tgt_altitude_ft + groundOffset);
|
||||
|
@ -504,6 +556,7 @@ void FGAIAircraft::doGroundAltitude() {
|
|||
altitude_ft += 0.1 * ((tgt_altitude_ft+groundOffset) - altitude_ft);
|
||||
tgt_vs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGAIAircraft::announcePositionToController() {
|
||||
|
@ -527,6 +580,7 @@ void FGAIAircraft::announcePositionToController() {
|
|||
case 3: //Take off tower controller
|
||||
if (trafficRef->getDepartureAirport()->getDynamics()) {
|
||||
controller = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
|
||||
towerController = 0;
|
||||
} else {
|
||||
cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl;
|
||||
}
|
||||
|
@ -643,7 +697,6 @@ void FGAIAircraft::handleFirstWaypoint() {
|
|||
FGAIWaypoint* next = 0;// the next plus 1
|
||||
|
||||
spinCounter = 0;
|
||||
tempReg = "";
|
||||
|
||||
//TODO fp should handle this
|
||||
fp->IncrementWaypoint(eraseWaypoints);
|
||||
|
@ -676,9 +729,13 @@ void FGAIAircraft::handleFirstWaypoint() {
|
|||
if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
|
||||
{
|
||||
use_perf_vs = false;
|
||||
tgt_vs = (curr->getCrossat() - prev->getAltitude())
|
||||
/ (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
|
||||
/ 6076.0 / prev->getSpeed()*60.0);
|
||||
//tgt_vs = (curr->getCrossat() - prev->getAltitude())
|
||||
// / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
|
||||
// / 6076.0 / prev->getSpeed()*60.0);
|
||||
double vert_dist_ft = curr->getCrossat() - altitude_ft;
|
||||
double err_dist = prev->getCrossat() - altitude_ft;
|
||||
double dist_m = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
|
||||
tgt_vs = calcVerticalSpeed(vert_dist_ft, dist_m, speed, err_dist);
|
||||
checkTcas();
|
||||
tgt_altitude_ft = curr->getCrossat();
|
||||
} else {
|
||||
|
@ -730,6 +787,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
|||
if (tgt_speed > -0.5) {
|
||||
tgt_speed = -0.5;
|
||||
}
|
||||
//assertSpeed(tgt_speed);
|
||||
if (fp->getPreviousWaypoint()->getSpeed() < tgt_speed) {
|
||||
fp->getPreviousWaypoint()->setSpeed(tgt_speed);
|
||||
}
|
||||
|
@ -747,7 +805,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
|||
// << lead_dist << " " << curr->name
|
||||
// << " Ground target speed " << groundTargetSpeed << endl;
|
||||
double bearing = 0;
|
||||
if (speed > 50) { // don't do bearing calculations for ground traffic
|
||||
// don't do bearing calculations for ground traffic
|
||||
bearing = getBearing(fp->getBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr));
|
||||
if (bearing < minBearing) {
|
||||
minBearing = bearing;
|
||||
|
@ -755,12 +813,11 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
|||
minBearing = 10;
|
||||
}
|
||||
if ((minBearing < 360.0) && (minBearing > 10.0)) {
|
||||
speedFraction = cos(minBearing *SG_DEGREES_TO_RADIANS);
|
||||
speedFraction = 0.5 + (cos(minBearing *SG_DEGREES_TO_RADIANS) * 0.5);
|
||||
} else {
|
||||
speedFraction = 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (trafficRef) {
|
||||
//cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
|
||||
/* if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
|
||||
|
@ -768,20 +825,25 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
|
|||
<< _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl;
|
||||
}*/
|
||||
}
|
||||
if ((dist_to_go < lead_dist) || (bearing > (minBearing * 1.1))) {
|
||||
if ((dist_to_go < lead_dist) ||
|
||||
((dist_to_go > prev_dist_to_go) && (bearing > (minBearing * 1.1))) ) {
|
||||
minBearing = 360;
|
||||
speedFraction = 1.0;
|
||||
prev_dist_to_go = HUGE_VAL;
|
||||
return true;
|
||||
} else {
|
||||
prev_dist_to_go = dist_to_go;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FGAIAircraft::aiTrafficVisible() {
|
||||
SGGeod userPos(SGGeod::fromDeg(fgGetDouble("/position/longitude-deg"),
|
||||
fgGetDouble("/position/latitude-deg")));
|
||||
|
||||
return (SGGeodesy::distanceNm(userPos, pos) <= TRAFFICTOAIDISTTODIE);
|
||||
bool FGAIAircraft::aiTrafficVisible()
|
||||
{
|
||||
SGVec3d cartPos = SGVec3d::fromGeod(pos);
|
||||
const double d2 = (TRAFFICTOAIDISTTODIE * SG_NM_TO_METER) *
|
||||
(TRAFFICTOAIDISTTODIE * SG_NM_TO_METER);
|
||||
return (distSqr(cartPos, globals->get_aircraft_positon_cart()) < d2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -816,9 +878,27 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) {
|
|||
}
|
||||
if (prev->contains(string("DepartureHold"))) {
|
||||
//cerr << "Passing point DepartureHold" << endl;
|
||||
scheduleForATCTowerDepartureControl(2);
|
||||
scheduleForATCTowerDepartureControl(1);
|
||||
}
|
||||
|
||||
if (prev->contains(string("Accel"))) {
|
||||
takeOffStatus = 3;
|
||||
}
|
||||
//if (prev->contains(string("landing"))) {
|
||||
// if (speed < _performance->vTaxi() * 2) {
|
||||
// fp->shortenToFirst(2, "legend");
|
||||
// }
|
||||
//}
|
||||
//if (prev->contains(string("final"))) {
|
||||
//
|
||||
// cerr << getCallSign() << " "
|
||||
// << fp->getPreviousWaypoint()->getName()
|
||||
// << ". Alt = " << altitude_ft
|
||||
// << " vs " << vs
|
||||
// << " horizontal speed " << speed
|
||||
// << "Previous crossAT " << fp->getPreviousWaypoint()->getCrossat()
|
||||
// << "Airport elevation" << getTrafficRef()->getArrivalAirport()->getElevation()
|
||||
// << "Altitude difference " << (altitude_ft - fp->getPreviousWaypoint()->getCrossat()) << endl;
|
||||
//q}
|
||||
// This is the last taxi waypoint, and marks the the end of the flight plan
|
||||
// so, the schedule should update and wait for the next departure time.
|
||||
if (prev->contains("END")) {
|
||||
|
@ -877,6 +957,7 @@ void FGAIAircraft::controlSpeed(FGAIWaypoint* curr, FGAIWaypoint* next) {
|
|||
|
||||
if (fabs(speed_diff) > 10) {
|
||||
prevSpeed = speed;
|
||||
//assertSpeed(speed);
|
||||
if (next) {
|
||||
fp->setLeadDistance(speed, tgt_heading, curr, next);
|
||||
}
|
||||
|
@ -1005,13 +1086,14 @@ void FGAIAircraft::updateHeading() {
|
|||
// << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << endl;
|
||||
//if (headingDiff > 60) {
|
||||
groundTargetSpeed = tgt_speed; // * cos(headingDiff * SG_DEGREES_TO_RADIANS);
|
||||
//assertSpeed(groundTargetSpeed);
|
||||
//groundTargetSpeed = tgt_speed - tgt_speed * (headingDiff/180);
|
||||
//} else {
|
||||
// groundTargetSpeed = tgt_speed;
|
||||
//}
|
||||
if (sign(groundTargetSpeed) != sign(tgt_speed))
|
||||
groundTargetSpeed = 0.21 * sign(tgt_speed); // to prevent speed getting stuck in 'negative' mode
|
||||
|
||||
//assertSpeed(groundTargetSpeed);
|
||||
// Only update the target values when we're not moving because otherwise we might introduce an enormous target change rate while waiting a the gate, or holding.
|
||||
if (speed != 0) {
|
||||
if (headingDiff > 30.0) {
|
||||
|
@ -1040,6 +1122,9 @@ void FGAIAircraft::updateHeading() {
|
|||
// << hdg << ". Target " << tgt_heading << ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << "Heading change rate : " << headingChangeRate << " bacnk sence " << bank_sense << endl;
|
||||
hdg += headingChangeRate * dt * sqrt(fabs(speed) / 15);
|
||||
headingError = headingDiff;
|
||||
if (fabs(headingError) < 1.0) {
|
||||
hdg = tgt_heading;
|
||||
}
|
||||
} else {
|
||||
if (fabs(speed) > 1.0) {
|
||||
turn_radius_ft = 0.088362 * speed * speed
|
||||
|
@ -1112,7 +1197,12 @@ void FGAIAircraft::updateVerticalSpeedTarget() {
|
|||
tgt_vs = -_performance->descentRate();
|
||||
}
|
||||
} else {
|
||||
double max_vs = 4*(tgt_altitude_ft - altitude_ft);
|
||||
double vert_dist_ft = fp->getCurrentWaypoint()->getCrossat() - altitude_ft;
|
||||
double err_dist = 0; //prev->getCrossat() - altitude_ft;
|
||||
double dist_m = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), fp->getCurrentWaypoint());
|
||||
tgt_vs = calcVerticalSpeed(vert_dist_ft, dist_m, speed, err_dist);
|
||||
//cerr << "Target vs before : " << tgt_vs;
|
||||
/* double max_vs = 10*(tgt_altitude_ft - altitude_ft);
|
||||
double min_vs = 100;
|
||||
if (tgt_altitude_ft < altitude_ft)
|
||||
min_vs = -100.0;
|
||||
|
@ -1121,7 +1211,8 @@ void FGAIAircraft::updateVerticalSpeedTarget() {
|
|||
tgt_vs = max_vs;
|
||||
|
||||
if (fabs(tgt_vs) < fabs(min_vs))
|
||||
tgt_vs = min_vs;
|
||||
tgt_vs = min_vs;*/
|
||||
//cerr << "target vs : after " << tgt_vs << endl;
|
||||
}
|
||||
} //else
|
||||
// tgt_vs = 0.0;
|
||||
|
@ -1168,6 +1259,14 @@ void FGAIAircraft::handleATCRequests() {
|
|||
altitude_ft, dt);
|
||||
processATC(controller->getInstruction(getID()));
|
||||
}
|
||||
if (towerController) {
|
||||
towerController->updateAircraftInformation(getID(),
|
||||
pos.getLatitudeDeg(),
|
||||
pos.getLongitudeDeg(),
|
||||
hdg,
|
||||
speed,
|
||||
altitude_ft, dt);
|
||||
}
|
||||
}
|
||||
|
||||
void FGAIAircraft::updateActualState() {
|
||||
|
@ -1179,7 +1278,7 @@ void FGAIAircraft::updateActualState() {
|
|||
speed = _performance->actualSpeed(this, groundTargetSpeed, dt);
|
||||
else
|
||||
speed = _performance->actualSpeed(this, (tgt_speed *speedFraction), dt);
|
||||
|
||||
//assertSpeed(speed);
|
||||
updateHeading();
|
||||
roll = _performance->actualBankAngle(this, tgt_roll, dt);
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ public:
|
|||
int getTakeOffStatus() { return takeOffStatus; };
|
||||
|
||||
void checkTcas();
|
||||
double calcVerticalSpeed(double vert_ft, double dist_m, double speed, double error);
|
||||
|
||||
FGATCController * getATCController() { return controller; };
|
||||
|
||||
|
@ -181,6 +182,8 @@ private:
|
|||
time_t timeElapsed;
|
||||
|
||||
PerformanceData* _performance; // the performance data for this aircraft
|
||||
|
||||
void assertSpeed(double speed);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -970,7 +970,7 @@ void FGAIBallistic::handle_impact() {
|
|||
return;
|
||||
|
||||
if (_ht_agl_ft <= 0) {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: terrain impact material" << _mat_name);
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIBallistic: terrain impact material" << _mat_name);
|
||||
report_impact(_elevation_m);
|
||||
_impact_reported = true;
|
||||
|
||||
|
@ -983,7 +983,7 @@ void FGAIBallistic::handle_impact() {
|
|||
|
||||
void FGAIBallistic::handle_expiry() {
|
||||
|
||||
//SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: handle_expiry " << pos.getElevationM());
|
||||
//SG_LOG(SG_AI, SG_DEBUG, "AIBallistic: handle_expiry " << pos.getElevationM());
|
||||
|
||||
report_impact(pos.getElevationM());
|
||||
_expiry_reported = true;
|
||||
|
@ -1024,7 +1024,7 @@ void FGAIBallistic::report_impact(double elevation, const FGAIBase *object)
|
|||
else
|
||||
n->setStringValue("type", "terrain");
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: object impact " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIBallistic: object impact " << _name
|
||||
<< " lon " <<_impact_lon << " lat " <<_impact_lat << " sec " << _life_timer);
|
||||
|
||||
n->setDoubleValue("longitude-deg", _impact_lon);
|
||||
|
|
|
@ -129,9 +129,7 @@ FGAIBase::FGAIBase(object_type ot, bool enableHot) :
|
|||
|
||||
FGAIBase::~FGAIBase() {
|
||||
// Unregister that one at the scenery manager
|
||||
if (globals->get_scenery()) {
|
||||
globals->get_scenery()->get_scene_graph()->removeChild(aip.getSceneGraph());
|
||||
}
|
||||
removeModel();
|
||||
|
||||
if (props) {
|
||||
SGPropertyNode* parent = props->getParent();
|
||||
|
@ -143,6 +141,29 @@ FGAIBase::~FGAIBase() {
|
|||
fp = 0;
|
||||
}
|
||||
|
||||
/** Cleanly remove the model
|
||||
* and let the scenery database pager do the clean-up work.
|
||||
*/
|
||||
void
|
||||
FGAIBase::removeModel()
|
||||
{
|
||||
FGScenery* pSceneryManager = globals->get_scenery();
|
||||
if (pSceneryManager)
|
||||
{
|
||||
osg::ref_ptr<osg::Object> temp = _model.get();
|
||||
pSceneryManager->get_scene_graph()->removeChild(aip.getSceneGraph());
|
||||
// withdraw from SGModelPlacement and drop own reference (unref)
|
||||
aip.init( 0 );
|
||||
_model = 0;
|
||||
// pass it on to the pager, to be be deleted in the pager thread
|
||||
pSceneryManager->getPagerSingleton()->queueDeleteRequest(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIBase: Could not unload model. Missing scenery manager!");
|
||||
}
|
||||
}
|
||||
|
||||
void FGAIBase::readFromScenario(SGPropertyNode* scFileNode)
|
||||
{
|
||||
if (!scFileNode)
|
||||
|
@ -248,6 +269,12 @@ bool FGAIBase::init(bool search_in_AI_path) {
|
|||
|
||||
osg::Node * mdl = SGModelLib::loadPagedModel(f, props, new FGNasalModelData(props));
|
||||
|
||||
if (_model.valid())
|
||||
{
|
||||
// reinit, dump the old model
|
||||
removeModel();
|
||||
}
|
||||
|
||||
_model = new osg::LOD;
|
||||
_model->setName("AI-model range animation node");
|
||||
|
||||
|
@ -269,7 +296,7 @@ bool FGAIBase::init(bool search_in_AI_path) {
|
|||
_initialized = true;
|
||||
|
||||
} else if (!model_path.empty()) {
|
||||
SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model " << model_path);
|
||||
SG_LOG(SG_AI, SG_WARN, "AIBase: Could not load model " << model_path);
|
||||
// not properly installed...
|
||||
_installed = false;
|
||||
}
|
||||
|
@ -284,7 +311,7 @@ void FGAIBase::initModel(osg::Node *node)
|
|||
|
||||
if( _path != ""){
|
||||
props->setStringValue("submodels/path", _path.c_str());
|
||||
SG_LOG(SG_INPUT, SG_DEBUG, "AIBase: submodels/path " << _path);
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIBase: submodels/path " << _path);
|
||||
}
|
||||
|
||||
if( _parent!= ""){
|
||||
|
@ -293,7 +320,7 @@ void FGAIBase::initModel(osg::Node *node)
|
|||
|
||||
fgSetString("/ai/models/model-added", props->getPath().c_str());
|
||||
} else if (!model_path.empty()) {
|
||||
SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model " << model_path);
|
||||
SG_LOG(SG_AI, SG_WARN, "AIBase: Could not load model " << model_path);
|
||||
}
|
||||
|
||||
setDie(false);
|
||||
|
@ -582,7 +609,7 @@ void FGAIBase::_setSubID( int s ) {
|
|||
bool FGAIBase::setParentNode() {
|
||||
|
||||
if (_parent == ""){
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIBase: " << _name
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIBase: " << _name
|
||||
<< " parent not set ");
|
||||
return false;
|
||||
}
|
||||
|
@ -617,7 +644,7 @@ bool FGAIBase::setParentNode() {
|
|||
const string name = _selected_ac->getStringValue("name");
|
||||
return true;
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIBase: " << _name
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIBase: " << _name
|
||||
<< " parent not found: dying ");
|
||||
setDie(true);
|
||||
return false;
|
||||
|
|
|
@ -134,7 +134,7 @@ public:
|
|||
string _path;
|
||||
string _callsign;
|
||||
string _submodel;
|
||||
string _name;
|
||||
std::string _name;
|
||||
string _parent;
|
||||
|
||||
SGGeod userpos;
|
||||
|
@ -216,6 +216,8 @@ protected:
|
|||
void CalculateMach();
|
||||
double UpdateRadar(FGAIManager* manager);
|
||||
|
||||
void removeModel();
|
||||
|
||||
static int _newAIModelID();
|
||||
|
||||
private:
|
||||
|
|
|
@ -134,7 +134,7 @@ void FGAICarrier::update(double dt) {
|
|||
FGAIShip::update(dt);
|
||||
|
||||
//automatic turn into wind with a target wind of 25 kts otd
|
||||
//SG_LOG(SG_GENERAL, SG_ALERT, "AICarrier: MPControl " << MPControl << " AIControl " << AIControl);
|
||||
//SG_LOG(SG_AI, SG_ALERT, "AICarrier: MPControl " << MPControl << " AIControl " << AIControl);
|
||||
if (!MPControl && AIControl){
|
||||
|
||||
if(turn_to_launch_hdg){
|
||||
|
@ -496,7 +496,7 @@ void FGAICarrier::ReturnToBox(){
|
|||
bool FGAICarrier::OutsideBox() { //returns true if the carrier is outside operating box
|
||||
|
||||
if ( max_lat == 0 && min_lat == 0 && max_long == 0 && min_long == 0) {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AICarrier: No Operating Box defined" );
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AICarrier: No Operating Box defined" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -530,7 +530,7 @@ bool FGAICarrier::OutsideBox() { //returns true if the carrier is outside operat
|
|||
return true;
|
||||
}
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AICarrier: Inside Operating Box" );
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AICarrier: Inside Operating Box" );
|
||||
return false;
|
||||
|
||||
} // end OutsideBox
|
||||
|
|
|
@ -314,7 +314,7 @@ void FGAIEscort::setStationSpeed(){
|
|||
// these are the AI rules for the manoeuvring of escorts
|
||||
|
||||
if (_MPControl && _tgtrange > 4 * _stn_limit){
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIEscort: " << _name
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIEscort: " << _name
|
||||
<< " re-aligning to MP pos");
|
||||
pos = _tgtpos;
|
||||
speed = 0;
|
||||
|
|
|
@ -127,7 +127,7 @@ FGAIFlightPlan::FGAIFlightPlan(const string& filename)
|
|||
if (wpt->getName() == "END") wpt->setFinished(true);
|
||||
else wpt->setFinished(false);
|
||||
|
||||
waypoints.push_back( wpt );
|
||||
pushBackWaypoint( wpt );
|
||||
}
|
||||
|
||||
wpt_iterator = waypoints.begin();
|
||||
|
@ -192,7 +192,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
|
|||
|
||||
SGPropertyNode * node = root.getNode("flightplan");
|
||||
|
||||
//waypoints.push_back( init_waypoint );
|
||||
//pushBackWaypoint( init_waypoint );
|
||||
for (int i = 0; i < node->nChildren(); i++) {
|
||||
//cout << "Reading waypoint " << i << endl;
|
||||
FGAIWaypoint* wpt = new FGAIWaypoint;
|
||||
|
@ -208,7 +208,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
|
|||
|
||||
if (wpt->getName() == "END") wpt->setFinished(true);
|
||||
else wpt->setFinished(false);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
} // of node loop
|
||||
wpt_iterator = waypoints.begin();
|
||||
} catch (const sg_exception &e) {
|
||||
|
@ -223,12 +223,12 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
|
|||
time_t timeDiff = now-start;
|
||||
leg = 1;
|
||||
|
||||
if ((timeDiff > 60) && (timeDiff < 1200))
|
||||
if ((timeDiff > 60) && (timeDiff < 1500))
|
||||
leg = 2;
|
||||
else if ((timeDiff >= 1200) && (timeDiff < 1500)) {
|
||||
leg = 3;
|
||||
ac->setTakeOffStatus(2);
|
||||
}
|
||||
//else if ((timeDiff >= 1200) && (timeDiff < 1500)) {
|
||||
//leg = 3;
|
||||
//ac->setTakeOffStatus(2);
|
||||
//}
|
||||
else if ((timeDiff >= 1500) && (timeDiff < 2000))
|
||||
leg = 4;
|
||||
else if (timeDiff >= 2000)
|
||||
|
@ -305,7 +305,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
|
|||
{
|
||||
if ((dist > 100.0) && (useInitialWayPoint))
|
||||
{
|
||||
//waypoints.push_back(init_waypoint);;
|
||||
//pushBackWaypoint(init_waypoint);;
|
||||
waypoints.insert(i, init_waypoint);
|
||||
//cerr << "Using waypoint : " << init_waypoint->name << endl;
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac,
|
|||
// {
|
||||
// (*i)->speed = dist; // A hack
|
||||
// }
|
||||
//waypoints.push_back( wpt );
|
||||
//pushBackWaypoint( wpt );
|
||||
//cerr << "Using waypoint : " << (*i)->name
|
||||
// << ": course diff : " << crsDiff
|
||||
// << "Course = " << course
|
||||
|
@ -409,9 +409,18 @@ void FGAIFlightPlan::DecrementWaypoint(bool eraseWaypoints )
|
|||
}
|
||||
else
|
||||
wpt_iterator--;
|
||||
|
||||
}
|
||||
|
||||
void FGAIFlightPlan::eraseLastWaypoint()
|
||||
{
|
||||
delete (waypoints.back());
|
||||
waypoints.pop_back();;
|
||||
wpt_iterator = waypoints.begin();
|
||||
wpt_iterator++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// gives distance in feet from a position to a waypoint
|
||||
double FGAIFlightPlan::getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const{
|
||||
|
@ -504,10 +513,20 @@ void FGAIFlightPlan::resetWaypoints()
|
|||
wpt->setOn_ground ( (*i)->getOn_ground() );
|
||||
//cerr << "Recycling waypoint " << wpt->name << endl;
|
||||
deleteWaypoints();
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
}
|
||||
|
||||
void FGAIFlightPlan::pushBackWaypoint(FGAIWaypoint *wpt)
|
||||
{
|
||||
// std::vector::push_back invalidates waypoints
|
||||
// so we should restore wpt_iterator after push_back
|
||||
// (or it could be an index in the vector)
|
||||
size_t pos = wpt_iterator - waypoints.begin();
|
||||
waypoints.push_back(wpt);
|
||||
wpt_iterator = waypoints.begin() + pos;
|
||||
}
|
||||
|
||||
// Start flightplan over from the beginning
|
||||
void FGAIFlightPlan::restart()
|
||||
{
|
||||
|
@ -546,3 +565,11 @@ double FGAIFlightPlan::checkTrackLength(string wptName) {
|
|||
}
|
||||
return trackDistance;
|
||||
}
|
||||
|
||||
void FGAIFlightPlan::shortenToFirst(unsigned int number, string name)
|
||||
{
|
||||
while (waypoints.size() > number + 3) {
|
||||
eraseLastWaypoint();
|
||||
}
|
||||
(waypoints.back())->setName((waypoints.back())->getName() + name);
|
||||
}
|
||||
|
|
|
@ -165,6 +165,8 @@ public:
|
|||
FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
|
||||
FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
|
||||
|
||||
void shortenToFirst(unsigned int number, std::string name);
|
||||
|
||||
private:
|
||||
FGAIFlightPlan *sid;
|
||||
typedef std::vector <FGAIWaypoint*> wpt_vector_type;
|
||||
|
@ -195,6 +197,8 @@ private:
|
|||
bool createParking(FGAIAircraft *, FGAirport *, double radius);
|
||||
void deleteWaypoints();
|
||||
void resetWaypoints();
|
||||
void eraseLastWaypoint();
|
||||
void pushBackWaypoint(FGAIWaypoint *wpt);
|
||||
|
||||
bool createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline);
|
||||
void createDefaultLandingTaxi(FGAIAircraft *, FGAirport* aAirport);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <Environment/environment_mgr.hxx>
|
||||
#include <Environment/environment.hxx>
|
||||
#include <FDM/LaRCsim/basic_aero.h>
|
||||
|
||||
|
||||
/* FGAIFlightPlan::create()
|
||||
|
@ -190,11 +191,11 @@ void FGAIFlightPlan::createDefaultTakeoffTaxi(FGAIAircraft * ac,
|
|||
wpt =
|
||||
createOnGround(ac, "Airport Center", aAirport->geod(), airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
wpt =
|
||||
createOnGround(ac, "Runway Takeoff", runwayTakeoff, airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
|
||||
bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
||||
|
@ -242,7 +243,12 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
|||
}
|
||||
|
||||
intVec ids;
|
||||
int runwayId = gn->findNearestNode(runwayTakeoff);
|
||||
int runwayId = 0;
|
||||
if (gn->getVersion() > 0) {
|
||||
runwayId = gn->findNearestNodeOnRunway(runwayTakeoff);
|
||||
} else {
|
||||
runwayId = gn->findNearestNode(runwayTakeoff);
|
||||
}
|
||||
|
||||
// A negative gateId indicates an overflow parking, use a
|
||||
// fallback mechanism for this.
|
||||
|
@ -316,12 +322,15 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
|
|||
//cerr << "Setting departurehold point: " << endl;
|
||||
wpt->setName( wpt->getName() + string("DepartureHold"));
|
||||
}
|
||||
waypoints.push_back(wpt);
|
||||
if (taxiRoute->nodesLeft() == 0) {
|
||||
wpt->setName(wpt->getName() + string("Accel"));
|
||||
}
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
// Acceleration point, 105 meters into the runway,
|
||||
SGGeod accelPoint = rwy->pointOnCenterline(105.0);
|
||||
FGAIWaypoint *wpt = createOnGround(ac, "accel", accelPoint, apt->getElevation(), ac->getPerformance()->vRotate());
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
//cerr << "[done]" << endl;
|
||||
return true;
|
||||
|
@ -339,18 +348,18 @@ void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft * ac,
|
|||
wpt =
|
||||
createOnGround(ac, "Runway Exit", lastWptPos, airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
wpt =
|
||||
createOnGround(ac, "Airport Center", aAirport->geod(), airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
double heading, lat, lon;
|
||||
aAirport->getDynamics()->getParking(gateId, &lat, &lon, &heading);
|
||||
wpt =
|
||||
createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), airportElev,
|
||||
ac->getPerformance()->vTaxi());
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
|
||||
bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
|
||||
|
@ -376,7 +385,13 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
|
|||
}
|
||||
|
||||
intVec ids;
|
||||
int runwayId = gn->findNearestNode(lastWptPos);
|
||||
int runwayId = 0;
|
||||
if (gn->getVersion() == 1) {
|
||||
runwayId = gn->findNearestNodeOnRunway(lastWptPos);
|
||||
} else {
|
||||
runwayId = gn->findNearestNode(lastWptPos);
|
||||
}
|
||||
//cerr << "Using network node " << runwayId << endl;
|
||||
// A negative gateId indicates an overflow parking, use a
|
||||
// fallback mechanism for this.
|
||||
// Starting from gate 0 is a bit of a hack...
|
||||
|
@ -409,7 +424,7 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
|
|||
createOnGround(ac, buffer, tn->getGeod(), apt->getElevation(),
|
||||
ac->getPerformance()->vTaxi());
|
||||
wpt->setRouteIndex(route);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -474,7 +489,7 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
|||
//cerr << "Using " << accelDistance << " " << accelMetric << " " << vTakeoffMetric << endl;
|
||||
SGGeod accelPoint = rwy->pointOnCenterline(105.0 + accelDistance);
|
||||
wpt = createOnGround(ac, "rotate", accelPoint, airportElev, vTakeoff);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
accelDistance =
|
||||
((vTakeoffMetric * 1.1) * (vTakeoffMetric * 1.1) -
|
||||
|
@ -485,18 +500,18 @@ bool FGAIFlightPlan::createTakeOff(FGAIAircraft * ac, bool firstFlight,
|
|||
createOnGround(ac, "rotate", accelPoint, airportElev + 1000,
|
||||
vTakeoff * 1.1);
|
||||
wpt->setOn_ground(false);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
wpt = cloneWithPos(ac, wpt, "3000 ft", rwy->end());
|
||||
wpt->setAltitude(airportElev + 3000);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
// Finally, add two more waypoints, so that aircraft will remain under
|
||||
// Tower control until they have reached the 3000 ft climb point
|
||||
SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5);
|
||||
wpt = cloneWithPos(ac, wpt, "5000 ft", pt);
|
||||
wpt->setAltitude(airportElev + 5000);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -522,7 +537,7 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
|||
if (sid) {
|
||||
for (wpt_vector_iterator i = sid->getFirstWayPoint();
|
||||
i != sid->getLastWayPoint(); i++) {
|
||||
waypoints.push_back(clone(*(i)));
|
||||
pushBackWaypoint(clone(*(i)));
|
||||
//cerr << " Cloning waypoint " << endl;
|
||||
}
|
||||
} else {
|
||||
|
@ -530,15 +545,15 @@ bool FGAIFlightPlan::createClimb(FGAIAircraft * ac, bool firstFlight,
|
|||
assert( rwy != NULL );
|
||||
|
||||
SGGeod climb1 = rwy->pointOnCenterline(10 * SG_NM_TO_METER);
|
||||
wpt = createInAir(ac, "10000ft climb", climb1, vClimb, 10000);
|
||||
wpt = createInAir(ac, "10000ft climb", climb1, 10000, vClimb);
|
||||
wpt->setGear_down(true);
|
||||
wpt->setFlaps_down(true);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
SGGeod climb2 = rwy->pointOnCenterline(20 * SG_NM_TO_METER);
|
||||
wpt = cloneWithPos(ac, wpt, "18000ft climb", climb2);
|
||||
wpt->setAltitude(18000);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -560,6 +575,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
FGAIWaypoint *wpt;
|
||||
double vDescent = ac->getPerformance()->vDescent();
|
||||
double vApproach = ac->getPerformance()->vApproach();
|
||||
double vTouchdown = ac->getPerformance()->vTouchdown();
|
||||
|
||||
|
||||
//Beginning of Descent
|
||||
|
@ -607,7 +623,17 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
}
|
||||
|
||||
|
||||
double dAlt = alt - (apt->getElevation() + 2000);
|
||||
double dAlt = 0; // = alt - (apt->getElevation() + 2000);
|
||||
FGTaxiNode * tn = 0;
|
||||
if (apt->getDynamics()->getGroundNetwork()) {
|
||||
int node = apt->getDynamics()->getGroundNetwork()->findNearestNode(refPoint);
|
||||
tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
}
|
||||
if (tn) {
|
||||
dAlt = alt - ((tn->getElevationFt(apt->getElevation())) + 2000);
|
||||
} else {
|
||||
dAlt = alt - (apt->getElevation() + 2000);
|
||||
}
|
||||
|
||||
double nPoints = 100;
|
||||
|
||||
|
@ -736,7 +762,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
wpt = createInAir(ac, buffer, result, currentAltitude, vDescent);
|
||||
wpt->setCrossat(currentAltitude);
|
||||
wpt->setTrackLength((newDistance / nPoints));
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
//cerr << "Track Length : " << wpt->trackLength;
|
||||
//cerr << " Position : " << result.getLatitudeDeg() << " " << result.getLongitudeDeg() << " " << currentAltitude << endl;
|
||||
}
|
||||
|
@ -769,10 +795,19 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
}
|
||||
|
||||
//cerr << "creating circle between " << startval << " and " << endval << " using " << increment << endl;
|
||||
//FGTaxiNode * tn = apt->getDynamics()->getGroundNetwork()->findNearestNode(initialTarget);
|
||||
double currentAltitude = 0;
|
||||
if (tn) {
|
||||
currentAltitude = (tn->getElevationFt(apt->getElevation())) + 2000;
|
||||
} else {
|
||||
currentAltitude = apt->getElevation() + 2000;
|
||||
}
|
||||
|
||||
double trackLength = (2 * M_PI * initialTurnRadius) / 360.0;
|
||||
for (int i = startval; i != endval; i += increment) {
|
||||
SGGeod result;
|
||||
double currentAltitude = apt->getElevation() + 2000;
|
||||
//double currentAltitude = apt->getElevation() + 2000;
|
||||
|
||||
SGGeodesy::direct(secondaryTarget, i,
|
||||
initialTurnRadius, result, dummyAz2);
|
||||
snprintf(buffer, 16, "turn%03d", i);
|
||||
|
@ -780,31 +815,39 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
wpt->setCrossat(currentAltitude);
|
||||
wpt->setTrackLength(trackLength);
|
||||
//cerr << "Track Length : " << wpt->trackLength;
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
//cerr << " Position : " << result.getLatitudeDeg() << " " << result.getLongitudeDeg() << " " << currentAltitude << endl;
|
||||
}
|
||||
|
||||
|
||||
// The approach leg should bring the aircraft to approximately 4-6 out, after which the landing phase should take over.
|
||||
// The approach leg should bring the aircraft to approximately 4-6 nm out, after which the landing phase should take over.
|
||||
//cerr << "Phase 3: Approach" << endl;
|
||||
double tgt_speed = vApproach;
|
||||
distanceOut -= distanceCovered;
|
||||
double touchDownPoint = 0; //(rwy->lengthM() * 0.1);
|
||||
for (int i = 1; i < nPoints; i++) {
|
||||
SGGeod result;
|
||||
double currentDist = i * (distanceOut / nPoints);
|
||||
double currentAltitude =
|
||||
apt->getElevation() + 2000 - (i * 2000 / nPoints);
|
||||
//double currentAltitude =
|
||||
// apt->getElevation() + 2000 - (i * 2000 / (nPoints-1));
|
||||
double alt = currentAltitude - (i * 2000 / (nPoints - 1));
|
||||
snprintf(buffer, 16, "final%03d", i);
|
||||
result = rwy->pointOnCenterline((-distanceOut) + currentDist);
|
||||
wpt = createInAir(ac, buffer, result, currentAltitude, vApproach);
|
||||
wpt->setCrossat(currentAltitude);
|
||||
result = rwy->pointOnCenterline((-distanceOut) + currentDist + touchDownPoint);
|
||||
if (i == nPoints - 30) {
|
||||
tgt_speed = vTouchdown;
|
||||
}
|
||||
wpt = createInAir(ac, buffer, result, alt, tgt_speed);
|
||||
wpt->setCrossat(alt);
|
||||
wpt->setTrackLength((distanceOut / nPoints));
|
||||
// account for the extra distance due to an extended downwind leg
|
||||
if (i == 1) {
|
||||
wpt->setTrackLength(wpt->getTrackLength() + distanceCovered);
|
||||
}
|
||||
//cerr << "Track Length : " << wpt->trackLength;
|
||||
waypoints.push_back(wpt);
|
||||
//cerr << " Position : " << result.getLatitudeDeg() << " " << result.getLongitudeDeg() << " " << currentAltitude << endl;
|
||||
pushBackWaypoint(wpt);
|
||||
//if (apt->ident() == fgGetString("/sim/presets/airport-id")) {
|
||||
// cerr << " Position : " << result.getLatitudeDeg() << " " << result.getLongitudeDeg() << " " << currentAltitude << " " << apt->getElevation() << " " << distanceOut << endl;
|
||||
//}
|
||||
}
|
||||
|
||||
//cerr << "Done" << endl;
|
||||
|
@ -837,6 +880,7 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
ac->resetPositionFromFlightPlan();
|
||||
}
|
||||
waypoints[1]->setName( (waypoints[1]->getName() + string("legend")));
|
||||
waypoints.back()->setName(waypoints.back()->getName() + "LandingThreshold");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -845,12 +889,18 @@ bool FGAIFlightPlan::createDescent(FGAIAircraft * ac, FGAirport * apt,
|
|||
* Create a flight path from the "permision to land" point (currently
|
||||
hardcoded at 5000 meters from the threshold) to the threshold, at
|
||||
a standard glide slope angle of 3 degrees.
|
||||
Position : 50.0354 8.52592 384 364 11112
|
||||
******************************************************************/
|
||||
bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
||||
const string & fltType)
|
||||
{
|
||||
double vTouchdown = ac->getPerformance()->vTouchdown();
|
||||
//double vTaxi = ac->getPerformance()->vTaxi();
|
||||
double vTaxi = ac->getPerformance()->vTaxi();
|
||||
double decel = ac->getPerformance()->deceleration() * 1.4;
|
||||
|
||||
double vTouchdownMetric = (vTouchdown * SG_NM_TO_METER) / 3600;
|
||||
double vTaxiMetric = (vTaxi * SG_NM_TO_METER) / 3600;
|
||||
double decelMetric = (decel * SG_NM_TO_METER) / 3600;
|
||||
|
||||
//string rwyClass = getRunwayClassFromTrafficType(fltType);
|
||||
//double heading = ac->getTrafficRef()->getCourse();
|
||||
|
@ -860,34 +910,95 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
|
|||
|
||||
FGAIWaypoint *wpt;
|
||||
double aptElev = apt->getElevation();
|
||||
|
||||
SGGeod coord;
|
||||
double currElev = 0;
|
||||
char buffer[12];
|
||||
for (int i = 1; i < 10; i++) {
|
||||
snprintf(buffer, 12, "wpt%d", i);
|
||||
FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
|
||||
assert( rwy != NULL );
|
||||
|
||||
coord = rwy->pointOnCenterline(rwy->lengthM() * (i / 10.0));
|
||||
wpt = createOnGround(ac, buffer, coord, aptElev, (vTouchdown / i));
|
||||
wpt->setCrossat(apt->getElevation());
|
||||
waypoints.push_back(wpt);
|
||||
SGGeod refPoint = rwy->pointOnCenterline(0);
|
||||
FGTaxiNode *tn = 0;
|
||||
if (apt->getDynamics()->getGroundNetwork()) {
|
||||
int node = apt->getDynamics()->getGroundNetwork()->findNearestNode(refPoint);
|
||||
tn = apt->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
}
|
||||
if (tn) {
|
||||
currElev = tn->getElevationFt(apt->getElevation());
|
||||
} else {
|
||||
currElev = apt->getElevation();
|
||||
}
|
||||
|
||||
|
||||
SGGeod coord;
|
||||
|
||||
|
||||
/*double distanceOut = rwy->lengthM() * .1;
|
||||
double nPoints = 20;
|
||||
for (int i = 1; i < nPoints; i++) {
|
||||
snprintf(buffer, 12, "flare%d", i);
|
||||
double currentDist = i * (distanceOut / nPoints);
|
||||
double currentAltitude = apt->getElevation() + 20 - (i * 20 / nPoints);
|
||||
coord = rwy->pointOnCenterline((currentDist * (i / nPoints)));
|
||||
wpt = createInAir(ac, buffer, coord, currentAltitude, (vTouchdown));
|
||||
}*/
|
||||
double rolloutDistance =
|
||||
(vTouchdownMetric * vTouchdownMetric - vTaxiMetric * vTaxiMetric) / (2 * decelMetric);
|
||||
//cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
|
||||
int nPoints = 50;
|
||||
for (int i = 1; i < nPoints; i++) {
|
||||
snprintf(buffer, 12, "landing03%d", i);
|
||||
|
||||
coord = rwy->pointOnCenterline((rolloutDistance * ((double) i / (double) nPoints)));
|
||||
wpt = createOnGround(ac, buffer, coord, currElev, 2*vTaxi);
|
||||
wpt->setCrossat(currElev);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
wpt->setSpeed(vTaxi);
|
||||
double mindist = 1.1 * rolloutDistance;
|
||||
double maxdist = rwy->lengthM();
|
||||
//cerr << "Finding nearest exit" << endl;
|
||||
FGGroundNetwork *gn = apt->getDynamics()->getGroundNetwork();
|
||||
if (gn) {
|
||||
double min = 0;
|
||||
for (int i = ceil(mindist); i < floor(maxdist); i++) {
|
||||
coord = rwy->pointOnCenterline(mindist);
|
||||
int nodeId = 0;
|
||||
if (gn->getVersion() > 0) {
|
||||
nodeId = gn->findNearestNodeOnRunway(coord);
|
||||
} else {
|
||||
nodeId = gn->findNearestNode(coord);
|
||||
}
|
||||
if (tn)
|
||||
tn = gn->findNode(nodeId);
|
||||
else {
|
||||
break;
|
||||
}
|
||||
|
||||
double dist = SGGeodesy::distanceM(coord, tn->getGeod());
|
||||
if (dist < (min + 0.75)) {
|
||||
break;
|
||||
}
|
||||
min = dist;
|
||||
}
|
||||
if (tn) {
|
||||
wpt = createOnGround(ac, buffer, tn->getGeod(), currElev, vTaxi);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
}
|
||||
//cerr << "Done. " << endl;
|
||||
|
||||
/*
|
||||
//Runway Threshold
|
||||
wpt = createOnGround(ac, "Threshold", rwy->threshold(), aptElev, vTouchdown);
|
||||
wpt->crossat = apt->getElevation();
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
// Roll-out
|
||||
wpt = createOnGround(ac, "Center", rwy->geod(), aptElev, vTaxi*2);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
SGGeod rollOut = rwy->pointOnCenterline(rwy->lengthM() * 0.9);
|
||||
wpt = createOnGround(ac, "Roll Out", rollOut, aptElev, vTaxi);
|
||||
wpt->crossat = apt->getElevation();
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
@ -917,7 +1028,7 @@ bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
|
|||
wpt =
|
||||
createOnGround(ac, "taxiStart", SGGeod::fromDeg(lon2, lat2),
|
||||
aptElev, vTaxiReduced);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
geo_direct_wgs_84(0, lat, lon, heading,
|
||||
0.1 * radius, &lat2, &lon2, &az2);
|
||||
|
@ -925,12 +1036,12 @@ bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
|
|||
wpt =
|
||||
createOnGround(ac, "taxiStart2", SGGeod::fromDeg(lon2, lat2),
|
||||
aptElev, vTaxiReduced);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
wpt =
|
||||
createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), aptElev,
|
||||
vTaxiReduced);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
|
|||
init_waypoint->flaps_down= false;
|
||||
init_waypoint->finished = false;
|
||||
init_waypoint->on_ground = false;
|
||||
waypoints.push_back(init_waypoint);
|
||||
pushBackWaypoint(init_waypoint);
|
||||
routefile.append("Data/AI/FlightPlans");
|
||||
snprintf(buffer, 32, "%s-%s.txt",
|
||||
dep->getId().c_str(),
|
||||
|
@ -221,7 +221,7 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
|
|||
wpt->flaps_down= false;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = false;
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
|
||||
if (!(routefile.exists()))
|
||||
|
@ -274,7 +274,7 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
|
|||
wpt->flaps_down= false;
|
||||
wpt->finished = false;
|
||||
wpt->on_ground = false;
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -294,7 +294,7 @@ bool FGAIFlightPlan::createCruise(FGAIAircraft *ac, bool firstFlight, FGAirport
|
|||
double vCruise = ac->getPerformance()->vCruise();
|
||||
FGAIWaypoint *wpt;
|
||||
wpt = createInAir(ac, "Cruise", SGGeod::fromDeg(longitude, latitude), alt, vCruise);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
string rwyClass = getRunwayClassFromTrafficType(fltType);
|
||||
double heading = ac->getTrafficRef()->getCourse();
|
||||
|
@ -306,8 +306,8 @@ bool FGAIFlightPlan::createCruise(FGAIAircraft *ac, bool firstFlight, FGAirport
|
|||
SGGeod secondaryDescentPoint = rwy->pointOnCenterline(-10000);
|
||||
|
||||
wpt = createInAir(ac, "BOD", beginDescentPoint, alt, vCruise);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
wpt = createInAir(ac, "BOD2", secondaryDescentPoint, alt, vCruise);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
//FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
|
||||
wpt->setRouteIndex(-1);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
//cerr << "Success : GateId = " << gateId << endl;
|
||||
SG_LOG(SG_INPUT, SG_WARN, "Warning: Succesfully found a parking for a " <<
|
||||
|
@ -134,7 +134,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
|
||||
|
||||
wpt->setRouteIndex(rte);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
// some special considerations for the last point:
|
||||
waypoints.back()->setName(string("PushBackPoint"));
|
||||
|
@ -176,7 +176,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
|
|||
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
|
||||
|
||||
wpt->setRouteIndex((*ts)->getIndex());
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
}
|
||||
// cerr << "Done " << endl;
|
||||
waypoints.back()->setName(string("PushBackPoint"));
|
||||
|
@ -220,7 +220,7 @@ void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight,
|
|||
SGGeod coord = coord.fromDeg(lon, lat);
|
||||
FGAIWaypoint *wpt = createOnGround(ac, string("park"), coord, dep->getElevation(), vTaxiBackward);
|
||||
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||
10,
|
||||
|
@ -228,13 +228,13 @@ void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight,
|
|||
coord = coord.fromDeg(lon2, lat2);
|
||||
wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
|
||||
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||
2.2*radius,
|
||||
&lat2, &lon2, &az2 );
|
||||
coord = coord.fromDeg(lon2, lat2);
|
||||
wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
|
||||
waypoints.push_back(wpt);
|
||||
pushBackWaypoint(wpt);
|
||||
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ bool FGAIGroundVehicle::init(bool search_in_AI_path) {
|
|||
}
|
||||
|
||||
void FGAIGroundVehicle::update(double dt) {
|
||||
// SG_LOG(SG_GENERAL, SG_ALERT, "updating GroundVehicle: " << _name );
|
||||
// SG_LOG(SG_AI, SG_ALERT, "updating GroundVehicle: " << _name );
|
||||
FGAIShip::update(dt);
|
||||
|
||||
RunGroundVehicle(dt);
|
||||
|
@ -386,11 +386,11 @@ void FGAIGroundVehicle::AdvanceFP(){
|
|||
string parent_next_name =_selected_ac->getStringValue("waypoint/name-next");
|
||||
|
||||
while(fp->getNextWaypoint() != 0 && fp->getNextWaypoint()->getName() != "END" && count < 5){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<<" advancing waypoint to: " << parent_next_name);
|
||||
|
||||
if (fp->getNextWaypoint()->getName() == parent_next_name){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " not setting waypoint already at: " << fp->getNextWaypoint()->getName());
|
||||
return;
|
||||
}
|
||||
|
@ -401,7 +401,7 @@ void FGAIGroundVehicle::AdvanceFP(){
|
|||
next = fp->getNextWaypoint();
|
||||
|
||||
if (fp->getNextWaypoint()->getName() == parent_next_name){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " waypoint set to: " << fp->getNextWaypoint()->getName());
|
||||
return;
|
||||
}
|
||||
|
@ -412,12 +412,12 @@ void FGAIGroundVehicle::AdvanceFP(){
|
|||
|
||||
while(fp->getPreviousWaypoint() != 0 && fp->getPreviousWaypoint()->getName() != "END"
|
||||
&& count > -10){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " retreating waypoint to: " << parent_next_name
|
||||
<< " at: " << fp->getNextWaypoint()->getName());
|
||||
|
||||
if (fp->getNextWaypoint()->getName() == parent_next_name){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " not setting waypoint already at:" << fp->getNextWaypoint()->getName() );
|
||||
return;
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ void FGAIGroundVehicle::AdvanceFP(){
|
|||
next = fp->getNextWaypoint();
|
||||
|
||||
if (fp->getNextWaypoint()->getName() == parent_next_name){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " waypoint set to: " << fp->getNextWaypoint()->getName());
|
||||
return;
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ void FGAIGroundVehicle::RunGroundVehicle(double dt){
|
|||
//bool parent_restart = _selected_ac->getBoolValue("controls/restart");
|
||||
|
||||
if (parent_next_name == "END" && fp->getNextWaypoint()->getName() != "END" ){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " setting END: getting new waypoints ");
|
||||
AdvanceFP();
|
||||
setWPNames();
|
||||
|
@ -508,13 +508,13 @@ void FGAIGroundVehicle::RunGroundVehicle(double dt){
|
|||
if(_restart) _missed_count = 200;
|
||||
/*} else if (parent_next_name == "WAIT" && fp->getNextWaypoint()->name != "WAIT" ){*/
|
||||
} else if (parent_waiting && !_waiting){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " setting WAIT/WAITUNTIL: getting new waypoints ");
|
||||
AdvanceFP();
|
||||
setWPNames();
|
||||
_waiting = true;
|
||||
} else if (parent_next_name != "WAIT" && fp->getNextWaypoint()->getName() == "WAIT"){
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIGroundVeh1cle: " << _name
|
||||
<< " wait done: getting new waypoints ");
|
||||
_waiting = false;
|
||||
_wait_count = 0;
|
||||
|
@ -533,7 +533,7 @@ void FGAIGroundVehicle::RunGroundVehicle(double dt){
|
|||
setWPNames();
|
||||
} else if (_range_ft > (_x_offset +_parent_x_offset)* 4
|
||||
){
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIGroundVeh1cle: " << _name
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIGroundVeh1cle: " << _name
|
||||
<< " rescue: reforming train " << _range_ft
|
||||
);
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
if ((!mAllowExtrapolation && offset + lag < mTimeOffset)
|
||||
|| (offset - 10 > mTimeOffset)) {
|
||||
mTimeOffset = offset;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Resetting time offset adjust system to "
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Resetting time offset adjust system to "
|
||||
"avoid extrapolation: time offset = " << mTimeOffset);
|
||||
} else {
|
||||
// the error of the offset, respectively the negative error to avoid
|
||||
|
@ -178,7 +178,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
systemIncrement = err;
|
||||
mTimeOffset += systemIncrement;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Offset adjust system: time offset = "
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Offset adjust system: time offset = "
|
||||
<< mTimeOffset << ", expected longitudinal position error due to "
|
||||
" current adjustment of the offset: "
|
||||
<< fabs(norm(it->second.linearVel)*systemIncrement));
|
||||
|
@ -200,7 +200,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
// Find the first packet before the target time
|
||||
MotionInfo::iterator nextIt = mMotionInfo.upper_bound(tInterp);
|
||||
if (nextIt == mMotionInfo.begin()) {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Taking oldest packet!");
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Taking oldest packet!");
|
||||
// We have no packet before the target time, just use the first one
|
||||
MotionInfo::iterator firstIt = mMotionInfo.begin();
|
||||
ecPos = firstIt->second.position;
|
||||
|
@ -243,7 +243,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Unable to find property: " << (*firstPropIt)->id << "\n");
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Unable to find property: " << (*firstPropIt)->id << "\n");
|
||||
}
|
||||
++firstPropIt;
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
double intervalLen = intervalEnd - intervalStart;
|
||||
double tau = (tInterp - intervalStart)/intervalLen;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Multiplayer vehicle interpolation: ["
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Multiplayer vehicle interpolation: ["
|
||||
<< intervalStart << ", " << intervalEnd << "], intervalLen = "
|
||||
<< intervalLen << ", interpolation parameter = " << tau);
|
||||
|
||||
|
@ -323,7 +323,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Unable to find property: " << (*prevPropIt)->id << "\n");
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Unable to find property: " << (*prevPropIt)->id << "\n");
|
||||
}
|
||||
|
||||
++prevPropIt;
|
||||
|
@ -347,7 +347,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
double t = tInterp - motionInfo.time;
|
||||
t = SGMisc<double>::min(t, 5);
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Multiplayer vehicle extrapolation: "
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Multiplayer vehicle extrapolation: "
|
||||
"extrapolation time = " << t);
|
||||
|
||||
// Do a few explicit euler steps with the constant acceleration's
|
||||
|
@ -408,7 +408,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
}
|
||||
else
|
||||
{
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Unable to find property: " << (*firstPropIt)->id << "\n");
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Unable to find property: " << (*firstPropIt)->id << "\n");
|
||||
}
|
||||
|
||||
++firstPropIt;
|
||||
|
@ -444,7 +444,7 @@ void FGAIMultiplayer::update(double dt)
|
|||
roll = rDeg;
|
||||
pitch = pDeg;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Multiplayer position and orientation: "
|
||||
SG_LOG(SG_AI, SG_DEBUG, "Multiplayer position and orientation: "
|
||||
<< ecPos << ", " << hlOr);
|
||||
|
||||
//###########################//
|
||||
|
|
|
@ -103,7 +103,7 @@ void FGAIShip::readFromScenario(SGPropertyNode* scFileNode) {
|
|||
setSMPath(scFileNode->getStringValue("submodel-path", ""));
|
||||
|
||||
if (!flightplan.empty()) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "getting flightplan: " << _name );
|
||||
SG_LOG(SG_AI, SG_ALERT, "getting flightplan: " << _name );
|
||||
|
||||
FGAIFlightPlan* fp = new FGAIFlightPlan(flightplan);
|
||||
setFlightPlan(fp);
|
||||
|
@ -245,7 +245,7 @@ void FGAIShip::unbind() {
|
|||
|
||||
}
|
||||
void FGAIShip::update(double dt) {
|
||||
//SG_LOG(SG_GENERAL, SG_ALERT, "updating Ship: " << _name <<hdg<<pitch<<roll);
|
||||
//SG_LOG(SG_AI, SG_ALERT, "updating Ship: " << _name <<hdg<<pitch<<roll);
|
||||
// For computation of rotation speeds we just use finite differences here.
|
||||
// That is perfectly valid since this thing is not driven by accelerations
|
||||
// but by just apply discrete changes at its velocity variables.
|
||||
|
@ -580,7 +580,7 @@ void FGAIShip::setWPNames() {
|
|||
setCurrName(curr->getName());
|
||||
else{
|
||||
setCurrName("");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: current wp name error" );
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIShip: current wp name error" );
|
||||
}
|
||||
|
||||
if (next != 0)
|
||||
|
@ -588,9 +588,9 @@ void FGAIShip::setWPNames() {
|
|||
else
|
||||
setNextName("");
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: prev wp name " << prev->getName());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: current wp name " << curr->getName());
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: next wp name " << next->getName());
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: prev wp name " << prev->getName());
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: current wp name " << curr->getName());
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: next wp name " << next->getName());
|
||||
|
||||
}
|
||||
|
||||
|
@ -612,10 +612,10 @@ double FGAIShip::getCourse(double lat, double lon, double lat2, double lon2) con
|
|||
geo_inverse_wgs_84(lat, lon, lat2, lon2, &course, &recip, &distance);
|
||||
if (tgt_speed >= 0) {
|
||||
return course;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: course " << course);
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: course " << course);
|
||||
} else {
|
||||
return recip;
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: recip " << recip);
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: recip " << recip);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -682,7 +682,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
if (_next_name == "TUNNEL"){
|
||||
_tunnel = !_tunnel;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: " << _name << " " << sp_turn_radius_nm );
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: " << _name << " " << sp_turn_radius_nm );
|
||||
|
||||
fp->IncrementWaypoint(false);
|
||||
next = fp->getNextWaypoint();
|
||||
|
@ -699,7 +699,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
}else if(_next_name == "END" || fp->getNextWaypoint() == 0) {
|
||||
|
||||
if (_repeat) {
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "AIShip: "<< _name << " Flightplan repeating ");
|
||||
SG_LOG(SG_AI, SG_INFO, "AIShip: "<< _name << " Flightplan repeating ");
|
||||
fp->restart();
|
||||
prev = curr;
|
||||
curr = fp->getCurrentWaypoint();
|
||||
|
@ -713,11 +713,11 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
_lead_angle = 0;
|
||||
AccelTo(prev->getSpeed());
|
||||
} else if (_restart){
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "AIShip: " << _name << " Flightplan restarting ");
|
||||
SG_LOG(SG_AI, SG_INFO, "AIShip: " << _name << " Flightplan restarting ");
|
||||
_missed_count = 0;
|
||||
initFlightPlan();
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: " << _name << " Flightplan dying ");
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIShip: " << _name << " Flightplan dying ");
|
||||
setDie(true);
|
||||
_dt_count = 0;
|
||||
return;
|
||||
|
@ -726,7 +726,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
} else if (_next_name == "WAIT") {
|
||||
|
||||
if (_wait_count < next->getTime_sec()) {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: " << _name << " waiting ");
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: " << _name << " waiting ");
|
||||
setSpeed(0);
|
||||
_waiting = true;
|
||||
_wait_count += _dt_count;
|
||||
|
@ -734,7 +734,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
_lead_angle = 0;
|
||||
return;
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: " << _name
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: " << _name
|
||||
<< " wait done: getting new waypoints ");
|
||||
_waiting = false;
|
||||
_wait_count = 0;
|
||||
|
@ -757,7 +757,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
_until_time = next->getTime();
|
||||
setUntilTime(next->getTime());
|
||||
if (until_time_sec > time_sec) {
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "AIShip: " << _name << " "
|
||||
SG_LOG(SG_AI, SG_INFO, "AIShip: " << _name << " "
|
||||
<< curr->getName() << " waiting until: "
|
||||
<< _until_time << " " << until_time_sec << " now " << time_sec );
|
||||
setSpeed(0);
|
||||
|
@ -765,7 +765,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
_waiting = true;
|
||||
return;
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_INFO, "AIShip: "
|
||||
SG_LOG(SG_AI, SG_INFO, "AIShip: "
|
||||
<< _name << " wait until done: getting new waypoints ");
|
||||
setUntilTime("");
|
||||
fp->IncrementWaypoint(false);
|
||||
|
@ -787,7 +787,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
|
||||
} else {
|
||||
//now reorganise the waypoints, so that next becomes current and so on
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: " << _name << " getting new waypoints ");
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: " << _name << " getting new waypoints ");
|
||||
fp->IncrementWaypoint(false);
|
||||
prev = fp->getPreviousWaypoint(); //first waypoint
|
||||
curr = fp->getCurrentWaypoint(); //second waypoint
|
||||
|
@ -820,14 +820,14 @@ void FGAIShip::ProcessFlightPlan(double dt) {
|
|||
if (finite(_course))
|
||||
TurnTo(_course);
|
||||
else
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: Bearing or Range is not a finite number");
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIShip: Bearing or Range is not a finite number");
|
||||
|
||||
_dt_count = 0;
|
||||
} // end Processing FlightPlan
|
||||
|
||||
bool FGAIShip::initFlightPlan() {
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: " << _name << " initializing waypoints ");
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIShip: " << _name << " initializing waypoints ");
|
||||
|
||||
bool init = false;
|
||||
_start_sec = 0;
|
||||
|
@ -841,7 +841,7 @@ bool FGAIShip::initFlightPlan() {
|
|||
next = fp->getNextWaypoint(); //third waypoint (might not exist!)
|
||||
|
||||
while (curr->getName() == "WAIT" || curr->getName() == "WAITUNTIL") { // don't wait when initialising
|
||||
SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: " << _name << " re-initializing waypoints ");
|
||||
SG_LOG(SG_AI, SG_DEBUG, "AIShip: " << _name << " re-initializing waypoints ");
|
||||
fp->IncrementWaypoint(false);
|
||||
curr = fp->getCurrentWaypoint();
|
||||
next = fp->getNextWaypoint();
|
||||
|
@ -889,7 +889,7 @@ bool FGAIShip::initFlightPlan() {
|
|||
_missed_count = 0;
|
||||
_new_waypoint = true;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: " << _name << " done initialising waypoints " << _tunnel);
|
||||
SG_LOG(SG_AI, SG_ALERT, "AIShip: " << _name << " done initialising waypoints " << _tunnel);
|
||||
if (prev)
|
||||
init = true;
|
||||
|
||||
|
|
|
@ -414,7 +414,7 @@ void FGAIWingman::Join(double dt) {
|
|||
_formate_to_ac = true;
|
||||
_join = false;
|
||||
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, _name << " joined " << " RANGE " << distance
|
||||
SG_LOG(SG_AI, SG_ALERT, _name << " joined " << " RANGE " << distance
|
||||
<< " SPEED " << speed );
|
||||
|
||||
return;
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
#include "performancedata.hxx"
|
||||
#include "AIAircraft.hxx"
|
||||
|
||||
|
||||
// For now, make this a define
|
||||
// Later on, additional class variables can simulate settings such as braking power
|
||||
// also, the performance parameters can be tweaked a little to add some personality
|
||||
// to the AIAircraft.
|
||||
#define BRAKE_SETTING 1.6
|
||||
|
||||
PerformanceData::PerformanceData(double acceleration,
|
||||
double deceleration,
|
||||
double climbRate,
|
||||
|
@ -59,7 +66,7 @@ double PerformanceData::actualSpeed(FGAIAircraft* ac, double tgt_speed, double d
|
|||
} else if (speed_diff < 0.0) { // decelerate
|
||||
if (ac->onGround()) {
|
||||
// deceleration performance is better due to wheel brakes.
|
||||
speed -= 3 * _deceleration * dt;
|
||||
speed -= BRAKE_SETTING * _deceleration * dt;
|
||||
} else {
|
||||
speed -= _deceleration * dt;
|
||||
}
|
||||
|
@ -130,7 +137,7 @@ double PerformanceData::actualVerticalSpeed(FGAIAircraft* ac, double tgt_vs, dou
|
|||
double vs = ac->getVerticalSpeed();
|
||||
double vs_diff = tgt_vs - vs;
|
||||
|
||||
if (fabs(vs_diff) > 10.0) {
|
||||
if (fabs(vs_diff) > .001) {
|
||||
if (vs_diff > 0.0) {
|
||||
vs += _climbRate * dt / 3.0; //TODO avoid hardcoded 3 secs to attain climb rate from level flight
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
inline double vRotate () { return _vRotate; };
|
||||
inline double maximumBankAngle () { return _maxbank; };
|
||||
inline double acceleration () { return _acceleration; };
|
||||
inline double deceleration () { return _deceleration; };
|
||||
inline double vTaxi () { return _vTaxi; };
|
||||
inline double vTakeoff () { return _vTakeOff; };
|
||||
inline double vClimb () { return _vClimb; };
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
#include <GUI/gui.h> // mkDialog
|
||||
#include <GUI/new_gui.hxx>
|
||||
|
||||
typedef vector<string> StringVec;
|
||||
typedef vector<string>:: iterator StringVecIterator;
|
||||
typedef std::vector<std::string> StringVec;
|
||||
typedef StringVec::iterator StringVecIterator;
|
||||
|
||||
|
||||
class FGATCDialogNew {
|
||||
|
|
|
@ -140,6 +140,27 @@ time_t ActiveRunway::requestTimeSlot(time_t eta)
|
|||
return newEta;
|
||||
}
|
||||
|
||||
void ActiveRunway::printDepartureCue()
|
||||
{
|
||||
cout << "Departure cue for " << rwy << ": " << endl;
|
||||
for (AircraftVecIterator atc = departureCue.begin(); atc != departureCue.end(); atc++) {
|
||||
cout << " " << (*atc)->getCallSign() << " " << (*atc)->getTakeOffStatus();
|
||||
cout << " " << (*atc)->_getLatitude() << " " << (*atc)->_getLongitude() << (*atc)-> getSpeed() << " " << (*atc)->getAltitude() << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FGAIAircraft* ActiveRunway::getFirstOfStatus(int stat)
|
||||
{
|
||||
for (AircraftVecIterator atc =departureCue.begin(); atc != departureCue.end(); atc++) {
|
||||
if ((*atc)->getTakeOffStatus() == stat)
|
||||
return (*atc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FGTrafficRecord
|
||||
**************************************************************************/
|
||||
|
@ -165,13 +186,13 @@ void FGTrafficRecord::setPositionAndIntentions(int pos,
|
|||
intVecIterator i = intentions.begin();
|
||||
if ((*i) != pos) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"Error in FGTrafficRecord::setPositionAndIntentions");
|
||||
//cerr << "Pos : " << pos << " Curr " << *(intentions.begin()) << endl;
|
||||
"Error in FGTrafficRecord::setPositionAndIntentions at " << SG_ORIGIN);
|
||||
cerr << "Pos : " << pos << " Curr " << *(intentions.begin()) << endl;
|
||||
for (intVecIterator i = intentions.begin();
|
||||
i != intentions.end(); i++) {
|
||||
//cerr << (*i) << " ";
|
||||
cerr << (*i) << " ";
|
||||
}
|
||||
//cerr << endl;
|
||||
cerr << endl;
|
||||
}
|
||||
intentions.erase(i);
|
||||
} else {
|
||||
|
@ -850,7 +871,7 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
|
|||
// // update position of the current aircraft
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: updating aircraft without traffic record");
|
||||
"AI error: updating aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
i->setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||
current = i;
|
||||
|
@ -860,7 +881,15 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
|
|||
// see if we already have a clearance record for the currently active runway
|
||||
// NOTE: dd. 2011-08-07: Because the active runway has been constructed in the announcePosition function, we may safely assume that is
|
||||
// already exists here. So, we can simplify the current code.
|
||||
|
||||
ActiveRunwayVecIterator rwy = activeRunways.begin();
|
||||
//if (parent->getId() == fgGetString("/sim/presets/airport-id")) {
|
||||
// for (rwy = activeRunways.begin(); rwy != activeRunways.end(); rwy++) {
|
||||
// rwy->printDepartureCue();
|
||||
// }
|
||||
//}
|
||||
|
||||
rwy = activeRunways.begin();
|
||||
while (rwy != activeRunways.end()) {
|
||||
if (rwy->getRunwayName() == current->getRunway()) {
|
||||
break;
|
||||
|
@ -883,8 +912,15 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
|
|||
}
|
||||
} */
|
||||
// only bother with aircraft that have a takeoff status of 2, since those are essentially under tower control
|
||||
FGAIAircraft* ac= rwy->getFirstAircraftInDepartureCue();
|
||||
if (ac->getTakeOffStatus() == 1) {
|
||||
ac->setTakeOffStatus(2);
|
||||
}
|
||||
if (current->getAircraft()->getTakeOffStatus() == 2) {
|
||||
current -> setHoldPosition(false);
|
||||
} else {
|
||||
current->setHoldPosition(true);
|
||||
}
|
||||
int clearanceId = rwy->getCleared();
|
||||
if (clearanceId) {
|
||||
if (id == clearanceId) {
|
||||
|
@ -893,11 +929,11 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
|
|||
} else {
|
||||
if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
|
||||
rwy->setCleared(id);
|
||||
FGAIAircraft *ac = rwy->getFirstOfStatus(1);
|
||||
if (ac)
|
||||
ac->setTakeOffStatus(2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -930,12 +966,12 @@ void FGTowerController::signOff(int id)
|
|||
rwy->updateDepartureCue();
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff");
|
||||
"AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff at " << SG_ORIGIN);
|
||||
}
|
||||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Aircraft without traffic record is signing off from tower");
|
||||
"AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN);
|
||||
} else {
|
||||
i->getAircraft()->resetTakeOffStatus();
|
||||
i = activeTraffic.erase(i);
|
||||
|
@ -965,7 +1001,7 @@ bool FGTowerController::hasInstruction(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: checking ATC instruction for aircraft without traffic record");
|
||||
"AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
return i->hasInstruction();
|
||||
}
|
||||
|
@ -989,7 +1025,7 @@ FGATCInstruction FGTowerController::getInstruction(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: requesting ATC instruction for aircraft without traffic record");
|
||||
"AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
return i->getInstruction();
|
||||
}
|
||||
|
@ -1084,7 +1120,7 @@ bool FGStartupController::hasInstruction(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: checking ATC instruction for aircraft without traffic record");
|
||||
"AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
return i->hasInstruction();
|
||||
}
|
||||
|
@ -1108,7 +1144,7 @@ FGATCInstruction FGStartupController::getInstruction(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: requesting ATC instruction for aircraft without traffic record");
|
||||
"AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
return i->getInstruction();
|
||||
}
|
||||
|
@ -1131,7 +1167,7 @@ void FGStartupController::signOff(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Aircraft without traffic record is signing off from tower");
|
||||
"AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN);
|
||||
} else {
|
||||
//cerr << i->getAircraft()->getCallSign() << " signing off from startupcontroller" << endl;
|
||||
i = activeTraffic.erase(i);
|
||||
|
@ -1192,7 +1228,7 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
|
|||
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: updating aircraft without traffic record");
|
||||
"AI error: updating aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
i->setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||
current = i;
|
||||
|
@ -1287,6 +1323,7 @@ void FGStartupController::render(bool visible)
|
|||
|
||||
//for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
|
||||
double dx = 0;
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
|
||||
if (i->isActive(300)) {
|
||||
// Handle start point
|
||||
|
@ -1318,7 +1355,7 @@ void FGStartupController::render(bool visible)
|
|||
} else {
|
||||
elevationStart = ((i)->getAircraft()->_getAltitude() * SG_FEET_TO_METER);
|
||||
}
|
||||
double elevationEnd = segment->getEnd()->getElevation();
|
||||
double elevationEnd = segment->getEnd()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
|
||||
SGGeod center2 = end;
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
|
@ -1356,7 +1393,7 @@ void FGStartupController::render(bool visible)
|
|||
geode->addDrawable(geometry);
|
||||
//osg::Node *custom_obj;
|
||||
SGMaterial *mat;
|
||||
if (segment->hasBlock()) {
|
||||
if (segment->hasBlock(now)) {
|
||||
mat = matlib->find("UnidirectionalTaperRed");
|
||||
} else {
|
||||
mat = matlib->find("UnidirectionalTaperGreen");
|
||||
|
@ -1380,8 +1417,8 @@ void FGStartupController::render(bool visible)
|
|||
obj_trans->setDataVariance(osg::Object::STATIC);
|
||||
FGTaxiSegment *segment = parent->getGroundNetwork()->findSegment(k);
|
||||
|
||||
double elevationStart = segment->getStart()->getElevation();
|
||||
double elevationEnd = segment->getEnd ()->getElevation();
|
||||
double elevationStart = segment->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
double elevationEnd = segment->getEnd ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
|
||||
SGGeod center2 = segment->getStart()->getGeod();
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
|
@ -1433,7 +1470,7 @@ void FGStartupController::render(bool visible)
|
|||
geode->addDrawable(geometry);
|
||||
//osg::Node *custom_obj;
|
||||
SGMaterial *mat;
|
||||
if (segment->hasBlock()) {
|
||||
if (segment->hasBlock(now)) {
|
||||
mat = matlib->find("UnidirectionalTaperRed");
|
||||
} else {
|
||||
mat = matlib->find("UnidirectionalTaperGreen");
|
||||
|
@ -1534,7 +1571,7 @@ void FGApproachController::updateAircraftInformation(int id, double lat, double
|
|||
// // update position of the current aircraft
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: updating aircraft without traffic record");
|
||||
"AI error: updating aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
i->setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||
current = i;
|
||||
|
@ -1582,7 +1619,7 @@ void FGApproachController::signOff(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Aircraft without traffic record is signing off from approach");
|
||||
"AI error: Aircraft without traffic record is signing off from approach at " << SG_ORIGIN);
|
||||
} else {
|
||||
i = activeTraffic.erase(i);
|
||||
}
|
||||
|
@ -1611,7 +1648,7 @@ bool FGApproachController::hasInstruction(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: checking ATC instruction for aircraft without traffic record");
|
||||
"AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
return i->hasInstruction();
|
||||
}
|
||||
|
@ -1635,7 +1672,7 @@ FGATCInstruction FGApproachController::getInstruction(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: requesting ATC instruction for aircraft without traffic record");
|
||||
"AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
return i->getInstruction();
|
||||
}
|
||||
|
|
|
@ -372,9 +372,11 @@ public:
|
|||
FGAIAircraft* getFirstAircraftInDepartureCue() {
|
||||
return departureCue.size() ? *(departureCue.begin()) : NULL;
|
||||
};
|
||||
FGAIAircraft* getFirstOfStatus(int stat);
|
||||
void updateDepartureCue() {
|
||||
departureCue.erase(departureCue.begin());
|
||||
}
|
||||
void printDepartureCue();
|
||||
};
|
||||
|
||||
typedef vector<ActiveRunway> ActiveRunwayVec;
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
#include <sstream>
|
||||
|
||||
using std::ostringstream;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
FGATCDialog *current_atcdialog;
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
#include "ATCutils.hxx"
|
||||
#include "ATCmgr.hxx"
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
using std::cout;
|
||||
using std::cout;
|
||||
using boost::ref;
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <FDM/fdm_shell.hxx>
|
||||
|
||||
#include "replay.hxx"
|
||||
#include "flightrecorder.hxx"
|
||||
|
@ -234,6 +233,17 @@ FGReplay::update( double dt )
|
|||
stamp("begin");
|
||||
|
||||
if ( disable_replay->getBoolValue() )
|
||||
{
|
||||
if (fgGetBool("/sim/freeze/master",false)||
|
||||
fgGetBool("/sim/freeze/clock",false))
|
||||
{
|
||||
fgSetBool("/sim/freeze/master",false);
|
||||
fgSetBool("/sim/freeze/clock",false);
|
||||
last_replay_state = 1;
|
||||
}
|
||||
else
|
||||
if ((replay_master->getIntValue() != 3)||
|
||||
(last_replay_state == 3))
|
||||
{
|
||||
current_replay_state = replay_master->getIntValue();
|
||||
replay_master->setIntValue(0);
|
||||
|
@ -241,37 +251,35 @@ FGReplay::update( double dt )
|
|||
replay_time_str->setStringValue("");
|
||||
disable_replay->setBoolValue(0);
|
||||
speed_up->setDoubleValue(1.0);
|
||||
fgSetString("/sim/messages/copilot", "Replay stopped");
|
||||
speed_up->setDoubleValue(1.0);
|
||||
if (fgGetBool("/sim/replay/mute",false))
|
||||
{
|
||||
fgSetBool("/sim/sound/enabled",true);
|
||||
fgSetBool("/sim/replay/mute",false);
|
||||
}
|
||||
fgSetString("/sim/messages/copilot", "Replay stopped. Your controls!");
|
||||
}
|
||||
}
|
||||
|
||||
int replay_state = replay_master->getIntValue();
|
||||
|
||||
if ((replay_state > 0)&&
|
||||
(last_replay_state == 0))
|
||||
{
|
||||
// replay is starting, suspend FDM
|
||||
/* FIXME we need to suspend/resume the FDM - not the entire FDM shell.
|
||||
* FDM isn't available via the global subsystem manager yet, so need a
|
||||
* method at the FDMshell for now */
|
||||
((FDMShell*) globals->get_subsystem("flight"))->getFDM()->suspend();
|
||||
}
|
||||
else
|
||||
if ((replay_state == 0)&&
|
||||
(last_replay_state > 0))
|
||||
{
|
||||
if (current_replay_state == 3)
|
||||
{
|
||||
// "my controls!" requested: pilot takes control at current replay position...
|
||||
// take control at current replay position ("My controls!").
|
||||
// May need to uncrash the aircraft here :)
|
||||
fgSetBool("/sim/crashed", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// replay was active, restore most recent frame
|
||||
// normal replay exit, restore most recent frame
|
||||
replay(DBL_MAX);
|
||||
}
|
||||
// replay is finished, resume FDM
|
||||
((FDMShell*) globals->get_subsystem("flight"))->getFDM()->resume();
|
||||
|
||||
// replay is finished
|
||||
last_replay_state = replay_state;
|
||||
return;
|
||||
}
|
||||
|
||||
// remember recent state
|
||||
|
@ -282,7 +290,8 @@ FGReplay::update( double dt )
|
|||
case 0:
|
||||
// replay inactive, keep recording
|
||||
break;
|
||||
case 1:
|
||||
case 1: // normal replay
|
||||
case 3: // prepare to resume normal flight at current replay position
|
||||
{
|
||||
// replay active
|
||||
double current_time = replay_time->getDoubleValue();
|
||||
|
@ -312,8 +321,6 @@ FGReplay::update( double dt )
|
|||
return; // don't record the replay session
|
||||
}
|
||||
case 2: // normal replay operation
|
||||
case 3: // replay operation, prepare to resume normal flight at current replay position
|
||||
// replay paused, no-op
|
||||
return; // don't record the replay session
|
||||
default:
|
||||
throw sg_range_exception("unknown FGReplay state");
|
||||
|
|
|
@ -146,6 +146,10 @@ void FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttr
|
|||
|
||||
void FGAirportDynamicsXMLLoader::endElement (const char * name) {
|
||||
//cout << "End element " << name << endl;
|
||||
if (name == string("version")) {
|
||||
_dynamics->getGroundNetwork()->addVersion(atoi(value.c_str()));
|
||||
//std::cerr << "version" << value<< std::endl;
|
||||
}
|
||||
if (name == string("AWOS")) {
|
||||
_dynamics->addAwosFreq(atoi(value.c_str()));
|
||||
//cerr << "Adding AWOS" << value<< endl;
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <Main/globals.hxx>
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
using std::sort;
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -68,12 +73,26 @@ void FGTaxiNode::setLongitude(const string& val)
|
|||
geod.setLongitudeDeg(processPosition(val));
|
||||
}
|
||||
|
||||
//void FGTaxiNode::sortEndSegments(bool byLength)
|
||||
//{
|
||||
// if (byLength)
|
||||
// sort(next.begin(), next.end(), sortByLength);
|
||||
// else
|
||||
// sort(next.begin(), next.end(), sortByHeadingDiff);
|
||||
//}
|
||||
|
||||
double FGTaxiNode::getElevationFt(double refelev)
|
||||
{
|
||||
double elevF = geod.getElevationFt();
|
||||
double elevationEnd = 0;
|
||||
if ((elevF == 0) || (elevF == refelev)) {
|
||||
SGGeod center2 = geod;
|
||||
FGScenery * local_scenery = globals->get_scenery();
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
|
||||
geod.setElevationM(elevationEnd);
|
||||
}
|
||||
}
|
||||
//cerr << "Returning elevation : " << geod.getElevationM() << ". Ref elev (feet) = " << refelev << endl;
|
||||
return geod.getElevationFt();
|
||||
}
|
||||
|
||||
double FGTaxiNode::getElevationM(double refelev)
|
||||
{
|
||||
double refelevFt = refelev * SG_METER_TO_FEET;
|
||||
double retval = getElevationFt(refelevFt);
|
||||
//cerr << "Returning elevation : " << geod.getElevationM() << ". Ref elev (meters) = " << refelev << endl;
|
||||
return geod.getElevationM();
|
||||
}
|
||||
|
|
|
@ -101,7 +101,8 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
|
|||
double getPathScore() { return pathScore; };
|
||||
double getLatitude() { return geod.getLatitudeDeg();};
|
||||
double getLongitude(){ return geod.getLongitudeDeg();};
|
||||
double getElevation() { return geod.getElevationM();};
|
||||
double getElevationM (double refelev=0);
|
||||
double getElevationFt(double refelev=0);
|
||||
|
||||
const SGGeod& getGeod() const { return geod; }
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <Airports/dynamics.hxx>
|
||||
|
||||
#include <AIModel/AIAircraft.hxx>
|
||||
#include <AIModel/performancedata.hxx>
|
||||
#include <AIModel/AIFlightPlan.hxx>
|
||||
|
||||
#include <ATC/atc_mgr.hxx>
|
||||
|
@ -51,6 +52,7 @@
|
|||
|
||||
#include "groundnetwork.hxx"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FGTaxiSegment
|
||||
**************************************************************************/
|
||||
|
@ -113,6 +115,44 @@ void FGTaxiSegment::setDimensions(double elevation)
|
|||
// headingDiff = fabs(headingDiff - 360);
|
||||
//}
|
||||
|
||||
void FGTaxiSegment::block(int id, time_t blockTime, time_t now)
|
||||
{
|
||||
BlockListIterator i = blockTimes.begin();
|
||||
while (i != blockTimes.end()) {
|
||||
if (i->getId() == id)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (i == blockTimes.end()) {
|
||||
blockTimes.push_back(Block(id, blockTime, now));
|
||||
sort(blockTimes.begin(), blockTimes.end());
|
||||
} else {
|
||||
i->updateTimeStamps(blockTime, now);
|
||||
}
|
||||
}
|
||||
|
||||
// The segment has a block if any of the block times listed in the block list is
|
||||
// smaller than the current time.
|
||||
bool FGTaxiSegment::hasBlock(time_t now)
|
||||
{
|
||||
for (BlockListIterator i = blockTimes.begin(); i != blockTimes.end(); i++) {
|
||||
if (i->getBlockTime() < now)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FGTaxiSegment::unblock(time_t now)
|
||||
{
|
||||
if (blockTimes.size()) {
|
||||
BlockListIterator i = blockTimes.begin();
|
||||
if (i->getTimeStamp() < (now - 30)) {
|
||||
blockTimes.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* FGTaxiRoute
|
||||
|
@ -220,6 +260,7 @@ FGGroundNetwork::FGGroundNetwork()
|
|||
count = 0;
|
||||
currTraffic = activeTraffic.begin();
|
||||
group = 0;
|
||||
version = 0;
|
||||
networkInitialized = false;
|
||||
|
||||
}
|
||||
|
@ -252,7 +293,7 @@ FGGroundNetwork::~FGGroundNetwork()
|
|||
node != nodes.end(); node++) {
|
||||
if (saveData) {
|
||||
cachefile << (*node)->getIndex () << " "
|
||||
<< (*node)->getElevation () << " "
|
||||
<< (*node)->getElevationM (parent->getElevation()*SG_FEET_TO_METER) << " "
|
||||
<< endl;
|
||||
}
|
||||
delete(*node);
|
||||
|
@ -296,7 +337,7 @@ void FGGroundNetwork::saveElevationCache() {
|
|||
node != nodes.end(); node++) {
|
||||
if (saveData) {
|
||||
cachefile << (*node)->getIndex () << " "
|
||||
<< (*node)->getElevation () << " "
|
||||
<< (*node)->getElevationM (parent->getElevation()*SG_FEET_TO_METER) << " "
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
@ -323,7 +364,7 @@ void FGGroundNetwork::addNodes(FGParkingVec * parkings)
|
|||
n.setIndex(i->getIndex());
|
||||
n.setLatitude(i->getLatitude());
|
||||
n.setLongitude(i->getLongitude());
|
||||
n.setElevation(parent->getElevation());
|
||||
n.setElevation(parent->getElevation()*SG_FEET_TO_METER);
|
||||
nodes.push_back(new FGTaxiNode(n));
|
||||
|
||||
i++;
|
||||
|
@ -452,6 +493,28 @@ int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
|
|||
return index;
|
||||
}
|
||||
|
||||
int FGGroundNetwork::findNearestNodeOnRunway(const SGGeod & aGeod)
|
||||
{
|
||||
double minDist = HUGE_VAL;
|
||||
int index = -1;
|
||||
|
||||
for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
|
||||
itr++) {
|
||||
if (!((*itr)->getIsOnRunway())) {
|
||||
continue;
|
||||
}
|
||||
double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
index = (*itr)->getIndex();
|
||||
//cerr << "Minimum distance of " << minDist << " for index " << index << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
int FGGroundNetwork::findNearestNode(double lat, double lon)
|
||||
{
|
||||
return findNearestNode(SGGeod::fromDeg(lon, lat));
|
||||
|
@ -628,7 +691,11 @@ void FGGroundNetwork::announcePosition(int id,
|
|||
rec.setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||
rec.setRadius(radius); // only need to do this when creating the record.
|
||||
rec.setAircraft(aircraft);
|
||||
if (leg == 2) {
|
||||
activeTraffic.push_front(rec);
|
||||
} else {
|
||||
activeTraffic.push_back(rec);
|
||||
}
|
||||
|
||||
} else {
|
||||
i->setPositionAndIntentions(currentPosition, intendedRoute);
|
||||
|
@ -653,7 +720,7 @@ void FGGroundNetwork::signOff(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Aircraft without traffic record is signing off");
|
||||
"AI error: Aircraft without traffic record is signing off at " << SG_ORIGIN);
|
||||
} else {
|
||||
i = activeTraffic.erase(i);
|
||||
}
|
||||
|
@ -684,7 +751,7 @@ bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, Traffic
|
|||
trans_num->setIntValue(-1);
|
||||
// PopupCallback(n);
|
||||
//cerr << "Selected transmission message " << n << endl;
|
||||
FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
|
||||
//FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
|
||||
FGATCDialogNew::instance()->removeEntry(1);
|
||||
} else {
|
||||
//cerr << "creating message for " << i->getAircraft()->getCallSign() << endl;
|
||||
|
@ -733,7 +800,7 @@ void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
|
|||
// update position of the current aircraft
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: updating aircraft without traffic record");
|
||||
"AI error: updating aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
i->setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||
current = i;
|
||||
|
@ -818,7 +885,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkSpeedAdjustment");
|
||||
"AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkSpeedAdjustment at " << SG_ORIGIN);
|
||||
}
|
||||
current = i;
|
||||
//closest = current;
|
||||
|
@ -830,6 +897,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
|||
SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
|
||||
//TrafficVector iterator closest;
|
||||
closest = current;
|
||||
closestOnNetwork = current;
|
||||
for (TrafficVectorIterator i = activeTraffic.begin();
|
||||
i != activeTraffic.end(); i++) {
|
||||
if (i == current) {
|
||||
|
@ -910,12 +978,13 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
|||
current->setSpeedAdjustment(closest->getSpeed() *
|
||||
(mindist / 100));
|
||||
needBraking = true;
|
||||
if (
|
||||
closest->getAircraft()->getTakeOffStatus() &&
|
||||
(current->getAircraft()->getTrafficRef()->getDepartureAirport() == closest->getAircraft()->getTrafficRef()->getDepartureAirport()) &&
|
||||
(current->getAircraft()->GetFlightPlan()->getRunway() == closest->getAircraft()->GetFlightPlan()->getRunway())
|
||||
)
|
||||
current->getAircraft()->scheduleForATCTowerDepartureControl(1);
|
||||
|
||||
// if (
|
||||
// closest->getAircraft()->getTakeOffStatus() &&
|
||||
// (current->getAircraft()->getTrafficRef()->getDepartureAirport() == closest->getAircraft()->getTrafficRef()->getDepartureAirport()) &&
|
||||
// (current->getAircraft()->GetFlightPlan()->getRunway() == closest->getAircraft()->GetFlightPlan()->getRunway())
|
||||
// )
|
||||
// current->getAircraft()->scheduleForATCTowerDepartureControl(1);
|
||||
} else {
|
||||
current->setSpeedAdjustment(0); // This can only happen when the user aircraft is the one closest
|
||||
}
|
||||
|
@ -929,7 +998,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
|||
}
|
||||
}
|
||||
}
|
||||
if ((closest == closestOnNetwork) && (current->getPriority() < closest->getPriority()) && needBraking) {
|
||||
if ((closest->getId() == closestOnNetwork->getId()) && (current->getPriority() < closest->getPriority()) && needBraking) {
|
||||
swap(current, closest);
|
||||
}
|
||||
}
|
||||
|
@ -960,11 +1029,23 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
} else {
|
||||
return;
|
||||
}
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkHoldPosition");
|
||||
"AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkHoldPosition at " << SG_ORIGIN);
|
||||
}
|
||||
current = i;
|
||||
//
|
||||
if (current->getAircraft()->getTakeOffStatus() == 1) {
|
||||
current->setHoldPosition(true);
|
||||
return;
|
||||
}
|
||||
if (current->getAircraft()->getTakeOffStatus() == 2) {
|
||||
//cerr << current->getAircraft()->getCallSign() << ". Taxi in position and hold" << endl;
|
||||
current->setHoldPosition(false);
|
||||
current->clearSpeedAdjustment();
|
||||
return;
|
||||
}
|
||||
bool origStatus = current->hasHoldPosition();
|
||||
current->setHoldPosition(false);
|
||||
SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
|
||||
|
@ -983,89 +1064,32 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
|||
} else {
|
||||
nx = tx;
|
||||
}
|
||||
if (tx->hasBlock() || nx->hasBlock() ) {
|
||||
//if (tx->hasBlock(now) || nx->hasBlock(now) ) {
|
||||
// current->setHoldPosition(true);
|
||||
//}
|
||||
SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
|
||||
SGGeod end (SGGeod::fromDeg(nx->getStart()->getLongitude(), nx->getStart()->getLatitude()));
|
||||
|
||||
double distance = SGGeodesy::distanceM(start, end);
|
||||
if (nx->hasBlock(now) && (distance < i->getRadius() * 4)) {
|
||||
current->setHoldPosition(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* for (i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
|
||||
if (i->getId() != current->getId()) {
|
||||
int node = current->crosses(this, *i);
|
||||
if (node != -1) {
|
||||
FGTaxiNode *taxiNode = findNode(node);
|
||||
|
||||
// Determine whether it's save to continue or not.
|
||||
// If we have a crossing route, there are two possibilities:
|
||||
// 1) This is an interestion
|
||||
// 2) This is oncoming two-way traffic, using the same taxiway.
|
||||
//cerr << "Hold check 1 : " << id << " has common node " << node << endl;
|
||||
|
||||
SGGeod other(SGGeod::
|
||||
fromDegM(i->getLongitude(), i->getLatitude(),
|
||||
i->getAltitude()));
|
||||
bool needsToWait;
|
||||
bool opposing;
|
||||
if (current->isOpposing(this, *i, node)) {
|
||||
needsToWait = true;
|
||||
opposing = true;
|
||||
//cerr << "Hold check 2 : " << node << " has opposing segment " << endl;
|
||||
// issue a "Hold Position" as soon as we're close to the offending node
|
||||
// For now, I'm doing this as long as the other aircraft doesn't
|
||||
// have a hold instruction as soon as we're within a reasonable
|
||||
// distance from the offending node.
|
||||
// This may be a bit of a conservative estimate though, as it may
|
||||
// be well possible that both aircraft can both continue to taxi
|
||||
// without crashing into each other.
|
||||
} else {
|
||||
opposing = false;
|
||||
if (SGGeodesy::distanceM(other, taxiNode->getGeod()) > 200) // 2.0*i->getRadius())
|
||||
{
|
||||
needsToWait = false;
|
||||
//cerr << "Hold check 3 : " << id <<" Other aircraft approaching node is still far away. (" << dist << " nm). Can safely continue "
|
||||
// << endl;
|
||||
} else {
|
||||
needsToWait = true;
|
||||
//cerr << "Hold check 4: " << id << " Would need to wait for other aircraft : distance = " << dist << " meters" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
double dist =
|
||||
SGGeodesy::distanceM(curr, taxiNode->getGeod());
|
||||
if (!(i->hasHoldPosition())) {
|
||||
|
||||
if ((dist < 200) && //2.5*current->getRadius()) &&
|
||||
(needsToWait) && (i->onRoute(this, *current)) &&
|
||||
//((i->onRoute(this, *current)) || ((!(i->getSpeedAdjustment())))) &&
|
||||
(!(current->getId() == i->getWaitsForId())))
|
||||
//(!(i->getSpeedAdjustment()))) // &&
|
||||
//(!(current->getSpeedAdjustment())))
|
||||
|
||||
{
|
||||
if (!(isUserAircraft(i->getAircraft()))) { // test code. Don't wait for the user, let the user wait for you.
|
||||
intVecIterator ivi = i->getIntentions().begin();
|
||||
while (ivi != i->getIntentions().end()) {
|
||||
if ((*ivi) > 0) {
|
||||
distance += segments[(*ivi)-1]->getLength();
|
||||
if ((segments[(*ivi)-1]->hasBlock(now)) && (distance < i->getRadius() * 4)) {
|
||||
current->setHoldPosition(true);
|
||||
current->setWaitsForId(i->getId());
|
||||
break;
|
||||
}
|
||||
//cerr << "Hold check 5: " << current->getCallSign() <<" Setting Hold Position: distance to node (" << node << ") "
|
||||
// << dist << " meters. Waiting for " << i->getCallSign();
|
||||
//if (opposing)
|
||||
//cerr <<" [opposing] " << endl;
|
||||
//else
|
||||
// cerr << "[non-opposing] " << endl;
|
||||
//if (i->hasSpeefAdjustment())
|
||||
// {
|
||||
// cerr << " (which in turn waits for ) " << i->
|
||||
} else {
|
||||
//cerr << "Hold check 6: " << id << " No need to hold yet: Distance to node : " << dist << " nm"<< endl;
|
||||
}
|
||||
ivi++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
bool currStatus = current->hasHoldPosition();
|
||||
current->setHoldPosition(origStatus);
|
||||
// Either a Hold Position or a resume taxi transmission has been issued
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
if ((now - lastTransmission) > 2) {
|
||||
available = true;
|
||||
}
|
||||
|
@ -1154,7 +1178,7 @@ bool FGGroundNetwork::checkForCircularWaits(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (trafficSize == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkForCircularWaits");
|
||||
"AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkForCircularWaits at " << SG_ORIGIN);
|
||||
}
|
||||
|
||||
current = i;
|
||||
|
@ -1246,7 +1270,7 @@ bool FGGroundNetwork::hasInstruction(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: checking ATC instruction for aircraft without traffic record");
|
||||
"AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
return i->hasInstruction();
|
||||
}
|
||||
|
@ -1269,7 +1293,7 @@ FGATCInstruction FGGroundNetwork::getInstruction(int id)
|
|||
}
|
||||
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||
"AI error: requesting ATC instruction for aircraft without traffic record");
|
||||
"AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
|
||||
} else {
|
||||
return i->getInstruction();
|
||||
}
|
||||
|
@ -1314,6 +1338,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
FGScenery * local_scenery = globals->get_scenery();
|
||||
double elevation_meters = 0.0;
|
||||
double elevation_feet = 0.0;
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
//for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
|
||||
double dx = 0;
|
||||
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
|
||||
|
@ -1345,7 +1370,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
} else {
|
||||
elevationStart = ((i)->getAircraft()->_getAltitude());
|
||||
}
|
||||
double elevationEnd = segments[pos]->getEnd()->getElevation();
|
||||
double elevationEnd = segments[pos]->getEnd()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
//cerr << "Using elevation " << elevationEnd << endl;
|
||||
|
||||
if ((elevationEnd == 0) || (elevationEnd = parent->getElevation())) {
|
||||
|
@ -1383,7 +1408,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
geode->addDrawable(geometry);
|
||||
//osg::Node *custom_obj;
|
||||
SGMaterial *mat;
|
||||
if (segments[pos]->hasBlock()) {
|
||||
if (segments[pos]->hasBlock(now)) {
|
||||
mat = matlib->find("UnidirectionalTaperRed");
|
||||
} else {
|
||||
mat = matlib->find("UnidirectionalTaperGreen");
|
||||
|
@ -1406,8 +1431,8 @@ void FGGroundNetwork::render(bool visible)
|
|||
obj_trans->setDataVariance(osg::Object::STATIC);
|
||||
|
||||
// Experimental: Calculate slope here, based on length, and the individual elevations
|
||||
double elevationStart = segments[k]->getStart()->getElevation();
|
||||
double elevationEnd = segments[k]->getEnd ()->getElevation();
|
||||
double elevationStart = segments[k]->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
double elevationEnd = segments[k]->getEnd ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
|
||||
if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
|
||||
SGGeod center2 = segments[k]->getStart()->getGeod();
|
||||
center2.setElevationM(SG_MAX_ELEVATION_M);
|
||||
|
@ -1457,7 +1482,7 @@ void FGGroundNetwork::render(bool visible)
|
|||
geode->addDrawable(geometry);
|
||||
//osg::Node *custom_obj;
|
||||
SGMaterial *mat;
|
||||
if (segments[k]->hasBlock()) {
|
||||
if (segments[k]->hasBlock(now)) {
|
||||
mat = matlib->find("UnidirectionalTaperRed");
|
||||
} else {
|
||||
mat = matlib->find("UnidirectionalTaperGreen");
|
||||
|
@ -1482,8 +1507,9 @@ string FGGroundNetwork::getName() {
|
|||
|
||||
void FGGroundNetwork::update(double dt)
|
||||
{
|
||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
|
||||
(*tsi)->unblock();
|
||||
(*tsi)->unblock(now);
|
||||
}
|
||||
int priority = 1;
|
||||
//sort(activeTraffic.begin(), activeTraffic.end(), compare_trafficrecords);
|
||||
|
@ -1493,6 +1519,8 @@ void FGGroundNetwork::update(double dt)
|
|||
i != parent->getDynamics()->getStartupController()->getActiveTraffic().end(); i++) {
|
||||
i->allowPushBack();
|
||||
i->setPriority(priority++);
|
||||
// in meters per second;
|
||||
double vTaxi = (i->getAircraft()->getPerformance()->vTaxi() * SG_NM_TO_METER) / 3600;
|
||||
if (i->isActive(60)) {
|
||||
|
||||
// Check for all active aircraft whether it's current pos segment is
|
||||
|
@ -1506,7 +1534,7 @@ void FGGroundNetwork::update(double dt)
|
|||
for (intVecIterator k = i->getIntentions().begin(); k != i->getIntentions().end(); k++) {
|
||||
if ((*k) == posReverse) {
|
||||
i->denyPushBack();
|
||||
segments[posReverse-1]->block();
|
||||
segments[posReverse-1]->block(i->getId(), now, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1514,13 +1542,15 @@ void FGGroundNetwork::update(double dt)
|
|||
}
|
||||
// if the current aircraft is still allowed to pushback, we can start reserving a route for if by blocking all the entry taxiways.
|
||||
if (i->pushBackAllowed()) {
|
||||
double length = 0;
|
||||
int pos = i->getCurrentPosition();
|
||||
if (pos > 0) {
|
||||
FGTaxiSegment *seg = segments[pos-1];
|
||||
FGTaxiNode *node = seg->getEnd();
|
||||
length = seg->getLength();
|
||||
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
|
||||
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
|
||||
(*tsi)->block();
|
||||
(*tsi)->block(i->getId(), now, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1529,9 +1559,11 @@ void FGGroundNetwork::update(double dt)
|
|||
if (pos > 0) {
|
||||
FGTaxiSegment *seg = segments[pos-1];
|
||||
FGTaxiNode *node = seg->getEnd();
|
||||
length += seg->getLength();
|
||||
time_t blockTime = now + (length / vTaxi);
|
||||
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
|
||||
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
|
||||
(*tsi)->block();
|
||||
(*tsi)->block(i->getId(), blockTime-30, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1540,11 +1572,14 @@ void FGGroundNetwork::update(double dt)
|
|||
}
|
||||
}
|
||||
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
|
||||
double length = 0;
|
||||
double vTaxi = (i->getAircraft()->getPerformance()->vTaxi() * SG_NM_TO_METER) / 3600;
|
||||
i->setPriority(priority++);
|
||||
int pos = i->getCurrentPosition();
|
||||
if (pos > 0) {
|
||||
if (segments[pos-1]->hasBlock()) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Taxiway incursion for AI aircraft" << i->getAircraft()->getCallSign());
|
||||
length = segments[pos-1]->getLength();
|
||||
if (segments[pos-1]->hasBlock(now)) {
|
||||
//SG_LOG(SG_GENERAL, SG_ALERT, "Taxiway incursion for AI aircraft" << i->getAircraft()->getCallSign());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1552,7 +1587,7 @@ void FGGroundNetwork::update(double dt)
|
|||
for (ivi = i->getIntentions().begin(); ivi != i->getIntentions().end(); ivi++) {
|
||||
int segIndex = (*ivi);
|
||||
if (segIndex > 0) {
|
||||
if (segments[segIndex-1]->hasBlock())
|
||||
if (segments[segIndex-1]->hasBlock(now))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1562,9 +1597,11 @@ void FGGroundNetwork::update(double dt)
|
|||
if (pos > 0) {
|
||||
FGTaxiSegment *seg = segments[pos-1];
|
||||
FGTaxiNode *node = seg->getEnd();
|
||||
length += seg->getLength();
|
||||
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
|
||||
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
|
||||
(*tsi)->block();
|
||||
time_t blockTime = now + (length / vTaxi);
|
||||
(*tsi)->block(i->getId(), blockTime - 30, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,9 +35,12 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
class Block;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::list;
|
||||
|
||||
#include "gnnode.hxx"
|
||||
#include "parking.hxx"
|
||||
|
@ -54,6 +57,25 @@ typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
|
|||
//typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
|
||||
//typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
|
||||
|
||||
class Block
|
||||
{
|
||||
private:
|
||||
int id;
|
||||
time_t blocktime;
|
||||
time_t touch;
|
||||
public:
|
||||
Block(int i, time_t bt, time_t curr) { id = i; blocktime= bt; touch = curr; };
|
||||
~Block() {};
|
||||
int getId() { return id; };
|
||||
void updateTimeStamps(time_t bt, time_t now) { blocktime = (bt < blocktime) ? bt : blocktime; touch = now; };
|
||||
const time_t getBlockTime() const { return blocktime; };
|
||||
time_t getTimeStamp() { return touch; };
|
||||
bool operator< (const Block &other) const { return blocktime < other.blocktime; };
|
||||
};
|
||||
|
||||
typedef vector<Block> BlockList;
|
||||
typedef BlockList::iterator BlockListIterator;
|
||||
|
||||
/***************************************************************************************
|
||||
* class FGTaxiSegment
|
||||
**************************************************************************************/
|
||||
|
@ -67,7 +89,7 @@ private:
|
|||
SGGeod center;
|
||||
bool isActive;
|
||||
bool isPushBackRoute;
|
||||
bool isBlocked;
|
||||
BlockList blockTimes;
|
||||
FGTaxiNode *start;
|
||||
FGTaxiNode *end;
|
||||
int index;
|
||||
|
@ -83,7 +105,6 @@ public:
|
|||
heading(0),
|
||||
isActive(0),
|
||||
isPushBackRoute(0),
|
||||
isBlocked(0),
|
||||
start(0),
|
||||
end(0),
|
||||
index(0),
|
||||
|
@ -99,7 +120,7 @@ public:
|
|||
center (other.center),
|
||||
isActive (other.isActive),
|
||||
isPushBackRoute (other.isPushBackRoute),
|
||||
isBlocked (other.isBlocked),
|
||||
blockTimes (other.blockTimes),
|
||||
start (other.start),
|
||||
end (other.end),
|
||||
index (other.index),
|
||||
|
@ -116,7 +137,7 @@ public:
|
|||
center = other.center;
|
||||
isActive = other.isActive;
|
||||
isPushBackRoute = other.isPushBackRoute;
|
||||
isBlocked = other.isBlocked;
|
||||
blockTimes = other.blockTimes;
|
||||
start = other.start;
|
||||
end = other.end;
|
||||
index = other.index;
|
||||
|
@ -144,15 +165,9 @@ public:
|
|||
isPushBackRoute = val;
|
||||
};
|
||||
void setDimensions(double elevation);
|
||||
void block() {
|
||||
isBlocked = true;
|
||||
}
|
||||
void unblock() {
|
||||
isBlocked = false;
|
||||
};
|
||||
bool hasBlock() {
|
||||
return isBlocked;
|
||||
};
|
||||
void block(int id, time_t blockTime, time_t now);
|
||||
void unblock(time_t now);
|
||||
bool hasBlock(time_t now);
|
||||
|
||||
FGTaxiNode * getEnd() {
|
||||
return end;
|
||||
|
@ -292,6 +307,7 @@ private:
|
|||
time_t nextSave;
|
||||
//int maxDepth;
|
||||
int count;
|
||||
int version;
|
||||
FGTaxiNodeVector nodes;
|
||||
FGTaxiNodeVector pushBackNodes;
|
||||
FGTaxiSegmentVector segments;
|
||||
|
@ -324,6 +340,9 @@ public:
|
|||
void addNode (const FGTaxiNode& node);
|
||||
void addNodes (FGParkingVec *parkings);
|
||||
void addSegment(const FGTaxiSegment& seg);
|
||||
void setVersion (int v) { version = v;};
|
||||
|
||||
int getVersion() { return version; };
|
||||
|
||||
void init();
|
||||
bool exists() {
|
||||
|
@ -335,6 +354,7 @@ public:
|
|||
|
||||
int findNearestNode(double lat, double lon);
|
||||
int findNearestNode(const SGGeod& aGeod);
|
||||
int findNearestNodeOnRunway(const SGGeod& aGeod);
|
||||
|
||||
FGTaxiNode *findNode(unsigned idx);
|
||||
FGTaxiSegment *findSegment(unsigned idx);
|
||||
|
@ -365,6 +385,7 @@ public:
|
|||
virtual void update(double dt);
|
||||
|
||||
void saveElevationCache();
|
||||
void addVersion(int v) {version = v; };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#include <ATC/CommStation.hxx>
|
||||
|
||||
using std::vector;
|
||||
using std::pair;
|
||||
|
||||
using namespace flightgear;
|
||||
|
||||
// magic import of a helper which uses FGPositioned internals
|
||||
|
@ -76,7 +78,6 @@ FGAirport::FGAirport(const string &id, const SGGeod& location, const SGGeod& tow
|
|||
|
||||
FGAirport::~FGAirport()
|
||||
{
|
||||
cerr << "Deleting Airport" << endl;
|
||||
delete _dynamics;
|
||||
}
|
||||
|
||||
|
@ -552,7 +553,7 @@ FGAirport::selectSID(const SGGeod& aDest, FGRunway* aRwy)
|
|||
<< (aRwy ? aRwy->ident() : "no runway preference"));
|
||||
}
|
||||
|
||||
return make_pair(sid, enroute);
|
||||
return std::make_pair(sid, enroute);
|
||||
}
|
||||
|
||||
pair<STAR*, WayptRef>
|
||||
|
@ -584,7 +585,7 @@ FGAirport::selectSTAR(const SGGeod& aOrigin, FGRunway* aRwy)
|
|||
}
|
||||
} // of STAR iteration
|
||||
|
||||
return make_pair(star, enroute);
|
||||
return std::make_pair(star, enroute);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ double AnalogComponent::clamp( double value ) const
|
|||
|
||||
bool AnalogComponent::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
|
||||
{
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "AnalogComponent::configure(" << nodeName << ")" << endl );
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "AnalogComponent::configure(" << nodeName << ")" );
|
||||
if( Component::configure( nodeName, configNode ) )
|
||||
return true;
|
||||
|
||||
|
@ -108,6 +108,6 @@ bool AnalogComponent::configure( const std::string & nodeName, SGPropertyNode_pt
|
|||
return true;
|
||||
}
|
||||
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "AnalogComponent::configure(" << nodeName << ") [unhandled]" << endl );
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "AnalogComponent::configure(" << nodeName << ") [unhandled]" );
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -36,14 +36,30 @@
|
|||
|
||||
#include "Main/fg_props.hxx"
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
using namespace FGXMLAutopilot;
|
||||
|
||||
class ComponentForge : public map<string,FunctorBase<Component> *> {
|
||||
public:
|
||||
virtual ~ ComponentForge();
|
||||
};
|
||||
|
||||
ComponentForge::~ComponentForge()
|
||||
{
|
||||
for( iterator it = begin(); it != end(); ++it )
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
static ComponentForge componentForge;
|
||||
|
||||
Autopilot::Autopilot( SGPropertyNode_ptr rootNode, SGPropertyNode_ptr configNode ) :
|
||||
_name("unnamed autopilot"),
|
||||
_serviceable(true),
|
||||
_rootNode(rootNode)
|
||||
{
|
||||
map<string,FunctorBase<Component> *> componentForge;
|
||||
|
||||
componentForge["pid-controller"] = new CreateAndConfigureFunctor<PIDController,Component>();
|
||||
componentForge["pi-simple-controller"] = new CreateAndConfigureFunctor<PISimpleController,Component>();
|
||||
componentForge["predict-simple"] = new CreateAndConfigureFunctor<Predictor,Component>();
|
||||
|
@ -58,13 +74,13 @@ Autopilot::Autopilot( SGPropertyNode_ptr rootNode, SGPropertyNode_ptr configNode
|
|||
SGPropertyNode_ptr node = configNode->getChild(i);
|
||||
string childName = node->getName();
|
||||
if( componentForge.count(childName) == 0 ) {
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "unhandled element <" << childName << ">" << endl );
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "unhandled element <" << childName << ">" << std::endl );
|
||||
continue;
|
||||
}
|
||||
|
||||
Component * component = (*componentForge[childName])(node);
|
||||
if( component->get_name().length() == 0 ) {
|
||||
ostringstream buf;
|
||||
std::ostringstream buf;
|
||||
buf << "unnamed_component_" << i;
|
||||
component->set_name( buf.str() );
|
||||
}
|
||||
|
@ -96,7 +112,7 @@ void Autopilot::add_component( Component * component )
|
|||
// check for duplicate name
|
||||
std::string name = component->get_name();
|
||||
for( unsigned i = 0; get_subsystem( name.c_str() ) != NULL; i++ ) {
|
||||
ostringstream buf;
|
||||
std::ostringstream buf;
|
||||
buf << component->get_name() << "_" << i;
|
||||
name = buf.str();
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
bool is_serviceable() const { return _serviceable; }
|
||||
|
||||
std::string get_name() const { return _name; }
|
||||
void set_name( std::string & name ) { _name = name; }
|
||||
void set_name( const std::string & name ) { _name = name; }
|
||||
|
||||
void add_component( Component * component );
|
||||
|
||||
|
|
|
@ -35,13 +35,17 @@
|
|||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using simgear::PropertyList;
|
||||
|
||||
class FGXMLAutopilotGroupImplementation : public FGXMLAutopilotGroup
|
||||
{
|
||||
public:
|
||||
virtual void addAutopilot( const std::string & name, SGPropertyNode_ptr apNode, SGPropertyNode_ptr config );
|
||||
virtual void removeAutopilot( const std::string & name );
|
||||
void init();
|
||||
void reinit();
|
||||
void update( double dt );
|
||||
|
@ -51,6 +55,30 @@ private:
|
|||
|
||||
};
|
||||
|
||||
void FGXMLAutopilotGroupImplementation::addAutopilot( const std::string & name, SGPropertyNode_ptr apNode, SGPropertyNode_ptr config )
|
||||
{
|
||||
BOOST_FOREACH( std::string & n, _autopilotNames ) {
|
||||
if( n == name ) {
|
||||
SG_LOG(SG_ALL, SG_ALERT, "NOT adding duplicate property rule name " << name );
|
||||
return;
|
||||
}
|
||||
}
|
||||
FGXMLAutopilot::Autopilot * ap = new FGXMLAutopilot::Autopilot( apNode, config );
|
||||
ap->set_name( name );
|
||||
set_subsystem( name, ap );
|
||||
_autopilotNames.push_back( name );
|
||||
}
|
||||
|
||||
void FGXMLAutopilotGroupImplementation::removeAutopilot( const std::string & name )
|
||||
{
|
||||
FGXMLAutopilot::Autopilot * ap = (FGXMLAutopilot::Autopilot*)get_subsystem( name );
|
||||
if( ap == NULL ) return; // ?
|
||||
remove_subsystem( name );
|
||||
delete ap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGXMLAutopilotGroupImplementation::update( double dt )
|
||||
{
|
||||
// update all configured autopilots
|
||||
|
@ -62,10 +90,7 @@ void FGXMLAutopilotGroupImplementation::reinit()
|
|||
SGSubsystemGroup::unbind();
|
||||
|
||||
for( vector<string>::size_type i = 0; i < _autopilotNames.size(); i++ ) {
|
||||
FGXMLAutopilot::Autopilot * ap = (FGXMLAutopilot::Autopilot*)get_subsystem( _autopilotNames[i] );
|
||||
if( ap == NULL ) continue; // ?
|
||||
remove_subsystem( _autopilotNames[i] );
|
||||
delete ap;
|
||||
removeAutopilot( _autopilotNames[i] );
|
||||
}
|
||||
_autopilotNames.clear();
|
||||
init();
|
||||
|
@ -89,21 +114,20 @@ void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, c
|
|||
if( rootNode == NULL )
|
||||
return;
|
||||
|
||||
PropertyList autopilotNodes = rootNode->getChildren(childName);
|
||||
for( PropertyList::size_type i = 0; i < autopilotNodes.size(); i++ ) {
|
||||
SGPropertyNode_ptr pathNode = autopilotNodes[i]->getNode( "path" );
|
||||
BOOST_FOREACH( SGPropertyNode_ptr autopilotNode, rootNode->getChildren(childName) ) {
|
||||
SGPropertyNode_ptr pathNode = autopilotNode->getNode( "path" );
|
||||
if( pathNode == NULL ) {
|
||||
SG_LOG( SG_ALL, SG_WARN, "No configuration file specified for this property-rule!");
|
||||
continue;
|
||||
}
|
||||
|
||||
string apName;
|
||||
SGPropertyNode_ptr nameNode = autopilotNodes[i]->getNode( "name" );
|
||||
SGPropertyNode_ptr nameNode = autopilotNode->getNode( "name" );
|
||||
if( nameNode != NULL ) {
|
||||
apName = nameNode->getStringValue();
|
||||
} else {
|
||||
std::ostringstream buf;
|
||||
buf << "unnamed_autopilot_" << i;
|
||||
buf << "unnamed_autopilot_" << autopilotNode->getIndex();
|
||||
apName = buf.str();
|
||||
}
|
||||
|
||||
|
@ -111,7 +135,7 @@ void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, c
|
|||
// check for duplicate names
|
||||
string name = apName;
|
||||
for( unsigned i = 0; get_subsystem( apName.c_str() ) != NULL; i++ ) {
|
||||
ostringstream buf;
|
||||
std::ostringstream buf;
|
||||
buf << name << "_" << i;
|
||||
apName = buf.str();
|
||||
}
|
||||
|
@ -119,31 +143,31 @@ void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, c
|
|||
SG_LOG( SG_ALL, SG_WARN, "Duplicate property-rule configuration name " << name << ", renamed to " << apName );
|
||||
}
|
||||
|
||||
SGPath config = globals->resolve_maybe_aircraft_path(pathNode->getStringValue());
|
||||
addAutopilotFromFile( apName, autopilotNode, pathNode->getStringValue() );
|
||||
}
|
||||
}
|
||||
|
||||
void FGXMLAutopilotGroup::addAutopilotFromFile( const std::string & name, SGPropertyNode_ptr apNode, const char * path )
|
||||
{
|
||||
SGPath config = globals->resolve_maybe_aircraft_path(path);
|
||||
if (config.isNull())
|
||||
{
|
||||
SG_LOG( SG_ALL, SG_ALERT, "Cannot find property-rule configuration file '" << pathNode->getStringValue() << "'." );
|
||||
SG_LOG( SG_ALL, SG_ALERT, "Cannot find property-rule configuration file '" << path << "'." );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
|
||||
|
||||
try {
|
||||
SGPropertyNode_ptr root = new SGPropertyNode();
|
||||
readProperties( config.str(), root );
|
||||
SGPropertyNode_ptr configNode = new SGPropertyNode();
|
||||
readProperties( config.str(), configNode );
|
||||
|
||||
SG_LOG( SG_AUTOPILOT, SG_INFO, "adding property-rule subsystem " << apName );
|
||||
FGXMLAutopilot::Autopilot * ap = new FGXMLAutopilot::Autopilot( autopilotNodes[i], root );
|
||||
ap->set_name( apName );
|
||||
set_subsystem( apName, ap );
|
||||
_autopilotNames.push_back( apName );
|
||||
SG_LOG( SG_AUTOPILOT, SG_INFO, "adding property-rule subsystem " << name );
|
||||
addAutopilot( name, apNode, configNode );
|
||||
|
||||
} catch (const sg_exception& e) {
|
||||
SG_LOG( SG_AUTOPILOT, SG_ALERT, "Failed to load property-rule configuration: "
|
||||
<< config.str() << ":" << e.getMessage() );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#ifndef _XMLAUTO_HXX
|
||||
#define _XMLAUTO_HXX 1
|
||||
|
||||
|
||||
/**
|
||||
* @brief Model an autopilot system by implementing a SGSubsystemGroup
|
||||
*
|
||||
|
@ -33,6 +32,9 @@ class FGXMLAutopilotGroup : public SGSubsystemGroup
|
|||
{
|
||||
public:
|
||||
static FGXMLAutopilotGroup * createInstance();
|
||||
void addAutopilotFromFile( const std::string & name, SGPropertyNode_ptr apNode, const char * path );
|
||||
virtual void addAutopilot( const std::string & name, SGPropertyNode_ptr apNode, SGPropertyNode_ptr config ) = 0;
|
||||
virtual void removeAutopilot( const std::string & name ) = 0;
|
||||
protected:
|
||||
FGXMLAutopilotGroup() : SGSubsystemGroup() {}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ bool Component::configure( SGPropertyNode_ptr configNode )
|
|||
|
||||
bool Component::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
|
||||
{
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "Component::configure(" << nodeName << ")" << endl );
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "Component::configure(" << nodeName << ")" << std::endl );
|
||||
|
||||
if ( nodeName == "name" ) {
|
||||
_name = configNode->getStringValue();
|
||||
|
@ -97,7 +97,7 @@ bool Component::configure( const std::string & nodeName, SGPropertyNode_ptr conf
|
|||
return true;
|
||||
} // enable
|
||||
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "Component::configure(" << nodeName << ") [unhandled]" << endl );
|
||||
SG_LOG( SG_AUTOPILOT, SG_BULK, "Component::configure(" << nodeName << ") [unhandled]" << std::endl );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "digitalcomponent.hxx"
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
using std::string;
|
||||
using namespace FGXMLAutopilot;
|
||||
|
||||
DigitalComponent::DigitalComponent() :
|
||||
|
|
|
@ -62,7 +62,8 @@ inline DigitalOutput::DigitalOutput() : _inverted(false)
|
|||
|
||||
inline void DigitalOutput::setProperty( SGPropertyNode_ptr node )
|
||||
{
|
||||
_node->setBoolValue( (_node = node)->getBoolValue() );
|
||||
_node = node;
|
||||
_node->setBoolValue( node->getBoolValue() );
|
||||
}
|
||||
|
||||
inline bool DigitalOutput::getValue() const
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
#include "functor.hxx"
|
||||
#include <deque>
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
|
||||
namespace FGXMLAutopilot {
|
||||
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
#include "inputvalue.hxx"
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
|
||||
namespace FGXMLAutopilot {
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,8 +35,7 @@ public:
|
|||
};
|
||||
|
||||
template <class TClass,class TBase> class CreateAndConfigureFunctor :
|
||||
public FunctorBase<TBase>,
|
||||
SGReferenced {
|
||||
public FunctorBase<TBase> {
|
||||
public:
|
||||
virtual TBase * operator()( SGPropertyNode_ptr configNode ) {
|
||||
TBase * base = new TClass();
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
using namespace FGXMLAutopilot;
|
||||
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
|
||||
PIDController::PIDController():
|
||||
AnalogComponent(),
|
||||
alpha( 0.1 ),
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
using namespace FGXMLAutopilot;
|
||||
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
|
||||
PISimpleController::PISimpleController() :
|
||||
AnalogComponent(),
|
||||
_int_sum( 0.0 )
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
using namespace FGXMLAutopilot;
|
||||
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
|
||||
Predictor::Predictor () :
|
||||
AnalogComponent(),
|
||||
_average(0.0)
|
||||
|
|
|
@ -71,6 +71,8 @@
|
|||
// my hardware/driver requires many more.
|
||||
#define POFF_UNITS 8
|
||||
|
||||
using std::map;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Local functions.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -135,7 +135,7 @@ double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_
|
|||
double c = abox->getDoubleValue("count", 5);
|
||||
int count = (int) (c + (sg_random() - 0.5) * c);
|
||||
|
||||
extent = max(w*w, extent);
|
||||
extent = std::max(w*w, extent);
|
||||
|
||||
for (int j = 0; j < count; j++) {
|
||||
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
#include "fgmetar.hxx"
|
||||
|
||||
|
||||
FGMetar::FGMetar(const string& icao, const string& proxy, const string& port, const string& auth) :
|
||||
SGMetar(icao, proxy, port, auth, _rq_time = globals->get_time_params()->get_cur_time()),
|
||||
FGMetar::FGMetar(const string& icao) :
|
||||
SGMetar(icao),
|
||||
_snow_cover(false)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -37,8 +37,7 @@ using std::string;
|
|||
|
||||
class FGMetar : public SGMetar, public SGReferenced {
|
||||
public:
|
||||
FGMetar(const string& icao, const string& proxy = "", const string& port = "",
|
||||
const string &auth = "");
|
||||
FGMetar(const string& icao);
|
||||
|
||||
long getAge_min() const;
|
||||
time_t getTime() const { return _time; }
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#endif
|
||||
#include "presets.hxx"
|
||||
|
||||
#include <cmath>
|
||||
#include <simgear/math/SGMisc.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
|
|
|
@ -330,7 +330,7 @@ void NoaaMetarRealWxController::requestMetar( MetarDataHandler * metarDataHandle
|
|||
string reply;
|
||||
|
||||
if( name == "X-TIME" ) {
|
||||
ostringstream buf;
|
||||
std::ostringstream buf;
|
||||
buf << globals->get_time_params()->get_cur_time();
|
||||
reply = buf.str();
|
||||
}
|
||||
|
|
|
@ -187,8 +187,8 @@ void FGRidgeLift::update(double dt) {
|
|||
//boundaries
|
||||
double boundary2_m = 130.0; // in the lift
|
||||
if (lift_factor < 0.0) { // in the sink
|
||||
double highest_probe_temp= max ( probe_elev_m[1], probe_elev_m[2] );
|
||||
double highest_probe_downwind_m= max ( highest_probe_temp, probe_elev_m[3] );
|
||||
double highest_probe_temp= std::max ( probe_elev_m[1], probe_elev_m[2] );
|
||||
double highest_probe_downwind_m= std::max ( highest_probe_temp, probe_elev_m[3] );
|
||||
boundary2_m = highest_probe_downwind_m - probe_elev_m[0];
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ void FGRidgeLift::update(double dt) {
|
|||
agl_factor = 1.0;
|
||||
} else {
|
||||
agl_factor = exp(-(2 + probe_elev_m[0] / 2000) *
|
||||
(user_altitude_agl_m - boundary2_m) / max(probe_elev_m[0],200.0));
|
||||
(user_altitude_agl_m - boundary2_m) / std::max(probe_elev_m[0],200.0));
|
||||
}
|
||||
|
||||
double ground_wind_speed_mps = _surface_wind_speed_node->getDoubleValue() * SG_NM_TO_METER / 3600;
|
||||
|
|
|
@ -30,7 +30,12 @@
|
|||
#include <deque>
|
||||
|
||||
#include "terrainsampler.hxx"
|
||||
|
||||
using simgear::PropertyList;
|
||||
using std::deque;
|
||||
using std::vector;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
|
||||
#include <simgear/props/tiedpropertylist.hxx>
|
||||
|
||||
|
|
|
@ -284,7 +284,11 @@ void Gear::calcForce(RigidBody* body, State *s, float* v, float* rot)
|
|||
|
||||
// Don't bother if it's not down
|
||||
if(_extension < 1)
|
||||
{
|
||||
_wow = 0;
|
||||
_frac = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Dont bother if we are in the "wrong" ground
|
||||
if (!((_onWater&&!_ground_isSolid)||(_onSolid&&_ground_isSolid))) {
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
|
||||
#include "Hitch.hpp"
|
||||
|
||||
using std::vector;
|
||||
|
||||
namespace yasim {
|
||||
Hitch::Hitch(const char *name)
|
||||
{
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using std::setprecision;
|
||||
|
||||
#ifdef TEST_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
@ -20,7 +18,8 @@ using std::setprecision;
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
using std::setprecision;
|
||||
using std::endl;
|
||||
|
||||
namespace yasim {
|
||||
|
||||
|
@ -732,7 +731,7 @@ void Rotor::setParameter(const char *parametername, float value)
|
|||
p(rotor_correction_factor,1)
|
||||
SG_LOG(SG_INPUT, SG_ALERT,
|
||||
"internal error in parameter set up for rotor: '" <<
|
||||
parametername <<"'" << endl);
|
||||
parametername <<"'" << std::endl);
|
||||
#undef p
|
||||
}
|
||||
|
||||
|
|
|
@ -195,9 +195,10 @@ void YASim::update(double dt)
|
|||
int iterations = _calc_multiloop(dt);
|
||||
|
||||
// If we're crashed, then we don't care
|
||||
if(_fdm->getAirplane()->getModel()->isCrashed()) {
|
||||
if(fgGetBool("/sim/crashed") || _fdm->getAirplane()->getModel()->isCrashed()) {
|
||||
if(!fgGetBool("/sim/crashed"))
|
||||
fgSetBool("/sim/crashed", true);
|
||||
_fdm->getAirplane()->getModel()->setCrashed(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -505,3 +506,19 @@ void YASim::copyFromYASim()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/** Reinit the FDM.
|
||||
* This is only used after a replay session and when the user requested to resume at
|
||||
* a past point of time. In thise case the FDM must reload all values from the property
|
||||
* tree (as given by the replay system). */
|
||||
void YASim::reinit()
|
||||
{
|
||||
// Process inputs. Use excessive value for dt to make sure all transition effects
|
||||
// have reached their final state (i.e. gear is extended/retracted) - which is vital
|
||||
// for many properties to be complete before the first FDM run (otherwise the gear may
|
||||
// still be up, thrust-reversers/speed-brakes/... may still be partially deployed...).
|
||||
_fdm->getExternalInput(1000);
|
||||
|
||||
// get current FDM values from the property tree
|
||||
copyToYASim(true);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ public:
|
|||
// Load externally set stuff into the FDM
|
||||
virtual void init();
|
||||
virtual void bind();
|
||||
virtual void reinit();
|
||||
|
||||
// Run an iteration
|
||||
virtual void update(double dt);
|
||||
|
|
|
@ -72,6 +72,17 @@ void FDMShell::init()
|
|||
{
|
||||
_props = globals->get_props();
|
||||
fgSetBool("/sim/fdm-initialized", false);
|
||||
|
||||
_wind_north = _props->getNode("environment/wind-from-north-fps", true);
|
||||
_wind_east = _props->getNode("environment/wind-from-east-fps", true);
|
||||
_wind_down = _props->getNode("environment/wind-from-down-fps", true);
|
||||
_control_fdm_atmo = _props->getNode("environment/params/control-fdm-atmosphere", true);
|
||||
_temp_degc = _props->getNode("environment/temperature-degc", true);
|
||||
_pressure_inhg = _props->getNode("environment/pressure-inhg", true);
|
||||
_density_slugft = _props->getNode("environment/density-slugft3", true);
|
||||
_data_logging = _props->getNode("/sim/temp/fdm-data-logging", true);
|
||||
_replay_master = _props->getNode("/sim/freeze/replay-state", true);
|
||||
|
||||
createImplementation();
|
||||
}
|
||||
|
||||
|
@ -138,30 +149,42 @@ void FDMShell::update(double dt)
|
|||
|
||||
// pull environmental data in, since the FDMs are lazy
|
||||
_impl->set_Velocities_Local_Airmass(
|
||||
_props->getDoubleValue("environment/wind-from-north-fps", 0.0),
|
||||
_props->getDoubleValue("environment/wind-from-east-fps", 0.0),
|
||||
_props->getDoubleValue("environment/wind-from-down-fps", 0.0));
|
||||
_wind_north->getDoubleValue(),
|
||||
_wind_east->getDoubleValue(),
|
||||
_wind_down->getDoubleValue());
|
||||
|
||||
if (_props->getBoolValue("environment/params/control-fdm-atmosphere")) {
|
||||
if (_control_fdm_atmo->getBoolValue()) {
|
||||
// convert from Rankine to Celsius
|
||||
double tempDegC = _props->getDoubleValue("environment/temperature-degc");
|
||||
double tempDegC = _temp_degc->getDoubleValue();
|
||||
_impl->set_Static_temperature((9.0/5.0) * (tempDegC + 273.15));
|
||||
|
||||
// convert from inHG to PSF
|
||||
double pressureInHg = _props->getDoubleValue("environment/pressure-inhg");
|
||||
double pressureInHg = _pressure_inhg->getDoubleValue();
|
||||
_impl->set_Static_pressure(pressureInHg * 70.726566);
|
||||
// keep in slugs/ft^3
|
||||
_impl->set_Density(_props->getDoubleValue("environment/density-slugft3"));
|
||||
_impl->set_Density(_density_slugft->getDoubleValue());
|
||||
}
|
||||
|
||||
bool doLog = _props->getBoolValue("/sim/temp/fdm-data-logging", false);
|
||||
bool doLog = _data_logging->getBoolValue();
|
||||
if (doLog != _dataLogging) {
|
||||
_dataLogging = doLog;
|
||||
_impl->ToggleDataLogging(doLog);
|
||||
}
|
||||
|
||||
if (!_impl->is_suspended())
|
||||
switch(_replay_master->getIntValue())
|
||||
{
|
||||
case 0:
|
||||
// normal FDM operation
|
||||
_impl->update(dt);
|
||||
break;
|
||||
case 3:
|
||||
// resume FDM operation at current replay position
|
||||
_impl->reinit();
|
||||
break;
|
||||
default:
|
||||
// replay is active
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FDMShell::createImplementation()
|
||||
|
@ -251,14 +274,3 @@ void FDMShell::createImplementation()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Return FDM subsystem.
|
||||
*/
|
||||
|
||||
SGSubsystem* FDMShell::getFDM()
|
||||
{
|
||||
/* FIXME we could drop/replace this method, when _impl was a added
|
||||
* to the global subsystem manager - like other proper subsystems... */
|
||||
return _impl;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ class FDMShell : public SGSubsystem
|
|||
{
|
||||
public:
|
||||
FDMShell();
|
||||
~FDMShell();
|
||||
virtual ~FDMShell();
|
||||
|
||||
virtual void init();
|
||||
virtual void reinit();
|
||||
|
@ -50,7 +50,6 @@ public:
|
|||
virtual void unbind();
|
||||
|
||||
virtual void update(double dt);
|
||||
SGSubsystem* getFDM();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -58,8 +57,12 @@ private:
|
|||
|
||||
TankPropertiesList _tankProperties;
|
||||
FGInterface* _impl;
|
||||
SGPropertyNode* _props; // root property tree for this FDM instance
|
||||
SGPropertyNode_ptr _props; // root property tree for this FDM instance
|
||||
bool _dataLogging;
|
||||
|
||||
SGPropertyNode_ptr _wind_north, _wind_east,_wind_down;
|
||||
SGPropertyNode_ptr _control_fdm_atmo,_temp_degc,_pressure_inhg;
|
||||
SGPropertyNode_ptr _density_slugft, _data_logging, _replay_master;
|
||||
};
|
||||
|
||||
#endif // of FG_FDM_SHELL_HXX
|
||||
|
|
|
@ -1388,21 +1388,15 @@ void MapWidget::drawAIAircraft(const SGPropertyNode* model, const SGGeod& pos, d
|
|||
drawLine(p, project(advance));
|
||||
}
|
||||
|
||||
if (validDataForKey((void*) model)) {
|
||||
setAnchorForKey((void*) model, p);
|
||||
return;
|
||||
}
|
||||
|
||||
// draw callsign / altitude / speed
|
||||
|
||||
|
||||
char buffer[1024];
|
||||
::snprintf(buffer, 1024, "%s\n%d'\n%dkts",
|
||||
model->getStringValue("callsign", "<>"),
|
||||
static_cast<int>(pos.getElevationFt() / 50.0) * 50,
|
||||
speedKts);
|
||||
|
||||
MapData* d = createDataForKey((void*) model);
|
||||
MapData* d = getOrCreateDataForKey((void*) model);
|
||||
d->setText(buffer);
|
||||
d->setLabel(model->getStringValue("callsign", "<>"));
|
||||
d->setPriority(speedKts > 5 ? 60 : 10); // low priority for parked aircraft
|
||||
|
@ -1434,18 +1428,13 @@ void MapWidget::drawAIShip(const SGPropertyNode* model, const SGGeod& pos, doubl
|
|||
drawLine(p, project(advance));
|
||||
}
|
||||
|
||||
if (validDataForKey((void*) model)) {
|
||||
setAnchorForKey((void*) model, p);
|
||||
return;
|
||||
}
|
||||
|
||||
// draw callsign / speed
|
||||
char buffer[1024];
|
||||
::snprintf(buffer, 1024, "%s\n%dkts",
|
||||
model->getStringValue("name", "<>"),
|
||||
speedKts);
|
||||
|
||||
MapData* d = createDataForKey((void*) model);
|
||||
MapData* d = getOrCreateDataForKey((void*) model);
|
||||
d->setText(buffer);
|
||||
d->setLabel(model->getStringValue("name", "<>"));
|
||||
d->setPriority(speedKts > 2 ? 30 : 10); // low priority for slow moving ships
|
||||
|
|
|
@ -42,6 +42,7 @@ class GraphicsContext;
|
|||
// gui.cxx
|
||||
extern void guiStartInit(osg::GraphicsContext*);
|
||||
extern bool guiFinishInit();
|
||||
extern bool openBrowser(string address);
|
||||
extern void mkDialog(const char *txt);
|
||||
extern void guiErrorMessage(const char *txt);
|
||||
extern void guiErrorMessage(const char *txt, const sg_throwable &throwable);
|
||||
|
|
|
@ -156,46 +156,60 @@ void guiErrorMessage (const char *txt, const sg_throwable &throwable)
|
|||
the Gui callback functions
|
||||
____________________________________________________________________*/
|
||||
|
||||
|
||||
// Hier Neu :-) This is my newly added code
|
||||
// Added by David Findlay <nedz@bigpond.com>
|
||||
// on Sunday 3rd of December
|
||||
|
||||
|
||||
void helpCb()
|
||||
{
|
||||
string command;
|
||||
openBrowser( "Docs/index.html" );
|
||||
}
|
||||
|
||||
SGPath path( globals->get_fg_root() );
|
||||
path.append( "Docs/index.html" );
|
||||
bool openBrowser(string address)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
// do not resolve addresses with given protocol, i.e. "http://...", "ftp://..."
|
||||
if (address.find("://")==string::npos)
|
||||
{
|
||||
// resolve local file path
|
||||
SGPath path(address);
|
||||
path = globals->resolve_maybe_aircraft_path(address);
|
||||
if (!path.isNull())
|
||||
address = path.str();
|
||||
else
|
||||
{
|
||||
mkDialog ("Sorry, file not found!");
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "openBrowser: Cannot find requested file '"
|
||||
<< address << "'.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
command = globals->get_browser();
|
||||
string command = globals->get_browser();
|
||||
string::size_type pos;
|
||||
if ((pos = command.find("%u", 0)) != string::npos)
|
||||
command.replace(pos, 2, path.str());
|
||||
command.replace(pos, 2, address);
|
||||
else
|
||||
command += " " + path.str();
|
||||
command += " " + address;
|
||||
|
||||
command += " &";
|
||||
system( command.c_str() );
|
||||
ok = (system( command.c_str() ) == 0);
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
// Look for favorite browser
|
||||
char win32_name[1024];
|
||||
# ifdef __CYGWIN__
|
||||
cygwin32_conv_to_full_win32_path(path.c_str(),win32_name);
|
||||
cygwin32_conv_to_full_win32_path(address.c_str(),win32_name);
|
||||
# else
|
||||
strncpy(win32_name,path.c_str(), 1024);
|
||||
strncpy(win32_name,address.c_str(), 1024);
|
||||
# endif
|
||||
ShellExecute ( NULL, "open", win32_name, NULL, NULL,
|
||||
SW_SHOWNORMAL ) ;
|
||||
|
||||
#endif
|
||||
|
||||
mkDialog ("Help started in your web browser window.");
|
||||
mkDialog("The file is shown in your web browser window.");
|
||||
return ok;
|
||||
}
|
||||
|
||||
#if defined( TR_HIRES_SNAP)
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
#include "new_gui.hxx"
|
||||
#include "menubar.hxx"
|
||||
|
||||
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using std::map;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// FIXME!!
|
||||
//
|
||||
|
@ -37,14 +38,6 @@ do_hires_snapshot_dialog (const SGPropertyNode * arg)
|
|||
}
|
||||
#endif // TR_HIRES_SNAP
|
||||
|
||||
extern void helpCb ();
|
||||
static bool
|
||||
do_help_dialog (const SGPropertyNode * arg)
|
||||
{
|
||||
helpCb();
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct {
|
||||
const char * name;
|
||||
SGCommandMgr::command_t command;
|
||||
|
@ -52,7 +45,6 @@ static struct {
|
|||
#if defined(TR_HIRES_SNAP)
|
||||
{ "old-hires-snapshot-dialog", do_hires_snapshot_dialog },
|
||||
#endif
|
||||
{ "old-help-dialog", do_help_dialog },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
|
|
@ -7,17 +7,12 @@
|
|||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h> // for SG_USING_STD
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
#include <plib/pu.h>
|
||||
|
||||
#include <map>
|
||||
using std::map;
|
||||
|
||||
#include <vector>
|
||||
using std::vector;
|
||||
|
||||
|
||||
class puMenuBar;
|
||||
class puObject;
|
||||
|
@ -124,7 +119,7 @@ private:
|
|||
puMenuBar * _menuBar;
|
||||
|
||||
// A map of bindings for the menubar.
|
||||
map<string,vector<SGBinding *> > _bindings;
|
||||
std::map<std::string,std::vector<SGBinding *> > _bindings;
|
||||
|
||||
// These are hoops that we have to jump through because PUI doesn't
|
||||
// do memory management for lists. We have to allocate the arrays,
|
||||
|
@ -132,11 +127,11 @@ private:
|
|||
// freed.
|
||||
char ** make_char_array (int size);
|
||||
puCallback * make_callback_array (int size);
|
||||
vector<char **> _char_arrays;
|
||||
vector<puCallback *> _callback_arrays;
|
||||
std::vector<char **> _char_arrays;
|
||||
std::vector<puCallback *> _callback_arrays;
|
||||
|
||||
// A map for {menu node path}->puObject translation.
|
||||
map<string, puObject *> _objects;
|
||||
std::map<std::string, puObject *> _objects;
|
||||
};
|
||||
|
||||
#endif // __MENUBAR_HXX
|
||||
|
|
|
@ -32,9 +32,9 @@
|
|||
extern puFont FONT_HELVETICA_14;
|
||||
extern puFont FONT_SANS_12B;
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of NewGUI.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -212,9 +212,10 @@ private:
|
|||
};
|
||||
|
||||
puFont *_font;
|
||||
map<const char*,FGColor*, ltstr> _colors;
|
||||
typedef map<const char*,FGColor*, ltstr>::iterator _itt_t;
|
||||
typedef map<const char*,FGColor*, ltstr>::const_iterator _citt_t;
|
||||
typedef std::map<const char*,FGColor*, ltstr> ColourDict;
|
||||
ColourDict _colors;
|
||||
typedef ColourDict::iterator _itt_t;
|
||||
typedef ColourDict::const_iterator _citt_t;
|
||||
|
||||
void clear_colors();
|
||||
|
||||
|
@ -311,8 +312,8 @@ private:
|
|||
// Path to the font directory
|
||||
SGPath _path;
|
||||
|
||||
typedef map<const string, fntTexFont*> TexFontMap;
|
||||
typedef map<const FntParams, fnt*, FntParamsLess> PuFontMap;
|
||||
typedef std::map<const std::string, fntTexFont*> TexFontMap;
|
||||
typedef std::map<const FntParams, fnt*, FntParamsLess> PuFontMap;
|
||||
TexFontMap _texFonts;
|
||||
PuFontMap _puFonts;
|
||||
|
||||
|
|
|
@ -31,8 +31,10 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
typedef string stdString; // puObject has a "string" member
|
||||
|
||||
|
@ -95,7 +97,7 @@ static void dumpProperties(const SGPropertyNode *node)
|
|||
case props::VEC3D:
|
||||
case props::VEC4D:
|
||||
{
|
||||
streamsize precision = cout.precision(15);
|
||||
std::streamsize precision = cout.precision(15);
|
||||
c->printOn(cout);
|
||||
cout.precision(precision);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
using simgear::PropertyList;
|
||||
using std::string;
|
||||
|
||||
void FGCommonInput::read_bindings (const SGPropertyNode * node, binding_list_t * binding_list, int modifiers, const string & module )
|
||||
{
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <Scripting/NasalSys.hxx>
|
||||
|
||||
using simgear::PropertyList;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
FGEventSetting::FGEventSetting( SGPropertyNode_ptr base ) :
|
||||
value(0.0)
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#define __FGEVENTINPUT_HXX
|
||||
|
||||
#include "FGCommonInput.hxx"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "FGButton.hxx"
|
||||
#include "FGDeviceConfigurationMap.hxx"
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
|
@ -57,7 +60,7 @@ protected:
|
|||
};
|
||||
|
||||
typedef SGSharedPtr<FGEventSetting> FGEventSetting_ptr;
|
||||
typedef vector<FGEventSetting_ptr> setting_list_t;
|
||||
typedef std::vector<FGEventSetting_ptr> setting_list_t;
|
||||
|
||||
/*
|
||||
* A wrapper class for a configured event.
|
||||
|
@ -99,12 +102,12 @@ public:
|
|||
/*
|
||||
* access for the name property
|
||||
*/
|
||||
string GetName() const { return name; }
|
||||
std::string GetName() const { return name; }
|
||||
|
||||
/*
|
||||
* access for the description property
|
||||
*/
|
||||
string GetDescription() const { return desc; }
|
||||
std::string GetDescription() const { return desc; }
|
||||
|
||||
virtual void update( double dt );
|
||||
|
||||
|
@ -113,10 +116,10 @@ public:
|
|||
protected:
|
||||
virtual void fire( SGBinding * binding, FGEventData & eventData );
|
||||
/* A more or less meaningfull description of the event */
|
||||
string desc;
|
||||
std::string desc;
|
||||
|
||||
/* One of the predefined names of the event */
|
||||
string name;
|
||||
std::string name;
|
||||
|
||||
/* A list of SGBinding objects */
|
||||
binding_list_t bindings[KEYMOD_MAX];
|
||||
|
@ -184,7 +187,7 @@ typedef class SGSharedPtr<FGInputEvent> FGInputEvent_ptr;
|
|||
class FGInputDevice : public SGReferenced {
|
||||
public:
|
||||
FGInputDevice() : debugEvents(false), grab(false) {}
|
||||
FGInputDevice( string aName ) : name(aName) {}
|
||||
FGInputDevice( std::string aName ) : name(aName) {}
|
||||
|
||||
virtual ~FGInputDevice();
|
||||
|
||||
|
@ -193,15 +196,15 @@ public:
|
|||
|
||||
virtual void Send( const char * eventName, double value ) = 0;
|
||||
|
||||
inline void Send( const string & eventName, double value ) {
|
||||
inline void Send( const std::string & eventName, double value ) {
|
||||
Send( eventName.c_str(), value );
|
||||
}
|
||||
|
||||
virtual const char * TranslateEventName( FGEventData & eventData ) = 0;
|
||||
|
||||
|
||||
void SetName( string name );
|
||||
string & GetName() { return name; }
|
||||
void SetName( std::string name );
|
||||
std::string & GetName() { return name; }
|
||||
|
||||
void HandleEvent( FGEventData & eventData );
|
||||
|
||||
|
@ -218,14 +221,14 @@ public:
|
|||
|
||||
bool GetGrab() const { return grab; }
|
||||
|
||||
const string & GetNasalModule() const { return nasalModule; }
|
||||
const std::string & GetNasalModule() const { return nasalModule; }
|
||||
|
||||
private:
|
||||
// A map of events, this device handles
|
||||
map<string,FGInputEvent_ptr> handledEvents;
|
||||
std::map<std::string,FGInputEvent_ptr> handledEvents;
|
||||
|
||||
// the device has a name to be recognized
|
||||
string name;
|
||||
std::string name;
|
||||
|
||||
// print out events comming in from the device
|
||||
// if true
|
||||
|
@ -236,7 +239,7 @@ private:
|
|||
bool grab;
|
||||
|
||||
SGPropertyNode_ptr deviceNode;
|
||||
string nasalModule;
|
||||
std::string nasalModule;
|
||||
};
|
||||
|
||||
typedef SGSharedPtr<FGInputDevice> FGInputDevice_ptr;
|
||||
|
@ -261,7 +264,7 @@ protected:
|
|||
unsigned AddDevice( FGInputDevice * inputDevice );
|
||||
void RemoveDevice( unsigned index );
|
||||
|
||||
map<int,FGInputDevice*> input_devices;
|
||||
std::map<int,FGInputDevice*> input_devices;
|
||||
FGDeviceConfigurationMap configMap;
|
||||
|
||||
SGPropertyNode_ptr nasalClose;
|
||||
|
|
|
@ -193,7 +193,7 @@ void FGJoystickInput::postinit()
|
|||
//
|
||||
// Initialize nasal groups.
|
||||
//
|
||||
ostringstream str;
|
||||
std::ostringstream str;
|
||||
str << "__js" << i;
|
||||
string module = str.str();
|
||||
nasalsys->createModule(module.c_str(), module.c_str(), "", 0);
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
|
||||
#include "FGMacOSXEventInput.hxx"
|
||||
|
||||
using std::stringstream;
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
#define GetHIDElementLongValue(element, key) ({ \
|
||||
long value = 0; \
|
||||
|
@ -612,7 +615,7 @@ void FGMacOSXInputDevice::Open() {
|
|||
|
||||
if (ret != kIOReturnSuccess) {
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Error creating a plugin for HID : " << GetName());
|
||||
throw exception();
|
||||
throw std::exception();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -626,14 +629,14 @@ void FGMacOSXInputDevice::Open() {
|
|||
(*plugin)->Release(plugin); // don't leak a ref
|
||||
if (devInterface == NULL) {
|
||||
return;
|
||||
throw exception();
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
// store the interface in this instance
|
||||
ret = (*devInterface)->open(devInterface, 0);
|
||||
if (ret != kIOReturnSuccess) {
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Error opening device interface: " << GetName());
|
||||
throw exception();
|
||||
throw std::exception();
|
||||
return;
|
||||
}
|
||||
CFDictionaryRef props = getProperties();
|
||||
|
|
|
@ -68,9 +68,9 @@ typedef enum {
|
|||
|
||||
class HIDElement;
|
||||
struct FGMacOSXEventData : public FGEventData {
|
||||
FGMacOSXEventData(string name, double value, double dt, int modifiers) :
|
||||
FGMacOSXEventData(std::string name, double value, double dt, int modifiers) :
|
||||
FGEventData(value, dt, modifiers), name(name) {}
|
||||
string name;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -92,7 +92,7 @@ public:
|
|||
HIDElement(CFDictionaryRef element, long page, long usage);
|
||||
virtual ~HIDElement() {}
|
||||
bool isUpdated();
|
||||
string getName() { return name; }
|
||||
std::string getName() { return name; }
|
||||
virtual void generateEvent(FGMacOSXInputDevice *device, double dt, int modifiers);
|
||||
virtual long read(IOHIDDeviceInterface **interface);
|
||||
virtual void write(IOHIDDeviceInterface **interface, double value) {
|
||||
|
@ -106,7 +106,7 @@ protected:
|
|||
float value;
|
||||
float lastValue;
|
||||
|
||||
string name;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class AxisElement : public HIDElement {
|
||||
|
@ -182,7 +182,7 @@ public:
|
|||
private:
|
||||
io_object_t device;
|
||||
IOHIDDeviceInterface **devInterface;
|
||||
map<string, HIDElement *> elements; // maps eventName and its relevant element for Send()
|
||||
std::map<std::string, HIDElement *> elements; // maps eventName and its relevant element for Send()
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -225,22 +225,22 @@ private:
|
|||
io_iterator_t removedIterator;
|
||||
|
||||
// maps FG device property ID (i.e. /input/events/device[ID]) with io_object for detaching devices
|
||||
map<io_object_t, unsigned> deviceIndices;
|
||||
std::map<io_object_t, unsigned> deviceIndices;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// For obtaining event name and type from both HID element page and usage
|
||||
//
|
||||
class HIDTypeByID : public map<long, pair<HIDUsageType, const char *>*> {
|
||||
class HIDTypeByID : public std::map<long, std::pair<HIDUsageType, const char *>*> {
|
||||
public:
|
||||
HIDTypeByID(struct HIDTypes *table) {
|
||||
for( int i = 0; table[i].key!= -1; i++ )
|
||||
(*this)[table[i].key] = new pair<HIDUsageType, const char *>(table[i].type, table[i].eventName);
|
||||
(*this)[table[i].key] = new std::pair<HIDUsageType, const char *>(table[i].type, table[i].eventName);
|
||||
}
|
||||
|
||||
~HIDTypeByID() {
|
||||
map<long, pair<HIDUsageType, const char *>*>::iterator it;
|
||||
std::map<long, std::pair<HIDUsageType, const char *>*>::iterator it;
|
||||
for (it = this->begin(); it != this->end(); it++) {
|
||||
delete (*it).second;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ public:
|
|||
|
||||
// key = (HID_element_page) << 16 | HID_element_usage)
|
||||
const char *getName(long key) {
|
||||
pair<HIDUsageType, const char *> *usageType = (*this)[key];
|
||||
std::pair<HIDUsageType, const char *> *usageType = (*this)[key];
|
||||
if (usageType == NULL) {
|
||||
return "";
|
||||
} else {
|
||||
|
@ -258,7 +258,7 @@ public:
|
|||
}
|
||||
|
||||
const HIDUsageType getType(long key) {
|
||||
pair<HIDUsageType, const char *> *usageType = (*this)[key];
|
||||
std::pair<HIDUsageType, const char *> *usageType = (*this)[key];
|
||||
if (usageType == NULL) {
|
||||
return kHIDUsageNotSupported;
|
||||
} else {
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include "FGMouseInput.hxx"
|
||||
#include "Main/globals.hxx"
|
||||
|
||||
using std::ios_base;
|
||||
|
||||
void ActivePickCallbacks::init( int b, const osgGA::GUIEventAdapter* ea )
|
||||
{
|
||||
// Get the list of hit callbacks. Take the first callback that
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
|
||||
#include "HUD.hxx"
|
||||
|
||||
using std::endl;
|
||||
using std::ifstream;
|
||||
|
||||
static float clamp(float f)
|
||||
{
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include <Airports/simple.hxx>
|
||||
|
||||
using std::cout;
|
||||
using std::string;
|
||||
|
||||
// Command callbacks for FlightGear
|
||||
|
||||
|
|
|
@ -68,10 +68,10 @@ const char* KLN89TimeCodes[20] = { "UTC", "GST", "GDT", "ATS", "ATD", "EST", "ED
|
|||
*/
|
||||
|
||||
// Used for storing airport town and county mapped by ID, since currently FG does not store this
|
||||
typedef map<string, string> airport_id_str_map_type;
|
||||
typedef std::map<std::string, std::string> airport_id_str_map_type;
|
||||
typedef airport_id_str_map_type::iterator airport_id_str_map_iterator;
|
||||
|
||||
typedef vector<KLN89Page*> kln89_page_list_type;
|
||||
typedef std::vector<KLN89Page*> kln89_page_list_type;
|
||||
typedef kln89_page_list_type::iterator kln89_page_list_itr;
|
||||
|
||||
class KLN89 : public DCLGPS {
|
||||
|
@ -150,14 +150,14 @@ private:
|
|||
void ToggleOBSMode();
|
||||
|
||||
// Initiate Direct To operation to the supplied ID.
|
||||
void DtoInitiate(const string& id);
|
||||
void DtoInitiate(const std::string& id);
|
||||
|
||||
//----------------------- Drawing functions which take CHARACTER units -------------------------
|
||||
// Render string s in display field field at position x, y
|
||||
// WHERE POSITION IS IN CHARACTER UNITS!
|
||||
// zero y at bottom?
|
||||
// invert: -1 => no inversion, 0 -> n => 1 char - s[invert] gets inverted, 99 => entire string gets inverted
|
||||
void DrawText(const string& s, int field, int px, int py, bool bold = false, int invert = -1);
|
||||
void DrawText(const std::string& s, int field, int px, int py, bool bold = false, int invert = -1);
|
||||
|
||||
void DrawLatitude(double d, int field, int px, int py);
|
||||
void DrawLongitude(double d, int field, int px, int py);
|
||||
|
@ -307,7 +307,7 @@ private:
|
|||
// Draw an airport or waypoint label on the moving map
|
||||
// Specify position by the map pixel co-ordinate of the left or right, bottom, of the *visible* portion of the label.
|
||||
// The black background quad will automatically overlap this by 1 pixel.
|
||||
void DrawLabel(const string& s, int x1, int y1, bool right_align = false);
|
||||
void DrawLabel(const std::string& s, int x1, int y1, bool right_align = false);
|
||||
|
||||
int GetLabelQuadrant(double h);
|
||||
int GetLabelQuadrant(double h1, double h2);
|
||||
|
@ -316,7 +316,7 @@ private:
|
|||
void DrawLine(int x1, int y1, int x2, int y2);
|
||||
|
||||
// Draw normal sized text on the moving map
|
||||
void DrawMapText(const string& s, int x, int y, bool draw_background = false);
|
||||
void DrawMapText(const std::string& s, int x, int y, bool draw_background = false);
|
||||
|
||||
void DrawMapUpArrow(int x, int y);
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "kln89_page.hxx"
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89Page::KLN89Page(KLN89* parent) {
|
||||
_kln89 = parent;
|
||||
_entInvert = false;
|
||||
|
|
|
@ -65,21 +65,21 @@ public:
|
|||
inline void SetEntInvert(bool b) { _entInvert = b; }
|
||||
|
||||
// Get / Set a waypoint id, NOT the page name!
|
||||
virtual void SetId(const string& s);
|
||||
virtual const string& GetId();
|
||||
virtual void SetId(const std::string& s);
|
||||
virtual const std::string& GetId();
|
||||
|
||||
inline int GetSubPage() { return(_subPage); }
|
||||
void SetSubPage(int n);
|
||||
|
||||
inline int GetNSubPages() { return(_nSubPages); }
|
||||
|
||||
inline const string& GetName() { return(_name); }
|
||||
inline const std::string& GetName() { return(_name); }
|
||||
|
||||
protected:
|
||||
|
||||
KLN89* _kln89;
|
||||
|
||||
string _name; // eg. "APT", "NAV" etc
|
||||
std::string _name; // eg. "APT", "NAV" etc
|
||||
int _nSubPages;
|
||||
// _subpage is zero based
|
||||
int _subPage; // The subpage gets remembered when other pages are displayed
|
||||
|
@ -97,18 +97,18 @@ protected:
|
|||
// Invert ID and display ENT in field 1
|
||||
bool _entInvert;
|
||||
|
||||
string _id; // The ID of the waypoint that the page is displaying.
|
||||
std::string _id; // The ID of the waypoint that the page is displaying.
|
||||
// Doesn't make sense for all pages, but does for all the data pages.
|
||||
|
||||
void ShowScratchpadMessage(const string& line1, const string& line2);
|
||||
void ShowScratchpadMessage(const std::string& line1, const std::string& line2);
|
||||
|
||||
bool _scratchpadMsg; // Set true when there is a scratchpad message to display
|
||||
double _scratchpadTimer; // Used for displaying the scratchpad messages for the right amount of time.
|
||||
string _scratchpadLine1;
|
||||
string _scratchpadLine2;
|
||||
std::string _scratchpadLine1;
|
||||
std::string _scratchpadLine2;
|
||||
|
||||
// TODO - remove this function from this class and use a built in method instead.
|
||||
string GPSitoa(int n);
|
||||
std::string GPSitoa(int n);
|
||||
};
|
||||
|
||||
#endif // _KLN89_PAGE_HXX
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include "kln89_page_alt.hxx"
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89AltPage::KLN89AltPage(KLN89* parent)
|
||||
: KLN89Page(parent) {
|
||||
_nSubPages = 2;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
class FGRunway;
|
||||
|
||||
struct AptFreq {
|
||||
string service;
|
||||
std::string service;
|
||||
unsigned short int freq;
|
||||
};
|
||||
|
||||
|
@ -49,15 +49,15 @@ public:
|
|||
void Knob2Left1();
|
||||
void Knob2Right1();
|
||||
|
||||
void SetId(const string& s);
|
||||
void SetId(const std::string& s);
|
||||
|
||||
private:
|
||||
// Update the cached airport details
|
||||
void UpdateAirport(const string& id);
|
||||
void UpdateAirport(const std::string& id);
|
||||
|
||||
string _apt_id;
|
||||
string _last_apt_id;
|
||||
string _save_apt_id;
|
||||
std::string _apt_id;
|
||||
std::string _last_apt_id;
|
||||
std::string _save_apt_id;
|
||||
const FGAirport* ap;
|
||||
|
||||
vector<FGRunway*> _aptRwys;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include <Main/fg_props.hxx>
|
||||
#include "kln89_page_cal.hxx"
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89CalPage::KLN89CalPage(KLN89* parent)
|
||||
: KLN89Page(parent) {
|
||||
_nSubPages = 8;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "kln89_page_dir.hxx"
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89DirPage::KLN89DirPage(KLN89* parent)
|
||||
: KLN89Page(parent) {
|
||||
_nSubPages = 1;
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
void Update(double dt);
|
||||
|
||||
void SetId(const string& s);
|
||||
void SetId(const std::string& s);
|
||||
|
||||
void CrsrPressed();
|
||||
void ClrPressed();
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
// Override the base class GetId function to return the waypoint ID under the cursor
|
||||
// on FPL0 page, if there is one and the cursor is on.
|
||||
// Otherwise return an empty string.
|
||||
inline const string& GetId() { return(_fp0SelWpId); }
|
||||
inline const std::string& GetId() { return(_fp0SelWpId); }
|
||||
|
||||
private:
|
||||
int _fpMode; // 0 = Dis, 1 = Dtk
|
||||
|
@ -56,7 +56,7 @@ private:
|
|||
|
||||
bool _bEntWp; // set true when a waypoint is being entered
|
||||
bool _bEntExp; // Set true when ent is expected to set the currently entered waypoint as entered.
|
||||
string _entWpStr; // The currently entered wp ID (need not be valid)
|
||||
std::string _entWpStr; // The currently entered wp ID (need not be valid)
|
||||
GPSWaypoint* _entWp; // Waypoint being currently entered
|
||||
|
||||
// The position of the cursor in a waypoint being entered
|
||||
|
@ -83,9 +83,9 @@ private:
|
|||
void Calc();
|
||||
|
||||
// The ID of the waypoint under the cursor in fpl0, if those conditions exist!
|
||||
string _fp0SelWpId;
|
||||
std::string _fp0SelWpId;
|
||||
|
||||
vector<string> _params;
|
||||
std::vector<std::string> _params;
|
||||
};
|
||||
|
||||
#endif // _KLN89_PAGE_FPL_HXX
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include <Navaids/fix.hxx>
|
||||
#include <Navaids/navrecord.hxx>
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89IntPage::KLN89IntPage(KLN89* parent)
|
||||
: KLN89Page(parent) {
|
||||
_nSubPages = 2;
|
||||
|
|
|
@ -42,12 +42,12 @@ public:
|
|||
void Knob2Left1();
|
||||
void Knob2Right1();
|
||||
|
||||
void SetId(const string& s);
|
||||
void SetId(const std::string& s);
|
||||
|
||||
private:
|
||||
string _int_id;
|
||||
string _last_int_id;
|
||||
string _save_int_id;
|
||||
std::string _int_id;
|
||||
std::string _last_int_id;
|
||||
std::string _save_int_id;
|
||||
const FGFix* _fp;
|
||||
FGNavRecord* _nearestVor;
|
||||
FGNavRecord* _refNav; // Will usually be the same as _nearestVor, and gets reset to _nearestVor when page looses focus.
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "kln89_page_nav.hxx"
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89NavPage::KLN89NavPage(KLN89* parent)
|
||||
: KLN89Page(parent) {
|
||||
_nSubPages = 4;
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
void LooseFocus();
|
||||
|
||||
// Returns the id string of the selected waypoint on NAV4 if valid, else returns an empty string.
|
||||
string GetNav4WpId();
|
||||
std::string GetNav4WpId();
|
||||
|
||||
private:
|
||||
int _posFormat; // 0 => lat,lon; 1 => ref to wp.
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "kln89_page_ndb.hxx"
|
||||
#include <Navaids/navrecord.hxx>
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89NDBPage::KLN89NDBPage(KLN89* parent)
|
||||
: KLN89Page(parent) {
|
||||
_nSubPages = 2;
|
||||
|
|
|
@ -40,12 +40,12 @@ public:
|
|||
void Knob2Left1();
|
||||
void Knob2Right1();
|
||||
|
||||
void SetId(const string& s);
|
||||
void SetId(const std::string& s);
|
||||
|
||||
private:
|
||||
string _ndb_id;
|
||||
string _last_ndb_id;
|
||||
string _save_ndb_id;
|
||||
std::string _ndb_id;
|
||||
std::string _last_ndb_id;
|
||||
std::string _save_ndb_id;
|
||||
FGNavRecord* np;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include "kln89_page_oth.hxx"
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89OthPage::KLN89OthPage(KLN89* parent)
|
||||
: KLN89Page(parent) {
|
||||
_nSubPages = 12;
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "kln89_page_vor.hxx"
|
||||
#include <Navaids/navrecord.hxx>
|
||||
|
||||
using std::string;
|
||||
|
||||
KLN89VorPage::KLN89VorPage(KLN89* parent)
|
||||
: KLN89Page(parent) {
|
||||
_nSubPages = 2;
|
||||
|
|
|
@ -40,12 +40,12 @@ public:
|
|||
void Knob2Left1();
|
||||
void Knob2Right1();
|
||||
|
||||
void SetId(const string& s);
|
||||
void SetId(const std::string& s);
|
||||
|
||||
private:
|
||||
string _vor_id;
|
||||
string _last_vor_id;
|
||||
string _save_vor_id;
|
||||
std::string _vor_id;
|
||||
std::string _last_vor_id;
|
||||
std::string _save_vor_id;
|
||||
FGNavRecord* np;
|
||||
};
|
||||
|
||||
|
|
|
@ -150,10 +150,18 @@ static osg::Vec2 mult(const osg::Vec2& v, const osg::Matrixf& m)
|
|||
class SymbolDef
|
||||
{
|
||||
public:
|
||||
SymbolDef() :
|
||||
enable(NULL)
|
||||
{}
|
||||
|
||||
bool initFromNode(SGPropertyNode* node)
|
||||
{
|
||||
type = node->getStringValue("type");
|
||||
enable = sgReadCondition(fgGetNode("/"), node->getChild("enable"));
|
||||
SGPropertyNode* enableNode = node->getChild("enable");
|
||||
if (enableNode) {
|
||||
enable = sgReadCondition(fgGetNode("/"), enableNode);
|
||||
}
|
||||
|
||||
int n=0;
|
||||
while (node->hasChild("state", n)) {
|
||||
string m = node->getChild("state", n++)->getStringValue();
|
||||
|
@ -164,10 +172,19 @@ public:
|
|||
}
|
||||
} // of matches parsing
|
||||
|
||||
xy0.x() = node->getFloatValue("x0", -5);
|
||||
xy0.y() = node->getFloatValue("y0", -5);
|
||||
if (node->hasChild("width")) {
|
||||
float w = node->getFloatValue("width");
|
||||
float h = node->getFloatValue("height", w);
|
||||
xy0.x() = -w * 0.5;
|
||||
xy0.y() = -h * 0.5;
|
||||
xy1.x() = w * 0.5;
|
||||
xy1.y() = h * 0.5;
|
||||
} else {
|
||||
xy0.x() = node->getFloatValue("x0", 0.0);
|
||||
xy0.y() = node->getFloatValue("y0", 0.0);
|
||||
xy1.x() = node->getFloatValue("x1", 5);
|
||||
xy1.y() = node->getFloatValue("y1", 5);
|
||||
}
|
||||
|
||||
double texSize = node->getFloatValue("texture-size", 1.0);
|
||||
|
||||
|
@ -193,7 +210,7 @@ public:
|
|||
|
||||
drawLine = node->getBoolValue("draw-line", false);
|
||||
lineColor = readColor(node->getChild("line-color"), color);
|
||||
drawRouteLeg = node->getBoolValue("draw-line", false);
|
||||
drawRouteLeg = node->getBoolValue("draw-leg", false);
|
||||
|
||||
stretchSymbol = node->getBoolValue("stretch-symbol", false);
|
||||
if (stretchSymbol) {
|
||||
|
@ -242,21 +259,19 @@ public:
|
|||
|
||||
bool matches(const string_set& states) const
|
||||
{
|
||||
string_set::const_iterator it = states.begin(),
|
||||
end = states.end();
|
||||
for (; it != end; ++it) {
|
||||
if (required_states.count(*it) == 0) {
|
||||
// required state not matched
|
||||
BOOST_FOREACH(const string& s, required_states) {
|
||||
if (states.count(s) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (excluded_states.count(*it) > 0) {
|
||||
// excluded state matched
|
||||
BOOST_FOREACH(const string& s, excluded_states) {
|
||||
if (states.count(s) != 0) {
|
||||
return false;
|
||||
}
|
||||
} // of applicable states iteration
|
||||
}
|
||||
|
||||
return true; // matches!
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -280,12 +295,10 @@ public:
|
|||
{
|
||||
assert(definition->hasText);
|
||||
string r;
|
||||
size_t lastPos = 0;
|
||||
|
||||
size_t pos = 0;
|
||||
int lastPos = 0;
|
||||
|
||||
for (; pos < definition->textTemplate.size();) {
|
||||
pos = definition->textTemplate.find('{', pos);
|
||||
while (true) {
|
||||
size_t pos = definition->textTemplate.find('{', lastPos);
|
||||
if (pos == string::npos) { // no more replacements
|
||||
r.append(definition->textTemplate.substr(lastPos));
|
||||
break;
|
||||
|
@ -378,6 +391,9 @@ NavDisplay::init ()
|
|||
string path = _Instrument->getStringValue("symbol-texture-path",
|
||||
"Aircraft/Instruments/Textures/nd-symbols.png");
|
||||
SGPath tpath = globals->resolve_aircraft_path(path);
|
||||
if (!tpath.exists()) {
|
||||
SG_LOG(SG_INSTR, SG_WARN, "ND symbol texture not found:" << path);
|
||||
}
|
||||
|
||||
// no mipmap or else alpha will mix with pixels on the border of shapes, ruining the effect
|
||||
_symbolTexture = SGLoadTexture2D(tpath, NULL, false, false);
|
||||
|
@ -396,6 +412,9 @@ NavDisplay::init ()
|
|||
_navRadio1Node = fgGetNode("/instrumentation/nav[0]", true);
|
||||
_navRadio2Node = fgGetNode("/instrumentation/nav[1]", true);
|
||||
|
||||
_excessDataNode = _Instrument->getChild("excess-data", 0, true);
|
||||
_excessDataNode->setBoolValue(false);
|
||||
|
||||
// OSG geometry setup
|
||||
_radarGeode = new osg::Geode;
|
||||
|
||||
|
@ -416,6 +435,7 @@ NavDisplay::init ()
|
|||
_geom->setTexCoordArray(0, _texCoords);
|
||||
|
||||
_quadColors = new osg::Vec4Array;
|
||||
_quadColors->setDataVariance(osg::Object::DYNAMIC);
|
||||
_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
_geom->setColorArray(_quadColors);
|
||||
|
||||
|
@ -425,6 +445,7 @@ NavDisplay::init ()
|
|||
|
||||
_geom->setInitialBound(osg::BoundingBox(osg::Vec3f(-256.0f, -256.0f, 0.0f),
|
||||
osg::Vec3f(256.0f, 256.0f, 0.0f)));
|
||||
|
||||
_radarGeode->addDrawable(_geom);
|
||||
_odg->allocRT();
|
||||
// Texture in the 2D panel system
|
||||
|
@ -513,11 +534,16 @@ NavDisplay::update (double delta_time_sec)
|
|||
_vertices->clear();
|
||||
_lineVertices->clear();
|
||||
_lineColors->clear();
|
||||
_quadColors->clear();
|
||||
_texCoords->clear();
|
||||
_textGeode->removeDrawables(0, _textGeode->getNumDrawables());
|
||||
|
||||
BOOST_FOREACH(SymbolDef* def, _rules) {
|
||||
if (def->enable) {
|
||||
def->enabled = def->enable->test();
|
||||
} else {
|
||||
def->enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
processRoute();
|
||||
|
@ -674,7 +700,7 @@ public:
|
|||
|
||||
void NavDisplay::limitDisplayedSymbols()
|
||||
{
|
||||
unsigned int maxSymbols = _Instrument->getIntValue("max-symbols");
|
||||
unsigned int maxSymbols = _Instrument->getIntValue("max-symbols", 100);
|
||||
if (_symbols.size() <= maxSymbols) {
|
||||
_excessDataNode->setBoolValue(false);
|
||||
return;
|
||||
|
@ -728,6 +754,8 @@ osg::Vec2 NavDisplay::projectGeod(const SGGeod& geod) const
|
|||
class Filter : public FGPositioned::Filter
|
||||
{
|
||||
public:
|
||||
double minRunwayLengthFt;
|
||||
|
||||
virtual bool pass(FGPositioned* aPos) const
|
||||
{
|
||||
if (aPos->type() == FGPositioned::FIX) {
|
||||
|
@ -738,6 +766,13 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (aPos->type() == FGPositioned::AIRPORT) {
|
||||
FGAirport* apt = (FGAirport*) aPos;
|
||||
if (!apt->hasHardRunwayOfLengthFt(minRunwayLengthFt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -753,6 +788,8 @@ public:
|
|||
void NavDisplay::findItems()
|
||||
{
|
||||
Filter filt;
|
||||
filt.minRunwayLengthFt = 2000;
|
||||
|
||||
FGPositioned::List items =
|
||||
FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
|
||||
|
||||
|
@ -792,7 +829,7 @@ void NavDisplay::processRoute()
|
|||
}
|
||||
|
||||
SymbolDefVector rules;
|
||||
findRules(wpt->type() , state, rules);
|
||||
findRules("waypoint" , state, rules);
|
||||
if (rules.empty()) {
|
||||
return; // no rules matched, we can skip this item
|
||||
}
|
||||
|
@ -886,7 +923,7 @@ bool NavDisplay::anyRuleMatches(const string& type, const string_set& states) co
|
|||
void NavDisplay::findRules(const string& type, const string_set& states, SymbolDefVector& rules)
|
||||
{
|
||||
BOOST_FOREACH(SymbolDef* candidate, _rules) {
|
||||
if (!candidate->enabled) {
|
||||
if (!candidate->enabled || (candidate->type != type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -935,7 +972,8 @@ void NavDisplay::computePositionedPropsAndHeading(FGPositioned* pos, SGPropertyN
|
|||
|
||||
switch (pos->type()) {
|
||||
case FGPositioned::VOR:
|
||||
case FGPositioned::LOC: {
|
||||
case FGPositioned::LOC:
|
||||
case FGPositioned::TACAN: {
|
||||
FGNavRecord* nav = static_cast<FGNavRecord*>(pos);
|
||||
nd->setDoubleValue("frequency-mhz", nav->get_freq());
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ public:
|
|||
virtual void update(double dt);
|
||||
|
||||
protected:
|
||||
string _name;
|
||||
std::string _name;
|
||||
int _num;
|
||||
double _time;
|
||||
double _updateInterval;
|
||||
|
@ -110,7 +110,7 @@ private:
|
|||
|
||||
void updateFont();
|
||||
|
||||
string _texture_path;
|
||||
std::string _texture_path;
|
||||
|
||||
|
||||
float _scale; // factor to convert nm to display units
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue