第二讲:Python与仿真环境搭建

说实话,每次带新人入门无人机路径规划,我最怕听到的就是「环境装好了,跑不起来」。

我自己踩过的坑,少说也有十几个版本。Anaconda 版本冲突、AirSim 连不上 Unreal、Gym 接口报错……嗯,今天这一讲,咱们就把这些坑一个一个填平。

2.1 Anaconda 环境配置

为什么非要用 Anaconda?说白了,就是隔离。

你想想看,一个项目用 TensorFlow 1.x,另一个用 PyTorch 2.0,要是装在一个 Python 里,迟早要打架。我早期吃过这个亏,一个 `pip install` 下去,整个环境崩了,重装花了两天。

核心思路: 每个项目一个独立环境,互不干扰。

2.1.1 安装 Anaconda

去官网下载对应系统的安装包。我个人习惯用 Miniconda,轻量,够用。

# 安装完成后,验证一下
conda --version
# 输出类似:conda 23.1.0

2.1.2 创建虚拟环境

我建议环境名就叫 `drone_rl`,清晰明了。

conda create -n drone_rl python=3.8
conda activate drone_rl

为什么选 Python 3.8?因为 AirSim 和 Gym 的兼容性最好。我试过 3.10,有些依赖包还没跟上。

2.1.3 安装核心依赖

包名 版本建议 用途
numpy ≥1.21 数值计算
matplotlib ≥3.5 可视化
opencv-python ≥4.6 图像处理
torch ≥1.12 深度学习框架
pip install numpy matplotlib opencv-python torch
小技巧: 用 `conda install` 装不了的包,再用 `pip`。混用容易出问题,我一般先试 conda。

2.2 AirSim 仿真器安装

AirSim 是微软开源的无人机/汽车仿真器。说白了,它就是一个虚拟世界,你的算法在里面飞,撞了也不心疼。

2.2.1 下载与安装

有两种方式:

  • 方式一: 直接下载预编译的二进制文件(推荐新手)
  • 方式二: 从源码编译(适合需要修改底层的人)

我个人建议先走方式一。我记得第一次编译源码,等了两个小时,结果报错……后来发现是 VS 版本不对。

# 克隆 AirSim 仓库
git clone https://github.com/Microsoft/AirSim.git
cd AirSim

# 安装 Python 客户端
pip install ./PythonClient

2.2.2 启动仿真环境

你需要一个 Unreal Engine 的环境文件(.exe 或 .app)。

AirSim 官方提供了几个示例场景,比如「Blocks」——一个简单的街区环境,适合做路径规划测试。

# 启动 Blocks 环境(Windows 示例)
./Blocks.sh

# 或者直接双击 Blocks.exe
注意: 启动时如果报错缺少 DLL,去装一下 Visual C++ Redistributable。我遇到过三次,都是这个原因。

2.2.3 验证连接

启动仿真后,运行 Python 客户端测试:

import airsim

client = airsim.MultirotorClient()
client.confirmConnection()
print("连接成功!")

# 让无人机起飞
client.enableApiControl(True)
client.armDisarm(True)
client.takeoffAsync().join()

如果看到无人机升空,恭喜你,环境搭好了。

2.3 OpenAI Gym 接口封装

为什么要封装 Gym 接口?因为强化学习算法都认 Gym 的格式。你想想看,如果每个仿真器都自己写一套接口,那算法工程师得累死。

2.3.1 Gym 标准接口

一个标准的 Gym 环境需要实现五个方法:

  • __init__:初始化环境
  • reset:重置环境,返回初始状态
  • step:执行动作,返回 (状态, 奖励, 是否结束, 信息)
  • render:可视化(可选)
  • close:关闭环境

2.3.2 封装 AirSim 为 Gym 环境

我直接给你一个简化版的模板,我在项目中就是这么用的:

import gym
from gym import spaces
import airsim
import numpy as np

class AirSimDroneEnv(gym.Env):
    def __init__(self):
        super(AirSimDroneEnv, self).__init__()
        
        # 定义动作空间:速度控制 (vx, vy, vz, yaw_rate)
        self.action_space = spaces.Box(
            low=np.array([-1, -1, -1, -1]),
            high=np.array([1, 1, 1, 1]),
            dtype=np.float32
        )
        
        # 定义状态空间:位置 (x, y, z) + 速度 (vx, vy, vz)
        self.observation_space = spaces.Box(
            low=np.array([-100, -100, -100, -10, -10, -10]),
            high=np.array([100, 100, 100, 10, 10, 10]),
            dtype=np.float32
        )
        
        # 连接 AirSim
        self.client = airsim.MultirotorClient()
        self.client.confirmConnection()
        
    def reset(self):
        self.client.reset()
        self.client.enableApiControl(True)
        self.client.armDisarm(True)
        self.client.takeoffAsync().join()
        return self._get_obs()
    
    def step(self, action):
        # 执行动作
        vx, vy, vz, yaw_rate = action
        self.client.moveByVelocityAsync(vx, vy, vz, 1).join()
        
        # 获取新状态
        obs = self._get_obs()
        
        # 计算奖励(简单示例:距离目标越近奖励越高)
        reward = self._compute_reward(obs)
        
        # 判断是否结束
        done = self._check_done(obs)
        
        return obs, reward, done, {}
    
    def _get_obs(self):
        state = self.client.getMultirotorState()
        pos = state.kinematics_estimated.position
        vel = state.kinematics_estimated.linear_velocity
        return np.array([pos.x_val, pos.y_val, pos.z_val,
                        vel.x_val, vel.y_val, vel.z_val])
    
    def _compute_reward(self, obs):
        # 简单奖励:距离原点越近越好
        distance = np.linalg.norm(obs[:3])
        return -distance
    
    def _check_done(self, obs):
        # 如果高度低于阈值,认为坠毁
        return obs[2] < -10
    
    def close(self):
        self.client.reset()
避坑指南: 我曾经在 `step` 函数里忘了加 `join()`,结果无人机只执行了 0.1 秒的动作就停了。记住,异步调用一定要等它完成。

2.4 知识体系总览

下面这张图,是我自己梳理的本章核心逻辑。你看一眼,心里就有数了。

Anaconda 环境 Python 3.8 + 依赖包 AirSim 仿真器 Unreal 环境 + Python API Gym 接口封装 reset / step / reward 强化学习算法训练 三者关系:Anaconda 提供运行环境,AirSim 提供仿真世界,Gym 提供统一接口 隔离依赖 虚拟飞行 算法兼容

2.5 常见问题与排查

我整理了几个高频问题,都是学员和我自己踩过的坑:

问题 原因 解决方案
AirSim 连接超时 仿真器未启动或端口被占用 检查 Unreal 环境是否运行,重启 AirSim
Gym 环境报错 动作空间维度不匹配 打印 action 的 shape,确认与定义一致
无人机不动 忘记调用 enableApiControl 在 reset 中加上 enableApiControl(True)
重要提醒: 每次训练前,记得先手动启动 AirSim 仿真器。我见过有人写了个脚本自动启动,结果 Unreal 崩溃了,训练数据全废。

好了,环境搭好,咱们就可以开始写真正的强化学习算法了。记住,环境搭建占整个项目 30% 的时间,别急,慢慢来。

专注资料整理