【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)

更新以gitee为准:

文章目录

  • 数据预测概念和适用方式
    • 线性系统的适用性
  • 数据预测算法和卡尔曼滤波公式推导
    • 状态空间方程和观测器
    • 先验估计
    • 后验估计
    • 卡尔曼增益系数计算
    • 先验误差协方差矩阵求解
  • 卡尔曼滤波五大公式
    • 预测
    • 校正
    • 更新
    • 公式简化和应用
  • Python实现
  • C语言实现
  • 附录:压缩字符串、大小端格式转换
    • 压缩字符串
      • 浮点数
      • 压缩Packed-ASCII字符串

数据预测概念和适用方式

实际上 数据预测才是卡尔曼滤波器最常见、最普通的功能
通常用在嵌入式领域和现代控制理论中
如传感器数据处理滤波等等
而数据预测在处理数据时 也跟递归一样可以减小方差
但总体而言 数据预测会跟随当前时刻的测量值变化而变化
递归测量到一定次数后则与上一次的估计值相近
这在第一章中我们有探讨
递归的公式中也可以看出来 随着时间增加 K会越来越小
在这里插入图片描述

无论是算术平均算法 还是卡尔曼算法 其都会逐渐减小
在这里插入图片描述

在这里插入图片描述

递归算法 适用条件是在测量静态目标时 由于测量有误差(通常正态分布) 而进行的类似算术平均根的求解
数据预测则适用于线性动态变化的目标

注意是线性 非线性需要用泰勒展开的扩展卡尔曼滤波

数据预测本质上就是将递归算法、数据融合、协方差矩阵等 共同融合起来的一个算法

在数据融合中 我们探讨了估计值与两种不同方式测量值的融合方式
其卡尔曼增益与两种测量方式的方差有关
在这里插入图片描述

在协方差矩阵中 两种完全不同的变量 其方差与协方差构成的矩阵可以反应出数据的相关性
协方差越大 数据相关性越强

数据预测则是综合考虑了以上等多方面算法 得出的一个最优解

可以理解成 数据预测就是在变化的数据中 综合考虑了上一次估计值与当前测量值的关系 并将其融合

也就是将一个不太准的计算结果和一个不太准的测量结果进行融合
从而可以用来预测下一时刻的变量变化 (也就是这一时刻到下一时刻的变化)
同时运用在测量方面 也可以有效减小数据的方差(也就是上一时刻到这一时刻的变化)

这就导致了两种情况:

  1. 数据变化较大时 譬如从50变化到100 变化量会被拉低 可能最后预测值算出来就是75
  2. 数据静态变化时 譬如跟递归算法中的例子相同 数据在一个期望值左右波动 且满足正态分布 预测值会减小方差

线性系统的适用性

另外 在前面两个章节中 都是对静态目标的求解
静态目标肯定是满足线性关系的
但对于非线性系统 普通的卡尔曼滤波算法也就不适用了 必须用扩展卡尔曼滤波

但是在实际应用中 我们可以把每次的数据变化都当作是线性的 因为我们要得到的是稳定后的数据

譬如角度计的值的变化 虽然卡尔曼滤波没法跟踪这种毫无规律的系统
但可以减小整体的方差 并且我们在读值的时候 也是读一个相对静态的值

再比如一个斜率为正值的线性系统 突然斜率为负值了 那么在转折点卡尔曼滤波肯定不适用
但是在斜率为负后 多测几组数据 卡尔曼滤波的误差又会再次收敛

对于完全处于运动状态的系统 普通的卡尔曼滤波就不适用了 这时候本来估计值就是个不准确的值 应选择更加相信测量值而非估计值

数据预测算法和卡尔曼滤波公式推导

一个典型的卡尔曼滤波数据预测例子就是:
一天中 天气的温度变化 满足一定规律 通常是晚上冷 白天热
譬如 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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/475809.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大模型时代的具身智能系列专题(十三)

