✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。
✅ 专业定制毕设、代码
✅如需沟通交流,查看文章底部二维码
(1)自适应分段正交匹配追踪与密度峰值聚类融合的信道重构:
针对IR-UWB信道具有固有稀疏性但多径时延密集的特点,提出了一种基于自适应分段正交匹配追踪与密度峰值聚类的信道估计算法。算法首先将接收信号与模板进行滑动相关,得到粗估计的路径时延集合。然后采用分段正交匹配追踪,将整个时延轴分为多个不重叠的区间,每个区间独立进行原子选择和残差更新。分段长度根据信道能量衰减曲线自适应调整:能量强的早期部分分段较细,能量弱的晚期部分分段较粗。每次迭代中,使用密度峰值聚类方法对候选原子进行聚类,每个簇只选择一个代表性最强原子加入支撑集,避免了相邻多径之间的互相干扰。与GOMP算法相比,该算法在信噪比5dB条件下归一化均方误差降低约3.8dB,且运行时间缩短42%。
(2)平方根扩展卡尔曼滤波的UWB/IMU紧组合定位:
为了提高室内定位的连续性和抗非视距能力,设计了一种基于平方根扩展卡尔曼滤波的UWB/IMU紧组合定位框架。将UWB测距值作为观测更新量的同时,IMU的加速度和角速度用于状态预测。平方根卡尔曼滤波采用协方差矩阵的Cholesky因子直接递推,避免了标准卡尔曼滤波中因数值不稳定导致矩阵非正定问题。状态量包括三维位置、速度、姿态四元数以及UWB时钟偏差。在UWB观测中,采用残差卡方检验剔除NLOS污染的测距值:当某个锚点的残差大于3倍标准差时,将其观测噪声协方差动态调高一个数量级。在走廊环境中的手持终端实验表明,该算法的平均定位误差为0.18米,相比单独UWB的0.45米和单独IMU积分漂移(5秒内1.2米)均有大幅提升,且位置输出频率达到100Hz。
(3)混合粒子滤波与字典学习的动态多径跟踪:
针对移动场景下多径成分的动态变化,构建了一种将粒子滤波与字典学习相结合的信道时变跟踪器。首先离线学习得到一个过完备字典,其中每个原子代表一种典型的多径分布模式。在线阶段,用粒子滤波估计信道的稀疏系数向量,每个粒子携带一组非零系数的位置和幅值。观测模型为接收信号与字典原子的线性组合,似然函数基于复高斯分布计算。粒子的重采样采用自适应策略,当有效粒子数低于总粒子数的一半时触发。同时,字典也会在线更新:每100个符号周期,将当前估计的信道脉冲响应作为新原子加入字典,并删除使用频率最低的原子。该算法在行人以1m/s速度移动的室内场景中,能够跟踪多径时延的变化,信道预测误差比标准卡尔曼滤波低27% ,且对突发遮挡具有更好的鲁棒性。
import numpy as np from scipy.linalg import cholesky, solve_triangular import scipy.sparse as sp # 自适应分段OMP(简化) def adaptive_segmented_omp(y, A, noise_var=0.1): n, m = A.shape residual = y.copy() support = [] # 根据能量包络自适应分段(假设分段边界已计算) seg_boundaries = [0, 50, 120, 200, 300] # 索引分段点 for seg_start, seg_end in zip(seg_boundaries[:-1], seg_boundaries[1:]): A_seg = A[:, seg_start:seg_end] for _ in range(2): # 每个分段最多选2个原子 corr = A_seg.T @ residual idx_in_seg = np.argmax(np.abs(corr)) global_idx = seg_start + idx_in_seg support.append(global_idx) # 更新残差 A_s = A[:, support] x_est = np.linalg.lstsq(A_s, y, rcond=None)[0] residual = y - A_s @ x_est if np.linalg.norm(residual) < noise_var: break return support, residual # 平方根扩展卡尔曼滤波(UKF平方根形式,此处为EKF平方根版本) class SquareRootEKF: def __init__(self, state_dim, meas_dim): self.S = np.eye(state_dim) # 协方差平方根 self.x = np.zeros(state_dim) self.Q = np.eye(state_dim)*0.01 self.R = np.eye(meas_dim)*0.1 self.H = np.zeros((meas_dim, state_dim)) def predict(self, F, B, u): self.x = F @ self.x + B @ u # 更新协方差平方根: S = chol(F @ S @ S.T @ F.T + Q) M = np.vstack([F @ self.S, cholesky(self.Q, lower=True).T]) # qr分解求平方根 Qr, Rr = np.linalg.qr(M.T, mode='reduced') self.S = Rr.T def update(self, z): # 计算卡尔曼增益平方根版本 S_meas = self.H @ self.S S_meas = np.vstack([S_meas, cholesky(self.R, lower=True).T]) _, R_meas = np.linalg.qr(S_meas.T, mode='reduced') K = solve_triangular(R_meas.T, (self.H @ self.S).T, lower=True).T K = K @ solve_triangular(R_meas, np.eye(R_meas.shape[0]), lower=True) innov = z - self.H @ self.x self.x = self.x + K @ innov # 更新协方差平方根 I_KH = np.eye(len(self.x)) - K @ self.H self.S = I_KH @ self.S # 粒子滤波+字典学习动态跟踪(简化粒子更新) def particle_filter_dict_update(y, atoms, particles, weights): # atoms: 过完备字典矩阵 (n x L) # particles: 每个粒子是一个系数向量(稀疏表示) L = atoms.shape[1] n_particles = particles.shape[0] # 计算每个粒子的似然 likelihoods = [] for p in particles: reconstruction = atoms @ p error = y - reconstruction likelihood = np.exp(-np.linalg.norm(error)**2 / (2*0.05)) likelihoods.append(likelihood) weights = weights * np.array(likelihoods) weights /= np.sum(weights) # 重采样 if 1.0 / np.sum(weights**2) < n_particles/2: indices = np.random.choice(n_particles, n_particles, p=weights) particles = particles[indices] weights = np.ones(n_particles)/n_particles # 字典更新(提取当前最佳估计的信道响应) best_idx = np.argmax(weights) best_coeff = particles[best_idx] # 如果新原子与原子库相关性低于阈值,则替换最老原子 return particles, weights, best_coeff if __name__ == '__main__': # 测试平方根EKF组合定位 ekf = SquareRootEKF(state_dim=10, meas_dim=3) # 位置3维观测 # 模拟UWB测距值(伪) z_uwb = np.array([1.5, 2.0, 2.5]) ekf.H[:,:3] = np.eye(3) ekf.update(z_uwb) print(f'更新后位置: {ekf.x[:3]}') ",如有问题,可以直接沟通
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