diff --git a/Tools/autotest/arduplane.py b/Tools/autotest/arduplane.py index 97c7b19b55f..d275812dc90 100644 --- a/Tools/autotest/arduplane.py +++ b/Tools/autotest/arduplane.py @@ -1557,14 +1557,7 @@ class AutoTestPlane(vehicle_test_suite.TestSuite): self.start_subtest("Test Failsafe: Deploy Parachute") self.load_mission("plane-parachute-mission.txt") self.set_current_waypoint(1) - self.set_parameters({ - "CHUTE_ENABLED": 1, - "CHUTE_TYPE": 10, - "SERVO9_FUNCTION": 27, - "SIM_PARA_ENABLE": 1, - "SIM_PARA_PIN": 9, - "FS_LONG_ACTN": 3, - }) + self.setup_simulated_parachute({"FS_LONG_ACTN": 3}) self.change_mode("AUTO") self.progress("Disconnecting GCS") self.set_heartbeat_rate(0) @@ -1979,17 +1972,42 @@ class AutoTestPlane(vehicle_test_suite.TestSuite): self.disarm_vehicle(force=True) self.reboot_sitl() - def Parachute(self): - '''Test Parachute''' - self.set_rc(9, 1000) - self.set_parameters({ + def setup_simulated_parachute(self, extra_parameters=None): + '''set the vehicle and its simulated parachute up, without firing it + + SIM_Parachute deploys as soon as the PWM on SIM_PARA_PIN reads 1250 + or more, and it begins watching that pin the moment the pin number + is set. Setting the pin in the same set_parameters() call as the + release servo's function therefore races the servo output: until + AP_Parachute has driven the channel to CHUTE_SERVO_OFF (1100 by + default, below the trigger) it still holds whatever the last test + left there, and anything at or above 1250 fires the chute during + setup. The "BANG!" then arrives before the test starts waiting for + it, and the real release later in the test is silent because the + chute has already gone. + + So configure the vehicle first, wait for the release servo to reach + its off position, and only then let the simulation watch the pin. + ''' + parameters = { "CHUTE_ENABLED": 1, "CHUTE_TYPE": 10, "SERVO9_FUNCTION": 27, - "SIM_PARA_ENABLE": 1, + } + if extra_parameters is not None: + parameters.update(extra_parameters) + self.set_parameters(parameters) + self.wait_servo_channel_value(9, 1250, comparator=operator.lt, timeout=10) + self.set_parameters({ "SIM_PARA_PIN": 9, + "SIM_PARA_ENABLE": 1, }) + def Parachute(self): + '''Test Parachute''' + self.set_rc(9, 1000) + self.setup_simulated_parachute() + self.load_mission("plane-parachute-mission.txt") self.set_current_waypoint(1) self.change_mode('AUTO') @@ -2002,14 +2020,7 @@ class AutoTestPlane(vehicle_test_suite.TestSuite): def ParachuteSinkRate(self): '''Test Parachute (SinkRate triggering)''' self.set_rc(9, 1000) - self.set_parameters({ - "CHUTE_ENABLED": 1, - "CHUTE_TYPE": 10, - "SERVO9_FUNCTION": 27, - "SIM_PARA_ENABLE": 1, - "SIM_PARA_PIN": 9, - "CHUTE_CRT_SINK": 9, - }) + self.setup_simulated_parachute({"CHUTE_CRT_SINK": 9}) self.progress("Takeoff") self.takeoff(alt=300) @@ -7545,14 +7556,7 @@ class AutoTestPlane(vehicle_test_suite.TestSuite): def DO_PARACHUTE(self): '''test triggering parachute via mavlink''' - self.set_parameters({ - "CHUTE_ENABLED": 1, - "CHUTE_TYPE": 10, - "SERVO9_FUNCTION": 27, - "SIM_PARA_ENABLE": 1, - "SIM_PARA_PIN": 9, - "FS_LONG_ACTN": 3, - }) + self.setup_simulated_parachute({"FS_LONG_ACTN": 3}) for command in self.run_cmd, self.run_cmd_int: # We release the parachute sitting on the ground, which the # vehicle permits only while it has never flown: