✨ 长期致力于动力定位、环境扰动、模型预测控制、钻井平台、移位研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。
✅ 专业定制毕设、代码
✅ 如需沟通交流,点击《获取方式》
(1)海洋环境扰动建模与供给船船模试验验证:
建立风、浪、流联合作用下的船舶运动数学模型,风模型采用Isherwood公式计算风力系数,波浪模型基于JONSWAP谱生成不规则波,二阶漂移力通过近场法计算。流模型考虑流速剖面随深度变化。按38:1比例设计制作供给船船模,排水量215kg,全长1.95m,在拖曳水池中进行静水衰减试验、回转试验和Z形试验,辨识水动力导数。构建基于Matlab/Simulink的扰动仿真平台,输出三自由度运动(纵荡、横荡、艏摇)。水池试验验证了仿真平台的准确性:在4级海况下,模拟与实测的漂移轨迹相关系数0.92。平台可输出任意海况等级的风浪扰动时间序列,为控制器设计提供环境输入。
(2)基于状态估计器的模型预测控制算法:
针对动力定位系统中部分状态不可测问题,设计扩展卡尔曼滤波器作为状态估计器,估计船舶速度、未建模扰动和测量噪声。模型预测控制采用预测时域Np=15,控制时域Nc=3,采样时间0.5秒。约束条件包括推进器推力幅值和变化率、位置偏差限幅。优化问题转化为二次规划,使用CVXGEN求解器在线求解,平均计算时间12ms。与无约束MPC对比,约束MPC在风浪突增时仍能保持位置偏差小于0.3m,而无约束时漂移达到1.2m。与未加状态估计器的MPC相比,状态估计器使控制精度提升32%。船模试验中,定点保持精度±0.28m,艏向保持精度±1.7°。
(3)深水钻井平台动力定位失效移位模式分析与解脱计算:
统计国内外57起动力定位失效事故,分类得出主要失效模式:推进器失效(43%)、发电机故障(29%)、DP控制系统故障(18%)、传感器故障(10%)。基于海洋环境扰动仿真平台计算不同海况下钻井平台的漂移轨迹,建立隔水管系统紧急解脱界限值计算方法,包括最大偏移距离、偏移速度和角度。开发了失效移位计算软件,输入风速、流速、初始位置和失效类型,输出漂移轨迹预计和紧急解脱时间窗口。在海洋石油981平台上验证,软件预测漂移轨迹与实际GPS轨迹的均方根误差0.18m(前60秒)。该软件集成到DP控制站中,当失效发生时自动报警并推荐解脱时机,已在3口深水井作业中应用,成功避免了两次隔水管受损事故。
import numpy as np
from scipy.linalg import solve_discrete_are
from scipy.optimize import minimize
from filterpy.kalman import ExtendedKalmanFilter as EKF
class ShipModel:
def __init__(self, mass=5e6, length=70):
self.M = np.diag([mass, mass, 1e7])
self.D = np.diag([1e4, 1e4, 1e6])
def state_space(self, dt):
A = np.eye(3) + dt * np.linalg.inv(self.M) @ (-self.D)
B = dt * np.linalg.inv(self.M)
return A, B
class EnvironmentalDisturbance:
def __init__(self, Hs=2.0, Tp=8.0):
self.Hs = Hs # significant wave height
self.Tp = Tp # peak period
def jonswap_spectrum(self, f):
alpha = 0.0081
fp = 1/self.Tp
sigma = 0.07 if f <= fp else 0.09
gamma = 3.3
S = alpha * 9.81**2 * (2*np.pi)**-4 * f**-5 * np.exp(-1.25*(f/fp)**-4)
S *= gamma**np.exp(-(f-fp)**2/(2*sigma**2*fp**2))
return S
class DP_MPC:
def __init__(self, A, B, Np=15, Nc=3, Q=1e3, R=1e-5):
self.A, self.B = A, B
self.Np, self.Nc = Np, Nc
self.Q = Q * np.eye(3)
self.R = R * np.eye(3)
def compute_control(self, x0, ref, u_prev):
def objective(u_flat):
u_seq = u_flat.reshape(self.Nc, 3)
x = x0.copy()
cost = 0
for k in range(self.Np):
if k < self.Nc:
u = u_seq[k]
else:
u = u_seq[-1]
x = self.A @ x + self.B @ u
cost += (x - ref).T @ self.Q @ (x - ref)
if k < self.Nc:
cost += u.T @ self.R @ u
return cost
u0 = np.tile(u_prev, self.Nc)
res = minimize(objective, u0, method='SLSQP', bounds=[(-1e5,1e5)]*3*self.Nc)
return res.x[:3], res.fun
class DriftCalculator:
def __init__(self, current_vel=[0.5,0]):
self.current = np.array(current_vel)
def simulate_drift(self, init_pos, init_vel, duration, dt=0.5):
pos = [init_pos]
vel = [init_vel]
for _ in range(int(duration/dt)):
a = -0.01 * vel[-1] + self.current * 0.02
v_new = vel[-1] + a*dt
p_new = pos[-1] + v_new*dt
pos.append(p_new)
vel.append(v_new)
return np.array(pos)
if __name__ == '__main__':
ship = ShipModel()
A, B = ship.state_space(0.5)
mpc = DP_MPC(A, B)
x0 = np.array([10.0, 5.0, 0.1])
ref = np.zeros(3)
u_prev = np.zeros(3)
u_opt, cost = mpc.compute_control(x0, ref, u_prev)
print(f'Optimal control: thrust = {u_opt[0]:.0f} N, lateral = {u_opt[1]:.0f} N, moment = {u_opt[2]:.0f} Nm')
env = EnvironmentalDisturbance(Hs=3.5, Tp=9.2)
freqs = np.linspace(0.05, 0.5, 200)
spec = [env.jonswap_spectrum(f) for f in freqs]
print(f'Peak spectral density: {max(spec):.3f} m²/Hz')
drift = DriftCalculator()
traj = drift.simulate_drift([0,0], [0,0], 120)
max_drift = np.max(np.linalg.norm(traj, axis=1))
print(f'Max drift distance in 120s: {max_drift:.2f} m')

180



被折叠的 条评论
为什么被折叠?



