☰
基于MASAC的多无人机协同路径规划Python实现与避坑指南
2026/10/1 5:38:28 网站建设 项目流程

简介:多架无人机在同一空域执行任务,互相避让、同时到达,是路径规划领域极具挑战的协同问题。传统算法因环境动态变化和机间耦合难以高效求解,而强化学习通过与环境交互自主学习控制策略,为连续决策问题提供了新思路。SAC作为高效的最大熵连续控制算法,在多智能体扩展为MASAC后,可让每架无人机基于局部观测独立决策,同时借助中心化Critic评估全局协同效果,从而实现时间与空间上的编队协同。该方案广泛应用于低空物流、编队巡逻、灾难搜救等场景。本文围绕MASAC的建模过程与Python工程落地,梳理状态空间设计、奖励函数构建、训练循环实现及常见调试陷阱,帮助开发者应对真实工程挑战。

1. 先弄清楚MASAC多无人机协同路径规划在做什么

无人机做协同路径规划,难的不是让一架飞机从A飞到B避开障碍,而是多架飞机要在接近的时间窗口里同时到达各自目标,全程不撞障碍物、不互相挤成一团。这个问题用经典路径规划算法写起来很痛苦:每架飞机的计划都会影响其他飞机,障碍一变就要全盘重算。基于MASAC强化学习算法的多无人机协同路径规划,本质是用多智能体强化学习把这套“互相避让、互相等待”的协同策略训出来。MASAC是SAC在多智能体方向的扩展:每架飞机用自己的局部观测独立决策,训练时由一个能看见全局的Critic教它怎么协同。下面会把建模、Python落地和踩坑点讲透,适合想把手上的无人机路径规划代码从单机搬到多机的人,零基础建议先补一下SAC的入门资料再回来看。

2. 把协同路径规划拆成强化学习问题:运动学模型、状态空间与奖励函数

2.1 面向路径规划,用二维点质量模型就够了

多无人机协同路径规划里最容易被新手上手就劝退的点,是试图把四旋翼的全动力学模型塞进强化学习训练。无人机全动力学模型包含姿态角、角速度、旋翼转速,适合做飞控层的控制器验证,不适合做路径规划层的策略学习。训练一次强化学习要跑几十万到几百万步,每一步都在全动力学仿真器里做积分,时间成本直接翻几十倍,而路径规划层的上层算法在绝大多数情况下并不关心姿态是怎么转过去的。

我一般会把无人机简化成带速度上限和加速度上限的质点模型:位置和速度作为状态,控制量是加速度。加速度上限模拟执行机构的响应能力,速度上限模拟平台本身的飞行包线。低空编队和室内巡航场景把高度锁死,二维平面模型完全够用;遇到真三维地形穿越,把z轴加回来,动作维度从2变成3,障碍物从圆变成球,其余逻辑不变。这个“先用二维跑通上层算法”的做法,是无人机路径规划算法落地最常见的第一步。

具体的仿真参数按100m×100m任务地图来设:控制周期dt=0.1s,最大速度5.0m/s,最大加速度2.0m/s²,机间安全距离2.0m,到达判定半径5.0m。单回合格局下,最大步数设在300到500之间,保证无人机有足够时间从地图一端飞到另一端,同时不会在目标点附近无限徘徊。

模型参数默认值作用
dt0.1s控制周期,也是训练时环境的步长
max_vel5.0m/s速度上限,更新后直接截断
max_acc2.0m/s²动作经此映射成真实加速度
safe_dist2.0m机间最小安全距离,小于即碰撞
goal_radius5.0m进入该范围视为到达目标点
map_size100.0m地图边长,位置限幅范围

2.2 状态空间:Actor只看局部,Critic才看全局

多智能体强化学习里最容易踩的坑,是把“每个智能体观测什么”和“Critic能看见什么”混在一起。先分清两个概念:Actor是执行策略的网络,它只能拿到第i架无人机自己的局部观测;Critic是训练阶段评估价值的网络,它可以拿到所有无人机的状态和动作。这个结构叫中心化训练、去中心化执行,也是MASAC能学到协同行为的前提。

单架无人机的局部观测s_i,我习惯按这个顺序拼接:自身位置、自身速度、目标点相对位置、邻机相对位置、最近障碍物相对位置与距离、自身编号one-hot编码。位置用相对量而不是绝对量,是为了让策略对地图平移具有一定的泛化能力,换个起点布局不至于完全失效。邻机相对位置取的是通信范围以内的飞机,例如20m通信半径;超出范围的飞机不参与观测拼接,这样扩展到更多无人机时观测维度不会无限膨胀。

