Skip to content

Commit aca6900

Browse files
committed
feat(flightcontroller): Make MAVFTP more robust on F4 processors
1 parent f77bfd9 commit aca6900

1 file changed

Lines changed: 85 additions & 8 deletions

File tree

ardupilot_methodic_configurator/backend_flightcontroller.py

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from ardupilot_methodic_configurator.annotate_params import Par
3232
from ardupilot_methodic_configurator.argparse_check_range import CheckRange
3333
from ardupilot_methodic_configurator.backend_flightcontroller_info import BackendFlightcontrollerInfo
34-
from ardupilot_methodic_configurator.backend_mavftp import MAVFTP
34+
from ardupilot_methodic_configurator.backend_mavftp import MAVFTP, MAVFTPSettings
3535

3636
# pylint: disable=too-many-lines
3737

@@ -596,21 +596,82 @@ def __download_params_via_mavlink(
596596
break
597597
return parameters
598598

599+
def _create_robust_mavftp_settings(self) -> MAVFTPSettings:
600+
"""
601+
Create robust MAVFTP settings optimized for STM32 F4 controllers under workload.
602+
603+
Returns:
604+
MAVFTPSettings: Configured settings with increased timeouts and reduced burst sizes
605+
606+
"""
607+
return MAVFTPSettings(
608+
[
609+
("debug", int, 0),
610+
("pkt_loss_tx", int, 0),
611+
("pkt_loss_rx", int, 0),
612+
("max_backlog", int, 3), # Reduced backlog for better reliability
613+
("burst_read_size", int, 60), # Smaller burst size for stability
614+
("write_size", int, 60),
615+
("write_qsize", int, 3),
616+
("idle_detection_time", float, 8.0), # Increased for heavy workload scenarios
617+
("read_retry_time", float, 3.0), # Increased retry time
618+
("retry_time", float, 2.0), # Increased retry time
619+
]
620+
)
621+
599622
def download_params_via_mavftp(
600623
self, progress_callback: Union[None, Callable[[int, int], None]] = None
601624
) -> tuple[dict[str, float], dict[str, "Par"]]:
602625
if self.master is None:
603626
return {}, {}
604-
mavftp = MAVFTP(self.master, target_system=self.master.target_system, target_component=self.master.target_component)
627+
628+
# Create more robust MAVFTP settings for parameter download
629+
# STM32 F4 controllers under workload need longer timeouts
630+
mavftp_settings = self._create_robust_mavftp_settings()
631+
632+
mavftp = MAVFTP(
633+
self.master,
634+
target_system=self.master.target_system,
635+
target_component=self.master.target_component,
636+
settings=mavftp_settings,
637+
)
605638

606639
def get_params_progress_callback(completion: float) -> None:
607640
if progress_callback is not None and completion is not None:
608641
progress_callback(int(completion * 100), 100)
609642

610643
complete_param_filename = "complete.param"
611644
default_param_filename = "00_default.param"
612-
mavftp.cmd_getparams([complete_param_filename, default_param_filename], progress_callback=get_params_progress_callback)
613-
ret = mavftp.process_ftp_reply("getparams", timeout=10)
645+
646+
# Retry logic for increased robustness with STM32 F4 controllers under workload
647+
max_retries = 3
648+
base_timeout = 15
649+
650+
for attempt in range(max_retries):
651+
try:
652+
mavftp.cmd_getparams(
653+
[complete_param_filename, default_param_filename], progress_callback=get_params_progress_callback
654+
)
655+
# Progressive timeout increase for each retry attempt
656+
timeout = base_timeout * (2**attempt) # 15s, 30s, 60s
657+
logging_info(_("Attempt %d/%d: Requesting parameters with %ds timeout"), attempt + 1, max_retries, timeout)
658+
ret = mavftp.process_ftp_reply("getparams", timeout=timeout)
659+
660+
if ret.error_code == 0:
661+
break # Success, exit retry loop
662+
663+
if attempt < max_retries - 1: # Don't sleep after last attempt
664+
sleep_time = 2**attempt # 1s, 2s, 4s exponential backoff
665+
logging_warning(_("Parameter download attempt %d failed, retrying in %ds..."), attempt + 1, sleep_time)
666+
time_sleep(sleep_time)
667+
else:
668+
logging_error(_("All %d parameter download attempts failed"), max_retries)
669+
670+
except Exception as e:
671+
logging_error(_("Exception during parameter download attempt %d: %s"), attempt + 1, str(e))
672+
if attempt < max_retries - 1:
673+
sleep_time = 2**attempt
674+
time_sleep(sleep_time)
614675
pdict = {}
615676
# add a file sync operation to ensure the file is completely written
616677
time_sleep(0.3)
@@ -1077,14 +1138,23 @@ def upload_file(
10771138
"""Upload a file to the flight controller."""
10781139
if self.master is None:
10791140
return False
1080-
mavftp = MAVFTP(self.master, target_system=self.master.target_system, target_component=self.master.target_component)
1141+
1142+
# Use robust MAVFTP settings for better reliability with STM32 F4 controllers
1143+
mavftp_settings = self._create_robust_mavftp_settings()
1144+
mavftp = MAVFTP(
1145+
self.master,
1146+
target_system=self.master.target_system,
1147+
target_component=self.master.target_component,
1148+
settings=mavftp_settings,
1149+
)
10811150

10821151
def put_progress_callback(completion: float) -> None:
10831152
if progress_callback is not None and completion is not None:
10841153
progress_callback(int(completion * 100), 100)
10851154

10861155
mavftp.cmd_put([local_filename, remote_filename], progress_callback=put_progress_callback)
1087-
ret = mavftp.process_ftp_reply("CreateFile", timeout=10)
1156+
# Increased timeout for better reliability
1157+
ret = mavftp.process_ftp_reply("CreateFile", timeout=20)
10881158
if ret.error_code != 0:
10891159
ret.display_message()
10901160
return ret.error_code == 0
@@ -1104,7 +1174,14 @@ def download_last_flight_log(
11041174
logging_error(error_msg)
11051175
return False
11061176

1107-
mavftp = MAVFTP(self.master, target_system=self.master.target_system, target_component=self.master.target_component)
1177+
# Use robust MAVFTP settings for better reliability with STM32 F4 controllers
1178+
mavftp_settings = self._create_robust_mavftp_settings()
1179+
mavftp = MAVFTP(
1180+
self.master,
1181+
target_system=self.master.target_system,
1182+
target_component=self.master.target_component,
1183+
settings=mavftp_settings,
1184+
)
11081185

11091186
def get_progress_callback(completion: float) -> None:
11101187
if progress_callback is not None and completion is not None:
@@ -1193,7 +1270,7 @@ def _get_log_number_by_scanning(self, mavftp: MAVFTP) -> Union[int, None]:
11931270
# Test if this log file exists
11941271
temp_test_file = f"temp_test_{mid}.tmp"
11951272
mavftp.cmd_get([remote_filename, temp_test_file])
1196-
ret = mavftp.process_ftp_reply("OpenFileRO", timeout=5) # Must be > idle_detection_time (3.7s)
1273+
ret = mavftp.process_ftp_reply("OpenFileRO", timeout=2) # Short timeout for existence check
11971274

11981275
# Clean up the temp file if it was created
11991276
if os.path.exists(temp_test_file):

0 commit comments

Comments
 (0)