Skip to content

Latest commit

 

History

History
298 lines (223 loc) · 11.9 KB

QuickStart_zh.md

File metadata and controls

298 lines (223 loc) · 11.9 KB

DBRL: A Gym Dogfighting Simulation Benchmark for Reinforcement Learning Research

快速入门

准备工作

DBRL基于空气动力学软件JSBSimDogfight 2搭建空战仿真平台。

如需使用基于JSBSim搭建的视距内缠斗仿真环境,可以运行如下代码安装Python-JSBSim:

pip install jsbsim

安装的JSBSim可能不包括JSBSim Github页面中的全部文件,建议您将如上链接中的文件拷贝进JSBSim源文件地址中。

这里只提供Dogfight 2环境在Windows系统下运行的示例,如果需要在Linux系统中运行Harfang3D Dog-Fight,可以下载Linux版Harfang。如需使用基于Dogfight 2搭建的导弹躲避仿真环境,可以在Windows PowerShell中运行如下代码进行软件下载与配置:

wget -Uri https://github.com/harfang3d/dogfight-sandbox-hg2/releases/download/1.0.2/dogfight-sandbox-hg2-win64.7z -OutFile "df2.7z"

7z x -odf2/ df2.7z

mv ./df2/dogfight-sandbox-hg2/ {DBRL}/src/environments/dogfightEnv/dogfight_sandbox_hg2/

del df2/, df2.7z

其中,{DBRL}需要替换为本项目所在的路径,在命令行中使用7z指令需要将您的7zip安装位置添加至path系统变量,您同样可以手动进行文件下载,解压缩,重命名与移动操作。

JSBSim的可视化功能基于FlightGear实现,如需在使用JSBSim的过程中将空战的飞行过程可视化显示,请在FlightGear官网中安装FlightGear软件。如需对缠斗中的两架飞机分别进行可视化,请在{JSBSim}/data_output/下复制两份flightgear.xml文件,分别命名为flightgear{1/2}.xml,并将flightgear2.xml第18行中的5550修改为5551。上述操作中的{JSBSim}为Python JSBSim库所在的路径;如需查看JSBSim源文件地址,可以运行如下代码:

import jsbsim

print(jsbsim.get_default_root_dir())

在运行需要可视化的接战仿真中,请在FlightGear启动时使用如下参数:

--fdm=null --native-fdm=socket,in,60,,5550,udp

如果您的系统语言非英语,且出现了FlightGear在操纵键盘后卡住的情况,您可以尝试使用其他输入法来解决这个问题。详情可见论坛

在运行同时对两架飞机可视化的仿真中,请分别使用

--fdm=null --native-fdm=socket,in,60,,5550,udp --multiplay=out,10,127.0.0.1,5000 --multiplay=in,10,127.0.0.1,5001 --callsign=Test1

--fdm=null --native-fdm=socket,in,60,,5550,udp --multiplay=out,10,127.0.0.1,5001 --multiplay=in,10,127.0.0.1,5000 --callsign=Test2

参数。

