mirror of https://github.com/ArduPilot/ardupilot
autotest: fix frsky passthrough test
Mainly through polling much faster, but also allowing for statustexts in different orders from frsky/statustext
This commit is contained in:
parent
618282e996
commit
073a9e3390
|
@ -2116,8 +2116,8 @@ class AutoTestCopter(AutoTest):
|
||||||
|
|
||||||
self.reboot_sitl()
|
self.reboot_sitl()
|
||||||
# Test UAVCAN GPS ordering working
|
# Test UAVCAN GPS ordering working
|
||||||
gps1_det_text = self.wait_statustext("GPS 1: specified as UAVCAN.*", regex=True, check_context=True)
|
gps1_det_text = self.wait_text("GPS 1: specified as UAVCAN.*", regex=True, check_context=True)
|
||||||
gps2_det_text = self.wait_statustext("GPS 2: specified as UAVCAN.*", regex=True, check_context=True)
|
gps2_det_text = self.wait_text("GPS 2: specified as UAVCAN.*", regex=True, check_context=True)
|
||||||
gps1_nodeid = int(gps1_det_text.split('-')[1])
|
gps1_nodeid = int(gps1_det_text.split('-')[1])
|
||||||
gps2_nodeid = int(gps2_det_text.split('-')[1])
|
gps2_nodeid = int(gps2_det_text.split('-')[1])
|
||||||
if gps1_nodeid is None or gps2_nodeid is None:
|
if gps1_nodeid is None or gps2_nodeid is None:
|
||||||
|
@ -2145,11 +2145,11 @@ class AutoTestCopter(AutoTest):
|
||||||
gps1_det_text = None
|
gps1_det_text = None
|
||||||
gps2_det_text = None
|
gps2_det_text = None
|
||||||
try:
|
try:
|
||||||
gps1_det_text = self.wait_statustext("GPS 1: specified as UAVCAN.*", regex=True, check_context=True)
|
gps1_det_text = self.wait_text("GPS 1: specified as UAVCAN.*", regex=True, check_context=True)
|
||||||
except AutoTestTimeoutException:
|
except AutoTestTimeoutException:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
gps2_det_text = self.wait_statustext("GPS 2: specified as UAVCAN.*", regex=True, check_context=True)
|
gps2_det_text = self.wait_text("GPS 2: specified as UAVCAN.*", regex=True, check_context=True)
|
||||||
except AutoTestTimeoutException:
|
except AutoTestTimeoutException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -968,8 +968,8 @@ class FRSkySPort(FRSky):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def check_poll(self):
|
def check_poll(self):
|
||||||
self.progress("check poll")
|
|
||||||
now = self.get_time()
|
now = self.get_time()
|
||||||
|
# self.progress("check poll (%u)" % now)
|
||||||
|
|
||||||
# sometimes ArduPilot will not respond to a poll - for
|
# sometimes ArduPilot will not respond to a poll - for
|
||||||
# example, if you poll an unhealthy RPM sensor then we will
|
# example, if you poll an unhealthy RPM sensor then we will
|
||||||
|
@ -4114,6 +4114,13 @@ class AutoTest(ABC):
|
||||||
return
|
return
|
||||||
context.collections[msg_type] = []
|
context.collections[msg_type] = []
|
||||||
|
|
||||||
|
def context_collection(self, msg_type):
|
||||||
|
'''return messages in collection'''
|
||||||
|
context = self.context_get()
|
||||||
|
if msg_type not in context.collections:
|
||||||
|
raise NotAchievedException("Not collecting (%s)" % str(msg_type))
|
||||||
|
return context.collections[msg_type]
|
||||||
|
|
||||||
def context_clear_collection(self, msg_type):
|
def context_clear_collection(self, msg_type):
|
||||||
'''clear collection of message type msg_type'''
|
'''clear collection of message type msg_type'''
|
||||||
context = self.context_get()
|
context = self.context_get()
|
||||||
|
@ -4671,7 +4678,7 @@ class AutoTest(ABC):
|
||||||
#################################################
|
#################################################
|
||||||
def delay_sim_time(self, seconds_to_wait):
|
def delay_sim_time(self, seconds_to_wait):
|
||||||
"""Wait some second in SITL time."""
|
"""Wait some second in SITL time."""
|
||||||
self.drain_mav_unparsed()
|
self.drain_mav()
|
||||||
tstart = self.get_sim_time()
|
tstart = self.get_sim_time()
|
||||||
tnow = tstart
|
tnow = tstart
|
||||||
self.progress("Delaying %f seconds" % (seconds_to_wait,))
|
self.progress("Delaying %f seconds" % (seconds_to_wait,))
|
||||||
|
@ -5386,7 +5393,7 @@ Also, ignores heartbeats not from our target system'''
|
||||||
|
|
||||||
def wait_ekf_flags(self, required_value, error_bits, timeout=30):
|
def wait_ekf_flags(self, required_value, error_bits, timeout=30):
|
||||||
self.progress("Waiting for EKF value %u" % required_value)
|
self.progress("Waiting for EKF value %u" % required_value)
|
||||||
self.drain_mav_unparsed()
|
self.drain_mav()
|
||||||
last_print_time = 0
|
last_print_time = 0
|
||||||
tstart = self.get_sim_time()
|
tstart = self.get_sim_time()
|
||||||
while timeout is None or self.get_sim_time_cached() < tstart + timeout:
|
while timeout is None or self.get_sim_time_cached() < tstart + timeout:
|
||||||
|
@ -5440,22 +5447,28 @@ Also, ignores heartbeats not from our target system'''
|
||||||
raise AutoTestTimeoutException("Failed to get EKF.flags=%u disabled" % not_required_value)
|
raise AutoTestTimeoutException("Failed to get EKF.flags=%u disabled" % not_required_value)
|
||||||
|
|
||||||
def wait_text(self, *args, **kwargs):
|
def wait_text(self, *args, **kwargs):
|
||||||
return self.wait_statustext(*args, **kwargs)
|
'''wait for text to appear from vehicle, return that text'''
|
||||||
|
statustext = self.wait_statustext(*args, **kwargs)
|
||||||
|
if statustext is None:
|
||||||
|
return None
|
||||||
|
return statustext.text
|
||||||
|
|
||||||
def statustext_in_collections(self, text, regex=False):
|
def statustext_in_collections(self, text, regex=False):
|
||||||
|
'''searches for text in STATUSTEXT collection, returns message if found'''
|
||||||
c = self.context_get()
|
c = self.context_get()
|
||||||
if "STATUSTEXT" not in c.collections:
|
if "STATUSTEXT" not in c.collections:
|
||||||
raise NotAchievedException("Asked to check context but it isn't collecting!")
|
raise NotAchievedException("Asked to check context but it isn't collecting!")
|
||||||
for statustext in [x.text for x in c.collections["STATUSTEXT"]]:
|
for x in c.collections["STATUSTEXT"]:
|
||||||
|
self.progress(" statustext=%s vs text=%s" % (x.text, text))
|
||||||
if regex:
|
if regex:
|
||||||
if re.match(text, statustext):
|
if re.match(text, x.text):
|
||||||
return statustext
|
return x
|
||||||
elif text.lower() in statustext.lower():
|
elif text.lower() in x.text.lower():
|
||||||
return statustext
|
return x
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def wait_statustext(self, text, timeout=20, the_function=None, check_context=False, regex=False, wallclock_timeout=False):
|
def wait_statustext(self, text, timeout=20, the_function=None, check_context=False, regex=False, wallclock_timeout=False):
|
||||||
"""Wait for a specific STATUSTEXT."""
|
"""Wait for a specific STATUSTEXT, return that statustext message"""
|
||||||
|
|
||||||
# Statustexts are often triggered by something we've just
|
# Statustexts are often triggered by something we've just
|
||||||
# done, so we have to be careful not to read any traffic that
|
# done, so we have to be careful not to read any traffic that
|
||||||
|
@ -5484,11 +5497,11 @@ Also, ignores heartbeats not from our target system'''
|
||||||
self.re_match = re.match(text, m.text)
|
self.re_match = re.match(text, m.text)
|
||||||
if self.re_match:
|
if self.re_match:
|
||||||
statustext_found = True
|
statustext_found = True
|
||||||
statustext_full = m.text
|
statustext_full = m
|
||||||
if text.lower() in m.text.lower():
|
if text.lower() in m.text.lower():
|
||||||
self.progress("Received expected text: %s" % m.text.lower())
|
self.progress("Received expected text: %s" % m.text.lower())
|
||||||
statustext_found = True
|
statustext_found = True
|
||||||
statustext_full = m.text
|
statustext_full = m
|
||||||
|
|
||||||
self.install_message_hook(mh)
|
self.install_message_hook(mh)
|
||||||
if wallclock_timeout:
|
if wallclock_timeout:
|
||||||
|
@ -5937,7 +5950,7 @@ Also, ignores heartbeats not from our target system'''
|
||||||
'''mavlink2 required'''
|
'''mavlink2 required'''
|
||||||
target_system = 1
|
target_system = 1
|
||||||
target_component = 1
|
target_component = 1
|
||||||
self.drain_mav_unparsed()
|
self.drain_mav()
|
||||||
self.progress("Sending mission_request_list")
|
self.progress("Sending mission_request_list")
|
||||||
tstart = self.get_sim_time()
|
tstart = self.get_sim_time()
|
||||||
self.mav.mav.mission_request_list_send(target_system,
|
self.mav.mav.mission_request_list_send(target_system,
|
||||||
|
@ -7525,7 +7538,7 @@ Also, ignores heartbeats not from our target system'''
|
||||||
def poll_message(self, message_id, timeout=10):
|
def poll_message(self, message_id, timeout=10):
|
||||||
if type(message_id) == str:
|
if type(message_id) == str:
|
||||||
message_id = eval("mavutil.mavlink.MAVLINK_MSG_ID_%s" % message_id)
|
message_id = eval("mavutil.mavlink.MAVLINK_MSG_ID_%s" % message_id)
|
||||||
self.drain_mav_unparsed()
|
self.drain_mav()
|
||||||
tstart = self.get_sim_time() # required for timeout in run_cmd_get_ack to work
|
tstart = self.get_sim_time() # required for timeout in run_cmd_get_ack to work
|
||||||
self.send_poll_message(message_id)
|
self.send_poll_message(message_id)
|
||||||
self.run_cmd_get_ack(
|
self.run_cmd_get_ack(
|
||||||
|
@ -9342,7 +9355,7 @@ switch value'''
|
||||||
self.progress("received param (0x%02x) (id=%u value=%u)" %
|
self.progress("received param (0x%02x) (id=%u value=%u)" %
|
||||||
(value, param_id, param_value))
|
(value, param_id, param_value))
|
||||||
frame_type = param_value
|
frame_type = param_value
|
||||||
hb = self.wait_heartbeat()
|
hb = self.mav.messages['HEARTBEAT']
|
||||||
hb_type = hb.type
|
hb_type = hb.type
|
||||||
self.progress("validate_params: HEARTBEAT type==%f frsky==%f param_id=%u" % (hb_type, frame_type, param_id))
|
self.progress("validate_params: HEARTBEAT type==%f frsky==%f param_id=%u" % (hb_type, frame_type, param_id))
|
||||||
if param_id != 1:
|
if param_id != 1:
|
||||||
|
@ -9390,7 +9403,8 @@ switch value'''
|
||||||
while len(wants):
|
while len(wants):
|
||||||
self.progress("Still wanting (%s)" % ",".join([("0x%02x" % x) for x in wants.keys()]))
|
self.progress("Still wanting (%s)" % ",".join([("0x%02x" % x) for x in wants.keys()]))
|
||||||
wants_copy = copy.copy(wants)
|
wants_copy = copy.copy(wants)
|
||||||
t2 = self.get_sim_time()
|
self.drain_mav()
|
||||||
|
t2 = self.get_sim_time_cached()
|
||||||
if t2 - tstart > 300:
|
if t2 - tstart > 300:
|
||||||
self.progress("Failed to get frsky passthrough data")
|
self.progress("Failed to get frsky passthrough data")
|
||||||
self.progress("Counts of sensor_id polls sent:")
|
self.progress("Counts of sensor_id polls sent:")
|
||||||
|
@ -9425,17 +9439,24 @@ switch value'''
|
||||||
# test we get statustext strings. This relies on ArduPilot
|
# test we get statustext strings. This relies on ArduPilot
|
||||||
# emitting statustext strings when we fetch parameters. (or,
|
# emitting statustext strings when we fetch parameters. (or,
|
||||||
# now, an updating-barometer statustext)
|
# now, an updating-barometer statustext)
|
||||||
tstart = self.get_sim_time_cached()
|
tstart = self.get_sim_time()
|
||||||
old_data = None
|
old_data = None
|
||||||
text = ""
|
text = ""
|
||||||
target_text = self.mav.recv_match(
|
self.context_collect('STATUSTEXT')
|
||||||
type='STATUSTEXT',
|
self.run_cmd(mavutil.mavlink.MAV_CMD_PREFLIGHT_CALIBRATION,
|
||||||
blocking=True,
|
0, # p1
|
||||||
timeout=10
|
0, # p2
|
||||||
)
|
1, # p3, baro
|
||||||
self.progress("Got STATUSTEXT: %s, waiting for same text from frsky" % target_text.text)
|
0, # p4
|
||||||
|
0, # p5
|
||||||
|
0, # p6
|
||||||
|
0) # p7
|
||||||
|
|
||||||
|
received_frsky_texts = []
|
||||||
|
last_len_received_statustexts = 0
|
||||||
while True:
|
while True:
|
||||||
now = self.get_sim_time()
|
self.drain_mav()
|
||||||
|
now = self.get_sim_time_cached()
|
||||||
if now - tstart > 60: # it can take a *long* time to get these messages down!
|
if now - tstart > 60: # it can take a *long* time to get these messages down!
|
||||||
raise NotAchievedException("Did not get statustext in time")
|
raise NotAchievedException("Did not get statustext in time")
|
||||||
frsky.update()
|
frsky.update()
|
||||||
|
@ -9459,14 +9480,32 @@ switch value'''
|
||||||
if (x & 0x7f) == 0x00:
|
if (x & 0x7f) == 0x00:
|
||||||
last = True
|
last = True
|
||||||
if last:
|
if last:
|
||||||
m = re.match(target_text.text, text)
|
m = None
|
||||||
|
text = text.rstrip("\0")
|
||||||
|
self.progress("Received frsky text (%s)" % (text,))
|
||||||
|
self.progress("context texts: %s" % str([x.text for x in self.context_collection('STATUSTEXT')]))
|
||||||
|
m = self.statustext_in_collections(text)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
want_sev = target_text.severity
|
want_sev = m.severity
|
||||||
if severity != want_sev:
|
if severity != want_sev:
|
||||||
raise NotAchievedException("Incorrect severity; want=%u got=%u" % (want_sev, severity))
|
raise NotAchievedException("Incorrect severity; want=%u got=%u" % (want_sev, severity))
|
||||||
self.progress("Got statustext (%s)" % m.group(0))
|
self.progress("Got statustext (%s)" % m.text)
|
||||||
break
|
break
|
||||||
|
received_frsky_texts.append((severity, text))
|
||||||
text = ""
|
text = ""
|
||||||
|
received_statustexts = self.context_collection('STATUSTEXT')
|
||||||
|
if len(received_statustexts) != last_len_received_statustexts:
|
||||||
|
last_len_received_statustexts = len(received_statustexts)
|
||||||
|
self.progress("received statustexts: %s" % str([x.text for x in received_statustexts]))
|
||||||
|
self.progress("received frsky texts: %s" % str(received_frsky_texts))
|
||||||
|
for (want_sev, text) in received_frsky_texts:
|
||||||
|
for m in received_statustexts:
|
||||||
|
if m.text == text:
|
||||||
|
if want_sev != m.severity:
|
||||||
|
raise NotAchievedException("Incorrect severity; want=%u got=%u" % (want_sev, severity))
|
||||||
|
self.progress("Got statustext (%s)" % text)
|
||||||
|
break
|
||||||
|
self.context_stop_collecting('STATUSTEXT')
|
||||||
|
|
||||||
self.wait_ready_to_arm()
|
self.wait_ready_to_arm()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue