Tools: autotest: add test for ekf navigation speed limits

This commit is contained in:
Peter Barker 2018-10-03 08:28:21 +10:00 committed by Andrew Tridgell
parent 3be9f35264
commit 14d2012f54
2 changed files with 74 additions and 12 deletions

View File

@ -142,14 +142,17 @@ class AutoTestCopter(AutoTest):
self.progress("Ran command") self.progress("Ran command")
self.wait_for_alt(alt_min) self.wait_for_alt(alt_min)
def takeoff(self, alt_min=30, takeoff_throttle=1700): def takeoff(self,
alt_min=30,
takeoff_throttle=1700,
require_absolute=True):
"""Takeoff get to 30m altitude.""" """Takeoff get to 30m altitude."""
self.progress("TAKEOFF") self.progress("TAKEOFF")
self.mavproxy.send('switch 6\n') # stabilize mode self.mavproxy.send('switch 6\n') # stabilize mode
self.wait_mode('STABILIZE') self.wait_mode('STABILIZE')
if not self.armed(): if not self.armed():
self.progress("Waiting reading for arm") self.progress("Waiting reading for arm")
self.wait_ready_to_arm() self.wait_ready_to_arm(require_absolute=require_absolute)
self.set_rc(3, 1000) self.set_rc(3, 1000)
self.arm_vehicle() self.arm_vehicle()
self.set_rc(3, takeoff_throttle) self.set_rc(3, takeoff_throttle)
@ -951,6 +954,57 @@ class AutoTestCopter(AutoTest):
self.progress("CIRCLE OK for %u seconds" % holdtime) self.progress("CIRCLE OK for %u seconds" % holdtime)
# fly_optical_flow_limits - test EKF navigation limiting
def fly_optical_flow_limits(self):
ex = None
self.context_push()
try:
self.set_parameter("SIM_FLOW_ENABLE", 1)
self.set_parameter("FLOW_ENABLE", 1)
self.set_parameter("RNGFND_TYPE", 1)
self.set_parameter("RNGFND_MIN_CM", 0)
self.set_parameter("RNGFND_MAX_CM", 4000)
self.set_parameter("RNGFND_PIN", 0)
self.set_parameter("RNGFND_SCALING", 12.12, epsilon=0.01)
self.set_parameter("SIM_GPS_DISABLE", 1)
self.reboot_sitl()
self.takeoff(alt_min=2, require_absolute=False)
self.mavproxy.send('mode loiter\n')
self.wait_mode('LOITER')
# speed should be limited to <10m/s
self.set_rc(2, 1000)
tstart = self.get_sim_time()
timeout = 60
while self.get_sim_time_cached() - tstart < timeout:
m = self.mav.recv_match(type='VFR_HUD', blocking=True)
spd = m.groundspeed
self.progress("%0.1f: Low Speed: %f" %
(self.get_sim_time_cached() - tstart, spd))
if spd > 8:
self.progress("Speed should be limited by EKF optical flow limits")
raise NotAchievedException()
self.progress("Moving higher")
self.change_alt(60)
self.wait_groundspeed(10, 100, timeout=60)
except Exception as e:
ex = e
self.set_rc(2, 1500)
self.context_pop()
self.reboot_sitl()
if ex is not None:
raise ex
# fly_autotune - autotune the virtual vehicle # fly_autotune - autotune the virtual vehicle
def fly_autotune(self): def fly_autotune(self):
@ -1893,6 +1947,10 @@ class AutoTestCopter(AutoTest):
# Circle mode # Circle mode
self.run_test("Fly CIRCLE mode", self.fly_circle) self.run_test("Fly CIRCLE mode", self.fly_circle)
# Optical flow limits test
self.run_test("Fly Optical Flow limits",
self.fly_optical_flow_limits)
# RTL # RTL
self.run_test("RTL after CIRCLE mode", self.fly_RTL) self.run_test("RTL after CIRCLE mode", self.fly_RTL)