迪士尼研究中心 瑞士苏黎世迪斯尼研究中心致力于不同领域的业务活动&#xff0c;其中包括电影、电视、公园和度假村以及消费产品。我们针对所有这些领域进行科研工作。我们开发能使我们将后道生产元素整合到前级生产中的技术。由此可节省许多昂贵的效果&#xff0c;这些效果最…

IDEA2023设置控制台日志输出到本地文件

1、Run->Edit Configurations 2、选择要输出日志的日志&#xff0c;右侧&#xff0c;IDEA2023的Logs在 Modify option 里 选中就会展示Logs栏。注意一定要先把这个日志文件创建出来&#xff0c;不然不会自动创建日志文件的 IDEA以前版本的Logs会直接展示出来 3、但是…

o1的风又吹到多模态,直接吹翻了GPT-4o-mini

开源LLaVA-o1&#xff1a;一个设计用于进行自主多阶段推理的新型VLM。与思维链提示不同&#xff0c;LLaVA-o1独立地参与到总结、视觉解释、逻辑推理和结论生成的顺序阶段。 LLaVA-o1超过了一些更大甚至是闭源模型的性能&#xff0c;例如Gemini-1.5-pro、GPT-4o-mini和Llama-3.…

AJAX的基本使用

AJAX的基本使用 &#x1f389;&#x1f389;&#x1f389;欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!&#x1f64f;&#x1f64f;&#x…

DDei在线设计器V1.2.43版发布

2024-11-21-----V1.2.43 一、bug 修复 1. 修复只读情况下&#xff0c;连线依然可以通过特殊点调整的 bug 2. 修复了同一页面多个实例时&#xff0c;部分方法只会引用最后一个实例的问题 3. 修复了组合控件和容器控件改变容器后没有清理的问题&#xff0c;优化了容器的实现 4. …

C++进阶:哈希表实现

目录 一:哈希表的概念 1.1直接定址法 1.2哈希冲突 1.3负载因子 1.4实现哈希函数的方法 1.4.1除法散列法/除留余数法 1.4.2乘法散列法 1.4.3全域散列法 1.5处理哈希冲突 1.5.1开放地址法 线性探测 二次探测 ​编辑 双重散列 1.5.2链地址法 二.代码实现 2.1开放地址…

鸿蒙NEXT开发案例:血型遗传计算

【引言】 血型遗传计算器是一个帮助用户根据父母的血型预测子女可能的血型的应用。通过选择父母的血型&#xff0c;应用程序能够快速计算出孩子可能拥有的血型以及不可能拥有的血型。这个过程不仅涉及到了简单的数据处理逻辑&#xff0c;还涉及到UI设计与交互体验的设计。 【…

(十八)JavaWeb后端开发案例——会话/yml/过滤器/拦截器

目录 1.业务逻辑实现 1.1 登录校验技术——会话 1.1.1Cookie 1.1.2session 1.1.3JWT令牌技术 2.参数配置化 3.yml格式配置文件 4.过滤器Filter 5.拦截器Interceptor 1.业务逻辑实现 Day10-02. 案例-部门管理-查询_哔哩哔哩_bilibili //Controller层/*** 新增部门*/Pos…

2024.5 AAAiGLaM:通过邻域分区和生成子图编码对领域知识图谱对齐的大型语言模型进行微调

GLaM: Fine-Tuning Large Language Models for Domain Knowledge Graph Alignment via Neighborhood Partitioning and Generative Subgraph Encoding 问题 如何将特定领域知识图谱直接整合进大语言模型&#xff08;LLM&#xff09;的表示中&#xff0c;以提高其在图数据上自…

amd显卡和nVidia显卡哪个好 amd和英伟达的区别介绍

AMD和英伟达是目前市场上最主要的两大显卡品牌&#xff0c;它们各有自己的特点和优势&#xff0c;也有不同的适用场景和用户群体。那么&#xff0c;AMD显卡和英伟达显卡到底哪个好&#xff1f;它们之间有什么区别&#xff1f;我们又该如何选择呢&#xff1f;本文将从以下几个方…

