【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
更新以gitee为准:
文章目录
- 数据预测概念和适用方式
- 线性系统的适用性
- 数据预测算法和卡尔曼滤波公式推导
- 状态空间方程和观测器
- 先验估计
- 后验估计
- 卡尔曼增益系数计算
- 先验误差协方差矩阵求解
- 卡尔曼滤波五大公式
- 预测
- 校正
- 更新
- 公式简化和应用
- Python实现
- C语言实现
- 附录:压缩字符串、大小端格式转换
- 压缩字符串
- 浮点数
- 压缩Packed-ASCII字符串
数据预测概念和适用方式
实际上 数据预测才是卡尔曼滤波器最常见、最普通的功能
通常用在嵌入式领域和现代控制理论中
如传感器数据处理滤波等等
而数据预测在处理数据时 也跟递归一样可以减小方差
但总体而言 数据预测会跟随当前时刻的测量值变化而变化
递归测量到一定次数后则与上一次的估计值相近
这在第一章中我们有探讨
递归的公式中也可以看出来 随着时间增加 K会越来越小
无论是算术平均算法 还是卡尔曼算法 其都会逐渐减小
递归算法 适用条件是在测量静态目标时 由于测量有误差(通常正态分布) 而进行的类似算术平均根的求解
数据预测则适用于线性动态变化的目标
注意是线性 非线性需要用泰勒展开的扩展卡尔曼滤波
数据预测本质上就是将递归算法、数据融合、协方差矩阵等 共同融合起来的一个算法
在数据融合中 我们探讨了估计值与两种不同方式测量值的融合方式
其卡尔曼增益与两种测量方式的方差有关
在协方差矩阵中 两种完全不同的变量 其方差与协方差构成的矩阵可以反应出数据的相关性
协方差越大 数据相关性越强
数据预测则是综合考虑了以上等多方面算法 得出的一个最优解
可以理解成 数据预测就是在变化的数据中 综合考虑了上一次估计值与当前测量值的关系 并将其融合
也就是将一个不太准的计算结果和一个不太准的测量结果进行融合
从而可以用来预测下一时刻的变量变化 (也就是这一时刻到下一时刻的变化)
同时运用在测量方面 也可以有效减小数据的方差(也就是上一时刻到这一时刻的变化)
这就导致了两种情况:
- 数据变化较大时 譬如从50变化到100 变化量会被拉低 可能最后预测值算出来就是75
- 数据静态变化时 譬如跟递归算法中的例子相同 数据在一个期望值左右波动 且满足正态分布 预测值会减小方差
线性系统的适用性
另外 在前面两个章节中 都是对静态目标的求解
静态目标肯定是满足线性关系的
但对于非线性系统 普通的卡尔曼滤波算法也就不适用了 必须用扩展卡尔曼滤波
但是在实际应用中 我们可以把每次的数据变化都当作是线性的 因为我们要得到的是稳定后的数据
譬如角度计的值的变化 虽然卡尔曼滤波没法跟踪这种毫无规律的系统
但可以减小整体的方差 并且我们在读值的时候 也是读一个相对静态的值
再比如一个斜率为正值的线性系统 突然斜率为负值了 那么在转折点卡尔曼滤波肯定不适用
但是在斜率为负后 多测几组数据 卡尔曼滤波的误差又会再次收敛
对于完全处于运动状态的系统 普通的卡尔曼滤波就不适用了 这时候本来估计值就是个不准确的值 应选择更加相信测量值而非估计值
数据预测算法和卡尔曼滤波公式推导
一个典型的卡尔曼滤波数据预测例子就是:
一天中 天气的温度变化 满足一定规律 通常是晚上冷 白天热
譬如 20 21 24 28 30 29 26 25 23 22 21
在实际测量中 可能会出现:
20.5 21.3 24.5 28.7 30.1 29.5 26.2 25.4 22.8 22.9 22.1
可以看到 最后一次温度出现了小范围的波动
假如温度计测量误差是0.5 那么这个波动情有可原 这是偶然出现的
这个测量值也并不能说明那个时间点 温度又有了回升
而如果加了卡尔曼滤波 就会将这一部分滤掉 从新变成从低到高 再从高到低的关系
这个是针对线性变化的数据
这个是一维的线性变化
另外 卡尔曼滤波还主要用于数据预测
状态空间方程和观测器
针对某一系统 其随时间变化有一定的规律
根据现代控制理论递归思想 我们可以写成如下形式:
其中 Xk是当前状态变量
X(k-1)是上一时刻的状态变量
A是状态转移矩阵(状态矩阵)
B是控制输入矩阵(控制矩阵)
Uk是当前的控制输入
状态转移矩阵:一个系统的某些因素在转移中,第n次结果只受第n-1的结果影响,即只与当前所处状态有关,而与过去状态无关。
如果是静态系统 那么就是单位矩阵1 但通常写成[1 1 / 0 1]的形式 其模就是1
控制输入矩阵:即改变状态变量的外部输入值
控制输入:外部影响系统变量的输入 如果没有外部扰动 那么通常取0
譬如温度的变化满足一次关系
也就是y=kx+b
那么当前时刻的值 就等于上一时刻的值 加上k*单位时间
譬如y=2k+3
第0时刻为3 第1时刻为5 第2时刻为7…
每一时刻都是上一次时刻的值 加上k*单位时间1 也就是2
那么状态转移矩阵算出来就是2 控制输入矩阵是0
如果 某一时刻 外部输入导致了数据变化 那么控制输入矩阵就不是0了
同时 如果某一时刻对系统进行了加热 那么就有了外部输入 Uk 就需要在数据上再加上一个Uk的值
Uk是一个变化的值 静态时就为0
比如加5度 那么就变成了y=2k+3+5
第0时刻为2 第1时刻为10 第2时刻为12…
同时 如果对该系统进行测量 如果测量准确 则每次测量的结果都是当前的状态变量值
譬如第1时刻温度为5 测量出来也肯定是1*5
可以表达成以下形式:
其中 H是测量矩阵 通常为单位矩阵 写作[1 0 / 0 1]的形式(除非测量结果是成比例不准的 但这几乎不存在 如果存在 人为换算即可)
同时 每次系统的更新都会存在噪声 称为过程噪声或者系统噪声 引入并记为w
譬如就算每小时温度增加1度 但可能某一时刻只增加了0.9度
另外 测量也是有误差的 就像先前数据融合讨论的一样 存在测量噪声 引入并记为v
那么就可以写成如下形式:
次公式就是状态空间方程
过程噪声和测量噪声通常都满足正态分布
且期望值为0
过程噪声的协方差矩阵为Q
测量噪声的协方差矩阵为R
这里的Q、R值可以就直接叫做系统误差和测量误差
同时也是系统噪声和测量噪声的方差
所以本质上卡尔曼滤波 就是用数据融合的思想 融合了系统误差和测量误差 最后得到一个最优的估计值
也就是将一个不太准的计算结果和一个不太准的测量结果进行融合
最后得到的估计值误差要比这两者都要小 所以能有效减小系统数据的方差
同时也能预测下一个时刻的估计值
在预测方面 就是将状态空间方程作为一个观测器使用 已知当前时刻的值 来估计后一时刻的值
先验估计
在状态空间方程中 可以看到状态和误差噪声的关系
如果没有噪声 我们可以直接得到当前的系统变量值:
但噪声是不可避免的
所以我们只能得到估计系统值 记为X_Hat 再加一个上标的-表示算出来的估计值 也就是系统估计值
对于系统估计值X_Hat有以下关系:
也就是上一次的估计值与这一时刻的系统估计值关系
这也就是先验估计
同时 对于测量结果而言 测量估计值与当前测量值的关系为:
也就是测量矩阵的逆矩阵*测量值
这两个算出来的和测出来的X估计值都是不准确的
因为误差没法准确估计
后验估计
得到先验估计以后 我们要引入噪声
那么现在就要用到卡尔曼滤波器 做数据融合 去得到最终的估计值 X_Hat 也就是后验估计
结合卡尔曼滤波的数据融合思想 我们可以定义估计结果为:
其中 G是一个系数
同样 当G为0时 估计值=先验估计值 当G为1时 估计值=测量估计值
也就融合了系统估计值和测量估计值的最终结果
而G的大小决定了是相信根据系统变化规律算出来的结果 还是根据测量算出来的结果
G与卡尔曼增益系数的关系为:
那么方程就写成了:
这里K的取值范围为0到H逆
且:
那么现在就又要找到一个最佳的卡尔曼增益系数 使得估计值最贴近真实值(误差最小)
卡尔曼增益系数计算
不用猜就知道 K的取值与上面提到的系统误差和测量误差有关
引入估计误差ek 则与估计值、真实值的关系为:
e也满足正态分布 且方差为P P也是e矩阵和e矩阵转置的期望
假如有两项e1和e2(也就是两种误差)
则:
那么它的期望就为:
根据概率论公式:
某样本的方差=该样本平方的期望-该样本期望的平方
而对于期望为0的正态分布 该样本期望的平方为0
所以:
其中σ1和σ2就是两种误差的标准差
这就是两种误差的协方差公式
要使误差e的方差P最小 那就是这个协方差矩阵的迹最小
那么就是要找到K 使得以下式子的值最小:
带入估计误差公式得:
其中:
I是单位矩阵
同样 先验也有误差 记为ek上标- 等于实际值与先验估计值的误差
则P就为:
根据公式:
带入得:
对于独立事件A、B有:
E(AB)=E(A)E(B)
所以:
则:
计P上标-为先验误差的方差
则:
同理
所以
即测量误差
代入后得到估计误差的协方差矩阵方程:
它的迹为:
现在要求K 使得迹最小 则就是对dK求导为0:
其中 矩阵相乘的求导公式为:
那么就可以求得卡尔曼增益系数
当R特别大时 Kk趋近于0
当R特别小时 Kk趋近于H的逆矩阵
这就是误差最小时卡尔曼增益的计算公式
再看到先前的公式 满足规律
先验误差协方差矩阵求解
上文提到的先验误差公式:
如果要求Kk则需要先求Pk-
代入先验估计方程:
得到:
还是带入独立事件期望公式
另外 e(k-1)和其转置的期望就是上一次的估计误差协方差矩阵
同时带入系统误差Q
得到当前的先验误差协方差矩阵与上一次的估计误差协方差矩阵的关系:
到此就可以求出卡尔曼滤波的五大公式了 并且可以将其应用出来了
卡尔曼滤波五大公式
进行卡尔曼滤波共有三个部分要做
按步骤顺序分为五个公式
预测
求出先验估计和先验误差协方差矩阵
校正
求出卡尔曼增益和后验估计
更新
代入Kk的值 最后得到Pk
更新估计误差协方差矩阵
公式简化和应用
在嵌入式、现代控制理论中
A矩阵通常为1
B矩阵未知但不受外部输入影响的话 U通常就为0
H矩阵也为1
并且如果是针对静态目标的话 这几项矩阵实际上也就为1
那么就可以简化为以下几个公式
按步骤分别是:
Python实现
上面公式按Python来实现的话就是:
def Prediction(measure,result_last=0,covariance_last=0,Q=0.018,R=0.0542):result_priori = result_lastcovariance_priori = covariance_last + Qkg = covariance_priori/(covariance_priori + R)result_last = result_priori + kg*(measure - result_priori)covariance_last = (1-kg)*covariance_priorireturn result_last,covariance_last
运行和调用结果:
v = [10.5,20.6,30.8,40.6,45.3,48.0,47.5,44.5,46.0,43.8,55.5,53.5,56.1,65.2,67.6,68.9,72.2,80.1,81.5,82.6,83.4,84.6,83.5,83.1,85.0,84.5,84.0,83.6,83.9,83.2,84.1,85.6,84.3,84.0,86.5,85.5,85.0,84.8,84.5,84.5,85.1]a=[]
b=[]
c=[]
d=[]def Prediction(measure,result_last=0,covariance_last=0,Q=0.018,R=0.0542):result_priori = result_lastcovariance_priori = covariance_last + Qkg = covariance_priori/(covariance_priori + R)result_last = result_priori + kg*(measure - result_priori)covariance_last = (1-kg)*covariance_priorireturn result_last,covariance_lastresult_last = v[0]
covariance_last = 0for i in range(len(v)):result_last,covariance_last = Prediction(v[i],result_last,covariance_last,5,3)a.append(result_last)print(result_last)plt.figure(4)
plt.plot(v,color="g")
plt.plot(a,color="b")
10.5
17.531645569620252
26.854454203262236
36.52035749751738
42.694663752563144
46.42567852323806
47.181203021790296
45.29562713905005
45.79098257239374
44.390809326126174
52.20342998159353
53.115252454036465
55.21429828136791
62.23681700454024
66.00851518486351
68.04197330570614
70.96613638757006
77.38959365081972
80.28026737213725
81.91163653085387
82.95833916863266
84.11284931225781
83.68185849247561
83.27266219633323
84.48742530555566
84.49626855259646
84.14726401585693
83.7623965417261
83.85916719333677
83.39560298049119
83.89097540372485
85.09285961415652
84.53527521576893
84.1588389541316
85.80527780658561
85.59058892713347
85.17525288812938
84.9113535140978
84.62206610736457
84.53622221290566
84.93270311901878
图像:
可以看到蓝线显著在绿线突变时变得平滑
如果减小R 即减小测量误差则会:
表示相信测量结果
反之减小Q则会:
表示相信先验估计结果
C语言实现
函数:
typedef struct
{double Measure_Now;double Result_Last;double Covariance_Last;double Q;double R;
}Kalman_Filter_Prediction_Struct;Kalman_Filter_Prediction_Struct Kalman_Filter_Prediction(Kalman_Filter_Prediction_Struct Stu);Kalman_Filter_Prediction_Struct Kalman_Filter_Prediction(Kalman_Filter_Prediction_Struct Stu)
{double Result_Priori = Stu.Result_Last;double Covariance_Priori = Stu.Covariance_Last + Stu.Q;double kg = Covariance_Priori/(Covariance_Priori + Stu.R);Stu.Result_Last = Result_Priori + kg*(Stu.Measure_Now - Result_Priori);Stu.Covariance_Last = (1-kg)*Covariance_Priori;return Stu;
}
调用:
void Prediction(void)
{double v[41] = {10.5,20.6,30.8,40.6,45.3,48.0,47.5,44.5,46.0,43.8,55.5,53.5,56.1,65.2,67.6,68.9,72.2,80.1,81.5,82.6,83.4,84.6,83.5,83.1,85.0,84.5,84.0,83.6,83.9,83.2,84.1,85.6,84.3,84.0,86.5,85.5,85.0,84.8,84.5,84.5,85.1};Kalman_Filter_Prediction_Struct Stu;uint8_t i=0;Stu.Q=5;Stu.R=3; Stu.Covariance_Last=0.0f;Stu.Result_Last=v[0];for(i=0;i<41;i++){Stu.Measure_Now=v[i];Stu = Kalman_Filter_Prediction(Stu);printf("%f \n",Stu.Result_Last);}
}
调用结果:
10.500000
17.531646
26.854454
36.520357
42.694664
46.425679
47.181203
45.295627
45.790983
44.390809
52.203430
53.115252
55.214298
62.236817
66.008515
68.041973
70.966136
77.389594
80.280267
81.911637
82.958339
84.112849
83.681858
83.272662
84.487425
84.496269
84.147264
83.762397
83.859167
83.395603
83.890975
85.092860
84.535275
84.158839
85.805278
85.590589
85.175253
84.911354
84.622066
84.536222
84.932703
与Python保持一致
附录:压缩字符串、大小端格式转换
压缩字符串
首先HART数据格式如下:
重点就是浮点数和字符串类型
Latin-1就不说了 基本用不到
浮点数
浮点数里面 如 0x40 80 00 00表示4.0f
在HART协议里面 浮点数是按大端格式发送的 就是高位先发送 低位后发送
发送出来的数组为:40,80,00,00
但在C语言对浮点数的存储中 是按小端格式来存储的 也就是40在高位 00在低位
浮点数:4.0f
地址0x1000对应00
地址0x1001对应00
地址0x1002对应80
地址0x1003对应40
若直接使用memcpy函数 则需要进行大小端转换 否则会存储为:
地址0x1000对应40
地址0x1001对应80
地址0x1002对应00
地址0x1003对应00
大小端转换:
void swap32(void * p)
{uint32_t *ptr=p;uint32_t x = *ptr;x = (x << 16) | (x >> 16);x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);*ptr=x;
}
压缩Packed-ASCII字符串
本质上是将原本的ASCII的最高2位去掉 然后拼接起来 比如空格(0x20)
四个空格拼接后就成了
1000 0010 0000 1000 0010 0000
十六进制:82 08 20
对了一下表 0x20之前的识别不了
也就是只能识别0x20-0x5F的ASCII表
压缩/解压函数后面再写:
//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_ASCII_to_Pack(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{if(str_len%4){return 0;}uint8_t i=0;memset(buf,0,str_len/4*3); for(i=0;i<str_len;i++){if(str[i]==0x00){str[i]=0x20;}}for(i=0;i<str_len/4;i++){buf[3*i]=(str[4*i]<<2)|((str[4*i+1]>>4)&0x03);buf[3*i+1]=(str[4*i+1]<<4)|((str[4*i+2]>>2)&0x0F);buf[3*i+2]=(str[4*i+2]<<6)|(str[4*i+3]&0x3F);}return 1;
}//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_Pack_to_ASCII(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{if(str_len%4){return 0;}uint8_t i=0;memset(str,0,str_len);for(i=0;i<str_len/4;i++){str[4*i]=(buf[3*i]>>2)&0x3F;str[4*i+1]=((buf[3*i]<<4)&0x30)|(buf[3*i+1]>>4);str[4*i+2]=((buf[3*i+1]<<2)&0x3C)|(buf[3*i+2]>>6);str[4*i+3]=buf[3*i+2]&0x3F;}return 1;
}
相关文章:
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter) 更新以gitee为准: 文章目录 数据预测概念和适用方式线性系统的适用性 数据预测算法和卡尔曼滤波公式推导状态空间方程和观测器先验估计后验估计…...
神经网络问题之一:梯度消失(Vanishing Gradient)
梯度消失(Vanishing Gradient)问题是深度神经网络训练中的一个关键问题,它主要发生在反向传播过程中,导致靠近输入层的权重更新变得非常缓慢甚至几乎停滞,严重影响网络的训练效果和性能。 图1 在深度神经网络中容易出现…...
【微软:多模态基础模型】(4)统一视觉模型
欢迎关注[【youcans的AGI学习笔记】](https://blog.csdn.net/youcans/category_12244543.html)原创作品 【微软:多模态基础模型】(1)从专家到通用助手 【微软:多模态基础模型】(2)视觉理解 【微…...
npm | Yarn | pnpm Node.js包管理器比较与安装
一、包管理器比较 参考原文链接: 2024 Node.js Package Manager 指南:npm、Yarn、pnpm 比较 — 2024 Node.js Package Manager Guide: npm, Yarn, pnpm Compared (nodesource.com) 以下是对 Node.js 的三个包管理工具 npm、Yarn 和 pnpm 的优缺点总结&am…...
建造者模式
什么是建造者模式? 建造者模式(Builder Pattern)是一种设计模式,用来一步步创建复杂的对象,而不用直接去调用复杂的构造函数或手动设置大量属性。 你可以: • 按步骤“搭建”对象。 • 自由选择要设置的部…...
Spring Boot核心概念:应用配置
Spring Boot提供了强大的配置系统,允许开发者通过配置文件轻松管理应用的配置。支持的主要配置文件格式有两种:application.properties和application.yml。 application.properties与application.yml application.properties和application.yml是Spring…...
linux环境安装cuda toolkit
1 全新安装 如果环境中没安装过cuda版本, 这种情况下比较简单。 直接在https://developer.nvidia.com/cuda-toolkit-archive选择对应版本下载安装即可。 如下为安装cuda toolkit 11.8. 2 环境中已经存在其他版本 这种情况下比较复杂一些。 首先要确认最高支持的版…...
WebSocket实战,后台修改订单状态,前台实现数据变更,提供前端和后端多种语言
案例场景: 在实际的后台中需要变更某个订单的状态,在官网中不刷新页面,可以自动更新状态 在前端页面实现订单状态的实时更新(不刷新页面),可以通过 WebSocket 的方式与后台保持通信,监听订单状态…...
实时通信协议概述:WebRTC、RTP/RTCP、RTMP、HLS 和 FLV 的比较与应用
文章目录 一、协议总览二、WebRTC2.1 时序图2.2 代码示例 三、RTP/RTCP3.1 时序图3.2 代码示例 四、RTMP4.1 时序图4.2 代码示例 五、HLS5.1 时序图5.2 代码示例 六、总结 一、协议总览 协议/格式细节对比适用场景用法WebRTC使用 UDP 传输协议,支持 P2P 通信&#…...
Vue路由
目录 1. 安装 vue-router 2. 创建 Vue 项目结构 3. 配置路由 4. 在 main.js 中使用路由 5. 在 App.vue 中添加 6. 创建组件 7. 运行你的应用 在 Vue.js 2 中,路由管理通常通过 vue-router 插件来实现。vue-router 是一个官方的路由管理器,允许你…...
uniapp开发微信小程序笔记3-全局配置、导航栏配置、tabBar配置
前言: 本文记录的是微信小程序的全局配置、导航栏配置、tabBar配置 一、全局配置: 可以直接查官方文档:pages.json 页面路由 | uni-app官网,有非常详细的文档说明 都是在 pages.json里面做配置的,我们可以看到已经有…...
Hash table类算法【leetcode】
哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素 那么哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里。 例如要查询一个名字是否在这所学校里。 要枚举的话时间复杂度是O(n),但如果使用哈希…...
多算法模型(BI-LSTM GRU Mamba ekan xgboost)实现功率预测
概述 本项目旨在通过结合多算法模型网络实现功率预测。包括数据处理、特征工程、模型训练、模型推理和结果输出,最终结果以 JSON 格式返回。 代码地址:代码...
html 图片转svg 并使用svg路径来裁剪html元素
1.png转svg 工具地址: Vectorizer – 免费图像矢量化 打开svg图片,复制其中的path中的d标签的路径 查看生成的svg路径是否正确 在线SVG路径预览工具 - UU在线工具 2.在html中使用svg路径 <svg xmlns"http://www.w3.org/2000/svg" width"318px" height…...
贴代码框架PasteForm特性介绍之select,selects,lselect和reload
简介 PasteForm是贴代码推出的 “新一代CRUD” ,基于ABPvNext,目的是通过对Dto的特性的标注,从而实现管理端的统一UI,借助于配套的PasteBuilder代码生成器,你可以快速的为自己的项目构建后台管理端!目前管…...
【Redis】实现异步秒杀功能
一、将判断条件提前缓存到redis中 将判断条件缓存到redis中,如果判断成功直接操作redis中的数据,然后将数据写入redis,如果成功返回一个值。然后根据这个值判断是否成功,如果成功把用户id,优惠卷id,订单id存…...
React的API✅
createContext createContext要和useContext配合使用,可以理解为 “React自带的redux或mobx” ,事实上redux就是用context来实现的。但是一番操作下来我还是感觉,简单的context对视图的更新的细粒度把控比不上mobx,除非配合memo等…...
2024亚太杯数学建模C题【Development Analyses and Strategies for Pet Industry 】思路详解
C:宠物行业及相关产业的发展分析与战略 随着人们消费观念的发展,宠物行业作为一个新兴产业,正在全球范围内逐渐积聚势头,这得益于快速的经济发展和人均收入的提高。1992年,中国小动物保护协会成立,随后1993…...
使用Notepad++工具去除重复行
使用Notepad工具去除重复行 参考链接:https://blog.csdn.net/londa/article/details/108981396 一 、使用正则表达式 1、对文本进行排序,让重复行排在一起 2、使用正则表达式替换(注意)^(.*?)$\s?^(?.*^\1$) 在替换时选择正…...
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
AI 驱动 3D 动画 大家好,我是石小石!随着 Web 技术的发展,Three.js 成为构建 3D 图形和动画的主流工具。与此同时,人工智能(AI)在图像处理、动作生成等领域表现出强大能力。将 AI 与 Three.js 结合&#x…...
VScode clangd插件安装
前提 在VScode中写C代码时,总会用到 C/C 这个插件,也就自然而然地使用了这个插件带来的代码跳转和代码提示功能。但是当代码变地很多时,就会变得非常慢。所以经过调查后弃用C/C 插件的这个功能,使用 clangd 这个插件来提示C代码和…...
Swift从0开始学习 对象和类 day3
类(Class) 是一种类型或模板,描述了对象的特征和行为。对象(Object) 是类的实例,实际的实体,拥有自己的数据。 新入门的教学都喜欢用“人”来举例为类,在这里我也用“人”吧 //&…...
Linux——从命令行配置网络
1.使用nmcli添加静态网络连接 nmcli con add con-name static-addr \ ifname eth0 type ethernet ipv4.method manual ipv4.dns 172.25.250.220 \ ipv4.addresses 172.25.250.10/24 ipv4.gateway 172.25.250.254 命令概述 这是一条使用 nmcli(NetworkManager 命令…...
RabbitMQ实现异步下单与退单
前言: 在电商项目中的支付模块也是一个很重要的模块,其中下订操作以及退订操作就是主要的操作。其次的下单是同步下单,也就是第三方支付、数据库扣减、积分增加、等等其他业务操作,等待全部执行完毕后向用户返回成功响应请求。对…...
[Python] 编程入门:理解变量类型
文章目录 [toc] 整数常见操作 浮点数字符串字符串中混用引号问题字符串长度计算字符串拼接 布尔类型动态类型特性类型转换结语 收录专栏:[Python] 在编程中,变量是用于存储数据的容器,而不同的变量类型则用来存储不同种类的数据。Python 与 C…...
C++ —— 剑斩旧我 破茧成蝶—C++11
江河入海,知识涌动,这是我参与江海计划的第2篇。 目录 1. C11的发展历史 2. 列表初始化 2.1 C98传统的{} 2.2 C11中的{} 2.3 C11中的std::initializer_list 3. 右值引用和移动语义 3.1 左值和右值 3.2 左值引用和右值引用 3.3 引用延长生命周期…...
Perl 简介
Perl 简介 Perl 是一种高级、通用、解释型、动态编程语言。由 Larry Wall 于 1987 年首次发布,它结合了 C、sed、awk 和 shell 脚本语言的特性。Perl 最初被设计用于文本处理,如报告生成和文件转换,但随着时间的推移,它已经发展成…...
Transformer中的Self-Attention机制如何自然地适应于目标检测任务
Transformer中的Self-Attention机制如何自然地适应于目标检测任务: 特征图的降维与重塑 首先,Backbone(如ResNet、VGG等)会输出一个特征图,这个特征图通常具有较高的通道数、高度和宽度(例如CHWÿ…...
【Linux篇】初学Linux,如何快速搭建Linux开发环境
文章目录 前言1. Linux背景介绍1.1 UNIX的发展历史1.2 Linux的发展历史 2. 企业应用现状3. 开源3.1 探索Linux源代码3.2 开源 VS 闭源 4. Linux的版本4.1 技术线4.2 商业产品线 5. os概念,定位6. 搭建Linux环境6.1 Linux环境的搭建方式6.2 购买云服务器 7. 使用XShe…...
竞赛思享会 | 2024年第十届数维杯国际数学建模挑战赛D题【代码+演示】
Hello,这里是Easy数模!以下idea仅供参考,无偿分享! 题目背景 本题旨在通过对中国特定城市的房产、人口、经济、服务设施等数据进行分析,评估其在应对人口老龄化、负增长趋势和极端气候事件中的韧性与可持续发展能力。…...
vim 使用技巧
使用技巧 正常模式(Normal Mode)插入模式(Insert Mode)命令模式(Command Mode) vim常用三种模式包括正常模式,插入模式,命令模式。 正常模式(Normal Mode) 进…...
CSS-flex布局
flex常用语法 display: flex 父级元素相关 flex-direction 主轴方向【水平方向(默认)、垂直方向】justify-content 主轴上的对齐方式【flex-end结束对齐、space-between两端对齐、center】align-items 交叉轴的对齐方式【center、flex-end】flex-wrap…...
小R的随机播放顺序
问题描述 小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌,播放后将其从歌单中移除。如果歌单中还有歌曲,则会将当前第一首歌移到最后一首。这个过程会一直重复,直到歌单中没有任何歌曲。 例如,给定歌单 [5, 3, 2, 1,…...
docker常见命令
1.启动容器 docker run 运行容器 docker run -d 守护线程运行容器 docker run -p 80:80 指定端口运行容器,左侧为服务器端口,右侧为容器端口 docker run --rm 停止容器后销毁 docker --name 指定容器名称 2.停止容器 docker stop (id/name) …...
C语言-指针作为函数返回值及二级指针
1、指针作为函数返回值 c语言允许函数的返回值是一个指针(地址)我们将这样的函数称为指针函数,下面的例子定义一了一个函数strlong(),用来返回两个字符串中较长的一个: 1. #include <stdio…...
kotlin
参考资料: 参考资料 1、kotlin编译原理是先编译为class文件,再在java 虚拟机上执行2、变量 var 1 变量 val 2 常量 kotlin存在类型推导机制 var c:Int 1kotlin不存在基本类型,将全部使用对象类型3、函数 fun test(){}fun add(a:Int,b Int…...
【STM32】USART串口数据包
数据包的作用是将一个个单独的数据打包起来,方便进行多字节的数据通信 数据包格式 HEX数据包 文本数据包 数据包接收 HEX数据包接收(固定包长) 文本数据包接收(可变包长) 串口收发HEX数据包 接线图 Serial模块 se…...
开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频
文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 本文主要介绍如何在Windows系统电脑使用整合包一键部署开源TTS语音克隆神器GPT-SoVITS,并结合cpolar内网穿透工…...
echarts 图表resize() 报错Cannot read properties of undefined (reading ‘type‘)
原因是我使用了this.trainChart来接收数据,应该使用let或者var定义trainChart,就不会出现错误了。 错误代码如下: 原本 定义的echarts export default {data() {return {: null}} }现在 var trainChart null export default { }...
寻的制导律:从理论到应用的全景展示(下)
寻的制导律:从理论到应用的全景展示(下) 第六章 制导系统设计与实现 在制导系统的设计与实现过程中,系统需求分析、硬件与软件架构设计以及实现与测试方法是关键的三个环节。通过系统化的方法论,可以确保制导系统在复…...
ChatGPT 与其他 AI 技术在短视频营销中的技术应用与协同策略
摘要: 本文深入探讨了 ChatGPT 及其他 AI 技术在短视频营销中的应用。从技术层面剖析了这些技术如何助力短视频内容创作、个性化推荐、用户互动以及营销效果评估等多方面,通过具体方法分析、数据引用与大模型工具介绍,旨在为短视频营销领域提…...
使用PSpice进行第一个电路的仿真
1、单击【开始】菜单,选择【OrCAD Capture CIS Lite】。 2、单击【File】>【New】>【Project】。 3、①填入Name下面的文本框(提示:项目名称不要出现汉字); ②选择【Analog or Mixed A/D】; ③单击【…...
SparkSQL 对 SQL 查询的优化静态优化和动态优化两大部分介绍
SparkSQL 对 SQL 查询的优化主要分为 静态优化 和 动态优化 两大部分,其中静态优化主要在查询编译时进行,而动态优化则是在查询执行过程中进行。SparkSQL 的优化包括了多种技术,例如 RBO(基于规则的优化)、CBO…...
Android 网络请求(二)OKHttp网络通信
学习笔记 OkHttp 是一个非常强大且流行的 HTTP 客户端库,广泛用于 Android 开发中进行网络请求。与 HttpURLConnection 相比,OkHttp 提供了更简单、更高效的 API,特别是在处理复杂的 HTTP 请求时。 如何使用 OkHttp 进行网络请求 以下是使…...
游戏引擎学习第15天
视频参考:https://www.bilibili.com/video/BV1mbUBY7E24 关于游戏中文件输入输出(IO)操作的讨论。主要分为两类: 只读资产的加载 这部分主要涉及游戏中用于展示和运行的只读资源,例如音乐、音效、美术资源(如 3D 模型和…...
【机器学习】聚类算法原理详解
聚类算法 性能度量: 外部指标 jaccard系数(简称JC)FM指数(简称FMI)Rand指数(简称RI) 内部指标 DB指数(简称DBI)Dunn指数(简称DI) 距离计算&am…...
android 使用MediaPlayer实现音乐播放--基础介绍
Android 多媒体框架支持播放各种常见媒体类型,因此 可轻松地将音频、视频和图片集成到您的应用中。你可以播放音频或 从存储在应用资源(原始资源)的媒体文件(原始资源)中获取独立文件 或从通过网络连接到达的数据流中&…...
【人工智能】PyTorch、TensorFlow 和 Keras 全面解析与对比:深度学习框架的终极指南
文章目录 PyTorch 全面解析2.1 PyTorch 的发展历程2.2 PyTorch 的核心特点2.3 PyTorch 的应用场景 TensorFlow 全面解析3.1 TensorFlow 的发展历程3.2 TensorFlow 的核心特点3.3 TensorFlow 的应用场景 Keras 全面解析4.1 Keras 的发展历程4.2 Keras 的核心特点4.3 Keras 的应用…...
transformer.js(二):关于pipe管道的一切
前面的章节 transformer.js(一):这个前端大模型运行框架的可运行环境、使用方式、代码示例以及适合与不适合的场景介绍了transformer.js的应用场景。 pipe 管道(Pipeline) 作为 Transformer.js 的核心功能之一…...
django宠物服务管理系统
摘 要 宠物服务管理系统是一种专门为宠物主人和宠物服务提供商设计的软件。它可以帮助用户快速找到附近的宠物医院、宠物美容店、宠物寄养中心等服务提供商,并预订相关服务。该系统还提供了一系列实用的功能。通过使用宠物服务管理系统,用户可以更加方便…...