View File

@ -640,13 +640,14 @@ class AutoTest(ABC):
return True return True
return False return False
def set_parameter(self, name, value, add_to_context=True): def set_parameter(self, name, value, add_to_context=True, epsilon=0.00001):
"""Set parameters from vehicle.""" """Set parameters from vehicle."""
old_value = self.get_parameter(name, retry=2) old_value = self.get_parameter(name, retry=2)
for i in range(1, 10): for i in range(1, 10):
self.mavproxy.send("param set %s %s\n" % (name, str(value))) self.mavproxy.send("param set %s %s\n" % (name, str(value)))
returned_value = self.get_parameter(name) returned_value = self.get_parameter(name)
if returned_value == float(value): delta = float(value) - returned_value
if abs(delta) < epsilon:
# yes, exactly equal. # yes, exactly equal.
if add_to_context: if add_to_context:
self.context_get().parameters.append((name, old_value)) self.context_get().parameters.append((name, old_value))
@ -1158,12 +1159,13 @@ class AutoTest(ABC):
# self.mav.flightmode, mode)) # self.mav.flightmode, mode))
self.progress("Got mode %s" % mode) self.progress("Got mode %s" % mode)
def wait_ready_to_arm(self, timeout=None): def wait_ready_to_arm(self, timeout=None, require_absolute=True):
# wait for EKF checks to pass # wait for EKF checks to pass
self.progress("Waiting reading for arm") self.progress("Waiting reading for arm")
return self.wait_ekf_happy(timeout=timeout) return self.wait_ekf_happy(timeout=timeout,
require_absolute=require_absolute)
def wait_ekf_happy(self, timeout=30): def wait_ekf_happy(self, timeout=30, require_absolute=True):
"""Wait for EKF to be happy""" """Wait for EKF to be happy"""
""" if using SITL estimates directly """ """ if using SITL estimates directly """
@ -1176,14 +1178,16 @@ class AutoTest(ABC):
mavutil.mavlink.ESTIMATOR_VELOCITY_HORIZ | mavutil.mavlink.ESTIMATOR_VELOCITY_HORIZ |
mavutil.mavlink.ESTIMATOR_VELOCITY_VERT | mavutil.mavlink.ESTIMATOR_VELOCITY_VERT |
mavutil.mavlink.ESTIMATOR_POS_HORIZ_REL | mavutil.mavlink.ESTIMATOR_POS_HORIZ_REL |
mavutil.mavlink.ESTIMATOR_POS_HORIZ_ABS | mavutil.mavlink.ESTIMATOR_PRED_POS_HORIZ_REL)
mavutil.mavlink.ESTIMATOR_POS_VERT_ABS |
mavutil.mavlink.ESTIMATOR_PRED_POS_HORIZ_REL |
mavutil.mavlink.ESTIMATOR_PRED_POS_HORIZ_ABS)
# none of these bits must be set for arming to happen: # none of these bits must be set for arming to happen:
error_bits = (mavutil.mavlink.ESTIMATOR_CONST_POS_MODE | error_bits = (mavutil.mavlink.ESTIMATOR_CONST_POS_MODE |
mavutil.mavlink.ESTIMATOR_GPS_GLITCH |
mavutil.mavlink.ESTIMATOR_ACCEL_ERROR) mavutil.mavlink.ESTIMATOR_ACCEL_ERROR)
if require_absolute:
required_value |= (mavutil.mavlink.ESTIMATOR_POS_HORIZ_ABS |
mavutil.mavlink.ESTIMATOR_POS_VERT_ABS |
mavutil.mavlink.ESTIMATOR_PRED_POS_HORIZ_ABS)
error_bits |= mavutil.mavlink.ESTIMATOR_GPS_GLITCH
self.progress("Waiting for EKF value %u" % required_value) self.progress("Waiting for EKF value %u" % required_value)
last_err_print_time = 0 last_err_print_time = 0
last_print_time = 0 last_print_time = 0