☰
改进鲸鱼优化算法在机械臂时间最优轨迹规划中的应用与复现
2026/10/17 1:51:37 网站建设 项目流程

复现论文这件事,最怕两件事:一是论文写得像PPT,二是你把代码跑通了却说不清为什么。这篇《改进鲸鱼优化算法在机械臂时间最优轨迹规划的应用》属于典型的“算法改进+工程应用”组合——在一个被研究了二三十年的机械臂轨迹规划问题上,把2016年才提出的鲸鱼优化算法(WOA)改了一版,然后端上一组漂亮的对比曲线。复现它,我个人觉得比复现那些纯理论算法有意思,因为你要同时处理不等式约束、多项式插值和群智能算法这三件事。这篇文章会把我从搭建关节空间轨迹模型开始,到跑出改进WOA与标准WOA对比结果的整个流程,拆开给你看。

1. 从标题拆解:论文实际上解决了一个什么问题

1.1 机械臂时间最优轨迹规划的本质

机械臂干活,时间就是成本。但时间最优不是简单地把速度拉到最大,而要在每个关节都必须满足速度、加速度、加加速度上限的前提下,尽可能压缩全程时间。轨迹规划一般在关节空间做,因为关节空间里运动学约束最直接。给出一组经过逆解得到的关节角路径点,例如从起点依次经过几个中间点到达终点,我们要用多项式插值把这些点串成光滑曲线,每个关节在路径点处保持位置、速度、加速度连续。

相邻路径点之间有一段轨迹,每段都有自己的持续时间 h1, h2, ..., hm,优化变量就是这些时间。轨迹越短,插值曲线的峰值速度和峰值加速度越大,一碰到约束就是极限;轨迹越长,越不容易违反约束但总时间会变大。所以时间最优轨迹规划天然是一个带非线性约束的优化问题,本质上是在“时间维度”上做资源分配。

1.2 为什么用鲸鱼优化算法(WOA)而不是梯度类方法

因为目标函数对时间变量没有显式可导的解析表达式,约束还是大量隐式约束,速度和加速度峰值要通过采样计算。传统准牛顿法在这个问题里很难用,缺乏梯度信息,而且优化曲面存在大量局部极值。鲸鱼优化算法(Whale Optimization Algorithm,WOA)是2016年被提出的群智能算法,数学形式简单,核心就是模拟座头鲸的泡泡网捕食策略,分三种行为:包围猎物、螺旋逼近、无目标随机搜索。拿它做连续变量优化非常顺手,对初值不敏感,适合处理这种多约束、多峰值的工程问题。

WOA的另一个优势是控制参数少。标准WOA里最关键的就一个 A 向量,通过阈值 |A|<1 和 |A|≥1 来切换局部开发与全局搜索,没有额外的交叉变异算子,实现起来不容易出错。这对复现来说非常重要,算法结构一旦复杂,调参成本就会翻几倍,论文里写不清楚的地方反而容易成为坑。

1.3 “改进”的落点在哪里

标准WOA的缺点是学术界公认的:初始种群靠随机数生成,分布不可控;收敛因子 a 从2线性降到0,与算法真实的搜索进程不匹配;后期所有鲸鱼都朝当前最优解靠拢,一旦那个最优解是局部极值就再也出不来。论文标题里提到“改进鲸鱼优化算法”,我复现时采用了文献里最常见、也最容易落地的三件套改进:

  • Tent混沌映射初始化种群,让初始解尽可能均匀覆盖时间序列的搜索空间;
  • 收敛因子改用非线性衰减,前期多保持全局探索能力,后期快速转局部开发;
  • 位置更新时加入自适应惯性权重,让鲸鱼前期多听自己的经验、后期更贴最优解。

这三招单独拎出来每一个都不稀奇,但组合在一起确实能把标准WOA在轨迹优化里的收敛速度和最终质量明显拉起来。后面我会一步步讲清楚每一处改动在代码里是怎么做的,以及为什么这样改有效。

2. 机械臂轨迹规划的建模与适应度函数设计

2.1 关节空间里的五次多项式插值

轨迹规划大致分两类:笛卡尔空间规划直线圆弧,关节空间规划多项式曲线。对于时间最优这个目标,关节空间加高次多项式是主流方案。三次多项式只能保证位置和速度连续,加速度会有突变,实际机器人顶端会抖,所以论文里普遍用五次多项式。

五次多项式有六个系数 a0 到 a5,刚好对应起点终点的位置、速度、加速度六个边界条件。以第 i 段轨迹为例:

θ(t) = a0 + a1·t + a2·t² + a3·t³ + a4·t⁴ + a5·t⁵