Critic的输入则是所有智能体观测的拼接和所有智能体动作的拼接,即S = [s_1,...,s_n]和A = [a_1,...,a_n]。对4机编队来说,如果每个智能体观测是50维,Critic输入就是200维状态加8维动作。这个维度并不算高,普通256宽度的MLP就够用了。需要注意的是,Critic能看全局不代表Actor能看全局,否则部署时一旦某一架飞机通信丢包或延迟,策略立刻失效。

2.3 奖励函数:从单机可跑通到多机协同分三步加

多无人机协同路径规划的奖励函数设计,我的建议是分三步叠加,不要第一次就把所有项全部塞进去。第一步只放到达奖励和距离势能引导,确保单智能体环境下能把一架飞机从起点训到目标点。距离势能是r = 2.0 × (上一时刻到目标的距离 - 当前时刻到目标的距离),它给了无人机一个连续梯度,不然只靠最终+100的到达奖励,稀疏奖励下策略完全学不动。

第二步加入障碍物惩罚。障碍物惩罚不要用“碰到就给-50”的硬惩罚,用软惩罚更稳:当无人机进入障碍物影响半径时,惩罚按距离线性递减,奖励曲面连续可导,Critic拟合起来容易得多。第三步才是多机协同项:机间碰撞惩罚和到达时间差惩罚。到达时间差惩罚可以让先到的飞机学会等待、后到的飞机学会加速,而不是各飞各的、到得早晚无所谓。

奖励项建议取值说明
到达目标+100进入goal_radius即触发
距离势能2.0 × (d_prev - d_cur)引导持续靠近目标
障碍物软惩罚50 × (1 - d_obs / R_obs)进入影响半径后线性增加
机间碰撞惩罚-30小于safe_dist时触发
到达时间差惩罚0.5 × std(arrive_time)协同项,按全局到达时间计算

数值尺度有一个硬经验:奖励分量之间的量级差不要超过两个数量级。如果距离势能每步给2分,机间碰撞一次扣30分,障碍物一次扣50分,Critic主要精力全在拟合碰撞惩罚上,协同项会被直接淹没。先单机跑,再加避障,最后加协同项,每加一步都重新观察奖励曲线是否还能稳住,这个顺序能省掉大量调参时间。

2.4 任务与终止条件:固定目标分配还是动态分配

多无人机协同路径规划的任务定义里,目标分配方式决定了问题难度。最稳妥的起步方案是固定目标分配:第0架飞机固定去0号目标点,第1架去1号目标点,以此类推。动态目标分配属于任务分配层的另一个问题,需要额外加匹配网络或用匈牙利算法在线解算,和路径规划耦合起来训练难度会陡增。

我建议第一版先把固定分配跑通,多机协同体现在时间协同和空间避让上:到达时间尽量一致、机间距离始终大于安全值、避障时不互相干扰。终止条件设成“所有智能体都到达或者超过最大步数”,单架飞机到达目标点后动作立即置零保持悬停,等队友跟上,否则先到者还在乱飞,会把整个协同到达的语义破坏掉。

3. 从SAC到MASAC:中心化Critic与去中心化Actor为什么能协同

3.1 SAC的核心逻辑:最大熵与随机策略

SAC能成为连续动作控制场景最常用的深度强化学习算法,关键在它的目标函数不止包含累计奖励,还包含策略熵。最大化熵意味着策略不会过早坍缩成一条确定性曲线,而是会保留一定程度的不确定性。这对多智能体场景特别重要:其他无人机策略在训练中持续变化,过于确定性的策略很容易被环境变化甩出可用区间,随机策略天然带宽泛化余量。

SAC的动作采样用重参数化技巧。Actor输出的是动作均值和对数标准差,构造高斯分布后先用标准正态分布采样噪声,再通过z = μ + σ·ε得到动作,最后用tanh压到[-1,1]区间。这个做法的价值是能保留“采样”这个随机过程的同时,让梯度可以回传到网络参数上,否则随机采样没法做反向传播。多智能体版本里,每个智能体的动作维度通常只有2或3,重参数化计算代价很小,所以MASAC不像MADDPG那样受限于确定性策略。

SAC里还保留了双Critic结构:两个独立的Q网络分别估计价值,最终用两个网络的最小值作为目标值。这是降低Q值过估计的常用手段。多智能体场景下,Critic输入维度更高、样本覆盖密度更低,Q值过高估计被进一步放大,因此这个取最小值的操作不仅不能省,反而是保证训练稳定的关键。

