第二讲: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
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
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()
2.4 知识体系总览
下面这张图,是我自己梳理的本章核心逻辑。你看一眼,心里就有数了。
2.5 常见问题与排查
我整理了几个高频问题,都是学员和我自己踩过的坑:
| 问题 | 原因 | 解决方案 |
|---|---|---|
| AirSim 连接超时 | 仿真器未启动或端口被占用 | 检查 Unreal 环境是否运行,重启 AirSim |
| Gym 环境报错 | 动作空间维度不匹配 | 打印 action 的 shape,确认与定义一致 |
| 无人机不动 | 忘记调用 enableApiControl | 在 reset 中加上 enableApiControl(True) |
好了,环境搭好,咱们就可以开始写真正的强化学习算法了。记住,环境搭建占整个项目 30% 的时间,别急,慢慢来。