Try to catch NaN SGGeod position before we pass them to the intersect
visitor, so we don’t fill the console/logs with error messages: we
catch NaNs in other places.
Previously we always used the default download dir, and ignored any
user override of this. Use the active download dir as the base for
the cache dir.
Also write the cache dir to the property tree, and wipe it on a
clean uninstall.
GUIDs aren’t stable across different builds of the cache, which causes
odd behaviour when switching between stable and next. Use idents and
lat-lon instead, since these should be stable.
Avoid a per-update() lookup of the AI controls properties. As part
of this, bypass updatePrimaryTargetValues for the user aircraft,
where it doesn’t make sense.
We previously ignored mp packets if their .time was very different from local
time, but this stops time-compensation (e.g. with simple-time) from working and
is unnecessary because we clean up old packets anyway.
Also removed unnecessary erase of mp packets after interpolation.
When we fail to find the request aircraft, ensure we log the paths
to Sentry. If the user didn’t supply any aircraft paths at all, or
was using a hangar aircraft, adjust the error dialog text, to make
it a bit clearer what is going wrong.
Otherwise a SGSharedPtr is implicitly created on ai_list.push_back(model). It's not clear to the caller that FGAIManager takes care of the passed raw pointer.
Also fixes a bug for swift using the passed dangling pointer after the created SGSharedPtr of FGAIManager got out of scope and deleted the resource.
As this commit mainly addresses the swift crash (also for backport to LTS) it doesn't fix other calls to ::attach(..) which might also use the raw pointer afterwards.
Use a transient index for the poly-lines. This avoids NavCache disk
contention when multiple copies of FG race after the rebuild completes.
Should reduce locking errors early in startup.
Some propellers could start windmilling very easily under mild wind conditions (11 kts). And in stronger wind the propeller could even generate some power and torque strong enough to turn the aircraft upside down.
This was due to the combination of:
- Propellers generating power (wind turbine) for advance ratio higher than 1.0 (is it plausible !?!)
- Powers and torques computed with ludicrously small RPMs.
So this commit basically filters out extremely small RPMs in order to avoid huge numbers resulting from division by small values.
Some spacecraft send out-of-range engine numbers from the JSBsim side.
Should probably be fixed in JSBsim itself but let’s check here to
keep compat with existing FDMs.
out command, in option curently overwrite the rate given by the out option
eg: --multiplay=out,20,localhost,5000 --multiplay=in,,,5003 end with a tx
rate of "0" and this end with the default value 10 later
Disable error-reports in ‘developer-mode’, and only consider aircraft
errors critical if they happen before postinit().
Add logic to show the correct report when a popup is clicked.
- Lower the allowable minimum propeller inertia from 1e-3 to 1e-6
- Account for the vehicle angular rates in the computation of propellers local velocities.
- Apply the engine torque to the vehicle (The aerodynamic torque was applied until now but it is the engine generated torque that the aircraft is actually submitted to)
- Prevent FGPiston from sending negative powers to thrusters
- Fixed FGMagnetometer : no need to update the magnetic field every time step.
- FGMassBalance: remove a direct reference to FGGroundReactions
FGRenderer::update() happens after the CameraGroup is updated, which causes the
Compositor to use the previous frame cull mask. Setting the cull masks
explicitly during FGRenderer::update() fixes the issue.
Check the _initialized flag inside the listener, to avoid a crash
if Nasal sets fgcom properties during its startup, which happens
before FGCom runs its own postinit()
Ticket: https://sourceforge.net/p/flightgear/codetickets/2574/
Assess how critical the error is, and based on this, show a popup
instead of the dialog in some cases. Add commands to allow delayed
display of the main dialog, and stepping through multiple error
reports in the dialog.
Also add a new error category for shader errors, since these are
always emitted from the render thread and we can’t easily attribute
them to an aircraft, scenery or core feature.
Add an assertion that controller has been cleared before the AIAircraft
destructor is run. If it’s not, then we are too late, don’t try to
sign off since the controller is probably gone.
Sentry-Id: FLIGHTGEAR-15
Tidying up:
* change to use direct initializtion
* put all of member variables in alpha order
* adjust init spacing to make init values clear.
* change all member variables to start with an underscore. The reason for this isn't clear but some had an underscore and some didn't; so although I don't know what the convention was intended for this seems to be the appropriate changes.
Previous commit removed the logic that sets the tower position and altitude; this commit fixes this.
Also added limits and default for tower altitude because there are a lot of towers that are at the same altitude as the airport; this is clearly a lack of data. Also there are some towers that are ludicrously high (e.g. KLSV). This commit defines a reasonable minimum and maximum values for tower altitude; together with a default altitude which will be added to the airport elevation when the tower altitude is outside of these ranges (above airpot altitude).
---------------
I used the following queries can against the navdata cache to figure out what sensible values were:
to locate overly tall towers
select a.type, a.ident, a.name, (p.elev_m - a.elev_m) from positioned as p
inner join positioned as a on a.octree_node = p.octree_node
where p.type=22 and a.type=1 and abs(p.elev_m - a.elev_m) > 100
to locate towers at ground level:
select a.type, a.ident, a.name, (p.elev_m - a.elev_m) from positioned as p
inner join positioned as a on a.octree_node = p.octree_node
where p.type=22 and a.type=1 and abs(p.elev_m - a.elev_m) < 0.1
to calculate the average tower height
select avg(p.elev_m - a.elev_m) from positioned as p
inner join positioned as a on a.octree_node = p.octree_node
where p.type=22 and a.type=1 and abs(p.elev_m - a.elev_m)
Moved motion test code into separate function and removed some now-unnecessary
logging.
Moved extrapolation code into separate method.
Converted some stray tabs into spaces.
FGReplay was using time t, AIMultiplayer was using t+dt. The fix is to make
FGReplay also use t+dt.
scripts/python/recordreplay.py
Make --test-motion-mp test for this problem - we check that user and mp
aircraft are a constant distance apart when replaying.
src/AIModel/AIMultiplayer.cxx
Create properties showing distance moved since start by user and mp
aircraft, which can then be tested by recordreplay.py.
src/Aircraft/replay.cxx
Increment current_time by dt before calling replay(current_time), to
ensure that replay() sees the time as is later used by AIMultiplayer (via
/sim/replay/time).
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").
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.
Reject invalid frequencies from apt.dat in the loader, and fix
25Khz encoding to be the exact value (i.e round frequencies ending
in 20 and 70 to 25 and 75)
Fix ATCdialog to show 3 digits of comm radio frequency at all times,
and remove its rounding-conversion.
Finally, expand the tests to capture the new behaviour. Test for
EPLL is disabled for now because it contains an invalid frequency.
Still need to add SVG support, but this improves feedback (eg hover)
for many icons in the launcher. Will remove the redundant PNGs in
another commit once other pieces are done.
The problem was that we were recording aircraft state before the FDM updated
it, which meant that simtime changes were out of step with aircraft position by
one frame.
The fix is to run the FGReplay subsystem after the FDM subsystem
instead of before, which simply requires changing the code to use
SGSubsystemMgr::POST_FDM.
This makes './flightgear/scripts/python/recordreplay.py --test-motion' pass (it
previously failed).
Setting sim/replay/log-raw-speed logs raw speed to
/sim/replay/log-raw-speed-values/value[].
'scripts/python/recordreplay.py --test-motion' uses this to test for a bug
where the user aircraft simtime and signals information don't quite match in
continuous recordings.
1. A canvas can be placed on dynamically created models.
Implemented by adding a new placement factory.
2. Added a "loaded" property in every "models/model[...]"
path to track when a model is finally loaded by OSG.
See https://forum.flightgear.org/viewtopic.php?f=30&t=38318
Avoid double-setting or conflicting aircraft arguments being passed:
when the user enters an aircraft related argument manually, disable
the launcher setting them.
Include command line / launcher options in the detailed report, and
pause the sim when showing an error dialog, in case the report
occurs at an unfortunate time.
Compute the local time value inside the TimeManager, so that the
UI doesn’t need to rely on the default clock instrument (which
might not exist) to show correct local time.
Also fix updating of time-offset/time-zone, to be based on distance
travelled instead of elapsed wall-clock time.
(needs an FGData update as well)
Ticket-Id: https://sourceforge.net/p/flightgear/codetickets/2514/
Since we’re not using target_link_libraries, we need to explicitly
define fgfsObjects (which contains main.cxx) as depending on the
embedded resources target.
Remove use of BUILDING_TESTSUITE from headers. Where possible, move
test APIs to their own file in the test_suite dir (testApis.cxx). For
some others, add them to a special list of ‘sources which depend on
the build mode’. This will hopefully go away with some further
refactoring.
The end time is updated in background when replaying from url, so we must not
set /sim/replay/end-time elsewhere. So we now only set /sim/replay/end-time in
FGReplay::get_end_time() if recording is not Continuous.
* Support the native fdm, gui and ctrl protocols over DDS
* Add fgfdm_log as an fdm over DDS command line logging utility
Usage:
--native-fdm=dds,out,60
--native-ctrls=dds,in,60
etc.
FGFlightRecorder::replay():
Fixed behaviour when going back in time while replaying - we were not
replaying initial property changes correctly because we deliberately
don't load signals data for some frames when we are only interested in
multiplayer or extra properties.
Removed incorrect code that tried to avoid replaying the same frame twice
in succession.
FGReplay::update(double dt):
Improved how we figure out which frames we need to replay just for multiplayer
or extra property changes.
FGReplay::makeTapePath():
New fn containing the code for converting tape name into path by prepending
tape dir and appending .fgtape as necessary. Called when loading tape at
startup or at runtime.
Cached some more property nodes in SGPropertyNode_ptr's.
Don't recordCHAT_MSG_ID messages; unfortunately it looks like most (all?)
chat message text is received as part of POS_DATA_ID messages tied to
sim/multiplay/chat, so this doesn't actually avoid recording chat messages.
We used to modify the --aircraft and --airport options when handling
--load-tape, which invalidated iterators and for example could cause later
options to be ignored.
The solution here is rather crude - we store the new options in globals to
ensure that they are used in preference later on.
We now put local file inside directory specified in /sim/replay/tape-directory,
and also use 'url-' prefix on leafname.
E.g. with
--prop:/sim/replay/tape-directory=.../fgtapes and
--load-tape=http://foo.com/harrier-gr3-continuous.fgtape
- the local file is:
.../fgtapes/url_foo.com_harrier-gr3-continuous.fgtape
Add timestamp to saved reports, and the file name, and print the
time-stamp for occurences in a saved report. Add de-duplication
support to avoid generating huge reports for recurring errors.
Not complete yet, but add the ability to pass context in from the
AIBase to the loader thread. Also add error context to more places
in AI / scenario loading.
A few versions of the Windows Intel drivers seem to crash while
performing the OpenGL check; re-order the code to try and prevent
this.
Sentry-Id: FLIGHTGEAR-K7R
Don’t fail to select the language, when the UI language includes
a ‘script’ value, as happens for Chinese on macOS.
Thanks to Sidi Liang for reporting.
Fix a bug where we would copy-assign a PropertyObject, when we
actually wanted to copy the value.
Thanks to Sascha Reißner for tracking the problem down.
Need to use simgear::HTTP::FileRequestRef shared pointer, otherwise
HTTPFileRequest will delete it after the transfer.
Also changed callback to a lambda to match reinstated simgear API.
The fgfs executable is the unit within which it makes sense to check
preconditions with assert. We are not in control of aircraft code in the same
way.
This allows debug build of test-suite to check handling of out-of-range view
numbers.
E.g. for --load-tape=http[s]://foo.com/foo/bar/wibble.fgtape, we download in
the background to a file called foo.com_[MD5]_wibble.fgtape, where [MD5] is an
8-character hash of /foo/bar.
We assume any existing file contains valid data and only download any remaining
data (by specifying an http Range header).
Also, when loading/downloading and replaying continuous recordings at startup,
we set the aircraft and airport from the recording.
src/Aircraft/replay.cxx
src/Aircraft/replay.hxx
FGReplay::loadContinuousHeader()
Loads properties from Continuous recording's header, distinguishing
between failure due to incorrect header, or due to a truncated file.
FGReplay::indexContinuousRecording()
Contains Continuous recording indexing code, in a form that can be used
in background while we are downloading.
Added a mutex to protect m_continuous_in_time_to_frameinfo, which can now
be modified in background as Continuous recording is downloaded.
src/Main/fg_init.cxx
src/Main/options.cxx
fgOptLoadTape():
Modified to handle --load-tape=<url>. We start download, and read
the header before returning, so that we can force the FDM to use the
recording's aircraft instead of the user's default. Limit recording
download rate if /sim/replay/download-max-bytes-per-sec is set, by
calling new filerequest->setMaxBytesPerSec().
Recording of extra properties is only supported in Continuous recordings.
Modified Continuous recording format to allow future forwards
compatibility. See docs-mini/README-recordings.md for details. This breaks
compatibility with previously-generated Continuous recordings, but this only
affects next.
To reduce overhead we record all extra property values in the first frame and
then later frames contain only extra property changes. When replaying, if the
user jumps backwards we replay all extra property changes since the start of
the recording. Similarly if the user jumps forwards, we replay any intervening
extra property changes.
Recording extra properties:
This is enabled by:
/sim/replay/record-extra-properties
The extra properties that are recorded are identified by the property
paths in the values of /sim/replay/record-extra-properties-paths/path[]
properties. We record the entire tree for each specified path.
Recording of main window position size:
We have specific support for record and replay of main window position/size.
This is enabled by:
/sim/replay/record-main-window
Recording of main window view:
We have specific support for recording the view type and direction/zoom
settings.
This is enabled by:
/sim/replay/record-main-view
We record the /sim/current-view/ property tree, excluding some subtrees
that continuously vary but are not required for replaying of the view.
When replaying, we allow separate control of what extra property changes are
replayed, with:
/sim/replay/replay-extra-property-changes
/sim/replay/replay-extra-property-removal
/sim/replay/replay-main-window-position
/sim/replay/replay-main-window-size
/sim/replay/replay-main-view
We work around some problems caused by the use of tied properties when
replaying changes to view-number.
Window position issue:
When replaying window position and size changes, things get a little tricky
because osgViewer::GraphicsWindow::setWindowRectangle() takes a position
for the entire window, but osgGA::GUIEventAdapter::RESIZE events contain
the position of the interior of the window; for example the y values will
differ by the height of the window's titlebar. This can cause windows to
move progressively further down each time they are positioned or resized.
There doesn't seem to be a way of finding the size of a window's
furniture directly. So instead this commit adds a new method
osgGA::GUIEventAdapter::setWindowRectangleInteriorWithCorrection() which
wraps osgViewer::GraphicsWindow::setWindowRectangle(). We listen for the
following osgGA::GUIEventAdapter::RESIZE event and calculate corrections
for x and y position that are used for subsequent calls.
docs-mini/README-recordings.md:
Updated to document new Continuous format.
scripts/python/recordreplay.py:
New script to test various aspects of record/replay.
Other:
We now create convenience softlink to most recent continuous recording, using
SGPath::makeLink(). Note that SGPath::makeLink() currently does nothing on
Windows.
Changed format of Continuous recordings to contain a single property tree
in header. This is much simpler than having separate Config and Meta trees.
It was supposed to be in ft/min, but everything except AIAircraft was
using it as ft/sec. Change the name to AIBase::vs_fps and ensure the
same unit is used everywhere.
QML implementation of getting started tips, with a nice styled
background box. Tips are defined+positioned inline, and displayed
when their enclosing scope is active.
Translocation forces us to rebuild the nav-cache each launch, and might
mess up some other details, so let’s warn the user they should copy
the app to Applications or similar.
If the user double-clicks, and their system is slow, the action can
fire twice, which then breaks because we add options twice.
Sentry-Id: FLIGHTGEAR-HKV
Move forward 1 metre in tower view look from, to slightly improve view of
ground near tower.
Removed incorrect attempt to move towards target in other tower views, that
didn't work.
This means that the image on screen moves by the same distance as the mouse
(for small movements), regardless of window size or zoom level. Current mouse
drag handling in extra view windows is poor though - mouse is constrained by
screen size.
Would be good to do this for standard views as well, but the code in view.cxx
is more complex so haven't been able to figure out how.
Allow the option to have the marker beacon instrument use either the
correct timing, or ‘always on’ when the beacon is in range. Try to
ensure the audio is synchronised with the visual property. by using
the same timing values.
Also avoids losing sync when using the ‘audio-btn’ toggle, and increases
the update rate to allow accurate timing. Finally, switch from tied
properties to regular ones, so listeners on the beacon properties are
updated directly.
Configure the VPB elevation mesh via properties:
/scenery/elevation-mesh/sample-ratio controls the elevation
mesh sampling, allowing reduction in mesh size
/scenery/elevation-mesh/vertical-scale is just for fun and
scales the mesh vertically making mountains taller.
/scenery/elevation-mesh/constraint-gap-m controls how much below
airports etc. elevation vertices are forced to be.
[Marked as 'Partial' because, for me, reset eventually runs out of memory with
both composite-viewer and non-composite-viewer.]
fgStartNewReset(): pass existing composite_viewer to FGRenderer constructor so
that it is used after reset instead of us creating a new instance. Also reuse
existing osgViewer::View.
In FGRenderer::init(), don't create new osgViewer::CompositeViewer if
this->composite_viewer is already set.