add 飞行模式

This commit is contained in:
王鹏
2026-03-23 16:05:27 +08:00
parent f517c29579
commit 9b4a9d5ab8
21 changed files with 393 additions and 3 deletions

113
flight_mode.py Normal file
View File

@@ -0,0 +1,113 @@
"""
飞行模式逻辑:
- 从坐标 JSON 读取最后一个坐标点作为目的地
- 每帧调用 `CoordinatePatrol.simple_flight_navigate()` 执行:
1) 上马未上马则先上马mount_key/mount_hold_sec 从 game_state_config.json 读取)
2) 起飞
3) 飞向目的地坐标
4) 降落
"""
import json
import logging
from coordinate_patrol import CoordinatePatrol
logger = logging.getLogger(__name__)
def _load_last_waypoint_from_json(path):
"""读取与巡逻相同的 JSON 格式:[[x,y], ...],返回最后一个有效点 (x, y)。"""
if not path:
return None
try:
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
except Exception as e:
logger.warning("读取航线 JSON 失败: %s", e)
return None
if not isinstance(data, list):
return None
last = None
for item in data:
if isinstance(item, (list, tuple)) and len(item) >= 2:
try:
last = (float(item[0]), float(item[1]))
except (TypeError, ValueError):
continue
return last
class FlightModeBot:
"""飞行模式控制器:每次执行逻辑只推动状态前进一步。"""
def __init__(
self,
json_path,
log_callback=None,
*,
takeoff_key="space",
takeoff_hold_sec=2.0,
land_key="p",
land_hold_sec=2.0,
):
self._log = log_callback or (lambda _m: None)
self.destination = _load_last_waypoint_from_json(json_path)
self.done = False
# 上马按键与时长来自 game_state_config.json
try:
from game_state import load_layout_config
cfg = load_layout_config()
mount_key = str(cfg.get("mount_key", "x") or "x")
mount_hold_sec = float(cfg.get("mount_hold_sec", 1.6))
mount_retry_after_sec = float(cfg.get("mount_retry_after_sec", 2.0))
except Exception:
mount_key, mount_hold_sec, mount_retry_after_sec = "x", 1.6, 2.0
# 只用于 simple_flight_navigate 内部的 _ensure_mounted 与一些公共参数
self._patrol = CoordinatePatrol(
waypoints=[(0.0, 0.0)] if self.destination else [],
mount_key=mount_key,
mount_hold_sec=mount_hold_sec,
mount_retry_after_sec=mount_retry_after_sec,
)
self.takeoff_key = takeoff_key
self.takeoff_hold_sec = float(takeoff_hold_sec)
self.land_key = land_key
self.land_hold_sec = float(land_hold_sec)
if not self.destination:
self._log("❌ 飞行模式JSON 中无有效坐标点")
self.done = True
def execute_logic(self, state):
if self.done:
return
if state is None:
return
if not self.destination:
self.done = True
return
arrived = self._patrol.simple_flight_navigate(
state,
self.destination[0],
self.destination[1],
takeoff_key=self.takeoff_key,
takeoff_hold_sec=self.takeoff_hold_sec,
land_key=self.land_key,
land_hold_sec=self.land_hold_sec,
dismount_key=self._patrol.mount_key,
arrival_threshold=self._patrol.arrival_threshold,
mount_wait_sec=self._patrol.mount_hold_sec,
)
if arrived:
self._patrol.stop_all()
self.done = True
self._log("✅ 飞行模式:已到达目的地并降落完成")