给定起点关节角 q_start、终点关节角 q_end,起始速度 v0、终止速度 v1,起始加速度 acc0、终止加速度 acc1,加上这段的持续时间 h,六个未知数六个方程就能唯一解出。我复现时直接推导了解析公式,没调用矩阵求逆,这样计算更快,数值也更稳定。中间路径点的速度加速度怎么给?论文里要么通过前后段平均估算,要么直接设0。设0会让峰值加速度变大,但实现简单;我最终选了平均估算的方式,轨迹更平滑。

2.2 目标函数与约束惩罚

优化的原始目标是最小化总时间,也就是所有分段时间求和:

min T = Σ h_i

但光有这个目标,算法会疯狂压缩每一段时间,导致速度加速度全部爆表。所以必须带约束处理。工程里最实用的是外点惩罚函数法:

fitness = T + λ · V

T是总时间,V是所有关节在所有采样时刻超出约束的累计量,λ是惩罚系数。V的计算逻辑是:每个插值点算出速度、加速度、加加速度,如果某值超过对应上限,就把超出量平方后累加进来。平方是为了让轻微超限和严重超限拉开差距,引导算法朝约束边界内搜索。

这里有一个关键点:约束追踪不是一次性检查,而是在每一段轨迹的 [0, h] 区间内均匀采样,通常每段取100到200个采样点。采样点太少会漏掉峰值点,结果轨迹实际是超限的;采样点太多会拖慢WOA,因为每评估一次适应度就要对所有鲸鱼的所有段做采样循环。我复现时每段取了150个点,速度和约束检查的精度已经足够。

2.3 路径点与约束的典型配置

复现时先确定机械臂的自由度数和路径点数量。我用的是六自由度模型,为了让结果直观,我取其中三个主要关节参与优化,其余关节设成恒定角。路径点取六个,包括起点、终点和四个中间点,每行是一组关节角向量。约束设置为:角速度上限50度每秒、角加速度上限30度每秒平方、加加速度上限60度每秒立方。

这些数值不是论文原始值,但量级符合工业六轴机械臂的典型参数,复现出来的曲线形态和结论是一致的。需要提醒的是,路径点必须保证可达,最好由正向运动学/逆运动学验算过。我曾经偷懒直接手填一组角度,结果优化出来的轨迹虽然数学上合法,但机械臂构型在中间某个路径点附近发生奇异,曲线出现跳变,排查了半天才发现是路径点问题。

3. 标准WOA与改进WOA的算法实现细节

3.1 标准WOA的三个更新公式

先讲最原始的实现,后面所有改进都是在这个基础上改。每个鲸鱼个体就是一组解,把 h1 到 hm 拼接成一维向量。每次迭代先计算每个个体的适应度,找到当前最优解 X*。

标准WOA的更新分三种情况:

  • 包围猎物:先算 D = |C·X* − X|,然后 X_new = X* − A·D。其中 A = 2a·r − a,C = 2·r,r 是[0,1]均匀随机数。
  • 泡泡网攻击:抛一次硬币,以50%概率选择收缩包围,公式同上;另一半概率用螺旋更新:X_new = D'·exp(b·l)·cos(2πl) + X*,其中 D' = |X* − X|,l 是[−1,1]的随机数,b 是螺旋形状常数,取1。
  • 搜索猎物:当 |A| ≥ 1 时,不追当前最优解,而是随机选一个个体 X_rand,按 X_new = X_rand − A·|C·X_rand − X| 更新。

核心参数 a 从2线性降到0,迭代次数 T 控制下降速度。理解这三个公式的关键是:WOA没有单独的变异算子,全局搜索靠 |A|≥1 时的随机个体牵引,局部开发靠收缩包围和螺旋,两者概率相等。这既解释了WOA为什么结构通用,也解释了它为什么容易后期陷入局部最优——全局探索能力完全取决于一个线性衰减的参数,算法没有太多自救手段。

3.2 我第一次复现时的代码骨架

我用的就是常用的科学计算环境,numpy和matplotlib,所有算法手写,没有调用现成的优化库。标准WOA主循环非常短,核心逻辑如下:

for t in range(max_iter): a = 2 - 2 * t / max_iter for i in range(pop_size): r = np.random.rand() A = 2 * a * r - a C = 2 * np.random.rand() p = np.random.rand() if p < 0.5: if abs(A) < 1: D = np.abs(C * best_pos - positions[i]) new_pos = best_pos - A * D else: rand_idx = np.random.randint(pop_size) D = np.abs(C * positions[rand_idx] - positions[i]) new_pos = positions[rand_idx] - A * D else: D1 = np.abs(best_pos - positions[i]) l = 2 * np.random.rand() - 1 new_pos = D1 * np.exp(l) * np.cos(2 * np.pi * l) + best_pos # 边界处理 + 更新

写的时候要注意两点:A 和 C 每次更新时重新生成随机数,不能循环外只算一次;随机索引 rand_idx 要排除当前个体,否则会出现自己更新自己的情况。这些细节在论文里不会写,但直接影响复现结果,我最早跑出来的收敛曲线一直震荡,就是因为随机索引没排掉当前个体。

