Files
2026-03-17 10:51:32 +08:00

98 lines
2.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Layer 0感知层 - 全局状态黑板
维护无人机当前状态,供 Layer 4 执行包装层判断是否需要自动插入起飞逻辑。
后续可扩展:电量、模式、传感器状态等。
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
@dataclass
class Position:
"""ENU 坐标系下的位置(东-北-天)"""
x: float
y: float
z: float
def to_dict(self) -> dict[str, float]:
"""转换为字典,便于 JSON 序列化"""
return {"x": self.x, "y": self.y, "z": self.z}
@classmethod
def from_dict(cls, d: dict[str, Any]) -> Position:
"""从字典创建"""
return cls(x=float(d["x"]), y=float(d["y"]), z=float(d["z"]))
class DroneStateBlackboard:
"""
无人机状态黑板(全局单例)
供 Layer 4 的 wrap_and_build_tree 判断:
- 若 is_in_air == False自动在业务树前插入 [SystemCheck -> Takeoff] 子树
- 若 is_in_air == True直接执行业务树
"""
_instance: DroneStateBlackboard | None = None
def __new__(cls) -> DroneStateBlackboard:
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self) -> None:
# 避免重复初始化覆盖已有状态
if hasattr(self, "_initialized") and self._initialized:
return
self._initialized = True
self._is_in_air: bool = False
self._position: Position = Position(0.0, 0.0, 0.0)
# 预留扩展字段
self._extra: dict[str, Any] = {}
@property
def is_in_air(self) -> bool:
"""是否在空中True=已起飞False=在地面)"""
return self._is_in_air
@is_in_air.setter
def is_in_air(self, value: bool) -> None:
self._is_in_air = value
@property
def position(self) -> Position:
"""当前 ENU 坐标"""
return self._position
@position.setter
def position(self, value: Position) -> None:
self._position = value
def set_position(self, x: float, y: float, z: float) -> None:
"""便捷设置位置"""
self._position = Position(x=x, y=y, z=z)
def get_position_dict(self) -> dict[str, float]:
"""获取位置字典 {x, y, z}"""
return self._position.to_dict()
def set_extra(self, key: str, value: Any) -> None:
"""设置扩展字段(如 battery, mode"""
self._extra[key] = value
def get_extra(self, key: str, default: Any = None) -> Any:
"""获取扩展字段"""
return self._extra.get(key, default)
def reset(self) -> None:
"""重置为地面初始状态(用于测试或仿真重置)"""
self._is_in_air = False
self._position = Position(0.0, 0.0, 0.0)
self._extra.clear()