dogfight问题中(UAV 无人机空战——狗斗)—— 状态空间设计

- 完整状态空间定义(Python)
import numpy as np
from gymnasium import spaces
class AirCombatStateSpace:
def __init__(self):
# --------------------------
# 状态项索引(对应表1序号)
# --------------------------
self.state_dim = 20
# 1. 对方飞机距离/km: 0~150 → 归一化到 [0,1]
# 2. 对方飞机方位角/°: -180~180 → 归一化到 [-1,1]
# 3. 对方飞机俯仰角/°: -90~90 → 归一化到 [-1,1]
# 4. 对方雷达状态: 关机/扫描/跟踪 → 离散 0/1/2
# 5. 对方剩余武器数量: 0~6 → 归一化到 [0,1]
# 6. 对方武器状态: 未发射/在飞 → 离散 0/1
# 7. 对方武器方位角/°: -180~180 → 归一化到 [-1,1]
# 8. 对方武器俯仰角/°: -90~90 → 归一化到 [-1,1]
# 9. 我方飞机速度/(m·s⁻¹): 300~600 → 归一化到 [0,1]
# 10. 我方飞机航向角/°: -180~180 → 归一化到 [-1,1]
# 11. 我方飞机俯仰角/°: -90~90 → 归一化到 [-1,1]
# 12. 我方飞机滚转角/°: -180~180 → 归一化到 [-1,1]
# 13. 我方剩余油量/kg: 0~4500 → 归一化到 [0,1]
# 14. 我方雷达状态: 关机/扫描/跟踪 → 离散 0/1/2
# 15. 我方雷达已失跟时间/s: 0~150 → 归一化到 [0,1]
# 16. 我方雷达已开机时间/s: 0~10 → 归一化到 [0,1]
# 17. 我方雷达已关机时间/s: 0~10 → 归一化到 [0,1]
# 18. 干扰已持续时间/s: 0~10 → 归一化到 [0,1]
# 19. 我方剩余武器数量: 0~6 → 归一化到 [0,1]
# 20. 我方武器状态: 未发射/在飞 → 离散 0/1
# --------------------------
# 状态空间(连续 + 离散 统一为 Box 空间)
# --------------------------
# 为了兼容大部分 RL 框架,这里把所有状态都转为连续 [-1,1] 或 [0,1]
# 也可以用 spaces.Dict 或 spaces.Tuple 处理混合空间
self.observation_space = spaces.Box(
low=-1.0,
high=1.0,
shape=(self.state_dim,),
dtype=np.float32
)
def normalize_state(self, raw_state):
"""
将原始状态(20维)归一化到 [-1,1] / [0,1] 范围
输入: raw_state: list/array, 长度 20,对应表1各项原始值
输出: normalized_state: np.array, shape=(20,), 范围 [-1,1]
"""
s = np.array(raw_state, dtype=np.float32)
normalized = np.zeros_like(s)
# 1. 对方飞机距离 0~150 km → [0,1]
normalized[0] = np.clip(s[0] / 150.0, 0.0, 1.0)
# 2. 对方飞机方位角 -180~180° → [-1,1]
normalized[1] = np.clip(s[1] / 180.0, -1.0, 1.0)
# 3. 对方飞机俯仰角 -90~90° → [-1,1]
normalized[2] = np.clip(s[2] / 90.0, -1.0, 1.0)
# 4. 对方雷达状态(0:关机,1:扫描,2:跟踪)→ [0,1]
normalized[3] = np.clip(s[3] / 2.0, 0.0, 1.0)
# 5. 对方剩余武器数量 0~6 → [0,1]
normalized[4] = np.clip(s[4] / 6.0, 0.0, 1.0)
# 6. 对方武器状态(0:未发射,1:在飞)→ [0,1]
normalized[5] = np.clip(s[5], 0.0, 1.0)
# 7. 对方武器方位角 -180~180° → [-1,1]
normalized[6] = np.clip(s[6] / 180.0, -1.0, 1.0)
# 8. 对方武器俯仰角 -90~90° → [-1,1]
normalized[7] = np.clip(s[7] / 90.0, -1.0, 1.0)
# 9. 我方飞机速度 300~600 m/s → [0,1]
normalized[8] = np.clip((s[8] - 300.0) / 300.0, 0.0, 1.0)
# 10. 我方飞机航向角 -180~180° → [-1,1]
normalized[9] = np.clip(s[9] / 180.0, -1.0, 1.0)
# 11. 我方飞机俯仰角 -90~90° → [-1,1]
normalized[10] = np.clip(s[10] / 90.0, -1.0, 1.0)
# 12. 我方飞机滚转角 -180~180° → [-1,1]
normalized[11] = np.clip(s[11] / 180.0, -1.0, 1.0)
# 13. 我方剩余油量 0~4500 kg → [0,1]
normalized[12] = np.clip(s[12] / 4500.0, 0.0, 1.0)
# 14. 我方雷达状态(0:关机,1:扫描,2:跟踪)→ [0,1]
normalized[13] = np.clip(s[13] / 2.0, 0.0, 1.0)
# 15. 我方雷达已失跟时间 0~150 s → [0,1]
normalized[14] = np.clip(s[14] / 150.0, 0.0, 1.0)
# 16. 我方雷达已开机时间 0~10 s → [0,1]
normalized[15] = np.clip(s[15] / 10.0, 0.0, 1.0)
# 17. 我方雷达已关机时间 0~10 s → [0,1]
normalized[16] = np.clip(s[16] / 10.0, 0.0, 1.0)
# 18. 干扰已持续时间 0~10 s → [0,1]
normalized[17] = np.clip(s[17] / 10.0, 0.0, 1.0)
# 19. 我方剩余武器数量 0~6 → [0,1]
normalized[18] = np.clip(s[18] / 6.0, 0.0, 1.0)
# 20. 我方武器状态(0:未发射,1:在飞)→ [0,1]
normalized[19] = np.clip(s[19], 0.0, 1.0)
return normalized.astype(np.float32)
def denormalize_state(self, normalized_state):
"""
将归一化的状态 [-1,1]/[0,1] 转回原始范围(可选,用于调试/可视化)
"""
s = np.array(normalized_state, dtype=np.float32)
raw = np.zeros_like(s)
raw[0] = s[0] * 150.0
raw[1] = s[1] * 180.0
raw[2] = s[2] * 90.0
raw[3] = s[3] * 2.0
raw[4] = s[4] * 6.0
raw[5] = s[5]
raw[6] = s[6] * 180.0
raw[7] = s[7] * 90.0
raw[8] = s[8] * 300.0 + 300.0
raw[9] = s[9] * 180.0
raw[10] = s[10] * 90.0
raw[11] = s[11] * 180.0
raw[12] = s[12] * 4500.0
raw[13] = s[13] * 2.0
raw[14] = s[14] * 150.0
raw[15] = s[15] * 10.0
raw[16] = s[16] * 10.0
raw[17] = s[17] * 10.0
raw[18] = s[18] * 6.0
raw[19] = s[19]
return raw
- 使用示例(在自定义 Gym 环境中)
from gymnasium import Env
class AirCombatEnv(Env):
def __init__(self):
super().__init__()
self.state_helper = AirCombatStateSpace()
self.observation_space = self.state_helper.observation_space
# 动作空间可根据你的控制量自行定义
self.action_space = spaces.Discrete(...) # 或 spaces.Box(...)
def _get_observation(self):
# 假设从仿真中读取原始状态 raw_state (长度20)
raw_state = self._read_raw_state_from_simulation()
# 归一化后返回给 RL 算法
obs = self.state_helper.normalize_state(raw_state)
return obs
def _read_raw_state_from_simulation(self):
# 这里替换为你实际读取仿真数据的代码
return np.zeros(20)

本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址,还有个别文章是汇总网上多份资料所成,在这之中也必有疏漏未加标注处,如有侵权请与博主联系。
如果未特殊标注则为原创,遵循 CC 4.0 BY-SA 版权协议。
posted on 2026-06-27 15:32 Angry_Panda 阅读(3) 评论(0) 收藏 举报
浙公网安备 33010602011771号