3.3 改进三件套的具体实现

改进一:Tent混沌映射初始化。标准初始化是 X = lb + (ub − lb)·rand(),这会让初始解在搜索空间里分布不均匀,尤其种群规模不大时容易扎堆。改成先用Tent序列生成 N 个0到1之间的混沌数,再映射到 [lb, ub]:

x_{n+1} = 2x_n 当 x_n < 0.5 x_{n+1} = 2(1 − x_n) 当 x_n ≥ 0.5

Tent映射比Logistic映射更均匀,而且实现极简单。我对比过同样种群数和迭代数,用Tent初始化后,20次独立运行的最优值方差小了很多,说明算法稳定性确实靠初始分布拉起来了。

改进二:非线性收敛因子。标准 a = 2 − 2·(t/T),改成 a = 2·(1 − (t/T)^μ),其中 μ 取2。这个改动的直觉非常清楚:前期 a 衰减慢,|A| 在1附近震荡的时间更长,算法有更多机会做全局探索;后期 a 快速降低,鲸鱼快速转向局部开发。实测下来,对于5段、6段时间优化问题,μ=2或3效果都不错,取更大值反而会在后期过早收敛。

改进三:自适应惯性权重。标准WOA的位置更新其实没有“记住历史位置”的机制,改进时我给原位置加了一个随迭代变化的权重:

w = 0.9 - 0.5 * t / T X_new = w * X - A * D

前期 w 接近0.9,保留个体自身移动惯性,避免一上来就被最优解吸过去;后期 w 降到0.4附近,个体更贴最优解,做精细化搜索。还有一种做法是余弦形式 w = 0.5 + 0.5·cos(π·t/T),效果类似,我实测线性版本已经够用。

4. 实操全流程复现:从模型到对比曲线

4.1 仿真环境与整体流程

整个仿真我全程在Python环境下跑,除了numpy和matplotlib外没有使用任何现成优化库。完整流程可以分成五步:

  1. 定义路径点关节角矩阵和运动学约束参数;
  2. 编写五次多项式系数求解函数和适应度评估函数;
  3. 实现标准WOA类;
  4. 实现改进WOA类(混沌初始化、非线性a、自适应权重);
  5. 固定随机种子,两种算法各跑20次独立实验,记录收敛曲线和轨迹曲线并绘图。

为什么要跑20次?因为群智能算法本质是随机算法,单次运行的最优值说明不了问题。论文里如果只放一条收敛曲线,复现时一定要自己多做几次统计,才能判断改进策略到底是真有效还是碰运气。

4.2 代码细节:五次多项式系数与适应度函数

五次多项式系数求解是适应度函数的地基。我推导了解析公式,避免矩阵求逆的数值问题。给定起点 q0、终点 q1、速度 v0、v1、加速度 a0、a1 和时间 h,系数可以按下面思路算:

def poly_coeff(q0, q1, v0, v1, acc0, acc1, h): h2 = h * h h3 = h2 * h a0 = q0 a1 = v0 a2 = acc0 / 2.0 a3 = (20 * q1 - 20 * q0 - (8 * v0 + 12 * v1) * h - (3 * acc0 - acc1) * h2) / (2 * h3) a4 = (30 * q0 - 30 * q1 + (14 * v0 + 16 * v1) * h + (3 * acc0 - 2 * acc1) * h2) / (2 * h2 * h) a5 = (12 * q1 - 12 * q0 - (6 * v0 + 6 * v1) * h - (acc0 - acc1) * h2) / (2 * h2 * h3) return np.array([a0, a1, a2, a3, a4, a5])

适应度函数里,每一段轨迹都调用这个函数,然后在 [0, h] 区间均匀采样,算出速度、加速度、加加速度。峰值约束检查通过后,把所有超限量的平方累加到惩罚项里,再加上总时间作为最终适应度。

4.3 参数配置与随机性控制

我用的参数配置如下:

  • 种群数 N = 30;
  • 最大迭代 T = 120;
  • 每段时间下限 h_min = 1秒,上限 h_max = 8秒;
  • 路径点6个,优化变量维度 m = 5;
  • 惩罚系数 λ 根据约束违反量级调整,最终取10;
  • 每段轨迹采样点150个。

随机性控制是关键:两种算法必须共用同一个混沌初始化种子,也就是标准WOA也使用同样的初始种群,只是随后迭代过程不同。这样才能保证对比的是“改进策略”的效果,而不是初始化运气带来的差异。

4.4 结果解读:收敛曲线和轨迹曲线

在给定配置下,我复现出的典型结果如下(这里是示例数据,不同路径点和约束下的数值会变,但趋势不变):

