|
|
|
|
@ -1573,27 +1573,30 @@ class ControlStationUI(QMainWindow):
|
|
|
|
|
_log("INFO", f"Group {group_id} 準備切換模式為 {mode}")
|
|
|
|
|
self.statusBar().showMessage("正在切換模式", 1000)
|
|
|
|
|
|
|
|
|
|
# 使用 asyncio 執行(通過事件循環)
|
|
|
|
|
async def do_mode_changes_async():
|
|
|
|
|
for drone_id in group.selected_drone_ids:
|
|
|
|
|
# 使用 asyncio 執行(通過事件循環)。
|
|
|
|
|
# 並發:每台各自 set_mode + 各自等自己的 ACK,用 gather 同時發,
|
|
|
|
|
# 避免逐台 await 造成序列化(最壞情況 N×timeout 一路卡著)。
|
|
|
|
|
async def _change_one(drone_id):
|
|
|
|
|
try:
|
|
|
|
|
result = await self.monitor.set_mode(drone_id, mode)
|
|
|
|
|
|
|
|
|
|
if result:
|
|
|
|
|
msg = f"{drone_id} 切換成功"
|
|
|
|
|
_log("INFO", msg)
|
|
|
|
|
self.message_queue.put((msg, 2000))
|
|
|
|
|
else:
|
|
|
|
|
msg = f"{drone_id} 切換失敗"
|
|
|
|
|
_log("WARN", msg)
|
|
|
|
|
self.message_queue.put((msg, 2000))
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
msg = f"{drone_id} 錯誤: {str(e)}"
|
|
|
|
|
_log("ERROR", msg)
|
|
|
|
|
traceback.print_exc()
|
|
|
|
|
self.message_queue.put((msg, 2000))
|
|
|
|
|
|
|
|
|
|
async def do_mode_changes_async():
|
|
|
|
|
await asyncio.gather(
|
|
|
|
|
*(_change_one(did) for did in group.selected_drone_ids)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 通過事件循環提交異步任務
|
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
|
asyncio.run_coroutine_threadsafe(
|
|
|
|
|
@ -2584,17 +2587,18 @@ class ControlStationUI(QMainWindow):
|
|
|
|
|
if hasattr(self, 'orchestrator'):
|
|
|
|
|
self.orchestrator.friendly_speed = float(friendly_speed)
|
|
|
|
|
|
|
|
|
|
async def do_apply():
|
|
|
|
|
for did in friendly_ids:
|
|
|
|
|
async def _apply_one(did, speed, label):
|
|
|
|
|
try:
|
|
|
|
|
await self.monitor.set_speed(did, friendly_speed)
|
|
|
|
|
await self.monitor.set_speed(did, speed)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
_log("ERROR", f"[套用速度] 友機 {did} 失敗: {e}")
|
|
|
|
|
_log("ERROR", f"[套用速度] {label} {did} 失敗: {e}")
|
|
|
|
|
|
|
|
|
|
async def do_apply():
|
|
|
|
|
# 並發:友機各自 + 敵機,用 gather 同時發,各自等各自 ACK
|
|
|
|
|
tasks = [_apply_one(did, friendly_speed, "友機") for did in friendly_ids]
|
|
|
|
|
if enemy_id:
|
|
|
|
|
try:
|
|
|
|
|
await self.monitor.set_speed(enemy_id, enemy_speed)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
_log("ERROR", f"[套用速度] 敵機 {enemy_id} 失敗: {e}")
|
|
|
|
|
tasks.append(_apply_one(enemy_id, enemy_speed, "敵機"))
|
|
|
|
|
await asyncio.gather(*tasks)
|
|
|
|
|
|
|
|
|
|
asyncio.run_coroutine_threadsafe(do_apply(), asyncio.get_event_loop())
|
|
|
|
|
self.statusBar().showMessage(
|
|
|
|
|
|