3.2 MASAC的三个关键改动:独立Actor、全局Critic、带编号的经验池

和SAC相比,MASAC的改动集中在三个点。第一,每个智能体拥有一个完全独立的Actor网络,参数不共享,输入自己的局部观测,输出自己的动作分布。第二,Critic输入改成全局拼接向量:所有智能体的观测和所有智能体的动作。第三,经验回放池共享,但每条样本必须记录agent_id,否则更新时无法区分每条经验属于哪个智能体。

独立Actor网络意味着“去中心化执行”是硬约束,这和多无人机场景的物理现实一致:部署时每架飞机只能决定自己的动作,没有任何中央节点替它做决策。而Critic能看见全局,训练时可以回答“在所有飞机当前状态和动作下,某架飞机这样做的价值是多少”,这个全局视角是协同行为能够被评估和引导的前提。

对比方案Critic观测适用规模主要问题
独立SAC并行单机obs + 单机act2~3机智能体策略相互视为噪声,不收敛
MADDPG全局obs + 全局act3~10机确定性策略在连续动作空间容易不稳定
MASAC全局obs + 全局act3~10机Critic输入维度随N线性增长
MAPPO全局obs + 全局act10机以上采样效率要求高,训练更慢

实际选型时,如果你做的是10架以下无人机的小编队协同,MASAC是最稳的起点。超过20架或者通信拓扑受限,Actor需要考虑用图神经网络聚合邻居信息,纯拼接输入会让Critic和Actor的输入维度都难以处理。

3.3 中心化训练为什么是“协同”的来源,不是奖励函数逼出来的