对比维度标准WOA改进WOA
最优总时间/s6.315.78
平均总时间/s6.585.91
最差总时间/s7.026.24
标准差0.270.13
平均收敛代数4821

改进后的总时间缩短了大约7%,更重要的是标准差明显变小,说明算法稳定性提高。收敛曲线方面,标准WOA要到50代以后才逐渐下降到位,中间还会出现几次平台期;改进WOA基本在15到20代就落到优秀解附近,后面只是小幅微调。

轨迹曲线方面,改进后的各关节速度曲线明显更贴近约束边界,这是时间最优的直观体现。拿其中一个关节来看,它在某几段里稳定运行在48到50度每秒的区间,几乎压着上限走;标准WOA则明显留有余量,速度峰值只有42到44度每秒。原因其实很简单,改进后的解搜索效率更高,能找到更“紧”的解,把冗余时间挤掉了。

5. 复现中常踩的坑与排查思路

5.1 维度与边界设计导致“假最优”

我踩过最大的坑是维度设计错误。路径点有6个,时间分段数是5,但代码里初始化种群时却用了路径点个数作为维度,等于多搜索了一个无意义的时间维度。多出来的维度假设会得到很低的适应度,误导算法。检查方法很简单:在初始化函数里打一行 print 验证 shape,确保每个个体长度等于路径点数减1。

另一个坑是边界设计。h_min 设置太小时,比如0.01秒,轨迹会在极短时间内完成,速度加速度必然全面超限,惩罚项主导适应度,算法最后得到的“最优解”其实全是惩罚平衡出来的假解。h_max 设置太大则搜索空间冗余,收敛变慢。建议先用梯形速度规划粗略估算每段最短时间,把 h_min 设在这附近的0.8倍左右。

5.2 惩罚系数怎么调才靠谱

惩罚系数 λ 的选择非常讲究。我第一次跑的时候设 λ=1000,结果适应度函数值全是几千,时间项6秒左右完全被淹没,算法全靠惩罚信息搜索,收敛效果极差。后来我把 λ 设为1,惩罚又不够,算法给出的最优解明显违反速度约束。调参经验如下:

  1. 先不设置惩罚,单独跑一次标准WOA,统计初始种群中时间项和约束违反量的数量级;
  2. 设置 λ 时,让初始种群中常规个体里λ·V与T同量级,比如 T 是6、V 是0.8,λ 取8到10;
  3. 精细调整:如果最优解仍有约束违反,就适当调大;如果收敛异常慢,就调小。

最后我确定 λ=10,这个值下几乎所有约束都被满足,偶尔有个别采样点超限0.5%以内,说明正好压在约束边界上,符合时间最优的预期。

5.3 高次多项式系数的数值稳定性

五次多项式系数里面出现了 h⁻³、h⁻⁴ 这样的高阶项,h 很小时数值会变得非常大。用矩阵求逆或者线性方程组求解时,h 接近0,系数矩阵接近奇异,结果会产生毫无意义的巨大系数。解决办法是我前面给出的解析公式,同时给 h_min 设置下限,不让算法把时间压到病态区间。

另外要注意的是惩罚函数里的采样点数量。采样点太多,比如每段500个,会显著拖慢适应度评估;采样点太少又可能漏掉峰值点,导致约束检查不准确。我可以提供一个判断技巧:先用一个已知解,把采样点从50加到500,看看约束违反量是否变化,如果变化明显说明采样密度不够,如果基本不变说明当前的采样密度足够。

5.4 对比算法的公平性

复现类论文最容易被人质疑的一点就是对比不公平。我在跑对比实验时,固定了初始种群生成方式,标准WOA和改进WOA从同一个混沌种子出发。同时,迭代次数、种群数量、适应度函数、边界条件全部保持一致。如果只改进算法却增加迭代次数,那结果就没有说服力。

还有一个小细节:记录收敛曲线时,应该记录每次迭代当前最优个体的适应度,而不是种群平均适应度。种群平均适应度会受异常个体影响,曲线忽上忽下,看不出趋势。最优适应度的收敛曲线更平滑,也更符合论文里的呈现习惯。


复现完这篇论文,我最大的体会是:改进算法这类文章,最核心的不是把新算法发明得像天外飞仙,而是让“算法-目标函数-约束”三者咬合紧密。WOA在机械臂轨迹规划上的应用,本质上把轨迹规划问题变成了一个参数搜索问题。一次成功的复现,产出应该是三样东西:可运行的仿真代码、严谨的对比数据、对论文每个改进点为什么有效的直观理解。

最后再分享一个扩展技巧:如果你想把时间最优改成“时间+能量加权最优”或者“时间+冲击最小最优”,只需要修改适应度函数,把能量项或加加速度积分项加进去做加权,WOA算法主体一个都不用动。这会是一个很好的扩展方向,做课程设计或者论文延伸都很合适。

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

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

立即咨询