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:
parent
99bcc3ba24
commit
7753ce229d
3 changed files with 96 additions and 12 deletions
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue