From d2aef78a4be9d6fb7e2aea58791769991944fdae Mon Sep 17 00:00:00 2001 From: ken910606 Date: Wed, 20 May 2026 20:02:04 +0800 Subject: [PATCH] Update GUI 2.4.0: GPS Status --- src/GUI/drone_panel.py | 36 +++++++++++++++++++++++++-- src/GUI/gui.py | 51 ++++++++++++++++++++++++++++++++++++--- src/GUI/overview_table.py | 37 ++++++++++++++++------------ 3 files changed, 102 insertions(+), 22 deletions(-) diff --git a/src/GUI/drone_panel.py b/src/GUI/drone_panel.py index 3477126..1da0d7a 100644 --- a/src/GUI/drone_panel.py +++ b/src/GUI/drone_panel.py @@ -104,7 +104,7 @@ class DronePanel(QWidget): def _init_ui(self): """初始化UI""" self.setObjectName(f"panel_{self.drone_id}") - self.setFixedHeight(140) + self.setFixedHeight(160) _set_scaled_stylesheet(self, """ background-color: #2A2A2A; border-radius: 8px; @@ -196,8 +196,12 @@ class DronePanel(QWidget): # 第三行:高度 altitude_row = self._create_altitude_row() info_layout.addWidget(altitude_row) + + # 第四行:GNSS 定位狀態 + gnss_row = self._create_gnss_row() + info_layout.addWidget(gnss_row) - # 第四行:航向 + 速度 + # 第五行:航向 + 速度 nav_row = self._create_nav_row() info_layout.addWidget(nav_row) @@ -339,6 +343,34 @@ class DronePanel(QWidget): altitude_layout.addStretch() return altitude_row + + def _create_gnss_row(self): + """創建 GNSS 定位狀態行。""" + gnss_row = QWidget() + gnss_layout = QHBoxLayout(gnss_row) + gnss_layout.setContentsMargins(0, 0, 0, 0) + + fix_title = QLabel("定位:") + _set_scaled_stylesheet(fix_title, "color: #888; min-width: 50px;") + + self.fix_type_label = QLabel("--") + self.fix_type_label.setObjectName(f"{self.drone_id}_fix_type_label") + _set_scaled_stylesheet(self.fix_type_label, "color: #DDD;") + + error_title = QLabel("誤差(H/V):") + _set_scaled_stylesheet(error_title, "color: #888; margin-left: 8px;") + + self.gnss_error_label = QLabel("--") + self.gnss_error_label.setObjectName(f"{self.drone_id}_gnss_error") + _set_scaled_stylesheet(self.gnss_error_label, "color: #DDD;") + + gnss_layout.addWidget(fix_title) + gnss_layout.addWidget(self.fix_type_label) + gnss_layout.addWidget(error_title) + gnss_layout.addWidget(self.gnss_error_label) + gnss_layout.addStretch() + + return gnss_row def _create_position_row(self): """位置行已移除(位置座標不再顯示於面板)。""" diff --git a/src/GUI/gui.py b/src/GUI/gui.py index 56c78a3..4181593 100644 --- a/src/GUI/gui.py +++ b/src/GUI/gui.py @@ -147,7 +147,7 @@ class ToggleSwitch(QWidget): class ControlStationUI(QMainWindow): planning_finished = pyqtSignal(object) - VERSION = '2.3.1' + VERSION = '2.4.0' FONT_SCALE_MIN = 70 FONT_SCALE_MAX = 180 FONT_SCALE_DEFAULT = 100 @@ -414,7 +414,7 @@ class ControlStationUI(QMainWindow): self.right_vertical_splitter.setChildrenCollapsible(False) self.right_vertical_splitter.setStretchFactor(0, 0) self.right_vertical_splitter.setStretchFactor(1, 1) - self.right_vertical_splitter.setSizes([170, 700]) + self.right_vertical_splitter.setSizes([180, 640]) right_layout.addWidget(self.right_vertical_splitter) # 添加地圖 @@ -1072,7 +1072,7 @@ class ControlStationUI(QMainWindow): self.group_tab_widget.show() if hasattr(self, 'right_vertical_splitter'): total = sum(self.right_vertical_splitter.sizes()) or self.height() - group_height = getattr(self, '_last_group_panel_height', 170) + group_height = getattr(self, '_last_group_panel_height', 230) group_height = min(max(group_height, 120), max(120, total - 120)) self.right_vertical_splitter.setSizes([group_height, max(1, total - group_height)]) self.toggle_group_btn.setText("▼") @@ -2144,6 +2144,22 @@ class ControlStationUI(QMainWindow): if isinstance(panel, DronePanel): panel.update_field(field, text, color) + @staticmethod + def _format_gnss_fix_type(fix_type): + fix_labels = { + 0: "No GPS", + 1: "No GPS", + 2: "2D Fix", + 3: "3D Fix", + 4: "DGPS", + 5: "RTK Float", + 6: "RTK Fixed", + } + try: + return fix_labels.get(int(fix_type), f"Fix {fix_type}") + except (TypeError, ValueError): + return "--" + def update_overview_table(self, drone_id=None, field=None, value=None): if not hasattr(self, 'overview_table') or self.overview_table is None: return self.overview_table.set_drones(self.drones) @@ -2309,9 +2325,36 @@ class ControlStationUI(QMainWindow): alt = gps_data.get('alt', 0) if not hasattr(self.monitor, 'drone_gps'): self.monitor.drone_gps = {} - self.monitor.drone_gps[drone_id] = {'lat': lat, 'lon': lon, 'alt': alt} + self.monitor.drone_gps[drone_id] = gps_data.copy() self.queue_overview_update(drone_id, 'latitude', f"{lat:.6f}°") self.queue_overview_update(drone_id, 'longitude', f"{lon:.6f}°") + fix_type = gps_data.get('fix_type') + satellites_visible = gps_data.get('satellites_visible') + eph = gps_data.get('eph') + epv = gps_data.get('epv') + fix_text = self._format_gnss_fix_type(fix_type) + self.update_field(panel, drone_id, 'fix_type_label', fix_text) + if isinstance(eph, (int, float)) and isinstance(epv, (int, float)): + error_text = f"{eph:.1f}/{epv:.1f}" + else: + error_text = "--" + self.update_field(panel, drone_id, 'gnss_error', error_text) + self.queue_overview_update( + drone_id, 'fix_type', + fix_text + ) + self.queue_overview_update( + drone_id, 'satellites_visible', + str(satellites_visible) if satellites_visible is not None else "--" + ) + self.queue_overview_update( + drone_id, 'eph', + f"{eph:.2f}" if isinstance(eph, (int, float)) else "--" + ) + self.queue_overview_update( + drone_id, 'epv', + f"{epv:.2f}" if isinstance(epv, (int, float)) else "--" + ) elif msg_type == 'hud': hud_data = data diff --git a/src/GUI/overview_table.py b/src/GUI/overview_table.py index 1b739e3..5549530 100644 --- a/src/GUI/overview_table.py +++ b/src/GUI/overview_table.py @@ -6,8 +6,9 @@ class OverviewTable(QTableWidget): """總覽表格,顯示所有無人機的狀態資訊""" # 默認的資訊類型和映射 - DEFAULT_INFO_TYPES = ["模式", "ARM", "電壓", "經度", "緯度", "高度", "XY位置", "XY速度", "地速", "航向", - "空速", "油門", "海拔高度", "爬升率", "Roll", "Pitch", "Yaw", "丟包", "延遲"] + DEFAULT_INFO_TYPES = ["模式", "ARM", "電壓", "經度", "緯度", "FixType", "衛星數", "EPH", "EPV", + "高度", "XY位置", "XY速度", "地速", "航向", "空速", "油門", "海拔高度", + "爬升率", "Roll", "Pitch", "Yaw", "丟包", "延遲"] DEFAULT_INFO_TYPE_MAP = { "mode": 0, @@ -15,20 +16,24 @@ class OverviewTable(QTableWidget): "battery": 2, "longitude": 3, "latitude": 4, - "altitude": 5, - "local": 6, - "velocity": 7, - "groundspeed": 8, - "heading": 9, - "airspeed": 10, - "throttle": 11, - "hud_alt": 12, - "climb": 13, - "roll": 14, - "pitch": 15, - "yaw": 16, - "loss_rate": 17, - "ping": 18 + "fix_type": 5, + "satellites_visible": 6, + "eph": 7, + "epv": 8, + "altitude": 9, + "local": 10, + "velocity": 11, + "groundspeed": 12, + "heading": 13, + "airspeed": 14, + "throttle": 15, + "hud_alt": 16, + "climb": 17, + "roll": 18, + "pitch": 19, + "yaw": 20, + "loss_rate": 21, + "ping": 22 } def __init__(self, info_types=None, info_type_map=None, parent=None):