当前位置: 首页 > 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.jsqmd.com/news/847800/

相关文章:

  • NotebookLM脑机接口实测报告:从EEG信号预处理到实时语义映射,7步构建可复现BCI工作流
  • 选性价比高的蒸汽发生器,要看哪些选型标准? - 品牌企业推荐师(官方)
  • MRI绕组结构设计及均匀度优化算法【附算法】
  • 告别论文风控难题!okbiye 智能 AIGC 筛查与文本柔化重塑全方位解析
  • 从“广覆盖”到“精准康复”:重庆“星星的孩子”干预新方向 - 品牌企业推荐师(官方)
  • DJI大疆官方售后网点2026年5月最新400热线与售后服务指南 - 品牌企业推荐师(官方)
  • 如何快速获取免费的EB Garamond 12字体:古典优雅的终极排版解决方案
  • 用STM32G431和塔石NB-IoT模块,5分钟搞定阿里云MQTT设备上云(附完整配置流程)
  • Claude Code + Windows 桌面消息通知配置指南
  • PWM调制器小信号模型:从采样延迟到环路稳定性设计
  • 第14章 实践项目开发——智能温控系统14.5(下)
  • 告别Pico TTS!2024年Android离线TTS引擎实测:讯飞、Google、ITRI谁的中文语音更自然?
  • 大石桥宸智雅筑装饰官方联系方式合作电话 官方网站 官网 - 元点智创
  • 【JavaSE全面教学】Java IO流与文件操作Day14(2026年)
  • 转向现代C++——优先选用限定作用域的枚举型别,而非不限作用域的枚举型别
  • 【.NET新特性·第1篇】.NET 8:统一平台的成熟之作
  • AIGC应用工程师证书报考机构多维度实测对比 - 品牌企业推荐师(官方)
  • 26春 日总结22
  • Linux进程信息获取全攻略:从ps、top到/proc与psutil
  • 从链表到队列再到递归:三种C++解法搞定SWUST OJ#956约瑟夫问题(附完整代码)
  • 自己搭一个Java Web框架,你需要解决哪些问题
  • 从“马变斑马”到“卫星图转地图”:用CycleGAN/pix2pix玩转自定义数据集(附制作教程)
  • 告别抓瞎!手把手教你用逻辑分析仪调试SMBus电池管理通信(附BQ4050实战波形)
  • Linux网络数据包处理全流程:从系统调用到网卡驱动的深度解析
  • MySQL 单行函数笔记(日期时间函数)
  • 性价比高生产的重庆轴类加工厂哪家推荐 - 品牌企业推荐师(官方)
  • UVM验证中add_typewide_sequence与add_sequence的区别与实战应用
  • 别再乱定义坐标系了!ArcGIS数据处理中坐标系问题的终极排查手册
  • 信号处理与行为金融视角下的股价波动与量化投资建模方法【附代码】
  • 5分钟极速上手:BOTW-Save-Editor-GUI 塞尔达传说存档编辑器完整指南