Carrier improvements
- Calculate lineup deviation (degrees left/right)
- Position for touchdown added (for more accurate lineup and glideslope deviation checks)
- LSO position and Tower position added (for views)
- Better logic for controlling the FLOLS
- Added ability to start on a specific course (works better
with the launcher if the carrier starts on a recovery course
when positioning in air for recovery (approach)
- Support for normal, tower, LSO views (via controls/view-index)
- Aircraft can define offset for FLOLS in sim/model/reference-offset-{xyz}
Added the ability to find the nearest carrier to use as a tower
Rework of the tower position so that it updates frequently to support moving towers.
TODO: Need to review how to better implement/integrate 'sub-views' i.e. ai/models/carrier[]/controls/view-index which is actually a sub index for the tower view.
Moved interpolation code into new method
FGAIMultiplayer::FGAIMultiplayerInterpolate().
FGAIMultiplayer::update():
If simple-time is enabled, always use getMPProtocolClockSec() (or
/sim/replay/time if replaying) as current time, so that multiple instances
of Flightgear all using simple-time will all show user and MP aircraft
in the same relative positions.
When interpolating, don't special-case single iterator, instead pass the
single iterator as both args to FGAIMultiplayerInterpolate().
Fixed removal of outdated frames using mMotionInfo.erase() - previously
this was not done if we had done extrapolation, and with interpolation we
left one too many frames in place.
FGAIMultiplayer::addMotionInfo():
If simple-time is enabled, apply compensation to MP aircraft's .time fields
if incoming packets' .time field differs significantly from our local UTC
time.
This allows simple-time to work with non-simple-time MP aircraft, or with
simple-time MP aircraft whose UTC clocks differ from local UTC clock. But
without the guarantee of consistent rendering across Flightgear instances.
We don't calculate lag when compensating in this way.
With these changes, scripts/python/recordreplay.py --test-motion-mp passes (the
test sets /sim/replay/simple-time").
test_motion() now sets /sim/time/simple-time/enabled=true.
Also show any description items - these are generate by related changes to
src/AIModel/AIMultiplayer.cxx.
Also, when moving MP packets around, medium_term buffer can become empty. Have
added checks for empty short, medium and long term buffers when moving packets.
Simple-time mode is enabled by /sim/time/simple-time/enabled.
Simple-time is implemented by new TimeManager::computeTimeDeltasSimple()
method. This uses a plain UTC clock (e.g. with CLOCK_REALTIME /
gettimeofday()) for basic timing, and sets _mpProtocolClock (as returned by
getMPProtocolClockSec()) to the calculated FDM time.
We use our own fns to get UTC time and for sleeping, because
TimeManager doesn't work for us, e.g. SGTimeStamp::SGTimeStamp() uses
_POSIX_MONOTONIC_CLOCK if available so doesn't return UTC.
So getMPProtocolClockSec() now serves as a consistent time for both the
user aircraft and MP aircraft, avoiding problems where different Flightgear
instances could show aircraft in different relative positions.
For example it can be put into outgoing MP packets (which are about
the time/position of the user aircraft), and used as the target
time when calculating the position of multiplayer aircraft using
interpolation/extrapolation of incoming MP packets.
And getMPProtocolClockSec() can also be written into recordings, ensuring
that multiplayer replay will also show all aircraft with the correct relative
positions, regardless of varying frame rates at record or replay time. This is
tested by 'scripts/python/recordreplay.py --test-motion-mp'.
This is just for code clarity.
It changes the order of construction/registration of subsystems to match the
order in which subsystem groups are called when Flightgear is running.
JSBSim fails on startup if some properties are not already created; some of
these are created by FGReplay, and this is going wrong now that FGReplay is
being run after the FDM.
So have added a hack where we call FGReplay::init() as soone as FGReplay has
been created.