多智能体训练有一个本质问题:对任意一架无人机而言,其他无人机的策略都在不断变化,这导致环境转移概率P(s'|s, a)在训练期间是非平稳的。如果Critic不去看其他智能体的动作,它拟合出的Q函数就像在移动的沙丘上打地基,今天学到的价值明天就失效,训练自然发散。

MASAC把其他智能体的状态和动作直接拼进Critic输入,相当于把这种非平稳性显式建模到了价值函数里。Critic不再需要猜测队友下一步会做什么,它直接看到了队友的动作和状态,Q函数有了稳定的回归目标。Actor则通过Critic给出的梯度,间接学会“我现在这样飞,队友会怎么反应,最终对整支编队收益如何”的协同策略。所以协同不是靠奖励函数里塞进“协同项”挤出来的,而是中心化Critic带来的结构红利。

这里有一个常见的误解:有人会问“既然奖励里写了避碰惩罚,各飞各的也能学会避碰,为什么要上MASAC?”独立SAC并行训练确实能学会静态避障,但学不会时间协同。四架无人机同时到达目标点这个需求,单机奖励无法建模“全局到达时间差”,必须有一个能看见所有人的价值函数才能评估这个目标。这就是中心化Critic不可替代的原因。

4. 用Python落地MASAC:环境、网络与训练循环怎么组织

4.1 工程文件怎么切

一个能迭代的MASAC工程,我习惯切成四个文件:uav_env.py放无人机环境,包含运动学、奖励计算、碰撞检测;masac_networks.py放Actor和Critic网络定义;masac_train.py放训练循环和经验回放;eval.py放评估脚本和轨迹导出。环境、网络、训练三层分开,之后想换成MAPPO或MADDPG,只需要重写masac_train.py,环境和网络不用动。

4.2 环境step的核心实现

下面给一个最小可运行的环境骨架,step函数里包含了加速度控制、距离势能奖励、到达判定、避障软惩罚和机间碰撞惩罚。

# uav_env.py import numpy as np class UAVEnv: def __init__(self, n_agents=4, map_size=100.0, safe_dist=2.0, goal_radius=5.0, dt=0.1, max_vel=5.0, max_acc=2.0): self.n_agents = n_agents self.map_size = map_size self.safe_dist = safe_dist self.goal_radius = goal_radius self.dt = dt self.max_vel = max_vel self.max_acc = max_acc self.obstacles = [np.array([40.0, 40.0]), np.array([60.0, 60.0])] self.reset() def reset(self): # 固定初始位置,训练时建议替换为可复现随机起点 self.agents_pos = np.array([[10.0, 10.0], [90.0, 10.0], [10.0, 90.0], [90.0, 90.0]], dtype=float) self.agents_vel = np.zeros((self.n_agents, 2)) self.goals = np.array([[20.0, 20.0], [80.0, 20.0], [20.0, 80.0], [80.0, 80.0]], dtype=float) self.prev_dist = np.linalg.norm(self.agents_pos - self.goals, axis=1) return self._get_obs() def step(self, actions): # 动作从[-1,1]映射为加速度 actions = np.asarray(actions) * self.max_acc self.agents_vel = np.clip(self.agents_vel + actions * self.dt, -self.max_vel, self.max_vel) self.agents_pos = self.agents_pos + self.agents_vel * self.dt self.agents_pos = np.clip(self.agents_pos, 0.0, self.map_size) cur_dist = np.linalg.norm(self.agents_pos - self.goals, axis=1) rewards = 2.0 * (self.prev_dist - cur_dist) # 距离势能引导 for i in range(self.n_agents): if cur_dist[i] < self.goal_radius: # 到达目标 rewards[i] += 100.0 for obs_p in self.obstacles: # 障碍物软惩罚 d_obs = np.linalg.norm(self.agents_pos - obs_p, axis=1) rewards -= 50.0 * (d_obs < 6.0) * (1.0 - d_obs / 6.0) for i in range(self.n_agents): # 机间碰撞惩罚 for j in range(i + 1, self.n_agents): d_ij = np.linalg.norm(self.agents_pos[i] - self.agents_pos[j]) if d_ij < self.safe_dist: rewards[i] -= 30.0 rewards[j] -= 30.0 self.prev_dist = cur_dist dones = cur_dist < self.goal_radius return self._get_obs(), rewards, dones def _get_obs(self): # 实际项目中把目标相对位置、最近障碍物、邻机相对位置、one-hot编号拼进来 obs = [] for i in range(self.n_agents): obs.append(np.concatenate([ self.agents_pos[i], self.agents_vel[i], self.goals[i] - self.agents_pos[i]])) return obs

这段代码里有两个参数值得注意:障碍物软惩罚的影响半径用了6.0m,意味着无人机在距离障碍物6m以内就开始“减速”,惩罚随距离递减。这是刻意让惩罚管道连续化,避免无人机在障碍物边缘突然遭遇一个-50的阶跃,导致Critic学出一个陡峭的价值突变。机间碰撞惩罚用了硬阈值,距离小于2.0m直接各扣30分,因为机间安全距离本身就是硬约束,不能用“快撞了但没撞”来模糊处理。

4.3 Actor与Critic网络定义

Actor网络输出高斯策略的均值和标准差,Critic接收全局拼接向量。

# masac_networks.py import torch import torch.nn as nn import torch.nn.functional as F class Actor(nn.Module): def __init__(self, obs_dim, act_dim, hidden=256): super().__init__() self.fc1 = nn.Linear(obs_dim, hidden) self.fc2 = nn.Linear(hidden, hidden) self.mu_head = nn.Linear(hidden, act_dim) self.log_std_head = nn.Linear(hidden, act_dim) def forward(self, obs): h = F.relu(self.fc1(obs)) h = F.relu(self.fc2(h)) mu = self.mu_head(h) log_std = torch.clamp(self.log_std_head(h), -5.0, 0.0) std = log_std.exp() normal = torch.distributions.Normal(mu, std) z = normal.rsample() # 重参数化采样 action = torch.tanh(z) # 限制到[-1,1] log_prob = normal.log_prob(z).sum(-1, keepdim=True) log_prob -= torch.log(1.0 - action.pow(2) + 1e-6).sum(-1, keepdim=True) return action, log_prob class Critic(nn.Module): def __init__(self, all_obs_dim, all_act_dim): super().__init__() self.fc1 = nn.Linear(all_obs_dim + all_act_dim, 256) self.fc2 = nn.Linear(256, 256) self.fc3 = nn.Linear(256, 1) def forward(self, obs_all, act_all): x = torch.cat([obs_all, act_all], dim=-1) h = F.relu(self.fc1(x)) h = F.relu(self.fc2(h)) return self.fc3(h)

log_std做了[-5.0, 0.0]的截断,这是防止标准差在训练初期爆炸的常用手段。初始状态下网络输出接近零,log_std接近0意味着标准差接近1,动作接近均匀随机;训练过程中网络逐步降低log_std,策略才会慢慢确定下来。tanh把动作压到[-1,1],是为了让所有智能体的动作处于同一数值范围,方便Critic拼接输入。环境侧再把这个[-1,1]的动作乘以max_acc映射成真实加速度。

4.4 训练循环:全局样本如何收集和更新

样本收集时,每个智能体用自己的Actor独立决策,但存入经验池时不仅要存自己的obs和动作,还要存所有智能体的obs_all和act_all。因为更新Critic的时候需要全局信息,这条记录不能事后补。

# masac_train.py 片段 for episode in range(total_episodes): obs = env.reset() obs_all = np.concatenate(obs, axis=-1) # 全局观测拼接 step = 0 while not done and step < max_steps: actions, log_probs = [], [] for i in range(n_agents): s_i = torch.FloatTensor(obs[i]).unsqueeze(0) a_i, lp_i = actors[i](s_i) # 训练阶段采样动作 actions.append(a_i) log_probs.append(lp_i) act_all = torch.cat(actions, dim=-1) # 全局动作拼接 next_obs, rewards, dones = env.step( torch.cat(actions, dim=-1).detach().numpy()) next_obs_all = np.concatenate(next_obs, axis=-1) for i in range(n_agents): buffer.push( agent_id=i, obs_i=obs[i], act_i=actions[i], rew_i=rewards[i], done_i=dones[i], obs_all=obs_all, act_all=act_all, next_obs_all=next_obs_all) obs = next_obs obs_all = next_obs_all step += 1

更新阶段和SAC的更新公式一致,只有一处改动:Critic的输入不是单机观测和动作,而是全局拼接向量。Critic损失是双Q的MSE,Actor损失是alpha乘以当前策略log_prob减去在线Q值。唯一需要小心处理的细节是:计算Actor损失时,要重新采样第i个智能体的动作,并用新动作替换全局动作向量中的第i段,再送入Critic。如果直接沿用样本里的旧动作,Actor的梯度会错。

经验池方面,200000条容量对4机编队足够,至少能覆盖几十个完整回合。buffer需要超过1000条才开始更新,否则采出来的样本几乎都来自同一个回合开头,缺乏多样性。

4.5 超参起步模板与启动命令

超参起步我建议用这一组,适配4机场景:

超参数推荐值备注
学习率3e-4Adam,训练不稳时降到1e-4
gamma0.99最大步数300~500时足够
tau0.005target网络软更新系数
batch_size2564机编队默认值
buffer容量200000至少覆盖几十个回合
target_entropy-act_dim自动温度调节的目标熵
梯度裁剪10.0防止更新步长过大

先跑2机、10万步,确认奖励曲线能稳定上升,再加到4机、200万步。直接上4机在高维状态下报错或发散,很难分清是代码问题还是超参问题。

python masac_train.py --n_agents 2 --max_steps 200 --total_steps 100000 python masac_train.py --n_agents 4 --max_steps 400 --total_steps 2000000

5. 多无人机强化学习训练的常见坑:现象、原因与排查步骤

5.1 奖励曲线在涨,无人机却在目标附近画圈

现象:累计奖励持续上升,但把轨迹画出来,发现无人机在目标点附近来回绕飞,就是不进入goal_radius。原因通常是距离势能引导系数和避障惩罚的相互作用:越靠近目标,避障压力越大,继续靠近带来的势能收益低于避障惩罚,策略就停在了一个“绕着走更划算”的平衡点。

解决:先把势能系数从2.0降到0.5,同时检查目标点周围是否有障碍物距离过近。如果目标点就放在障碍物影响半径以内,无人机永远无法同时满足“靠近目标”和“远离障碍”两个条件。排查时把目标点挪到离障碍物至少10m的位置,问题会立刻消失。

5.2 同一套配置,两次训练结果天差地别

现象:代码没改,超参没改,第一次收敛,第二次发散。原因大概率是随机种子没固定。Python的random、numpy的全局随机、torch的初始化、环境的初始位置,任何一个没固定,训练过程都不可复现。

解决:在train.py入口统一固定种子,并且环境reset内部不要用np.random默认全局接口,改成显式传入seed的随机数生成器。另一个细节是:如果环境里初始位置是随机的,而你没有固定种子,单次训练的结果本身就带运气成分。排查时先固定全部种子,再判断算法好坏。

5.3 多机学成了同质化策略,全往一个目标点挤

现象:四架无人机有两个去了同一个目标点,另两个目标点空着。原因是Actor网络结构完全相同,如果局部观测里没有身份标识,且初始位置和目标分配存在对称性,多机很容易学到同一个策略。共享经验池会加剧这个问题,所有agent样本高度相似,梯度方向几乎相同。

解决:在局部观测里拼上one-hot编号,让每个Actor知道自己是几号机;同时检查奖励里有没有分工机制,比如到达时间差惩罚。只加避碰惩罚解决不了分工问题,避碰只会让它们互相让开,不会让它们各自去不同目标。如果加了one-hot还学不会分工,把环境恢复成固定初始位置、固定目标分配,先验证能收敛再放开随机布局。

5.4 自动温度调节失控,策略变成白噪声

现象:开了alpha自动调节后,熵权越来越大,动作几乎完全随机;或者alpha直接崩到0,策略坍缩成一条确定性曲线再难恢复。原因是target_entropy设得过大,超出策略能达到的熵上限,alpha不停增大去追逐一个无法实现的目标;alpha学习率设得太大,调节速度跟不上价值函数变化。

解决:把target_entropy设为负的动作维度,2维动作就是-2.0,3维动作就是-3.0,这个经验值和大多数连续控制场景匹配。alpha_lr不要超过3e-4。排查时可以先关闭自动调节,固定alpha=0.2跑通收敛,再开自动调节,这样能把问题范围缩小到温度超参上。

5.5 训练时表现正常,评估时到达率暴跌

现象:训练时用采样的随机动作,每回合奖励不错;评估时用均值动作,无人机反而到不了目标点,碰撞率还升高了。原因有两个:一是评估时用了带熵的随机采样,策略在均值附近抖动,在狭小通道或障碍物边缘抖动会导致碰撞;二是obs归一化统计量如果只在训练时更新,评估时统计量不匹配,输入分布发生偏移。

解决:评估时Actor强制取均值,不要采样,连续跑10个episode统计到达率、碰撞次数、平均到达时间。如果obs做了归一化,训练结束时要冻住mean/std,评估和部署必须使用同一份统计量。排查顺序先改评估逻辑,再查归一化。

6. 验证策略效果:奖励曲线之外,还要看轨迹回放和多场景泛化

6.1 先跑单机基线,再谈多机协同

拿到这套MASAC代码,第一件事不是直接训4机,而是把环境切成单智能体版本,用普通SAC训100000步。单机版本如果到达率到不了100%,问题在环境或奖励函数,不在MASAC。这个基线能隔离出大量低级问题,比如目标点被障碍物挡住、动作映射方向搞反、dt过大导致积分发散。我在这个环节至少省过五次“以为是算法问题,结果发现是环境bug”的情况。

单机基线跑通后再看两件事:平均到达步数是否在合理范围,以及奖励曲线末段是否还有明显的上升空间。如果单机都消耗了大量步数才到达,多机协同的时间窗口会更紧张,需要先降低任务难度。

6.2 导出轨迹,把每一局的飞行路径画出来

训练完成后,用下面的评估脚本把轨迹导出成npy文件,画图检查是否有交叉和绕路。

# eval.py 片段 for episode in range(10): obs = env.reset() traj = {i: [obs[i].copy()] for i in range(n_agents)} while not done: actions = [] for i in range(n_agents): with torch.no_grad(): mu = actors[i](torch.FloatTensor(obs[i]).unsqueeze(0))[0] actions.append(mu) obs, _, done = env.step(torch.cat(actions, dim=-1).numpy()) for i in range(n_agents): traj[i].append(obs[i].copy()) np.save(f"traj_ep{episode}.npy", np.array([traj[i] for i in range(n_agents)]))

画图时重点看三个信号:是否有两条轨迹在时间上同时经过同一个点;是否有飞机在目标点附近徘徊超过50步;是否有飞机为了避让队友绕了一个不必要的远路。这些信息在奖励曲线上完全看不出来,但轨迹图一眼就能定位问题。多无人机协同路径规划的输出不是一个数值指标,而是一组策略,轨迹回放是最直观的验收手段。

最后再做一个多布局泛化测试:换掉障碍物位置,不换网络权重,随机跑10个episode,记录到达率。强化学习策略不是搜索算法,泛化能力有限,这个测试不是为了证明它能应对任意未知环境,而是排查策略有没有过拟合到训练集布局上。如果换了布局后到达率从90%掉到30%,说明策略记住了障碍物位置而不是学会了避障逻辑,就需要在训练时随机化障碍物布局重训。

我现在拿到多机路径规划任务,不管用什么算法,第一件事永远是先跑单机版本。单机都跑不稳的曲线,再漂亮都是自欺欺人。这个习惯帮我躲过了大量无效调参,希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询