@@ -11914,7 +11914,7 @@ def GroundEffectCompensation_takeOffExpected(self):
1191411914 (duration, want_lt))
1191511915
1191611916 def TakeoffGroundEffectAlt(self):
11917- '''Test TKOFF_GNDEFF_ALT controls ground effect altitude threshold '''
11917+ '''Test TKOFF_GNDEFF_ALT and TKOFF_GNDEFF_TMO control ground effect '''
1191811918 self.context_push()
1191911919 self.set_parameter("LOG_FILE_DSRMROT", 1)
1192011920
@@ -11949,6 +11949,28 @@ def TakeoffGroundEffectAlt(self):
1194911949 "Smaller threshold should have shorter ground effect (small=%fs >= large=%fs)"
1195011950 % (total_small, total_large))
1195111951
11952+ # Subtest C: TKOFF_GNDEFF_TMO requires both timeout AND altitude
11953+ # With small altitude threshold but timeout set, ground effect should persist longer
11954+ self.start_subtest("TKOFF_GNDEFF_TMO extends ground effect duration")
11955+ self.set_parameters({
11956+ "TKOFF_GNDEFF_ALT": 0.5, # Small threshold - would clear quickly without timeout
11957+ "TKOFF_GNDEFF_TMO": 3, # Require 3s timeout as well
11958+ })
11959+ self.reboot_sitl()
11960+ self.takeoff(5, mode='ALT_HOLD')
11961+ self.delay_sim_time(5)
11962+ self.change_mode('LAND')
11963+ self.wait_disarmed()
11964+ durations_tmo = self.get_takeoffexpected_durations_from_current_onboard_log(ignore_multi=True)
11965+ total_tmo = sum(durations_tmo)
11966+ self.progress("takeoff_expected total with GNDEFF_TMO=3: %fs" % total_tmo)
11967+
11968+ # With timeout, ground effect should persist longer than without (even with small alt threshold)
11969+ if total_tmo <= total_small:
11970+ raise NotAchievedException(
11971+ "TKOFF_GNDEFF_TMO should extend ground effect (tmo=%fs <= no_tmo=%fs)"
11972+ % (total_tmo, total_small))
11973+
1195211974 self.context_pop()
1195311975 self.reboot_sitl()
1195411976
@@ -12005,6 +12027,42 @@ def VibrationRectificationBiasLearning(self):
1200512027 if abs(vrfb_z) > 0.001:
1200612028 raise NotAchievedException("INS_ACC_VRFB_Z should remain 0, got %f" % vrfb_z)
1200712029
12030+ # D: Verify bit 2 (inhibit EKF ground learning) works with full bitmask
12031+ # Value 7 = learn+save + use + inhibit ground learning
12032+ self.start_subtest("Full bitmask (7) with ground learning inhibit")
12033+ self.set_parameters({
12034+ "INS_ACC_VRFB_Z": 0,
12035+ "ACC_ZBIAS_LEARN": 7,
12036+ "SIM_ACC1_BIAS_Z": 0.15,
12037+ })
12038+ self.reboot_sitl()
12039+ self.wait_ready_to_arm()
12040+ # Fly and verify learning still works (bit 2 only affects disarmed state)
12041+ self.takeoff(10, mode='LOITER')
12042+ self.delay_sim_time(30)
12043+ self.land_and_disarm()
12044+ vrfb_z = self.get_parameter("INS_ACC_VRFB_Z")
12045+ self.progress("INS_ACC_VRFB_Z with full bitmask (7): %f" % vrfb_z)
12046+ if abs(vrfb_z) < 0.01:
12047+ raise NotAchievedException(
12048+ "INS_ACC_VRFB_Z should be non-zero with bitmask 7, got %f" % vrfb_z)
12049+
12050+ # E: Verify frozen correction survives flight (proxy for lane switch survival)
12051+ # After learning, fly again and verify the saved bias is still applied
12052+ self.start_subtest("Frozen correction persists across flights")
12053+ saved_vrfb_z = vrfb_z
12054+ self.reboot_sitl()
12055+ self.wait_ready_to_arm()
12056+ self.takeoff(10, mode='LOITER')
12057+ self.delay_sim_time(10)
12058+ self.land_and_disarm()
12059+ vrfb_z = self.get_parameter("INS_ACC_VRFB_Z")
12060+ # The saved bias should persist (may drift slightly due to continued learning)
12061+ if abs(vrfb_z) < 0.01:
12062+ raise NotAchievedException(
12063+ "INS_ACC_VRFB_Z should persist across flights, got %f" % vrfb_z)
12064+ self.progress("INS_ACC_VRFB_Z persisted: was %f, now %f" % (saved_vrfb_z, vrfb_z))
12065+
1200812066 self.context_pop()
1200912067 self.reboot_sitl()
1201012068
0 commit comments