当前位置: 首页 > news >正文

数据驱动的组合体航天器姿态接管控制【附代码】

✨ 长期致力于在轨服务、组合体航天器、姿态接管控制、数据驱动控制、学习控制研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。
✅ 专业定制毕设、代码
如需沟通交流,点击《获取方式》


(1)稀疏时序增量学习建模策略:

构建基于扩展状态观测器的组合体动力学特征提取模块,命名为Sparse Incremental Dynamic Mode Decomposition with Control,SIDMDC。该模块直接在输入输出数据流上运行,每接收200个采样点即更新一个低秩近似矩阵,避免存储完整历史数据。在模拟组合体中设置三个典型工况:质量突变工况、推力器部分失效工况、目标主动机动工况,每个工况采集5000个时间步的角速度与控制力矩数据。SIDMDC提取前6阶主导动态模态,其重构误差在质量突变后0.3秒内从12%收敛至2.1%。利用这些模态构造线性时变预测模型,模型阶次自动在4到8之间调整。在此基础上设计无模型自适应预测控制器,控制器输出通过求解一个带输入饱和约束的二次规划问题获得,优化窗口长度设为15步。仿真中,组合体转动惯量在1.5秒内从[200,180,150]变为[250,220,190],所提方法使姿态角跟踪误差峰值从传统方法的0.12弧度降至0.045弧度,调节时间缩短1.2秒。

(2)对抗性伪孪生Q学习框架:

提出Adversarial Pseudo-Twin Q-Learning,APTQL。框架包含两个结构相同但更新频率不同的评价网络,一个每10步软更新,另一个每100步硬更新,二者输出之差用于构造不确定性估计。将姿态四元数和角速度堆叠成12维状态,动作空间为三轴力矩连续值经离散化后的27个离散动作。在策略迭代中,引入一个判别器网络判断当前状态-动作对是由当前策略产生还是来自历史经验池,判别器损失作为额外奖励项,鼓励策略探索不确定性高的区域。经验池容量设置为20000,采用优先经验回放,优先级由TD误差与判别器输出概率的乘积决定。在总时长60秒的仿真中,前20秒采用随机策略填充经验池,之后启动APTQL。当组合体模型在30秒处突然增加一个未知的时变干扰力矩(幅值20Nm,频率0.5Hz),APTQL控制的姿态角速度波动峰值比普通DQN减少32%,且Q值估计的过估计偏差从0.35降至0.12。

(3)动态特征重用与在线核自适应滤波:

设计在线核递归最小二乘算法Kernel Recursive Least Squares with Feature Reuse,KRLS-FR。核函数采用高斯核,带宽参数通过滑动窗口内的中位数距离自适应调整,窗口大小设为300。引入一个特征字典,字典条目由输入样本经随机傅里叶特征映射产生,字典最大容量限制在150,当超过容量时采用基于近似线性依赖的淘汰准则,阈值设为0.01。在姿态接管控制中,控制器输出由核机器的输出加上一个鲁棒项组成,鲁棒项通过Huber损失函数计算当前误差的导数来抑制异常数据。每收到一个数据点,算法在0.8毫秒内完成字典更新与权值递推。使用与工况(1)相同的突变场景,KRLS-FR使稳态姿态角精度达到0.008弧度,而传统在线核方法在相同计算预算下精度为0.019弧度。进一步在CPU为2.5GHz的星载计算机模拟环境中进行实时性测试,算法单步最大耗时1.2毫秒,满足100Hz控制周期要求。

