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')
|
log( f'*** Replay showed uneven speed')
|
||||||
errors.append('1')
|
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:
|
if multiplayer:
|
||||||
examine_values()
|
examine_values()
|
||||||
examine_values('-multiplayer')
|
examine_values('-multiplayer')
|
||||||
examine_values('-multiplayer-post')
|
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:
|
else:
|
||||||
examine_values()
|
examine_values()
|
||||||
|
|
||||||
|
|
|
@ -286,6 +286,7 @@ void FGAIMultiplayer::update(double dt)
|
||||||
if (m_sim_replay_replay_state->getBoolValue())
|
if (m_sim_replay_replay_state->getBoolValue())
|
||||||
{
|
{
|
||||||
tInterp = m_sim_replay_time->getDoubleValue();
|
tInterp = m_sim_replay_time->getDoubleValue();
|
||||||
|
SG_LOG(SG_GENERAL, SG_BULK, "tInterp=" << std::fixed << std::setprecision(6) << tInterp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -660,7 +661,7 @@ void FGAIMultiplayer::update(double dt)
|
||||||
// For use with scripts/python/recordreplay.py --test-motion-mp.
|
// For use with scripts/python/recordreplay.py --test-motion-mp.
|
||||||
{
|
{
|
||||||
SGGeod pos_geod = pos;
|
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_0;
|
||||||
static SGVec3d s_pos_prev;
|
static SGVec3d s_pos_prev;
|
||||||
|
@ -695,17 +696,39 @@ void FGAIMultiplayer::update(double dt)
|
||||||
n->setStringValue(buffer);
|
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)
|
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;
|
int width=16;
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "Multiplayer-post aircraft callsign=" << _callsign << ":"
|
SG_LOG(SG_GENERAL, SG_ALERT, "Multiplayer-post aircraft callsign=" << _callsign << ":"
|
||||||
<< std::setprecision(5)
|
<< std::setprecision(5)
|
||||||
|
@ -721,7 +744,8 @@ void FGAIMultiplayer::update(double dt)
|
||||||
<< " t_dt=" << std::setw(width) << t_dt
|
<< " t_dt=" << std::setw(width) << t_dt
|
||||||
<< " dt=" << std::setw(width) << dt
|
<< " dt=" << std::setw(width) << dt
|
||||||
<< " distance0=" << std::setw(width) << distance0
|
<< " 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
|
<< " speed=" << std::setw(width) << speed
|
||||||
<< " delta_pos_norm=" << std::setw(width) << delta_pos_norm
|
<< " delta_pos_norm=" << std::setw(width) << delta_pos_norm
|
||||||
<< " calc_type=" << std::setw(width) << calc_type
|
<< " calc_type=" << std::setw(width) << calc_type
|
||||||
|
|
|
@ -1009,6 +1009,9 @@ FGReplay::update( double dt )
|
||||||
m_MultiplayMgr->ClearMotion();
|
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 );
|
bool IsFinished = replay( current_time );
|
||||||
if (IsFinished)
|
if (IsFinished)
|
||||||
{
|
{
|
||||||
|
@ -1022,7 +1025,6 @@ FGReplay::update( double dt )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current_time += dt;
|
|
||||||
was_finished_already = false;
|
was_finished_already = false;
|
||||||
}
|
}
|
||||||
replay_time->setDoubleValue(current_time);
|
replay_time->setDoubleValue(current_time);
|
||||||
|
|
Loading…
Reference in a new issue