|
| 1 | +# 无人机 Reinforcement Learning(强化学习)路径规划 |
| 2 | + |
| 3 | +使用 Reinforcement Learning(强化学习)与 AirSim 模拟器实现无人机自主路径规划。 |
| 4 | + |
| 5 | +## 概述 |
| 6 | + |
| 7 | +本项目实现了一个端到端的无人机路径规划 Reinforcement Learning(强化学习)流程: |
| 8 | +- **环境**:为 AirSim 多旋翼无人机定制的 OpenAI Gym 封装 |
| 9 | +- **算法**:Stable Baselines3(PPO/DQN) |
| 10 | +- **观测**:深度相机图像(84x84 灰度) |
| 11 | +- **动作**:7 个离散动作(±X/Y/Z + 悬停) |
| 12 | +- **奖励**:多任务奖励(距离惩罚 + 碰撞惩罚 + 成功奖励) |
| 13 | + |
| 14 | +## 项目结构 |
| 15 | + |
| 16 | +说明:项目名 `drone_rl_planner` 中的 `rl` 是 `Reinforcement Learning` 的缩写。 |
| 17 | + |
| 18 | +``` |
| 19 | +hh/ |
| 20 | +├── src/ |
| 21 | +│ ├── envs/ # 环境封装 |
| 22 | +│ │ ├── base_drone_env.py # AirSim Gym 环境 |
| 23 | +│ │ └── wrappers.py # 帧堆叠、归一化 |
| 24 | +│ ├── agents/ # 模型实现 |
| 25 | +│ ├── training/ # 训练流程 |
| 26 | +│ │ ├── train.py # 主训练脚本 |
| 27 | +│ │ ├── callbacks.py # 自定义回调 |
| 28 | +│ │ └── config.yaml # 超参数 |
| 29 | +│ ├── evaluation/ # 评估与可视化 |
| 30 | +│ │ ├── evaluate.py # 模型评估 |
| 31 | +│ │ ├── trajectory_vis.py # 3D 轨迹可视化 |
| 32 | +│ │ └── metrics.py # 性能指标 |
| 33 | +│ └── utils/ # 工具函数 |
| 34 | +│ ├── airsim_utils.py # AirSim 接口 |
| 35 | +│ └── reward_shaper.py # 奖励函数 |
| 36 | +├── data/ |
| 37 | +│ ├── logs/ # TensorBoard 日志 |
| 38 | +│ ├── checkpoints/ # 模型检查点 |
| 39 | +│ ├── best_model/ # 最优模型存储 |
| 40 | +│ └── results/ # 评估结果 |
| 41 | +├── tests/ # 单元测试 |
| 42 | +├── config.yaml # 训练配置 |
| 43 | +└── train.py # 快速启动脚本 |
| 44 | +``` |
| 45 | + |
| 46 | +## 安装 |
| 47 | + |
| 48 | +### 前置条件 |
| 49 | +- Python >= 3.10 |
| 50 | +- 本地运行的 AirSim 模拟器 |
| 51 | +- 支持 CUDA 的 GPU(可选但推荐) |
| 52 | + |
| 53 | +### 安装步骤 |
| 54 | + |
| 55 | +1. 克隆项目并安装依赖: |
| 56 | +```bash |
| 57 | +cd drone_rl_planner |
| 58 | +pip install -r requirements.txt |
| 59 | +``` |
| 60 | + |
| 61 | +或者使用 pip 可编辑安装: |
| 62 | +```bash |
| 63 | +pip install -e ".[dev]" |
| 64 | +``` |
| 65 | + |
| 66 | +2. 验证安装: |
| 67 | +```bash |
| 68 | +python -c "import gymnasium; import stable_baselines3; print('✓ Ready')" |
| 69 | +``` |
| 70 | + |
| 71 | +## 快速开始 |
| 72 | + |
| 73 | +### 1. 验证环境 |
| 74 | + |
| 75 | +```bash |
| 76 | +python -m pytest tests/test_env.py -v |
| 77 | +``` |
| 78 | + |
| 79 | +### 2. 训练模型 |
| 80 | + |
| 81 | +```bash |
| 82 | +# 默认训练(读取 config.yaml) |
| 83 | +python -m src.training.train |
| 84 | + |
| 85 | +# 自定义训练步数 |
| 86 | +python -m src.training.train --timesteps 500000 |
| 87 | + |
| 88 | +# 从检查点继续训练 |
| 89 | +python -m src.training.train --load ./data/checkpoints/drone_model_100000_steps.zip |
| 90 | +``` |
| 91 | + |
| 92 | +### 3. 评估模型 |
| 93 | + |
| 94 | +```bash |
| 95 | +# 评估已训练模型 |
| 96 | +python -m src.evaluation.evaluate ./data/best_model/final_model \ |
| 97 | + --episodes 20 \ |
| 98 | + --results-dir ./data/results/ |
| 99 | + |
| 100 | +# 使用随机策略 |
| 101 | +python -m src.evaluation.evaluate ./data/best_model/final_model --stochastic |
| 102 | +``` |
| 103 | + |
| 104 | +### 4. 可视化结果 |
| 105 | + |
| 106 | +```bash |
| 107 | +# 生成轨迹图 |
| 108 | +python -m src.evaluation.trajectory_vis \ |
| 109 | + --results-dir ./data/results/ \ |
| 110 | + --output-dir ./data/results/visualizations/ |
| 111 | + |
| 112 | +# 使用 TensorBoard 查看 |
| 113 | +tensorboard --logdir ./data/logs/ |
| 114 | +``` |
| 115 | + |
| 116 | +## 配置 |
| 117 | + |
| 118 | +编辑 `src/training/config.yaml` 可自定义: |
| 119 | + |
| 120 | +- **算法**:PPO(推荐)或 DQN |
| 121 | +- **学习率**:PPO 为 3e-4,DQN 为 1e-4 |
| 122 | +- **N Steps**:2048(轨迹采样长度) |
| 123 | +- **目标点**:航点坐标 |
| 124 | +- **奖励塑形**:距离系数、碰撞惩罚、成功奖励 |
| 125 | + |
| 126 | +示例: |
| 127 | +```yaml |
| 128 | +ppo: |
| 129 | + learning_rate: 0.0003 |
| 130 | + n_steps: 2048 |
| 131 | + batch_size: 64 |
| 132 | + gamma: 0.99 |
| 133 | + |
| 134 | +training: |
| 135 | + total_timesteps: 1000000 |
| 136 | + checkpoint_freq: 10000 |
| 137 | +``` |
| 138 | +
|
| 139 | +## 训练 |
| 140 | +
|
| 141 | +### 典型训练流程 |
| 142 | +
|
| 143 | +1. **初始化**(秒级) |
| 144 | + - 连接 AirSim |
| 145 | + - 验证环境 |
| 146 | + - 初始化模型 |
| 147 | +
|
| 148 | +2. **早期学习**(分钟级) |
| 149 | + - 模型探索环境 |
| 150 | + - 出现首次碰撞 |
| 151 | + - 奖励不再完全随机 |
| 152 | +
|
| 153 | +3. **收敛阶段**(小时级) |
| 154 | + - 成功率提升 |
| 155 | + - 每回合奖励趋于稳定 |
| 156 | + - 策略进入平台期 |
| 157 | +
|
| 158 | +### 监控训练进度 |
| 159 | +
|
| 160 | +训练期间可使用 TensorBoard: |
| 161 | +```bash |
| 162 | +tensorboard --logdir ./data/logs/ |
| 163 | +``` |
| 164 | + |
| 165 | +关键指标: |
| 166 | +- `rollout/ep_rew_mean`:平均回合奖励 |
| 167 | +- `train/policy_loss`:策略梯度损失 |
| 168 | +- `train/value_loss`:价值函数损失 |
| 169 | + |
| 170 | +### 停止条件 |
| 171 | + |
| 172 | +- 达到奖励阈值(可配置) |
| 173 | +- 连续 N 个回合无提升(耐心值) |
| 174 | +- 达到最大训练步数(默认 1M) |
| 175 | + |
| 176 | +## 评估 |
| 177 | + |
| 178 | +### 单模型评估 |
| 179 | + |
| 180 | +```python |
| 181 | +from src.evaluation.evaluate import evaluate_model |
| 182 | + |
| 183 | +results = evaluate_model( |
| 184 | + model_path="./data/best_model/final_model", |
| 185 | + n_episodes=20, |
| 186 | + deterministic=True |
| 187 | +) |
| 188 | +``` |
| 189 | + |
| 190 | +### 多模型对比 |
| 191 | + |
| 192 | +```python |
| 193 | +from src.evaluation.evaluate import compare_models |
| 194 | + |
| 195 | +comparison = compare_models( |
| 196 | + model_paths=[ |
| 197 | + "./data/checkpoints/drone_model_100000_steps.zip", |
| 198 | + "./data/checkpoints/drone_model_500000_steps.zip" |
| 199 | + ], |
| 200 | + n_episodes=10 |
| 201 | +) |
| 202 | +``` |
| 203 | + |
| 204 | +### 关键指标 |
| 205 | + |
| 206 | +- **成功率**:无碰撞到达目标的回合占比 |
| 207 | +- **碰撞率**:发生碰撞的回合占比 |
| 208 | +- **平均奖励**:每回合平均奖励 |
| 209 | +- **路径长度**:累计欧氏距离 |
| 210 | +- **回合长度**:完成任务所需步数 |
| 211 | + |
| 212 | +## 可视化 |
| 213 | + |
| 214 | +### 轨迹图 |
| 215 | + |
| 216 | +```bash |
| 217 | +python -m src.evaluation.trajectory_vis --results-dir ./data/results/ |
| 218 | +``` |
| 219 | + |
| 220 | +会生成: |
| 221 | +- 每个回合的 3D 轨迹 |
| 222 | +- 高度变化曲线 |
| 223 | +- 与原点距离随时间变化曲线 |
| 224 | + |
| 225 | +### TensorBoard |
| 226 | + |
| 227 | +```bash |
| 228 | +tensorboard --logdir ./data/logs/ |
| 229 | +``` |
| 230 | + |
| 231 | +可查看: |
| 232 | +- 奖励曲线 |
| 233 | +- 损失趋势 |
| 234 | +- 训练稳定性 |
| 235 | + |
| 236 | +## 结果 |
| 237 | + |
| 238 | +预期性能(完成训练后): |
| 239 | + |
| 240 | +| 指标 | 数值 | |
| 241 | +|--------|-------| |
| 242 | +| 成功率 | 70-90% | |
| 243 | +| 碰撞率 | 5-20% | |
| 244 | +| 平均奖励 | -20 到 +30 | |
| 245 | +| 平均回合长度 | 100-200 步 | |
| 246 | + |
| 247 | +## 故障排查 |
| 248 | + |
| 249 | +### 环境连接问题 |
| 250 | + |
| 251 | +**问题**:`Failed to connect to AirSim` |
| 252 | + |
| 253 | +**解决方案**: |
| 254 | +1. 确认 AirSim 模拟器已启动 |
| 255 | +2. 检查 `config.yaml` 中的 IP 地址(默认:127.0.0.1) |
| 256 | +3. 确认 41451 端口可访问 |
| 257 | + |
| 258 | +### 强化学习训练问题 |
| 259 | + |
| 260 | +**问题**:奖励值保持不变 |
| 261 | + |
| 262 | +**解决方案**: |
| 263 | +- 检查 `src/utils/reward_shaper.py` 中的奖励塑形逻辑 |
| 264 | +- 确认碰撞检测是否正常工作 |
| 265 | +- 检查 `data/logs/` 中是否有异常模式 |
| 266 | + |
| 267 | +**问题**:模型不收敛 |
| 268 | + |
| 269 | +**解决方案**: |
| 270 | +- 适当提高学习率 |
| 271 | +- 降低 batch size |
| 272 | +- 检查观测空间归一化 |
| 273 | + |
| 274 | +**问题**:CUDA/GPU 问题 |
| 275 | + |
| 276 | +**解决方案**: |
| 277 | +```bash |
| 278 | +# 强制使用 CPU 训练 |
| 279 | +python -m src.training.train --device cpu |
| 280 | +``` |
| 281 | + |
| 282 | +## 高级用法 |
| 283 | + |
| 284 | +### 自定义奖励函数 |
| 285 | + |
| 286 | +编辑 `src/utils/reward_shaper.py`: |
| 287 | + |
| 288 | +```python |
| 289 | +class CustomRewardShaper(SimpleRewardShaper): |
| 290 | + def compute_reward(self, position, collision, reached_target, info): |
| 291 | + # 在这里实现你的自定义逻辑 |
| 292 | + reward = ... |
| 293 | + return float(reward), done |
| 294 | +``` |
| 295 | + |
| 296 | +### 多环境并行训练 |
| 297 | + |
| 298 | +在 `config.yaml` 中设置: |
| 299 | +```yaml |
| 300 | +hardware: |
| 301 | + n_envs: 4 |
| 302 | + vec_env_type: "subproc" |
| 303 | +``` |
| 304 | +
|
| 305 | +### 使用不同算法 |
| 306 | +
|
| 307 | +```bash |
| 308 | +# 使用 DQN 训练 |
| 309 | +python -m src.training.train --algorithm DQN --timesteps 500000 |
| 310 | +``` |
| 311 | + |
| 312 | +## 后续改进 |
| 313 | + |
| 314 | +- [ ] 多智能体协同 |
| 315 | +- [ ] 动态障碍物 |
| 316 | +- [ ] Sim-to-real 迁移 |
| 317 | +- [ ] 用于部分可观测场景的 LSTM |
| 318 | +- [ ] 课程学习 |
| 319 | +- [ ] 安全约束强化学习 |
| 320 | + |
| 321 | +## 参考资料 |
| 322 | + |
| 323 | +- [Stable Baselines3](https://stable-baselines3.readthedocs.io/) |
| 324 | +- [AirSim Documentation](https://microsoft.github.io/AirSim/) |
| 325 | +- [Gymnasium](https://gymnasium.farama.org/) |
| 326 | + |
| 327 | +## 许可证 |
| 328 | + |
| 329 | +MIT |
| 330 | + |
| 331 | +## 联系方式 |
| 332 | + |
| 333 | +如有问题或建议,请在仓库中提交 issue。 |
0 commit comments