本文将详细介绍一个最近的一个研究,围绕多拖轮协同作业任务,构建基于三自由度水动力学的强化学习仿真与控制框架。
在拖轮智能体设计方面,控制输入定义为舵角与螺旋桨转速的二维连续动作空间,状态变量则涵盖大地坐标系下的位置、航向角以及船体坐标系下的纵向、横向和首摇速度。智能体通过高频仿真步长更新状态。
动力学建模采用了经典的水面船舶三自由度Fossen模型,通过欧拉法进行离散化。该模型系统地计算了拖轮的质量矩阵、附加质量矩阵、随速度变化的科里奥利矩阵,以及由正面和侧面水下投影面积估算的非线性二次阻力矩阵。螺旋桨推力则基于转速、直径和特定推力系数进行换算,从而建立了较符合物理实际的控制量到受力与运动状态的映射。下面详细介绍各个模块设计细节:
多个拖船智能体设计:
动作空间设计
拖轮的动作定义(连续动作,2 维)
每个时间步,拖轮智能体输出一个二维连续动作:At=[δt,nt]
其中:
- δt:表示舵角,范围为[-35, 35], 单位角度
- nt:表示螺旋桨转速 ,范围为[0, 265],单位rpm
拖轮的状态变量
xk=⎣⎡xkykψkukvkrk⎦⎤,uk=[δknk]
xk,yk :表示船舶在大地坐标系下的位置(单位是m)
ψk :表示船舶的航向角,单位是弧度
uk:表示船体坐标系下的纵向速度(Surge velocity,船头方向)。
vk:表示船体坐标系下的横向速度(Sway velocity,右舷方向)。
rk:表示船体坐标系下的首摇角速度(Yaw rate,转向快慢)。
δk:舵角(Rudder angle)。控制方向。
nk:螺旋桨转速(Propeller revolution speed,通常单位:rpm 或 r/s)。控制前进动力。
拖轮的运动学模型 [针对后3个公式查找论文]
模型采用了欧拉法(Euler Method)进行离散化:
xk+1yk+1ψk+1uk+1vk+1rk+1=xk+Δt⋅(ukcosψk−vksinψk)=yk+Δt⋅(uksinψk+vkcosψk)=ψk+Δt⋅rk=uk+Δt⋅(−Xuuk+Xu∣u∣∣uk∣uk+Xnnk2)=vk+Δt⋅(−Yvvk−Yrrk+Ygδk)=rk+Δt⋅(−Nvvk−Nrrk+Ngδk)
- 前两个公式的含义:船体坐标系下的纵向速度和横向速度,通过旋转矩阵(由航向角决定)转换到大地坐标系,从而更新船的x,y坐标。
• 这里利用了三角函数变换,将“随船动的速度”分解为“向东”和“向北”的速度。
- 第三个公式的含义:下一时刻的航向角 = 当前航向角 + 时间步长 x 角速度
- 第四个公式的含义:
智能体观测空间:
障碍物/他船
不要直接喂全局AIS列表,做成固定长度:
- 最近 N 个目标,每个目标含:
- 相对位置 (\Delta x,\Delta y)
- 相对速度
- CPA / TCPA
- 航向差
- 目标类别(船/浮标/码头设施)
周围环境感知向量:
从智能体中心向8个方向均匀射出100m长度的射线,如果射线碰撞到岸线,则计算射线长度,否则改射线长度为100m,将8个射线的长度编码成一个观测向量。
奖励函数设计
0.基本定义:
定义第i艘拖轮在t时刻的位置、航向、速度为:
pti∈R2,ψti,vti
目标船的位置、航向、速度分别为:
ptship,ψtship,vtship
第i艘拖船在目标船坐标系下的位置、航向偏差为:
p∗i(t),Δψ∗i(t)
其中,p∗i为期望拖船在目标船舶的位置,例如在船舶中心的左侧30m,前方80m;
Δψ∗i(t)为期望拖船在目标船的角度,例如在船舶中心的60°处。
定义截断算子:
clip[a,b](x)=min{b,max(a,x)}
1.全局奖励项:
Rtterm=⎩⎨⎧Csucc,−Ccol,−Cout,−Ctimeout,0,任务成功发生碰撞越界超时其他情况
其数值分别为500,600,600,300
2.误差项:
2.1位置误差:
ep,ti=R(ψtship)⊤(pti−ptship)−p∗i(t)
R(ψtship)⊤为转置矩阵,其目的是为了让大地坐标系下的拖船位置转换成目标船坐标系下
2.2航向误差:
eψ,ti=wrap(ψti−ψtship−Δψ∗i(t))
warp 是角度归一化函数,把任意角度差映射到一个标准范围内(−π,π]
2.3速度误差:
ev,ti=R(ψtship)⊤(vti−vtship)−v∗i(t)
通常来说,应保持拖船速度和目标船的速度一致,因此,v∗i(t)=0
3.误差归一化
3.1位置误差:
eˉp,ti=clip[0,1](Dref∥ep,ti∥)
Dref为位置误差归一化尺度,用于控制位置误差在奖励中的敏感范围,其取值与目标船尺寸、作业距离、机动空间大小有关,目标船设置为300m,参数在此取240m
3.2角度误差:
eˉψ,ti=clip[0,1](Ψref∣eψ,ti∣)
Ψref为航向误差归一化尺度,其取值与接近目标时的姿态偏差范围有关,在此取90度,即最大允许拖船垂直与目标船航向,如更加严格,可以取更小的数值
3.3相对速度归一化
eˉv,ti=clip[0,1](Vref∥ev,ti∥)
Vref为相对速度误差归一化尺度,用于刻画拖船与目标船之间速度不匹配的容忍范围,与目标船的速度有关数据中目标船的速度范围集中在6-12节,因此这个参数为0.4倍的最大速度,在此取2.5m/s
第i艘船的基础奖励可以简单的设置为:
ri(t)=−wpeˉp,ti+wprogclip[−1,1](dstep∥∥ep,t−1i∥∥−∥∥ep,ti∥∥)
其中,第一项表示误差惩罚,第二项表示接近奖励,其中,dstep=5m
在此处训练完成后,可以加入航向和航速的奖励函数:
ri(t)=−wpeˉp,ti+wprogclip[−1,1](dstep∥∥ep,t−1i∥∥−∥∥ep,ti∥∥)−wψeˉψ,ti−wveˉv,ti
wp=1.0,wprog=1.0,Rsuccess=100,Rfail=50
4.近场激活函数
σti=exp⎝⎛−(rcap∥ep,ti∥)2⎠⎞
rcap为近场激活半径,控制航向误差项和相对速度误差项何时开始显著起作用。 其决定拖船何时从接近阶段到精细对接阶段,此处取70m
5.单船任务奖励
Jti=wpeˉp,ti+σti(wψeˉψ,ti+wveˉv,ti)
wp,wψ,wv分别为位置误差、航向误差和相对速度误差的权重。其取值主要体现任务偏好,这里取1,0.5,0.7
任务奖励如下:
Rttask=N1i=1∑Nclip[−1,1](Jt−1i−Jti)
6.安全裕度;
安全裕度主要包括风险项:拖船之间的风险,拖船与动态障碍物的碰撞,拖船与静态障碍物的碰撞,拖船与边界、岸壁等的接近。
6.1拖船之间
定义拖船之间的距离为:
dij,ttt=∥∥pti−ptj∥∥
其中最小距离为:
dtt,ti=j=imindij,ttt
拖船之间的风险量化为:
qtt,ti=clip[0,1](dttsafedttsafe−dtt,ti)
dttsafe设定为50m
6.2环境交互
构建一个以拖船中心为椭圆中心、长轴沿航向方向的对称椭圆,其长轴为四倍船长,短轴为1.6倍船长,拖船和动态障碍物均使用这个船舶领域。
并定义拖船到某一障碍物k的相对角度为:
βik,t=wrap(atan2(yk,t−yti, xk,t−xti)−ψti)
则拖船中心到船舶域边界某一角度的距离为:
Di(βik,t)=bi2cos2βik,t+ai2sin2βik,taibi
6.2.1动态障碍物
对第k个 障碍物,其某一方向上到领域边界的距离为:
Dkdyn(βki,t)=bk2cos2βki,t+ak2sin2βki,takbk
则两者领域叠加后的距离为:
dik,tdyn,clr=dik,tcen−D(βik,t)−Dkdyn(βki,t)
取所有障碍物中最危险者:
ddyn,ti=k∈Otdynmindik,tdyn,clr
风险归一化:
qdyn,ti=clip[0,1](ddynsafeddynsafe−ddyn,ti)
其中安全距离取20m
6.2.2静态障碍物
静态障碍物的领域设置为圆形,
dik,tsta,clr=d(pti,Oksta)−D(βik,t)dsta,ti=k∈Otstamindik,tsta,clrqsta,ti=clip[0,1](dstasafedstasafe−dsta,ti)
类似的,d(pti,Oksta)为拖船中心到静态障碍物边界的最短距离
在此dstasafe=15m
6.3安全函数
Rtsafe=−N1i=1∑N(wtt(qtt,ti)2+wsta(qsta,ti)2+wdyn(qdyn,ti)2)
wtt=1.5,wsta=1.0,wdyn=1.3
7. 控制平滑:
Rtctrl=−N1i=1∑N⎣⎡(ΔnrefΔnL,ti)2+(ΔnrefΔnR,ti)2+(ΔδrefΔδL,ti)2+(ΔδrefΔδR,ti)2⎦⎤
其中,Δδref为5度(如果还是一直调整,可设置更小数值)
Δnref为0.1倍的最大转速
8.时间惩罚:
Rtstep=−cstep
c取0.002,如果存在拖延情况,加大取值
9.最终奖励
Rt=Rtterm+λtaskRttask+λsafeRtsafe+λctrlRtctrl+Rtstep
λtask,λsafe,λctrl 分别为任务推进项、安全项和控制平滑项的权重,取1.0, 2.0,0.02
10.成功判据:
∥ep,ti∥≤εp,∣eψ,ti∣≤εψ,∥ev,ti∥≤εv,mti≥0,∀i=1,…,N
其中 参数取值分别为10m, 20度, 0.3m/s ,连续20个时间步
3️⃣被牵引船舶运动设计:
从AIS数据集中提取油轮和货轮的数据进行插值,仿真的时候随机抽取一条 ,提供一个ship.csv 文件 ,csv列为: [mmsi, longitude, latitude, speed, heading, timestamp, shiptype]障碍物设计:
这里会提供很多个油轮或者货轮的数据,具体而言其长度应满足200m以上,国籍为外国
base_interp_1s.zip
4️⃣运动障碍物设计:
1. 障碍物船舶类型
中型船舶(货船、客船)
- 尺寸:长度 50-100m,宽度 10-20m
- 速度范围:4-7.5 m/s
- 运动特点:按航道规则航行,转向速率 1-2度/秒
大型船舶(油轮、集装箱船)
- 尺寸:长度 150-300m,宽度 30-50m
- 速度范围:5-10 m/s
- 运动特点:惯性大,转向速率 0.5-1度/秒,需要大转弯半径
2. 运动模式设计
模式1:航路点跟随 (Waypoint Following)
- 适用场景:船舶按预定航线航行(如进出港航线)
- 航路点定义:一系列经纬度坐标点 [(lon1,lat1), (lon2,lat2), ...]
- 到达判定:当船舶距离当前目标航点 < 50m 时,切换到下一个航点
- 转向控制:平滑转向,避免急转弯
模式2:横穿航道 (Channel Crossing)
- 适用场景:船舶从航道一侧横穿到另一侧(如渔船、小型货船)
- 起点和终点:在警戒区两侧边界附近随机生成
- 横穿角度:尽量垂直于航道方向(减少在航道内停留时间)
- 避让规则:必须避让主航道内的大型船舶,优先级最低
3. 碰撞避让规则(查一下论文,有没有相关的规范或者规定)
安全距离定义:
- 中型船舶:100m
- 大型船舶:200m
- 拖轮作业区:300m(其他船舶必须避让)
避让优先级(从高到低):
-
- 拖轮作业(最高优先级,其他船舶必须避让)
-
- 主航道内的大型船舶
-
- 主航道内的中型船舶
-
- 横穿航道的船舶(最低优先级)
4. 数据结构设计
obstacles.csv 文件格式:
[id, type,init_time,init_lon, init_lat, init_heading, init_speed, length, width, behavior_pattern, waypoints]
字段说明:
id: 障碍物唯一标识
type: 类型 (2=中型, 3=大型)
init_time:仿真系统中初始化的时间点
init_lon/lat: 初始经纬度
init_heading: 初始航向 (0-360度)
init_speed: 初始速度 (m/s)
length/width: 船体尺寸 (m)
behavior_pattern: 行为模式 (1=航路点跟随, 2=横穿航道)
waypoints: 航路点序列,JSON格式字符串,如 "[(lon1,lat1),(lon2,lat2)]" 或 "null"
5. 实现要点
- **碰撞检测:**计算 CPA (Closest Point of Approach) 和 TCPA (Time to CPA),当 CPA < 安全距离且 TCPA < 阈值时触发避让
- **运动更新:**每个时间步长更新位置、航向和速度,考虑转向速率限制
- **边界处理:**船舶离开地图范围后移除,可选择在边界动态生成新障碍物
- **性能优化:**使用空间分区(如网格)加速碰撞检测,只检测相邻区域的船舶
论文动力学建模:
![image.png]()
τ=⎣⎡cos(δl)sin(δl)lxsin(δl)+lycos(δl)cos(δr)sin(δr)lxsin(δr)+lycos(δr)⎦⎤T
其中T=[Tl,Tr]T, 表示调节左右推进器的转速nl和nr产生的推进力。 公式中的 δl 和 δr 表示左右推进器的旋转角度。lx 和 ly 表示左右推进器距离船舶两个对称轴xb和yb的距离.
矩阵的计算结果是3×1的向量,分别代表 [纵向力, 横向力, 首摇力矩]。
控制量: [nl,nr,δl,δr]
根据船厂提供的数据, lx的值为12m. ly估计为2.5m
转速与推力的关系为:
Tl=K⋅nl⋅∣nl∣
公式中出现绝对值是为了处理“倒船的情况”,K表示推力系数(由水密度,螺旋桨形状决定)
⚠️:nl的单位是rps
K的计算公式如下:
K=KT0⋅ρ⋅D4
KT0表示系泊工况推力系数,如果没有手册,常规导管螺旋桨的取值在0.3~0.5
ρ表示水密度,海水的密度为1025kg/m3
D表示螺旋桨直径,根据手册可知为:2.4m
参考代码:
def calculate_thrust(n_rpm, diameter_m, kt_fwd, kt_bwd=None, rho=1025.0):
"""
计算螺旋桨产生的推力 (Thrust)。
基于公式: T = K_T * rho * D^4 * n * |n|
参数:
n_rpm (float): 螺旋桨转速,单位:转/分 (RPM)。正数代表正转,负数代表反转。
diameter_m (float): 螺旋桨直径,单位:米 (m)。
kt_fwd (float): 前进(正转)时的推力系数 (无量纲,通常在 0.3~0.5 之间)。
kt_bwd (float, optional): 倒车(反转)时的推力系数。如果不传,默认取前进系数的 60%。
rho (float, optional): 流体密度,单位:kg/m^3。默认为海水密度 1025.0。
返回:
float: 推力,单位:牛顿 (N)。正值表示推力向前,负值表示拉力向后。
"""
if kt_bwd is None:
kt_bwd = kt_fwd * 0.6
n_rps = n_rpm / 60.0
current_kt = kt_fwd if n_rpm >= 0 else kt_bwd
thrust = current_kt * rho * (diameter_m ** 4) * n_rps * abs(n_rps)
return thrust
有了推力后继续看整体的动力学模型,又叫**Fossen 模型,这段公式描述的是一个船舶在水平面上的 3 自由度(3-DOF)**运动:纵荡 (Surge, 前后)、**横荡 (Sway, 左右)**和 首摇 (Yaw, 转向)。
先看运动学部分:
η˙=R(ψ)ν
其中η=[x,y,ψ]T,x和y表示船的绝对位置,ψ 表示船的航向角(比如正北是 0 度)。 ν=[u,v,r]T , u 表示船头朝前的速度,v表示船侧向漂移的速度,r表示船转头的角速度。
R表示一个旋转矩阵函数
展开写如下:
⎣⎡x˙y˙ψ˙⎦⎤=⎣⎡cos(ψ)sin(ψ)0−sin(ψ)cos(ψ)0001⎦⎤⎣⎡uvr⎦⎤
公式含义:负责把船自身的速度转换成地图上的位移速度。
再看动力学方程(受力分析):
本质上与 ma=F 一样:
Mν˙+C(ν)ν+D(ν)ν=τ+d
⚠️ 3dof仿真的质量是指排水量699 吨
- 计算质量矩阵M
M=MRB+MA
假设重心 (CG) 位于船体几何中心附近,为了简化,我们暂时忽略重心偏移带来的耦合项。
计算转动惯量: Iz=m×(kzzL)2 , kzz 是回转半径,对于拖轮这种宽船体,取值为0.25.
Iz=699,000×(0.25×36)2=699,000×81≈5.66×107kg⋅m2
再计算附加质量矩阵MA,拖轮水下形状复杂,但可用工程经验系数估算:
- 纵向附加质量Xu˙ ,通常为船体质量的5%~10%, Xu˙≈−0.05×m=−34,950 kg
- 横向附加质量Yv˙ , 横向阻力大,为船体质量的50%~80%, Yv˙≈−0.5×m=−349,500 kg
- 首摇附加转动惯量Nr˙:通常为刚体转动惯量的40%~60%, Nr˙≈−0.5×Iz=−2.83×107kg⋅m2
根据以上的结果带入公式可得M矩阵的值:
M=⎣⎡m−Xu^000m−Yv^000Iz−Nr^⎦⎤=⎣⎡7.34×1050001.05×1060008.49×107⎦⎤
(单位:kg,kg,kg⋅m2)
- 计算科里奥利矩阵 C(ν)
这个矩阵不需要新的参数,它是 M 矩阵和当前速度 ν=[u,v,r]T
的函数。
令:M11=7.34×105,M22=1.05×106 ,带入公式可得:
C(ν)=⎣⎡00M22v00−M11u−M22vM11u0⎦⎤=⎣⎡001.05×106⋅v00−7.34×105⋅u−1.05×106⋅v7.34×105⋅u0⎦⎤
注:科里奥利矩阵的数值随速度变化
- 计算计算阻力矩阵D(ν)
阻力分为线性阻力(低速时主导,如靠泊微操)和非线性阻力(高速时主导)。我们主要计算非线性部分,因为它是主要的能量消耗项。
DNL=diag(X∣u∣u∣u∣,Y∣v∣v∣v∣,N∣r∣r∣r∣)
在计算之前需要计算吃水T :
已知船长 (L): 36 m,船宽 (B): 11 m,质量 (m): 699 t=699,000 kg, 海水密度 (ρ): 1025kg/m3
排水量公式:
Δ=L×B×T×Cb×ρ
带入可得:699,000=36×11×T×0.58×1025
解得:
T≈3.0m
A. 纵向二次阻力系数 X∣u∣u
基于正面投影面积估算。
- 正面水下投影面积 AF≈B×T=11×3.0=33m2
- 纵向阻力系数 CDx, 一般船型取0.05~0.1
- 计算可得:X∣u∣u≈−21ρAFCDx=−0.5×1025×33×0.1≈−1,700 kg/m
⚠️:如果这艘拖船很钝(方头),纵向阻力系数可能会更大
B. 横向二次阻力系数 Y∣v∣v
这是拖轮最重要的参数,因为侧向漂移阻力巨大。
- 侧面水下投影面积 AL≈L×T=36×3.0=108m2
- 横向阻力系数CDy ,近似看作平板,取0.9
- 代入可得:Y∣v∣v≈−21ρALCDy=−0.5×1025×108×0.9≈−50,000 kg/m
C. 首摇二次阻力系数 N∣r∣r
这是一个力矩阻力,通常通过对横向阻力沿船长积分得到。
- 经验公式: N∣r∣r≈101×∣Y∣v∣v∣×L2
- 代入计算可得:N∣r∣r≈0.1×50,000×362≈−6,500,000kg⋅m2
D. 线性阻力系数(用于防止零速度除零错误)
通常取非线性系数的 1/10 或更小,主要用于数学稳定性。
-
Xu≈−500
-
Yv≈−5000
-
Nr≈−1,000,000
D(ν)矩阵实现:
D(ν)=⎣⎡500+1700∣u∣0005000+50000∣v∣000106+6.5×106∣r∣⎦⎤
(注意:公式中通常带负号,这里写的是绝对值,放在方程中时,正值即代表耗散)
物理引擎构建:
1.输入:当前的螺旋桨推力 (τ) 和环境干扰 (d)。
2.计算加速度:根据动力学方程,算出ν˙:
ν˙=M−1(τ+d−C(ν)ν−D(ν)ν)
3.引擎更通过时间步积分得到速度:νnew=νold+ν˙⋅Δt
4.坐标变换:利用航向角 ψ和旋转矩阵,将 ν 转换为 η˙
5.引擎更通过时间步积分得到位姿:ηnew=ηold+η˙⋅Δt
⚠️:M−1有解析解,只需要计算一次即可。
接下来的工作
1.场景数据加入
2.整合场景数据跟船舶动力学
3.打通godot强化学习框架
网址:godot_rl_agents/README.md 主页 ·埃德比奇/godot_rl_agents ·GitHub
已实现参考案例
4.强化学习框架
1.总体框架为集中训练分布式执行(CTDE)
5.论文章节安排
1.引言
2.动力学(或者是基础这一块的描述)
3.强化学习框架介绍
4.场景搭建与数据处理
5.仿真实验
6.结论