|
|
|
|
@ -32,7 +32,7 @@ from mission_group import (
|
|
|
|
|
# ================================================================================
|
|
|
|
|
|
|
|
|
|
class ControlStationUI(QMainWindow):
|
|
|
|
|
VERSION = '2.0.0'
|
|
|
|
|
VERSION = '2.0.1'
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super().__init__()
|
|
|
|
|
@ -43,8 +43,7 @@ class ControlStationUI(QMainWindow):
|
|
|
|
|
import queue
|
|
|
|
|
self.message_queue = queue.Queue()
|
|
|
|
|
|
|
|
|
|
# 初始化ROS2
|
|
|
|
|
rclpy.init()
|
|
|
|
|
# 初始化ROS2 Monitor(ROS2 本身在 main() 中已初始化)
|
|
|
|
|
self.monitor = DroneMonitor()
|
|
|
|
|
self.monitor.signals.update_signal.connect(self.update_ui)
|
|
|
|
|
|
|
|
|
|
@ -1723,8 +1722,42 @@ class ControlStationUI(QMainWindow):
|
|
|
|
|
event.accept()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
def main():
|
|
|
|
|
"""
|
|
|
|
|
GUI 應用程式的主入口點
|
|
|
|
|
|
|
|
|
|
標準 ROS2 + Qt 架構:
|
|
|
|
|
1. 在最外層/最前面只做一次 rclpy.init()
|
|
|
|
|
2. 啟動 Qt 應用程式
|
|
|
|
|
3. 在 finally 中做 rclpy.shutdown()
|
|
|
|
|
|
|
|
|
|
這樣可以確保所有 ROS2 相關操作都共享同一個初始化狀態
|
|
|
|
|
"""
|
|
|
|
|
# 第一步:在最外層只初始化一次 ROS2
|
|
|
|
|
print("🚀 [GUI] 初始化 ROS2...", flush=True)
|
|
|
|
|
rclpy.init()
|
|
|
|
|
print("✓ [GUI] ROS2 初始化完成", flush=True)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
# 第二步:啟動 Qt 應用程式
|
|
|
|
|
print("🚀 [GUI] 啟動 Qt 應用程式...", flush=True)
|
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
|
station = ControlStationUI()
|
|
|
|
|
station.show()
|
|
|
|
|
app.exec()
|
|
|
|
|
print("✓ [GUI] 應用程式已啟動", flush=True)
|
|
|
|
|
|
|
|
|
|
# 第三步:進入 Qt 事件循環(阻塞直到用戶關閉應用)
|
|
|
|
|
print("🎯 [GUI] 進入主事件循環,等待用戶操作...", flush=True)
|
|
|
|
|
sys.exit(app.exec())
|
|
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
# 第四步:只有當 GUI 視窗被關閉時,才做 ROS2 cleanup
|
|
|
|
|
print("\n🛑 [GUI] 應用程式關閉,正在清理 ROS2 資源...", flush=True)
|
|
|
|
|
if rclpy.ok():
|
|
|
|
|
rclpy.shutdown()
|
|
|
|
|
print("✓ [GUI] ROS2 已關閉", flush=True)
|
|
|
|
|
print("✓ [GUI] 應用程式完全退出", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main()
|