scripts/python/recordreplay.py: added test of multiplayer information.
New option: --test-motion-mp checks raw speed of multiplayer aircraft while replaying.
This commit is contained in:
parent
a606315bbb
commit
5de5419e25
1 changed files with 82 additions and 32 deletions
|
@ -45,6 +45,7 @@ Args:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import resource
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
@ -63,7 +64,7 @@ class Fg:
|
||||||
Runs flightgear. self.fg is a FlightGear.FlightGear instance, which uses
|
Runs flightgear. self.fg is a FlightGear.FlightGear instance, which uses
|
||||||
telnet to communicate with Flightgear.
|
telnet to communicate with Flightgear.
|
||||||
'''
|
'''
|
||||||
def __init__(self, aircraft, args, env=None):
|
def __init__(self, aircraft, args, env=None, telnet_port=None):
|
||||||
'''
|
'''
|
||||||
aircraft:
|
aircraft:
|
||||||
Specified as: --aircraft={aircraft}. This is separate from <args>
|
Specified as: --aircraft={aircraft}. This is separate from <args>
|
||||||
|
@ -78,8 +79,9 @@ class Fg:
|
||||||
self.aircraft = aircraft
|
self.aircraft = aircraft
|
||||||
args += f' --aircraft={aircraft}'
|
args += f' --aircraft={aircraft}'
|
||||||
|
|
||||||
port = 5500
|
if telnet_port is None:
|
||||||
args += f' --telnet={port}'
|
telnet_port = 5500
|
||||||
|
args += f' --telnet={telnet_port}'
|
||||||
args2 = args.split()
|
args2 = args.split()
|
||||||
|
|
||||||
environ = os.environ.copy()
|
environ = os.environ.copy()
|
||||||
|
@ -98,7 +100,15 @@ class Fg:
|
||||||
#
|
#
|
||||||
log(f'Command is: {args}')
|
log(f'Command is: {args}')
|
||||||
log(f'Running: {args2}')
|
log(f'Running: {args2}')
|
||||||
self.child = subprocess.Popen(args2, env=environ)
|
def preexec():
|
||||||
|
try:
|
||||||
|
resource.setrlimit(resource.RLIMIT_CORE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
|
||||||
|
except Exception as e:
|
||||||
|
log(f'*** preexec failed with e={e}')
|
||||||
|
raise
|
||||||
|
self.child = subprocess.Popen(args2, env=environ,
|
||||||
|
preexec_fn=preexec,
|
||||||
|
)
|
||||||
|
|
||||||
# Connect to flightgear's telnet server.
|
# Connect to flightgear's telnet server.
|
||||||
timeout = 15
|
timeout = 15
|
||||||
|
@ -112,7 +122,7 @@ class Fg:
|
||||||
raise Exception(text)
|
raise Exception(text)
|
||||||
try:
|
try:
|
||||||
log('Connecting... ')
|
log('Connecting... ')
|
||||||
self.fg = FlightGear.FlightGear('localhost', port)
|
self.fg = FlightGear.FlightGear('localhost', telnet_port)
|
||||||
log(f'Connected. timeout={timeout} dt={dt:.1f}')
|
log(f'Connected. timeout={timeout} dt={dt:.1f}')
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -286,27 +296,34 @@ def test_record_replay(
|
||||||
log('Test passed')
|
log('Test passed')
|
||||||
|
|
||||||
|
|
||||||
def test_motion(fgfs):
|
def test_motion(fgfs, multiplayer=False):
|
||||||
|
|
||||||
aircraft = 'ufo'
|
aircraft = 'ufo'
|
||||||
fg = Fg( aircraft, f'{fgfs} --aircraft={aircraft}')
|
fg = Fg( aircraft, f'{fgfs}')
|
||||||
path = f'{fg.aircraft}-continuous.fgtape'
|
path = f'{fg.aircraft}-continuous.fgtape'
|
||||||
|
|
||||||
if 0:
|
|
||||||
items = fg.fg.ls( '/sim')
|
|
||||||
log( '/sim is:')
|
|
||||||
for item in items:
|
|
||||||
log( f' {item}')
|
|
||||||
fg.close()
|
|
||||||
return
|
|
||||||
|
|
||||||
fg.waitfor('/sim/fdm-initialized', 1, timeout=45)
|
fg.waitfor('/sim/fdm-initialized', 1, timeout=45)
|
||||||
|
|
||||||
|
fg.fg['/controls/engines/engine[0]/throttle'] = 0
|
||||||
|
|
||||||
|
if multiplayer:
|
||||||
|
fg.fg['/sim/replay/record-multiplayer'] = True
|
||||||
|
fg2 = Fg( aircraft, f'{fgfs} --callsign=cgdae-t --multiplay=in,4,,5033 --read-only', telnet_port=5501)
|
||||||
|
fg2.waitfor('/sim/fdm-initialized', 1, timeout=45)
|
||||||
|
fg2.fg['/controls/engines/engine[0]/throttle'] = 0.1
|
||||||
|
time.sleep(1)
|
||||||
|
fgt = fg.fg['/controls/engines/engine[0]/throttle']
|
||||||
|
fg2t = fg2.fg['/controls/engines/engine[0]/throttle']
|
||||||
|
log(f'fgt={fgt} fg2t={fg2t}')
|
||||||
|
else:
|
||||||
|
fg.fg['/controls/engines/engine[0]/throttle'] = 0.1
|
||||||
|
|
||||||
# Run UFO with constant speed, varying the framerate so we check whether
|
# Run UFO with constant speed, varying the framerate so we check whether
|
||||||
# recorded speeds are affected.
|
# recorded speeds are affected.
|
||||||
#
|
#
|
||||||
fg.fg['/controls/engines/engine[0]/throttle'] = 0.1
|
|
||||||
fg.fg['/sim/frame-rate-throttle-hz'] = 5
|
fg.fg['/sim/frame-rate-throttle-hz'] = 5
|
||||||
|
if multiplayer:
|
||||||
|
fg2.fg['/sim/frame-rate-throttle-hz'] = 5
|
||||||
|
|
||||||
# Delay to let frame rate settle.
|
# Delay to let frame rate settle.
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
|
@ -321,26 +338,49 @@ def test_motion(fgfs):
|
||||||
|
|
||||||
# Restore original frame rate.
|
# Restore original frame rate.
|
||||||
fg.fg['/sim/frame-rate-throttle-hz'] = 5
|
fg.fg['/sim/frame-rate-throttle-hz'] = 5
|
||||||
|
if multiplayer:
|
||||||
|
fg2.fg['/sim/frame-rate-throttle-hz'] = 2
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
# Stop recording.
|
# Stop recording.
|
||||||
fg.fg['/sim/replay/record-continuous'] = 0
|
fg.fg['/sim/replay/record-continuous'] = 0
|
||||||
|
|
||||||
fg.close()
|
fg.close()
|
||||||
|
if multiplayer:
|
||||||
|
fg2.close()
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
path2 = os.readlink( path)
|
path2 = os.readlink( path)
|
||||||
g_cleanup.append(lambda: os.remove(path2))
|
g_cleanup.append(lambda: os.remove(path2))
|
||||||
|
|
||||||
|
if multiplayer:
|
||||||
|
fg = Fg( aircraft, f'{fgfs} --load-tape={path} --prop:/sim/replay/log-raw-speed-multiplayer=cgdae-t')
|
||||||
|
else:
|
||||||
fg = Fg( aircraft, f'{fgfs} --load-tape={path} --prop:/sim/replay/log-raw-speed=true')
|
fg = Fg( aircraft, f'{fgfs} --load-tape={path} --prop:/sim/replay/log-raw-speed=true')
|
||||||
fg.waitfor('/sim/fdm-initialized', 1, timeout=45)
|
fg.waitfor('/sim/fdm-initialized', 1, timeout=45)
|
||||||
fg.fg['/sim/frame-rate-throttle-hz'] = 10
|
fg.fg['/sim/frame-rate-throttle-hz'] = 10
|
||||||
fg.waitfor('/sim/replay/replay-state', 1)
|
fg.waitfor('/sim/replay/replay-state', 1)
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
fg.fg['/sim/frame-rate-throttle-hz'] = 2
|
||||||
|
time.sleep(5)
|
||||||
|
fg.fg['/sim/frame-rate-throttle-hz'] = 5
|
||||||
|
time.sleep(3)
|
||||||
|
fg.fg['/sim/frame-rate-throttle-hz'] = 7
|
||||||
|
|
||||||
fg.waitfor('/sim/replay/replay-state-eof', 1)
|
fg.waitfor('/sim/replay/replay-state-eof', 1)
|
||||||
|
|
||||||
items0 = fg.fg.ls( '/sim/replay/log-raw-speed-values')
|
def examine_values(infix=''):
|
||||||
|
items0 = fg.fg.ls( f'/sim/replay/log-raw-speed{infix}-values')
|
||||||
|
log(f'len(items0)={len(items0)}')
|
||||||
|
if not items0:
|
||||||
|
while 1:
|
||||||
|
log(f'*** hanging because failed to read contents of: /sim/replay/log-raw-speed{infix}-values')
|
||||||
|
time.sleep(5)
|
||||||
items = []
|
items = []
|
||||||
for item in items0:
|
for item in items0:
|
||||||
if item.name == 'value':
|
if item.name == 'value':
|
||||||
|
#log(f'have read item: {item}')
|
||||||
items.append(item)
|
items.append(item)
|
||||||
num_errors = 0
|
num_errors = 0
|
||||||
for item in items[:-1]: # Ignore last item because replay at end interpolates.
|
for item in items[:-1]: # Ignore last item because replay at end interpolates.
|
||||||
|
@ -350,9 +390,15 @@ def test_motion(fgfs):
|
||||||
num_errors += 1
|
num_errors += 1
|
||||||
prefix = '*'
|
prefix = '*'
|
||||||
log( f' {prefix} speed={speed} details: {item}')
|
log( f' {prefix} speed={speed} details: {item}')
|
||||||
fg.close()
|
|
||||||
assert num_errors == 0, 'Replay showed uneven speed.'
|
assert num_errors == 0, 'Replay showed uneven speed.'
|
||||||
|
|
||||||
|
if multiplayer:
|
||||||
|
examine_values('-multiplayer')
|
||||||
|
else:
|
||||||
|
examine_values()
|
||||||
|
|
||||||
|
fg.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
@ -398,11 +444,15 @@ if __name__ == '__main__':
|
||||||
fgfs_reverse = [0, 1]
|
fgfs_reverse = [0, 1]
|
||||||
elif arg == '--test-motion':
|
elif arg == '--test-motion':
|
||||||
do_test = 'motion'
|
do_test = 'motion'
|
||||||
|
elif arg == '--test-motion-mp':
|
||||||
|
do_test = 'motion-mp'
|
||||||
else:
|
else:
|
||||||
raise Exception(f'Unrecognised arg: {arg!r}')
|
raise Exception(f'Unrecognised arg: {arg!r}')
|
||||||
|
|
||||||
if do_test == 'motion':
|
if do_test == 'motion':
|
||||||
test_motion( fgfs)
|
test_motion( fgfs)
|
||||||
|
elif do_test == 'motion-mp':
|
||||||
|
test_motion( fgfs, True)
|
||||||
elif do_test == 'all':
|
elif do_test == 'all':
|
||||||
try:
|
try:
|
||||||
if fgfs_old:
|
if fgfs_old:
|
||||||
|
|
Loading…
Reference in a new issue