1
0
Fork 0

Fixed uneven replay of user vs multiplayer aircraft.

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).
This commit is contained in:
Julian Smith 2021-04-18 10:45:23 +01:00
parent 99bcc3ba24
commit 7753ce229d
3 changed files with 96 additions and 12 deletions

View file

@ -492,10 +492,68 @@ def test_motion(fgfs, multiplayer=False):
log( f'*** Replay showed uneven speed')
errors.append('1')
def show_values(paths):
if isinstance(paths, str):
paths = paths,
log(f'Values in {paths}:')
line2values = dict()
for i, path in enumerate(paths):
line = 0
for item in fg.fg.ls(path):
if item.name == 'value':
line2values.setdefault(line, []).append(item.value)
line += 1
for line in sorted(line2values.keys()):
t = ''
for value in line2values[line]:
t += f' {value}'
log(f' {t}')
if multiplayer:
examine_values()
examine_values('-multiplayer')
examine_values('-multiplayer-post')
if 0:
show_values('/sim/replay/log-raw-speed-multiplayer-post-relative-distance')
show_values('/sim/replay/log-raw-speed-multiplayer-post-relative-bearing')
show_values('/sim/replay/log-raw-speed-multiplayer-post-absolute-distance')
show_values('/sim/replay/log-raw-speed-multiplayer-post-user-absolute-distance')
def get_values(path):
'''
Returns <path>/value[] as a list.
'''
ret = []
for item in fg.fg.ls(path):
if item.name == 'value':
ret.append(item.value)
return ret
# Check that distance between user and mp is constant.
#
# The two paths below contain values[] that are the distances of the
# mp and user aircraft from their starting points. Both are moving at
# the same speed in the same direction, so the differences between each
# pair of values should be constant.
#
distances_mp = get_values('/sim/replay/log-raw-speed-multiplayer-post-absolute-distance')
distances_user = get_values('/sim/replay/log-raw-speed-multiplayer-post-user-absolute-distance')
log(f'len(distances_user)={len(distances_user)} len(distances_mp)={len(distances_mp)}')
assert len(distances_user) == len(distances_mp)
assert len(distances_user) > 20
for i in range(len(distances_user)):
distance_mp = distances_mp[i]
distance_user = distances_user[i]
delta = distance_mp - distance_user
if i == 0:
delta_original = delta
prefix = ' '
if abs(delta - delta_original) > 0.01:
#log('replay shows varying differences between user and mp aircraft')
errors.append('1')
prefix = '*'
log(f' {prefix} user={distance_user} mp={distance_mp} delta={delta}')
else:
examine_values()

View file

@ -286,6 +286,7 @@ void FGAIMultiplayer::update(double dt)
if (m_sim_replay_replay_state->getBoolValue())
{
tInterp = m_sim_replay_time->getDoubleValue();
SG_LOG(SG_GENERAL, SG_BULK, "tInterp=" << std::fixed << std::setprecision(6) << tInterp);
}
else
{
@ -660,7 +661,7 @@ void FGAIMultiplayer::update(double dt)
// For use with scripts/python/recordreplay.py --test-motion-mp.
{
SGGeod pos_geod = pos;
if (test_motion)
if (test_motion && !fgGetBool("/sim/replay/replay-state-eof"))
{
static SGVec3d s_pos_0;
static SGVec3d s_pos_prev;
@ -695,17 +696,39 @@ void FGAIMultiplayer::update(double dt)
n->setStringValue(buffer);
}
SGGeod user_pos_geod = SGGeod::fromDegFt(
fgGetDouble("/position/longitude-deg"),
fgGetDouble("/position/latitude-deg"),
fgGetDouble("/position/altitude-ft")
);
SGVec3d user_pos = SGVec3d::fromGeod(user_pos_geod);
double user_to_mp_distance = SGGeodesy::distanceM(user_pos_geod, pos_geod);
double user_to_mp_bearing = SGGeodesy::courseDeg(user_pos_geod, pos_geod);
double user_distance0 = length(user_pos - s_pos_0);
if (1)
{
fgGetNode("/sim/replay/log-raw-speed-multiplayer-post-relative-distance", true /*create*/)
->addChild("value")
->setDoubleValue(user_to_mp_distance)
;
fgGetNode("/sim/replay/log-raw-speed-multiplayer-post-relative-bearing", true /*create*/)
->addChild("value")
->setDoubleValue(user_to_mp_bearing)
;
fgGetNode("/sim/replay/log-raw-speed-multiplayer-post-absolute-distance", true /*create*/)
->addChild("value")
->setDoubleValue(distance0)
;
fgGetNode("/sim/replay/log-raw-speed-multiplayer-post-user-absolute-distance", true /*create*/)
->addChild("value")
->setDoubleValue(user_distance0)
;
}
if (verbose)
{
SGGeod user_pos_geod = SGGeod::fromDegFt(
fgGetDouble("/position/longitude-deg"),
fgGetDouble("/position/latitude-deg"),
fgGetDouble("/position/altitude-ft")
);
double user_to_mp_bearing = SGGeodesy::courseDeg(user_pos_geod, pos_geod);
double user_to_mp_distance = SGGeodesy::distanceM(user_pos_geod, pos_geod);
int width=16;
SG_LOG(SG_GENERAL, SG_ALERT, "Multiplayer-post aircraft callsign=" << _callsign << ":"
<< std::setprecision(5)
@ -721,7 +744,8 @@ void FGAIMultiplayer::update(double dt)
<< " t_dt=" << std::setw(width) << t_dt
<< " dt=" << std::setw(width) << dt
<< " distance0=" << std::setw(width) << distance0
<< " distance=" << std::setw(width) << distance
<< " user_distance0=" << std::setw(width) << user_distance0
<< " speed=" << std::setw(width) << speed
<< " speed=" << std::setw(width) << speed
<< " delta_pos_norm=" << std::setw(width) << delta_pos_norm
<< " calc_type=" << std::setw(width) << calc_type

View file

@ -1009,6 +1009,9 @@ FGReplay::update( double dt )
m_MultiplayMgr->ClearMotion();
}
current_time += dt;
SG_LOG(SG_GENERAL, SG_BULK, "current_time=" << std::fixed << std::setprecision(6) << current_time);
bool IsFinished = replay( current_time );
if (IsFinished)
{
@ -1022,7 +1025,6 @@ FGReplay::update( double dt )
}
else
{
current_time += dt;
was_finished_already = false;
}
replay_time->setDoubleValue(current_time);