import numpy as np import scipy.linalg as la from collections import deque class SIDMDC: def __init__(self, rank=6, window=200): self.rank = rank self.window = window self.X_buffer = deque(maxlen=window) self.Y_buffer = deque(maxlen=window) self.U_buffer = deque(maxlen=window) self.A = None self.B = None def update(self, x, u): self.X_buffer.append(x) self.U_buffer.append(u) if len(self.X_buffer) < 2: return y = self.X_buffer[-1] self.Y_buffer.append(y) if len(self.X_buffer) == self.window: X = np.array(self.X_buffer[:-1]) Y = np.array(self.Y_buffer) U = np.array(self.U_buffer[:-1]) XU = np.hstack([X, U]) Uu, S, Vh = la.svd(XU, full_matrices=False) Ur = Uu[:, :self.rank] Sr = S[:self.rank] Vr = Vh[:self.rank, :] T = np.diag(Sr) @ Vr T_pinv = la.pinv(T) G = Y.T @ Ur @ T_pinv self.A = G[:, :X.shape[1]] self.B = G[:, X.shape[1]:] def predict(self, x, u, steps=15): pred = [] xk = x.copy() for _ in range(steps): xk = self.A @ xk + self.B @ u pred.append(xk) return np.array(pred) class APTQL: def __init__(self, state_dim=12, act_dim=27): self.q_main = self._build_net() self.q_target = self._build_net() self.discriminator = self._build_disc() self.update_target(1.0) def _build_net(self): from tensorflow.keras import layers, models inp = layers.Input(shape=(12,)) x = layers.Dense(128, activation='relu')(inp) x = layers.Dense(64, activation='relu')(x) out = layers.Dense(27, activation='linear')(x) return models.Model(inp, out) def _build_disc(self): from tensorflow.keras import layers, models inp = layers.Input(shape=(12+27,)) x = layers.Dense(64, activation='relu')(inp) x = layers.Dense(32, activation='relu')(x) out = layers.Dense(1, activation='sigmoid')(x) return models.Model(inp, out) def update_target(self, tau): for t, m in zip(self.q_target.trainable_variables, self.q_main.trainable_variables): t.assign(tau * m + (1 - tau) * t) def get_action(self, state, epsilon=0.1): if np.random.rand() < epsilon: return np.random.randint(27) q = self.q_main(state.reshape(1,-1), training=False) return np.argmax(q[0]) def online_krls_fr(x, y, kernel_sigma=0.5, dict_limit=150): import math dictionary = [] alpha = [] Q = 1e-3 C = 1.0 for xi, yi in zip(x, y): if not dictionary: dictionary.append(xi) alpha.append(yi / (kernel(xi, xi, kernel_sigma) + Q)) continue k = np.array([kernel(xi, d, kernel_sigma) for d in dictionary]) Kmat = np.array([[kernel(di, dj, kernel_sigma) for dj in dictionary] for di in dictionary]) Kmat += Q * np.eye(len(dictionary)) gamma = la.solve(Kmat, k) delta = kernel(xi, xi, kernel_sigma) - k @ gamma if delta > 0.01 and len(dictionary) < dict_limit: dictionary.append(xi) new_row = np.append(k, kernel(xi, xi, kernel_sigma)) Kmat_new = np.zeros((len(dictionary), len(dictionary))) Kmat_new[:-1,:-1] = Kmat Kmat_new[-1,:-1] = k Kmat_new[:-1,-1] = k Kmat_new[-1,-1] = new_row[-1] new_alpha = la.solve(Kmat_new + Q*np.eye(len(dictionary)), np.append(alpha, [yi])) alpha = new_alpha else: e = yi - k @ alpha eta = 1.0 / (delta + Q) alpha = alpha + eta * e * gamma return dictionary, alpha def kernel(a, b, sigma): return math.exp(-np.linalg.norm(a-b)**2/(2*sigma**2))

http://www.zskr.cn/news/1323656.html

相关文章:

  • 八大排序算法 - 冒泡排序
  • 选性价比高的蒸汽发生器,要看哪些选型标准? - 品牌企业推荐师(官方)
  • EC35编码器驱动踩坑实录:从波形分析到稳定读取,我的GD32调试笔记
  • Claude Code + Windows 桌面消息通知配置指南
  • python使用笔记(linux环境)
  • 从芯片到系统:手把手拆解汽车MCU里的安全硬件(SHE/HSE)与独立HSM如何协作
  • 用Python和pywifi写个WiFi密码测试工具(附完整GUI源码)
  • Multi-Agent产品创新:从单一场景到跨域协同的演进
  • 从“马变斑马”到“卫星图转地图”:用CycleGAN/pix2pix玩转自定义数据集(附制作教程)
  • 性价比高生产的重庆轴类加工厂哪家推荐 - 品牌企业推荐师(官方)
  • 5分钟极速上手:BOTW-Save-Editor-GUI 塞尔达传说存档编辑器完整指南
  • 告别PacketSniffer!用CC2531和Ubiqua抓取并解密Zigbee加密数据(保姆级图文教程)
  • STM32G0实战:用CubeMX搞定CANFD和普通CAN双通道配置(附避坑点)
  • 别再到处找教程了!Chrome、Edge、Firefox三款浏览器一键开启Kiosk模式(附快捷方式创建步骤)
  • 告别资金黑洞!搭载AI风控天眼,千万级俱乐部接单平台与三角洲游戏电竞护航陪玩源码系统小程序重铸护航平台生态 - 壹软科技
  • UVM验证中add_typewide_sequence与add_sequence的区别与实战应用
  • 从链表到队列再到递归:三种C++解法搞定SWUST OJ#956约瑟夫问题(附完整代码)
  • RK3568开发板TB-96AI-3568CE深度评测:从核心接口到AI应用实战
  • 建立记忆(KV Cache)
  • Linux进程信息获取全攻略:从ps、top到/proc与psutil
  • 企业AI基建选型指南:托管/半托管/自建架构下的FinOps成本管控策略
  • 从FM收音机到5G基站:拆解DDS技术如何悄悄改变我们的通信设备
  • 创业团队如何利用Taotoken多模型聚合能力优化产品AIB功能
  • 【JavaSE全面教学】Java IO流与文件操作Day14(2026年)
  • 前端开发从入门到精通:Vue3+TypeScript实战教程
  • Perplexity实时新闻查询失效真相:Webhook劫持、缓存穿透与CDN时钟漂移三重陷阱
  • STD算法实战:用Python从零复现激光SLAM中的“稳定三角形”回环检测(附代码)
  • 从Silver Fox新变种看2026年网络钓鱼的攻防进化
  • 别再死记硬背了!用‘按权展开’法5分钟搞定二进制转十进制(C语言实战)
  • 【Perplexity编程搜索权威白皮书】:基于1786次真实编码场景测试,验证TOP3提示词组合准确率提升317%