1
0
Fork 0

Merge branch 'next' into comm-subsystem

This commit is contained in:
adrian 2011-10-29 12:22:00 +03:00
commit c6062ad93c
191 changed files with 3293 additions and 1681 deletions

View file

@ -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
View 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.

View file

@ -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>

View file

@ -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"

View file

@ -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,12 +546,16 @@ void FGAIAircraft::getGroundElev(double dt) {
void FGAIAircraft::doGroundAltitude() {
if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
(isStationary()))
altitude_ft = (tgt_altitude_ft + groundOffset);
else
altitude_ft += 0.1 * ((tgt_altitude_ft+groundOffset) - altitude_ft);
tgt_vs = 0;
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);
else
altitude_ft += 0.1 * ((tgt_altitude_ft+groundOffset) - altitude_ft);
tgt_vs = 0;
}
}
@ -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);

View file

@ -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);
};

View file

@ -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);

View file

@ -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;

View file

@ -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:

View file

@ -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

View file

@ -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;

View file

@ -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()
{
@ -545,4 +564,12 @@ double FGAIFlightPlan::checkTrackLength(string wptName) {
trackDistance = 0; // name not found
}
return trackDistance;
}
}
void FGAIFlightPlan::shortenToFirst(unsigned int number, string name)
{
while (waypoints.size() > number + 3) {
eraseLastWaypoint();
}
(waypoints.back())->setName((waypoints.back())->getName() + name);
}

View file

@ -164,6 +164,8 @@ public:
FGAIFlightPlan* getSID() { return sid; };
FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
void shortenToFirst(unsigned int number, std::string name);
private:
FGAIFlightPlan *sid;
@ -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);

View file

@ -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();
double currElev = 0;
char buffer[12];
FGRunway * rwy = apt->getRunwayByIdent(activeRunway);
assert( rwy != NULL );
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;
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);
/*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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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
);

View file

@ -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);
//###########################//

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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; };

View file

@ -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 {

View file

@ -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,22 +912,29 @@ 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) {
current->setHoldPosition(false);
}
} else {
if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
rwy->setCleared(id);
}
}
int clearanceId = rwy->getCleared();
if (clearanceId) {
if (id == clearanceId) {
current->setHoldPosition(false);
}
} else {
if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
rwy->setCleared(id);
FGAIAircraft *ac = rwy->getFirstOfStatus(1);
if (ac)
ac->setTakeOffStatus(2);
}
}
}
}
void FGTowerController::signOff(int id)
@ -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();
}

View file

@ -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;

View file

@ -41,6 +41,8 @@
#include <sstream>
using std::ostringstream;
using std::cerr;
using std::endl;
FGATCDialog *current_atcdialog;

View file

@ -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;

View file

@ -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"
@ -235,43 +234,52 @@ FGReplay::update( double dt )
if ( disable_replay->getBoolValue() )
{
current_replay_state = replay_master->getIntValue();
replay_master->setIntValue(0);
replay_time->setDoubleValue(0);
replay_time_str->setStringValue("");
disable_replay->setBoolValue(0);
speed_up->setDoubleValue(1.0);
fgSetString("/sim/messages/copilot", "Replay stopped");
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);
replay_time->setDoubleValue(0);
replay_time_str->setStringValue("");
disable_replay->setBoolValue(0);
speed_up->setDoubleValue(1.0);
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");

View file

@ -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;

View file

@ -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();
}

View file

@ -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; }

View file

@ -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);
activeTraffic.push_front(rec);
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.
current->setHoldPosition(true);
current->setWaitsForId(i->getId());
}
//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;
}
} else {
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);
break;
}
}
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);
}
}
}

View file

@ -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; };
};

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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 );

View file

@ -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());
if (config.isNull())
{
SG_LOG( SG_ALL, SG_ALERT, "Cannot find property-rule configuration file '" << pathNode->getStringValue() << "'." );
}
else
{
SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
addAutopilotFromFile( apName, autopilotNode, pathNode->getStringValue() );
}
}
try {
SGPropertyNode_ptr root = new SGPropertyNode();
readProperties( config.str(), root );
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 '" << path << "'." );
return;
}
SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
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 );
try {
SGPropertyNode_ptr configNode = new SGPropertyNode();
readProperties( config.str(), configNode );
} catch (const sg_exception& e) {
SG_LOG( SG_AUTOPILOT, SG_ALERT, "Failed to load property-rule configuration: "
<< config.str() << ":" << e.getMessage() );
continue;
}
}
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() );
return;
}
}

View file

@ -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() {}

View file

@ -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;
}

View file

@ -24,6 +24,7 @@
#include "digitalcomponent.hxx"
#include <Main/fg_props.hxx>
using std::string;
using namespace FGXMLAutopilot;
DigitalComponent::DigitalComponent() :

View file

@ -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

View file

@ -25,6 +25,11 @@
#include "functor.hxx"
#include <deque>
using std::map;
using std::string;
using std::endl;
using std::cout;
namespace FGXMLAutopilot {
/* --------------------------------------------------------------------------------- */