如需使用本项目中的强化学习模型src/models/*.py,请将本项目文件夹置于JSBSim目录下,即:

JSBSim/
├── DBRL/
│   ├── doc/
│   ├── log/
│   ├── src/
│   ├── test/
│   └── ...
├── aircraft/
├── scripts/
└── ...
使用方法

DBRL提供了OpenAI Gym格式的强化学习环境,可以通过Gym库进行调用。如需使用gym.make调用环境,请在Gym/envs下复制src/environments/*Env/文件夹,并在Gym/envs/__init__.py中添加如下代码:

register(
    id="DBRL{Jsbsim/Dogfight}-v0",
    entry_point="gym.envs.{jsbsim/dogfight}Env:{Jsbsim/Dogfight}Env",
)

如需查看gym源文件地址,可以运行如下代码:

pip show gym

调用环境时可以采用如下代码:

import gym

env = gym.make('DBRL{Jsbsim/Dogfight}-v0')
环境特征

DBRL-JSBSim提供了一个基于强化学习框架Gym的智能空战仿真环境,它的动作空间为:

gym.spaces.Box(
    low=np.array([-1, -1, -1, 0, 0, 0, 0]),
    high=np.array([1, 1, 1, 1, 1, 1, 1])
)

其中六个维度分别表示对副翼(Aileron)、升降舵(Elevator)、方向舵(Rudder)、油门(Throttle)、襟翼(Flap)、减速板(Speed brake)、扰流片(Spoiler)的操控。

状态空间为:

gym.spaces.Box(
    low=np.array([-360, -360, 0, -360, -360, -360] * 2),
    high=np.array([360, 360, 60000, 360, 360, 360] * 2)
)

其中六个维度分别表示飞机的纬度(Latitude)、经度(Longitude)、海拔(Height above sea level)、偏航角(Yaw)、俯仰角(Pitch)、滚转角(Roll),单位为度(Degree)与英尺(Feet)。

作为一场接战环境的初始化,class JSBSimEnv()接受两个class JSBSimFdm()作为输入变量:

class JsbsimEnv(Env):

    def __init__(
        self,
        fdm1=Fdm(fdm_id=1),
        fdm2=Fdm(fdm_id=2),
    ) -> None:

JSBSimFdm类储存在DBRL/src/environments/jsbsimEnv/jsbsimFdm.py中,它的构造函数接受如下参数作为输入:

class JsbsimFdm():

    def __init__(
        self,
        fdm_id       = 1,
        fdm_aircraft = 'f16',
        fdm_ic_v     = 500,
        fdm_ic_lat   = 0,
        fdm_ic_long  = 0,
        fdm_ic_h     = 20005.5,
        fdm_ic_psi   = 0,
        fdm_ic_theta = 0,
        fdm_ic_phi   = 0,
        fdm_hp       = 1,
        fdm_fgfs     = False,
        flight_mode  = 1
    ) -> None:

其中:fdm_id表示接战中飞机的编号,需要分别设置为12fdm_aircraft表示接战中飞机的型号;fdm_ic_*表示飞机的初始化特征;fdm_ic_v表示飞机的初始校正空速,单位为节(knot);fdm_ic_lat表示飞机的初始纬度;fdm_ic_long表示飞机的初始经度;fdm_ic_h表示飞机的初始海拔高度,单位为英尺;fdm_ic_psifdm_ic_thetafdm_ic_phi分别表示飞机的偏航角,俯仰角与滚转角;fdm_hp表示飞机的初始血量;fdm_fgfs表示飞机是否需要在FlightGear上进行可视化;flight_mode表示飞行模式(暂无效果)。

JSBSim将按照此处列出的三个欧拉角的先后顺序进行飞机姿态的计算,即,先设定飞机的偏航角,再在此基础上,依照参数设定飞机的俯仰角与滚转角。

DBRL提供的回报函数为当前帧对敌机造成的血量损失大小与敌机对自身造成伤害的差值,但也同样可以用JSBSimFdm类的getProperty()函数获得一些其他特征作为不同强化学习模型的回报函数。

def getProperty(
        self,
        prop,
    ) -> list:


DBRL-Dogfight提供了一个基于强化学习框架Gym的战斗机机动躲避智能决策仿真环境,作为环境的初始状态,智能体需要操控的飞机被另一架飞机发射的“流星”空空导弹锁定,智能体需要采取机动操纵躲避导弹的威胁。

Dogfight 2环境提供可选的动作空间包括:

if pitch_enable:
    action_infimum = np.append(action_infimum, -1)
    action_supermum = np.append(action_supermum, 1)
if roll_enable:
    action_infimum = np.append(action_infimum, -1)
    action_supermum = np.append(action_supermum, 1)
if yaw_enable:
    action_infimum = np.append(action_infimum, -1)
    action_supermum = np.append(action_supermum, 1)
if flaps_enable:
    action_infimum = np.append(action_infimum, 0)
    action_supermum = np.append(action_supermum, 1)
if throttle_enable:
    action_infimum = np.append(action_infimum, 0)
    action_supermum = np.append(action_supermum, 1)
if flare_enable:
    action_infimum = np.append(action_infimum, 0)
    action_supermum = np.append(action_supermum, 1)
action_space = Box(
    low=action_infimum,
    high=action_supermum,
)

其中六个维度分别表示对俯仰角(Pitch)、滚转角(Roll)、偏航角(Yaw)、襟翼(Flaps)、油门(Throttle)、干扰弹(Decoy flare)的操控。

可选状态空间包括:

if ego_plane_position:
    observation_infimum = np.append(observation_infimum, [-300, -300, -1])
    observation_supermum = np.append(observation_supermum, [300, 300, 200])
if ego_plane_attitude:
    observation_infimum = np.append(observation_infimum, [0, -360, -360])
    observation_supermum = np.append(observation_supermum, [360, 360, 360])
if oppo_plane_position:
    observation_infimum = np.append(observation_infimum, [-300, -300, -1])
    observation_supermum = np.append(observation_supermum, [300, 300, 200])
if oppo_plane_attitude:
    observation_infimum = np.append(observation_infimum, [0, -360, -360])
    observation_supermum = np.append(observation_supermum, [360, 360, 360])
if missile_position:
    observation_infimum = np.append(observation_infimum, [-300, -300, -1])
    observation_supermum = np.append(observation_supermum, [300, 300, 200])
if missile_attitude:
    observation_infimum = np.append(observation_infimum, [-315, -315, -315])
    observation_supermum = np.append(observation_supermum, [315, 315, 315])
if missile_relative_azimuth:
    observation_infimum = np.append(observation_infimum, [-1, -1, -1])
    observation_supermum = np.append(observation_supermum, [1, 1, 1])
observation_space = Box(
    low=observation_infimum,
    high=observation_supermum,
)

可选飞机的X坐标(÷100)、Y坐标(÷100)、Z坐标(÷50)、偏航角、俯仰角(×4)、滚转角(×4),导弹的X坐标(÷100)、Y坐标(÷100)、Z坐标(÷50)、偏航角(×100)、俯仰角(×100)、滚转角(×100),导弹相对于飞机的方位角等。

DogfightEnv的初始化需要与Dogfight 2软件进行连接,接受如下参数作为输入变量:

class DogfightEnv(Env):

    def __init__(
        self,
        host='10.184.0.0',
        port='50888',
        plane_slot=1,
        enemy_slot=3,
        missile_slot=1,
        rendering=False,
        record_status=0,
        initial_state='carrier',
        throttle_enable=False,
        flare_enable=False,
        ego_pose_enable=True,
        oppo_pose_enable=False,
        missile_pose_enable=True,
        missile_relative_azimuth_enable=False,
        msg=None,
    ) -> None:

在使用DogfightEnv环境前,需要先启动Dogfight 2软件,选择Network Mode,并将软件左上角显示的Host与Port作为参数传进环境中。

欢迎交流

如果您在使用过程中发现了任何错误,或者有任何需求与改进的建议,欢迎在Github Issues中提出,谢谢!