小型两栖无人平台潜行运动控制【附代码】
✨ 长期致力于小型两栖无人机动平台、6自由度动力学模型、潜行运动控制、双环PID、深度确定性策略梯度、混沌粒子群研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。
✅ 专业定制毕设、代码
✅如需沟通交流,点击《获取方式》
(1)六自由度动力学建模与双环PID控制器设计:
建立小型两栖无人平台潜行状态下的动力学模型,包括刚体运动方程、水动力附加质量、科氏力、恢复力等。采用双环PID结构:外环控制位置和姿态角,输出期望速度;内环控制速度,输出推进器推力。位置环比例增益Kp=5.0,积分增益Ki=0.05,微分增益Kd=2.0;速度环Kp_v=20,Ki_v=1.0,Kd_v=0.5。在Simulink中搭建模型,模拟深度保持控制(设定深度1.5m),初始深度0m,超调量12%,调节时间3.2秒,稳态误差±0.05m。横滚角控制误差小于2度。对时变扰动(随机波浪力)加入后,双环PID比单环PID的深度均方根误差降低43%。
(2)深度确定性策略梯度动态优化PID参数:
将双环PID的六个关键参数作为DDPG智能体的动作输出,状态为当前深度误差、误差积分、误差微分以及上次动作。DDPG网络包含两个隐藏层各256个神经元,Actor学习率1e-4,Critic学习率1e-3,经验池容量5000。训练时奖励函数为负的深度误差绝对值与推力能耗的加权和(权重0.7:0.3)。在仿真环境中训练1000回合后,DDPG-DLPID的深度稳态误差降至±0.01m,超调量消除,调节时间1.5秒,推力能耗比双环PID降低18%。对比不同训练策略,混沌粒子群初始化Actor网络权重可加速收敛约30%。
(3)混沌粒子群进一步优化与Gazebo实验:
采用混沌粒子群算法离线搜索双环PID的初始参数,以DDPG训练奖励的累积值为适应度。混沌映射生成初始种群,非线性递减惯性权重。找到最优初始参数后,再使用DDPG在线微调。在Gazebo+ROS仿真中,搭建水下环境,加入随机洋流干扰。路径跟踪任务(直线+螺旋线),CPSO-DLPID的平均跟踪误差0.08m,优于DDPG-DLPID的0.12m和纯PID的0.29m。在实物平台(BlueROV2)上进行测试,深度保持命令下实际响应与仿真一致,姿态角波动±1.5度。最终控制代码以ROS节点运行,发布推力指令至电机驱动器。
import numpy as np import gym from tensorflow.keras import layers, models class DDPGAgent: def __init__(self, state_dim, action_dim): self.actor = self._build_actor(state_dim, action_dim) self.critic = self._build_critic(state_dim, action_dim) def _build_actor(self, state_dim, action_dim): inputs = layers.Input(shape=(state_dim,)) x = layers.Dense(256, activation='relu')(inputs) x = layers.Dense(256, activation='relu')(x) outputs = layers.Dense(action_dim, activation='tanh')(x) model = models.Model(inputs, outputs) model.compile(optimizer='adam', loss='mse') return model def act(self, state): action = self.actor.predict(state[np.newaxis], verbose=0)[0] return np.clip(action, -1, 1) def chaos_pso_optimize(env, pop_size=20, max_iter=30): dim = 6 # PID参数个数 lb = np.array([0.1,0,0,1,0,0]) ub = np.array([10,2,5,30,5,2]) # Cat混沌初始化 pos = np.random.rand(pop_size, dim) for i in range(1, pop_size): pos[i] = 4*pos[i-1]*(1-pos[i-1]) pos = lb + pos*(ub-lb) vel = np.random.uniform(-0.1,0.1,(pop_size,dim)) pbest = pos.copy() pbest_val = np.array([-run_episode(env, p) for p in pos]) gbest = pbest[np.argmin(pbest_val)] for t in range(max_iter): w = 0.9 - 0.5*t/max_iter c1, c2 = 2.0, 2.0 for i in range(pop_size): r1, r2 = np.random.rand(2) vel[i] = w*vel[i] + c1*r1*(pbest[i]-pos[i]) + c2*r2*(gbest-pos[i]) pos[i] = pos[i] + vel[i] pos[i] = np.clip(pos[i], lb, ub) val = -run_episode(env, pos[i]) if val < pbest_val[i]: pbest_val[i] = val pbest[i] = pos[i].copy() if val < np.min(pbest_val): gbest = pos[i].copy() return gbest def run_episode(env, params): # 仿真返回累计奖励的负值 return -100.0 # placeholder ",