CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/Replay/check_replay.py
Views: 1798
1
#!/usr/bin/env python
2
3
'''
4
check that replay produced identical results
5
'''
6
7
from __future__ import print_function
8
9
def check_log(logfile, progress=print, ekf2_only=False, ekf3_only=False, verbose=False, accuracy=0.0, ignores=set()):
10
'''check replay log for matching output'''
11
from pymavlink import mavutil
12
progress("Processing log %s" % logfile)
13
failure = 0
14
errors = 0
15
count = 0
16
base_count = 0
17
counts = {}
18
base_counts = {}
19
20
mlog = mavutil.mavlink_connection(logfile)
21
22
ek2_list = ['NKF1','NKF2','NKF3','NKF4','NKF5','NKF0','NKQ', 'NKY0', 'NKY1']
23
ek3_list = ['XKF1','XKF2','XKF3','XKF4','XKF0','XKFS','XKQ','XKFD','XKV1','XKV2','XKY0','XKY1']
24
25
if ekf2_only:
26
mlist = ek2_list
27
elif ekf3_only:
28
mlist = ek3_list
29
else:
30
mlist = ek2_list + ek3_list
31
32
base = {}
33
for m in mlist:
34
base[m] = {}
35
36
while True:
37
m = mlog.recv_match(type=mlist)
38
if m is None:
39
break
40
if not hasattr(m,'C'):
41
continue
42
mtype = m.get_type()
43
if mtype not in counts:
44
counts[mtype] = 0
45
base_counts[mtype] = 0
46
core = m.C
47
if core < 100:
48
base[mtype][core] = m
49
base_count += 1
50
base_counts[mtype] += 1
51
continue
52
mb = base[mtype][core-100]
53
count += 1
54
counts[mtype] += 1
55
mismatch = False
56
for f in m._fieldnames:
57
if f == 'C':
58
continue
59
if "%s.%s" % (mtype, f) in ignores:
60
continue
61
v1 = getattr(m,f)
62
v2 = getattr(mb,f)
63
ok = v1 == v2
64
if not ok and accuracy > 0:
65
avg = (v1+v2)*0.5
66
margin = accuracy*0.01*avg
67
if abs(v1-v2) <= abs(margin):
68
ok = True
69
if not ok:
70
mismatch = True
71
errors += 1
72
progress("Mismatch in field %s.%s: %s %s" % (mtype, f, str(v1), str(v2)))
73
if mismatch:
74
progress(mb)
75
progress(m)
76
progress("Processed %u/%u messages, %u errors" % (count, base_count, errors))
77
if verbose:
78
for mtype in counts.keys():
79
progress("%s %u/%u %d" % (mtype, counts[mtype], base_counts[mtype], base_counts[mtype]-counts[mtype]))
80
count_delta = abs(count - base_count)
81
if count == 0 or count_delta > 100:
82
progress("count=%u count_delta=%u" % (count, count_delta))
83
failure += 1
84
if failure != 0 or errors != 0:
85
return False
86
return True
87
88
if __name__ == '__main__':
89
import sys
90
from argparse import ArgumentParser
91
parser = ArgumentParser(description=__doc__)
92
parser.add_argument("--ekf2-only", action='store_true', help="only check EKF2")
93
parser.add_argument("--ekf3-only", action='store_true', help="only check EKF3")
94
parser.add_argument("--verbose", action='store_true', help="verbose output")
95
parser.add_argument("--accuracy", type=float, default=0.0, help="accuracy percentage for match")
96
parser.add_argument("--ignore-field", action='append', default=[], help="ignore message field when comparing")
97
parser.add_argument("logs", metavar="LOG", nargs="+")
98
99
args = parser.parse_args()
100
101
failed = False
102
for filename in args.logs:
103
if not check_log(filename, print, args.ekf2_only, args.ekf3_only, args.verbose, accuracy=args.accuracy, ignores=args.ignore_field):
104
failed = True
105
106
if failed:
107
print("FAILED")
108
sys.exit(1)
109
print("Passed")
110
sys.exit(0)
111
112