接口加密了怎么测?

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、定义加密需求 确定哪些数据需要进行加密。这可以是用户敏感信息、密码、身份验证令牌等。确定使用的加密算法&#xff0c;如对称加密&#xff08;如AES&am…

接口上传视频和oss直传视频到阿里云组件

接口视频上传 <template><div class"component-upload-video"><el-uploadclass"avatar-uploader":action"uploadImgUrl":on-progress"uploadVideoProcess":on-success"handleUploadSuccess":limit"lim…

springboot基于数据挖掘的广州招聘可视化分析系统

摘 要 基于数据挖掘的广州招聘可视化分析系统是一个创新的在线平台&#xff0c;旨在通过深入分析大数据来优化和改善广州地区的招聘流程。系统利用Java语言、MySQL数据库&#xff0c;结合目前流行的 B/S架构&#xff0c;将广州招聘可视化分析管理的各个方面都集中到数据库中&a…

VIM的下载使用与基本指令【入门级别操作】

VIM——超级文本编辑器 在当今时代&#xff0c;功能极其复杂的代码编辑器和集成开发环境&#xff08;IDE&#xff09;有很多。 但如果只想要一个超轻量级的代码编辑器&#xff0c;用于 Unix、C 或其他语言/系统&#xff0c;而不需要那些华而不实的功能&#xff0c;该怎么办呢&…

心情追忆-首页“毒“鸡汤AI自动化

之前&#xff0c;我独自一人开发了一个名为“心情追忆”的小程序&#xff0c;旨在帮助用户记录日常的心情变化及重要时刻。我从项目的构思、设计、前端&#xff08;小程序&#xff09;开发、后端搭建到最终部署。经过一个月的努力&#xff0c;通过群聊分享等方式&#xff0c;用…

开源代码统计工具cloc的简单使用

一.背景 公司之前开发了个小系统&#xff0c;要去申请著作权&#xff0c;需要填写代码数量。应该怎么统计呢&#xff1f;搜索了一下&#xff0c;还是用开源工具cloc吧&#xff01;我的操作系统是windows&#xff0c;代码主要是java项目和vue项目。 二.到哪里找 可以去官方下载…

基于单片机的条形码识别结算设计

本设计基于单片机的条形码辨识与结算系统。该系统主要用于超市、商场等场所的商品结算&#xff0c;实现了在超市内对不同种类商品进行自动识别及自动分类结算的功能。该系统由STM32F103C8T6单片机、摄像头、显示、蜂鸣器报警、按键和电源等多个模块构成。该系统可实现商品自动识…

进程间通信的信号艺术:机制、技术与实战应用深度剖析

目录 1 什么是信号 2 为什么要有信号 3 对于信号的反应 3.1 默认行为 3.2 signal()函数 -- 自定义行为对信号做出反应 3.3 对信号进行忽略 4 信号的产生的类型 4.1 kill命令 4.2 键盘输入产生信号 4.3 系统调用接口 4.3.1 kill() 4.3.2 raise() 函数 4.4 软件条件 …

美畅物联丨JT/T 808 终端设备如何加入畅联云平台

在道路运输行业中&#xff0c;JT/T 808终端设备的应用正变得越来越广泛&#xff0c;把该设备接入畅联云平台&#xff0c;能够达成更高效的车辆管理与监控功能。今天&#xff0c;我们就来探讨一下JT/T 808终端设备接入畅联云平台的步骤与要点。 一、了解畅联云平台接入要求 首先…

【微服务】SpringBoot 整合ELK使用详解

目录 一、前言 二、为什么需要ELK 三、ELK介绍 3.1 什么是elk 3.2 elk工作原理 四、ELK搭建 4.1 搭建es环境 4.1.1 获取es镜像 4.1.2 启动es容器 4.1.3 配置es参数 4.1.4 重启es容器并访问 4.2 搭建kibana 4.2.1 拉取kibana镜像 4.2.2 启动kibana容器 4.2.3 修改…