尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

液压Stewart平台DDPG运动控制虚拟现实【附代码】

液压Stewart平台DDPG运动控制虚拟现实【附代码】 ✅博主简介擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导毕业论文、期刊论文经验交流。✅ 如需沟通交流扫描文章底部二维码。1联合仿真建模与虚拟现实环境搭建利用AMESim建立液压系统模型包括伺服阀、非对称液压缸、负载敏感泵和管路动态特性设置油液弹性模量700MPa阀口压降1MPa。在MATLAB/Simulink中搭建运动学反解和动力学反解模块采用牛顿欧拉法计算各缸所需力。通过Simulink-AMESim联合接口实现模型的实时数据交换采样周期5ms。同时在Unity3D中构建Stewart平台的3D虚拟现实环境利用UDP协议接收MATLAB输出的六自由度位姿信号驱动虚拟平台运动实现控制算法的可视化验证。该虚拟现实系统能够在不同负载工况下模拟平台的摇摆运动为深度强化学习提供了低成本的试错环境。2深度确定性策略梯度算法的自定义奖励与状态空间设计状态空间选取为当前平台位姿误差x,y,z,α,β,γ六个自由度、各缸位移以及上一步动作值共15维。动作空间为伺服阀的电压指令范围-10V到10V。奖励函数融合了轨迹跟踪精度和能量消耗两项奖励值R -0.5*|err| - 0.01*u^2 10*flag_success其中err为位姿误差向量范数flag_success表示误差小于阈值时触发的稀疏奖励。Actor网络和Critic网络均采用三层全连接神经元数目400-300-200使用批量归一化层加速收敛。经验回放池容量设置10万批大小64目标网络软更新系数τ0.001。在每轮训练开始阶段加入奥恩斯坦-乌伦贝克噪声增加探索性噪声参数θ0.15σ0.2。3训练结果与多工况泛化验证采用上述配置在虚拟环境中训练2000回合每回合时长10秒。奖励曲线在800回合后趋于收敛平均跟踪误差降至0.8mm。训练完成的智能体直接应用到三种不同工况正弦波运动振幅50mm频率1Hz、阶跃响应单自由度50mm阶跃、随机波浪信号。在所有工况下DDPG控制器均可稳定跟踪期望轨迹无需重新调整参数。特别是在随机波浪信号下误差均方根仅为1.2mm相比传统PID减少了63%的超调和震荡。将Simulink中搭建的数学模型与联合仿真模型进行对比活塞杆伸长量曲线吻合度达到98.7%验证了模型的准确性。import numpy as np import torch import torch.nn as nn import torch.optim as optim from collections import deque import random class Actor(nn.Module): def __init__(self, state_dim15, action_dim6, hidden400): super().__init__() self.net nn.Sequential(nn.Linear(state_dim,hidden), nn.ReLU(), nn.Linear(hidden,300), nn.ReLU(), nn.Linear(300,action_dim), nn.Tanh()) def forward(self, s): return self.net(s) * 10.0 class Critic(nn.Module): def __init__(self, state_dim15, action_dim6): super().__init__() self.fc1 nn.Linear(state_dimaction_dim, 400) self.fc2 nn.Linear(400,300) self.fc3 nn.Linear(300,1) def forward(self, s, a): x torch.cat([s,a], dim1) x torch.relu(self.fc1(x)); x torch.relu(self.fc2(x)); return self.fc3(x) class ReplayBuffer: def __init__(self, capacity100000): self.buffer deque(maxlencapacity) def push(self, s,a,r,s_,d): self.buffer.append((s,a,r,s_,d)) def sample(self, bs): return random.sample(self.buffer, bs) def ddpg_train(env, episodes2000): actor, target_actor Actor(), Actor() critic, target_critic Critic(), Critic() target_actor.load_state_dict(actor.state_dict()) target_critic.load_state_dict(critic.state_dict()) opt_a optim.Adam(actor.parameters(), lr1e-4) opt_c optim.Adam(critic.parameters(), lr1e-3) buffer ReplayBuffer() tau, gamma 0.001, 0.99 for ep in range(episodes): s env.reset() for step in range(2000): with torch.no_grad(): u actor(torch.FloatTensor(s)).numpy() noise np.random.normal(0, 0.2, size6) a np.clip(unoise, -10, 10) s_, r, done env.step(a) buffer.push(s,a,r,s_,done) if len(buffer.buffer) 128: batch buffer.sample(64) s_b torch.FloatTensor([b[0] for b in batch]) a_b torch.FloatTensor([b[1] for b in batch]) r_b torch.FloatTensor([b[2] for b in batch]) s2_b torch.FloatTensor([b[3] for b in batch]) done_b torch.FloatTensor([b[4] for b in batch]) q_target r_b gamma * (1-done_b) * target_critic(s2_b, target_actor(s2_b)) q_pred critic(s_b, a_b) loss_c nn.MSELoss()(q_pred, q_target.detach()) opt_c.zero_grad(); loss_c.backward(); opt_c.step() loss_a -critic(s_b, actor(s_b)).mean() opt_a.zero_grad(); loss_a.backward(); opt_a.step() for t,t_ in zip(actor.parameters(), target_actor.parameters()): t_.data.copy_(tau*t.data (1-tau)*t_.data) for t,t_ in zip(critic.parameters(), target_critic.parameters()): t_.data.copy_(tau*t.data (1-tau)*t_.data) s s_ if ep%1000: print(ep)如有问题可以直接沟通
返回列表