From 65bfbbbbb9c2034b58b02e33a8333f4bf2a19b1d Mon Sep 17 00:00:00 2001 From: James O'SHANNESSY <12959316+joshanne@users.noreply.github.com> Date: Fri, 20 Jun 2025 16:25:17 +1000 Subject: [PATCH] gui: Add support to configure the connection device from the CLI Allows the user to predefine the connection device by using: dronecan_gui_tool.py --interface Also allows to preconfigure some of the other args in the setup window, so a user preconfigure and select only the device they care about. --- dronecan_gui_tool/main.py | 28 +++++++++++++++++++++++++++- dronecan_gui_tool/setup_window.py | 12 +++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/dronecan_gui_tool/main.py b/dronecan_gui_tool/main.py index 183b5cc..611ffc2 100644 --- a/dronecan_gui_tool/main.py +++ b/dronecan_gui_tool/main.py @@ -21,6 +21,12 @@ parser.add_argument("--debug", action='store_true', help="enable debugging") parser.add_argument("--dsdl", help="path to custom DSDL") parser.add_argument("--signing-passphrase", help="MAVLink2 signing passphrase", default=None) +parser.add_argument("--interface", help="skip the setup dialog by setting the device to connect to") +parser.add_argument("--baudrate", help="set the baudrate", type=int, default=115200) +parser.add_argument("--bitrate", help="set the bitrate of the CAN Bus", type=int, default=1000000) +parser.add_argument("--bus", help="set the CAN Bus number", type=int, default=1) +parser.add_argument("--filtered", action='store_true', help="enable filtering of DroneCAN traffic") +parser.add_argument("--target-system", help="set the targetted system", type=int, default=0) args = parser.parse_args() @@ -60,6 +66,8 @@ # # Importing other stuff once the logging has been configured # +from serial import SerialException + import dronecan from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QSplitter, QAction @@ -578,7 +586,18 @@ def main(): while True: # Asking the user to specify which interface to work with try: - iface, iface_kwargs, dsdl_directory = run_setup_window(get_app_icon(), args.dsdl) + if args.interface is not None: + iface = args.interface + iface_kwargs = {} + iface_kwargs['baudrate'] = int(args.baudrate) + iface_kwargs['bitrate'] = int(args.bitrate) + iface_kwargs['bus_number'] = int(args.bus) + iface_kwargs['filtered'] = bool(args.filtered) + iface_kwargs['mavlink_target_system'] = int(args.target_system) + iface_kwargs['mavlink_signing_key'] = str(args.signing_passphrase if args.signing_passphrase is not None else '') + dsdl_directory = args.dsdl + else: + iface, iface_kwargs, dsdl_directory = run_setup_window(get_app_icon(), args.dsdl, args.baudrate, args.bitrate, args.bus, args.filtered, args.target_system, args.signing_passphrase) if not iface: sys.exit(0) except Exception as ex: @@ -624,6 +643,13 @@ def main(): # allow unrecognized messages on startup: logger.warning('DroneCAN Transfer Error occurred on startup', exc_info=True) break + except SerialException as ex: + logger.error('DroneCAN node init failed', exc_info=True) + show_error('Error', 'Could not find serial port', ex, blocking=True) + + # The serial port had a fault, so reset args and the interface and return to the setup window + args.interface = None + iface = None except Exception as ex: logger.error('DroneCAN node init failed', exc_info=True) show_error('Fatal error', 'Could not initialize DroneCAN node', ex, blocking=True) diff --git a/dronecan_gui_tool/setup_window.py b/dronecan_gui_tool/setup_window.py index c86dbe2..26068c0 100644 --- a/dronecan_gui_tool/setup_window.py +++ b/dronecan_gui_tool/setup_window.py @@ -158,7 +158,7 @@ def get_list(self): return copy.copy(self._ifaces) -def run_setup_window(icon, dsdl_path=None): +def run_setup_window(icon, dsdl_path=None, config_baudrate=DEFAULT_BAUD_RATE, config_bitrate=1000000, config_can_bus=1, enable_filtering=False, mavlink_target_system=0, mavlink_signing_key=''): win = QDialog() win.setWindowTitle('Application Setup') win.setWindowIcon(icon) @@ -179,12 +179,12 @@ def run_setup_window(icon, dsdl_path=None): bitrate = QSpinBox(win) bitrate.setMaximum(1000000) bitrate.setMinimum(10000) - bitrate.setValue(1000000) + bitrate.setValue(config_bitrate) bus_number = QSpinBox(win) bus_number.setMaximum(4) bus_number.setMinimum(1) - bus_number.setValue(1) + bus_number.setValue(config_can_bus) baudrate = QComboBox(win) baudrate.setEditable(True) @@ -198,16 +198,18 @@ def run_setup_window(icon, dsdl_path=None): baudrate.setValidator(QIntValidator(min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES))) baudrate.insertItems(0, map(str, STANDARD_BAUD_RATES)) - baudrate.setCurrentText(str(DEFAULT_BAUD_RATE)) + baudrate.setCurrentText(str(config_baudrate)) filtered = QCheckBox('Enable Filtering') + filtered.setChecked(enable_filtering) target_system = QSpinBox(win) target_system.setMaximum(255) target_system.setMinimum(0) - target_system.setValue(0) + target_system.setValue(mavlink_target_system) signing_key = PasswordEdit(win) + signing_key.setText(mavlink_signing_key) dir_selection = directory_selection.DirectorySelectionWidget(win, 'Location of custom DSDL definitions [optional]', path=dsdl_path, directory_only=True)