View file

@ -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 {
/**

View file

@ -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();

View file

@ -25,6 +25,9 @@
using namespace FGXMLAutopilot;
using std::endl;
using std::cout;
PIDController::PIDController():
AnalogComponent(),
alpha( 0.1 ),

View file

@ -25,6 +25,9 @@
using namespace FGXMLAutopilot;
using std::endl;
using std::cout;
PISimpleController::PISimpleController() :
AnalogComponent(),
_int_sum( 0.0 )

View file

@ -25,6 +25,9 @@
using namespace FGXMLAutopilot;
using std::endl;
using std::cout;
Predictor::Predictor () :
AnalogComponent(),
_average(0.0)

View file

@ -71,6 +71,8 @@
// my hardware/driver requires many more.
#define POFF_UNITS 8
using std::map;
////////////////////////////////////////////////////////////////////////
// Local functions.
////////////////////////////////////////////////////////////////////////

View file

@ -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++) {

View file

@ -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;

View file

@ -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; }

View file

@ -24,6 +24,7 @@
#endif
#include "presets.hxx"
#include <cmath>
#include <simgear/math/SGMisc.hxx>
#include <Main/fg_props.hxx>

View file

@ -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();
}

View file

@ -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;

View file

@ -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>

View file

@ -284,16 +284,20 @@ void Gear::calcForce(RigidBody* body, State *s, float* v, float* rot)
// Don't bother if it's not down
if(_extension < 1)
return;
{
_wow = 0;
_frac = 0;
return;
}
// Dont bother if we are in the "wrong" ground
if (!((_onWater&&!_ground_isSolid)||(_onSolid&&_ground_isSolid))) {
_wow = 0;
_frac = 0;
_wow = 0;
_frac = 0;
_compressDist = 0;
_rollSpeed = 0;
_casterAngle = 0;
return;
return;
}
// The ground plane transformed to the local frame.

View file

@ -7,6 +7,9 @@
#include "Hitch.hpp"
using std::vector;
namespace yasim {
Hitch::Hitch(const char *name)
{

View file

@ -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
}

View file

@ -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;
}
@ -311,7 +312,7 @@ void YASim::copyToYASim(bool copyState)
Math::set3(v, s.v);
if(copyState || needCopy)
model->setState(&s);
model->setState(&s);
// wind
Math::tmul33(xyz2ned, wind, wind);
@ -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);
}

View file

@ -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);

View file

@ -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())
_impl->update(dt);
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;
}

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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 ()
void helpCb()
{
string command;
SGPath path( globals->get_fg_root() );
path.append( "Docs/index.html" );
openBrowser( "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)

View file

@ -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 }
};

View file

@ -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

View file

@ -32,9 +32,9 @@
extern puFont FONT_HELVETICA_14;
extern puFont FONT_SANS_12B;
using std::map;
using std::string;
////////////////////////////////////////////////////////////////////////
// Implementation of NewGUI.
////////////////////////////////////////////////////////////////////////

View file

@ -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;

View file

@ -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);
}

View file

@ -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 )
{

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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();

View file

@ -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 {

View file

@ -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

View file

@ -40,6 +40,8 @@
#include "HUD.hxx"
using std::endl;
using std::ifstream;
static float clamp(float f)
{

View file

@ -52,6 +52,7 @@
#include <Airports/simple.hxx>
using std::cout;
using std::string;
// Command callbacks for FlightGear

View file

@ -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);

View file

@ -24,6 +24,8 @@
#include "kln89_page.hxx"
#include <Main/fg_props.hxx>
using std::string;
KLN89Page::KLN89Page(KLN89* parent) {
_kln89 = parent;
_entInvert = false;

View file

@ -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

View file

@ -25,6 +25,8 @@
#include "kln89_page_alt.hxx"
using std::string;
KLN89AltPage::KLN89AltPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 2;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -34,7 +34,7 @@ public:
void Update(double dt);
void SetId(const string& s);
void SetId(const std::string& s);
void CrsrPressed();
void ClrPressed();

View file

@ -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

View file

@ -29,6 +29,8 @@
#include <Navaids/fix.hxx>
#include <Navaids/navrecord.hxx>
using std::string;
KLN89IntPage::KLN89IntPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 2;

View file

@ -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.

View file

@ -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;

View file

@ -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.

View file

@ -28,6 +28,8 @@
#include "kln89_page_ndb.hxx"
#include <Navaids/navrecord.hxx>
using std::string;
KLN89NDBPage::KLN89NDBPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 2;

View file

@ -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;
};

View file

@ -27,6 +27,8 @@
#include "kln89_page_oth.hxx"
using std::string;
KLN89OthPage::KLN89OthPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 12;

View file

@ -28,6 +28,8 @@
#include "kln89_page_vor.hxx"
#include <Navaids/navrecord.hxx>
using std::string;
KLN89VorPage::KLN89VorPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 2;

View file

@ -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;
};

View file

@ -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,11 +172,20 @@ 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);
uv0.x() = node->getFloatValue("u0", 0) / texSize;
@ -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;
}
};
@ -279,14 +294,12 @@ public:
string text() const
{
assert(definition->hasText);
string r;
string r;
size_t lastPos = 0;
size_t pos = 0;
int lastPos = 0;
for (; pos < definition->textTemplate.size();) {
pos = definition->textTemplate.find('{', pos);
if (pos == string::npos) { // no more replacements
while (true) {
size_t pos = definition->textTemplate.find('{', lastPos);
if (pos == string::npos) { // no more replacements
r.append(definition->textTemplate.substr(lastPos));
break;
}
@ -301,7 +314,7 @@ public:
string spec = definition->textTemplate.substr(pos + 1, endReplacement - (pos + 1));
// look for formatter in spec
size_t colonPos = spec.find(':');
if (colonPos == string::npos) {
if (colonPos == string::npos) {
// simple replacement
r.append(props->getStringValue(spec));
} else {
@ -378,7 +391,10 @@ 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
@ -506,18 +527,23 @@ NavDisplay::update (double delta_time_sec)
_projectMat = osg::Matrixf::scale(_scale, _scale, 1.0) *
degRotation(-_view_heading) * _centerTrans;
_pos = SGGeod::fromDegFt(_user_lon_node->getDoubleValue(),
_user_lat_node->getDoubleValue(),
_user_alt_node->getDoubleValue());
_pos = SGGeod::fromDegFt(_user_lon_node->getDoubleValue(),
_user_lat_node->getDoubleValue(),
_user_alt_node->getDoubleValue());
_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();
@ -594,7 +620,7 @@ void NavDisplay::addSymbolToScene(SymbolInstance* sym)
_texCoords->push_back(osg::Vec2(def->uv1.x(), def->uv0.y()));
_texCoords->push_back(def->uv1);
_texCoords->push_back(osg::Vec2(def->uv0.x(), def->uv1.y()));
for (int i=0; i<4; ++i) {
_vertices->push_back(verts[i] + pos);
_quadColors->push_back(def->color);
@ -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());

View file

@ -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