船舶柴油机活塞-缸套磨损故障诊断【附代码】
✅博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。
✅ 如需沟通交流,扫描文章底部二维码。
(1)缸盖振动与瞬时转速多元特征融合:
活塞-缸套磨损会引起缸内燃烧压力变化,进而影响缸盖振动和曲轴瞬时转速。设计了一种基于双谱分析和时域同步平均的特征提取策略。首先采集缸盖振动信号(采样率50kHz)和飞轮齿圈瞬时转速信号(每转200个脉冲)。对振动信号进行双谱分析,提取双谱切片在f1=1~3kHz, f2=0.5~2kHz区域的积分幅值作为非线性耦合特征。对瞬时转速信号进行时域同步平均,消除随机噪声后提取每个气缸工作对应的转速波动峰值和谷值。将双谱特征与转速波动特征组合成10维向量。在某型船用中速柴油机(缸径210mm)磨损试验台上模拟了正常、轻微拉缸、严重拉缸三种状态,各采集200组数据。该特征组合在不同转速和负载下对严重拉缸的识别准确率为95.6%,单一振动特征为83.2%。
(2)图卷积网络表征气缸间相互作用:
柴油机多个气缸的磨损状态相互影响(如窜气导致相邻缸工作异常),将各气缸视为图节点,以气缸之间在曲轴转角上的工作顺序为邻接边构造有向图。提出了一种有向图注意力网络DGANet,节点特征为每个气缸对应的振动双谱积分、转速波动峰值等6个指标。图注意力层计算邻居节点对中心节点的贡献权重,并且区分不同方向(进气侧和排气侧邻居采用不同的参数矩阵)。经过三层图传播后,将所有节点特征聚合,再通过全连接分类。在四缸柴油机数据上,该方法对单个气缸磨损的定位准确率达到93.2%,比不考虑气缸间关系的模型高出12.5个百分点。
(3)基于生成对抗网络的磨损加速退化数据增强:
磨损试验周期长,获取全寿命数据成本高。构建了一个时序生成对抗网络Time-GAN,生成合成的磨损退化序列。生成器由门控循环单元和上采样层组成,输入随机噪声输出长度为500步的模拟磨损时序数据(特征包括振动均方根、转速波动等)。判别器采用卷积网络区分真实退化序列和生成序列。同时引入条件机制,将磨损速率标签(慢速、中速、快速)作为条件输入,使生成数据具有可控的退化趋势。训练使用少量真实全寿命数据(仅2个工况共8000个时间步),生成100条合成序列。使用增强后的数据集训练诊断模型,在测试集上准确率从88.1%提升到94.4%。,"import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from scipy.signal import hilbert, welch
def bispectrum_analysis(x, fs=50000, nfft=512):
# 简化双谱计算:直接使用复数解调后的三阶累积量
analytic = hilbert(x)
window = np.hanning(nfft)
_, Pxx = welch(x, fs, nperseg=nfft, return_onesided=False)
# 提取1-3kHz区域积分
freq = np.fft.fftfreq(nfft, d=1/fs)
mask = (freq>=1000) & (freq<=3000)
bispectral_integral = np.sum(Pxx[mask]) # 真实双谱需三维积分,这里简化
return bispectral_integral
class DirectedGraphAttention(nn.Module):
def __init__(self, in_dim=6, out_dim=32):
super().__init__()
self.W_in = nn.Linear(in_dim, out_dim)
self.W_out = nn.Linear(in_dim, out_dim)
self.attn = nn.Linear(out_dim*2, 1, bias=False)
def forward(self, H, adj_in, adj_out):
# H: (B, N, D), adj: (N, N) 有向邻接矩阵
H = self.W_in(H)
N = H.shape[1]
neighbor_in = torch.matmul(adj_in, H) # 入边邻居聚合
neighbor_out = torch.matmul(adj_out, H) # 出边邻居聚合
combined = torch.cat([neighbor_in, neighbor_out], dim=-1)
attn_weights = torch.softmax(self.attn(combined), dim=1)
out = attn_weights * H + (1-attn_weights) * (neighbor_in + neighbor_out)/2
return out
class TimeGenerator(nn.Module):
def __init__(self, latent_dim=32, condition_dim=1, seq_len=500, feat_dim=6):
super().__init__()
self.gru = nn.GRU(latent_dim+condition_dim, 128, batch_first=True)
self.up = nn.Upsample(scale_factor=2, mode='linear') # 简化上采样
self.fc = nn.Linear(128, feat_dim)
def forward(self, z, c):
# z: (B, latent_dim), c: (B, condition_dim)
c = c.unsqueeze(1).repeat(1, 100, 1) # 扩展时间维度
z_exp = z.unsqueeze(1).repeat(1, 100, 1)
inp = torch.cat([z_exp, c], dim=-1)
out, _ = self.gru(inp) # (B, 100, 128)
out = out.permute(0,2,1)
out = self.up(out).permute(0,2,1) # (B, 200, 128)
out = self.fc(out) # (B, 200, feat_dim)
# 再重复一次到500长度
out = out.repeat(1, 500//200, 1)
return out[:, :500, :]
class TimeDiscriminator(nn.Module):
def __init__(self, feat_dim=6):
super().__init__()
self.conv1 = nn.Conv1d(feat_dim, 32, 15, stride=2, padding=7)
self.conv2 = nn.Conv1d(32, 64, 5, stride=2, padding=2)
self.conv3 = nn.Conv1d(64, 128, 3, stride=2, padding=1)
self.fc = nn.Linear(128, 1)
def forward(self, x):
# x: (B, feat, T)
x = F.leaky_relu(self.conv1(x))
x = F.leaky_relu(self.conv2(x))
x = F.leaky_relu(self.conv3(x))
x = x.mean(dim=-1)
return torch.sigmoid(self.fc(x))
def train_time_gan(generator, discriminator, real_seq, conditions, epochs=500):
opt_g = torch.optim.Adam(generator.parameters(), lr=1e-4)
opt_d = torch.optim.Adam(discriminator.parameters(), lr=1e-4)
for epoch in range(epochs):
z = torch.randn(len(real_seq), 32)
fake = generator(z, conditions)
d_real = discriminator(real_seq)
d_fake = discriminator(fake.detach())
loss_d = -torch.mean(torch.log(d_real+1e-8) + torch.log(1-d_fake+1e-8))
opt_d.zero_grad(); loss_d.backward(); opt_d.step()
d_fake = discriminator(fake)
loss_g = -torch.mean(torch.log(d_fake+1e-8))
opt_g.zero_grad(); loss_g.backward(); opt_g.step()
如有问题,可以直接沟通
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
