【嵌入式算法】学习笔记(一):数字滤波算法

2023-05-16

文章目录

  • 摘要
  • 一、数字滤波简介
  • 二、常用数字滤波算法
    • 1.限幅滤波
    • 2.中值滤波
    • 3.算术平均滤波
    • 4.去极值平均滤波
    • 5.滑动平均滤波
    • 6.滑动加权滤波
    • 7.一阶滞后滤波
  • 三、数字滤波小结


摘要

最近在做直流电机的毕设中,由于需要采集转速,电流,电压,温度等参数,常规的采集容易受到干扰,所以特意复习了一下关于数字滤波有关的知识,并作出相应的整理。本文对数字滤波进行简单介绍,讲解七种常用的滤波算法并用C语言实现,并比较其优缺点。由于篇幅原因未能在嵌入式系统中实验,读者可以自行验证。本篇篇幅较长,建议收藏。

所用工具:

1、测试软件:Visual C++6.0

知识概括:

通过本篇文章您将学到:

1、数字滤波算法基础知识


一、数字滤波简介

很多嵌入式系统都需要通过AD转换方式采集模拟信号,当干扰作用于模拟信号之后,AD转换结果就会偏离真实值。如果仅采样一次,是无法确定该结果是否可信的,必须多次采样,得到一个AD转换的数据序列,通过某种处理后,才能得到一个可信度较高的结果。这种用软件算法从采样数据序列中提取逼近真值数据的方法,通常称为数字滤波。数字滤波有硬件滤波的功效,却节省了硬件投资。实现数字滤波功能的软件算法称为数字滤波算法,由于数字滤波算法的灵活性,其效果往往是硬件滤波电路达不到的。
数字滤波的不足之处就是需要消耗一定的CPU机时,在进行实时信号处理时必须充分考虑到这一点。当有用信号为高频信号,干扰信号为低频信号时,需要采用高通滤波,而实时高通滤波算法收到CPU速度的限制,往往力不从心,而硬件高通滤波器却很容易处理这种实时信号。当有用信号为低频信号(如温度,湿度,重量,水位等),其频率通常很低(甚至接近0.001Hz),而干扰信号频率先对较高(如各种电磁干扰),需要采用低通滤波。由于硬件低通滤波体积往往较大,与当前电子产品微型化趋势不相容。而当前CPU的速度在执行实时低通滤波算法时完全可以胜任,故数字滤波主要应用领域为实时低通滤波。在某些情况下,数字滤波也用来进行带通滤波。
对于非实时信息处理,由于不受处理速度的制约,数字滤波算法广泛应用于各种音频数据,图片数据和说数据的加工处理。
如果用硬件手段(FPGA/CPLD)来实现数字滤波,其处理速度将有质的飞越,滤波算法采用数学工具软件MATLAB来设计,滤波功能也将更加丰富多彩,应用频率范围也大大扩展。以下介绍在嵌入式系统中广泛使用的几种数字滤波算法,这些算法都是用软件进行实时低频信号处理,达到提高系统抗干扰能力的目的。


二、常用数字滤波算法

1.限幅滤波

生活经验告诉我们,很多物理量的变化是需要一定时间的,相邻两次采样值之间的变化有一个合理的限度(即有用信号高频分量的最高频率有限)。例如在热处理车间的大型电炉里,工作的温度变化不可能在短时间(采样间隔)内发生剧烈变化,如果相邻两次采样值之间的变化未超过预定范围,说明该采样值未受到明显干扰,可以采用。如果相邻两次采样值之间的变化超过预定范围,说明该采样值受到了明显干扰(毛刺型突发干扰),不能采用。对于不可信得采样数据,必须输出一个合理的替代数据,以保证采样数据序列的连续性和完整性。在要求不高的场合,可以用前一个采样数据来替代这个受干扰的采样数据。
限幅滤波C语言代码如下:

#include "stdafx.h"

int adcData[10]={10,12,15,13,14,25,16,16,20,9};            //手动定义ADC采集的值

#define D 10                                               //相邻两次采样值之间最大允许变化值
int history;                                               //上次采样值

int main(int argc, char* argv[])
{
	int neo;                                               //定义本次采样值
	history=adcData[0];                                    //定义上次采样值初值
	for(int i=0;i<10;i++)                                  //循环访问数组adcData
	{
		neo=adcData[i];                                    //将数组里的元素作为本次采样值
		if(i>0)                                            //i=0时,无上次采样值,故判断
		{
			if((neo-history>D)||(history-neo>D))           //限幅判断
				neo=history;                               //如果超过最大变化值,则新值变为上次采样值
			history=neo;                                   //本次采样值变为上次采样值,开始下一轮循环
		}
		printf("%d\n",neo);                                //输出滤波后的值
 	}
	return 0;
}

//循环neo输出结果为:10,12,15,13,14,14,16,16,20,20
//可见第六位和第10位由于相差超过10,故被前一个值替换

当被检测物理量处于明显变化阶段时,相邻两个采样值之间的差别也比较明显,这时用前一个采样值来替代当前受干扰的采样值存在较大的误差。因此,可以利用被检测物理量的变化趋势来进行预测,选择一个更加合理的数据来替代当前受干扰的采样值,使得替代误差大大减小。
为了掌握被检测物理量当前变化趋势,至少需要两个以上的采样值历史记录。我们采用最简单的线性预测算法,只有两个历史采样值就可以了。线性预测算法的含义为“当前采样值的变化趋势与前一次采样值的变化趋势相同”,即采样值在短期内保持相同的上升趋势和下降趋势。由于代码类似,只是加一些限制条件,故这里省略。
限幅滤波的关键是合理确定采样周期和相邻两次采样值的最大允许变化值。采样周期可以通过检测精度(硬件是AD模块分辨率,软件是采样频率)和物理量最大变化速率(比如温度每秒钟对多上升多少摄氏度)来计算。另外,采样周期不能太短,必须大于干扰的持续时间,一面一次干扰造成两次以上的采样值不准确。
限幅滤波本质上是低通滤波,由于毛刺型突发干扰为高频干扰,故可以被很好地滤除。另一方面,限幅滤波采用限幅手段来达到滤波目的,对于幅度比较小的噪声干扰无能为力,即不能滤除随机干扰,因而只能用于对精度要求不是很高的场合。

2.中值滤波

限幅滤波有一个潜在的隐患,在连续两个以上采样周期受到强干扰后,系统可能会不稳定。因此,限幅滤波只能在基本没有干扰的场合下采样,他只能滤除极个别偶发的毛刺型干扰。在环境恶化,干扰频繁的情况下,可以采用中值滤波算法来处理。该算法描述是:连续进行奇数次采样,然后将采样得到的数据样本进行排序,取中间数据样本作为有效采样值。例如连续采样5次,得到5个采样数据样本(例如17、17、29、27、16),然后进行排序(16、17、17、27、29),最后取中间的(第三个,即17)采样数据样本作为有效采样值输出。由于受到干扰的采样值偏离有效采样值,排序后必然处于两端的位置,只要受到干扰的采样数据样本个数小于总采样数据样本数目的一半,就可以确保中值采样数据样本的有效性。
在采样中值滤波算法时,需要确定两个采样周期:一个是主采样周期(T0)和子采样周期(T1),每个主采样周期输出一个有效采样值,具体的时间长度由系统精度和有效信号的高频分量决定。每个子采样周期进行一次采样操作,它是由干扰频繁程度和连续采样次数N决定。
在这里插入图片描述

采用中值滤波算法必须满足以下条件:
被采样的物理量本身在连续N次子采样周期期间是基本稳定的,其变化量小于系统精度要求,可以忽略不计。
每次干扰的最长持续时间已知,相邻两次干扰的间隔时间虽然不定,但远大于一次干扰的持续时间。这样,可以使得连续采样的数据样本中被干扰的样本数目不会超过总样本数目N的一半,确保中值样本的有效性。
中值滤波C语言代码如下:

#include "stdafx.h"

int adcData[20]={10,12,15,13,14,25,16,16,20,9,               //手动定义ADC采集的值
				13,14,25,16,16,20,9,10,12,15}; 

#define N 5                                                  //定义N个数取中值

int value_buff[N];                                           //定义中值计算缓冲区

int main(int argc, char* argv[])
{
	int neo;                                                 //定义滤波计算完输出的值
	char temp;                                               //定义冒泡排序法临时变量
	for(int major_col=0;major_col<20;major_col+=N)           //定义主采样周期,每个包括N个子采样周期
	{
		for(int minor_col=0;minor_col<N;minor_col++)         //采集每个子采样周期的值
		{
			value_buff[minor_col]=adcData[minor_col+major_col];
		}
		//冒泡排序法
		for(int i=0;i<N-1;i++)
		{
			for(int j=0;j<N-i-1;j++)
			{
				if(value_buff[j]>value_buff[j+1])
				{
					temp=value_buff[j];
					value_buff[j]=value_buff[j+1];
					value_buff[j+1]=temp;
				}
			}
 		}
		neo=value_buff[(N-1)/2];                            //输出的值取缓冲区内的中值
		printf("%d\n",neo);
  	}
	return 0;
}

//循环neo输出结果为:13,16,16,12
//可见四个主采样周期的值都是子采样周期数据的中值

中值滤波本质上也是低通滤波,由于毛刺型突发干扰为高频干扰,故可以被很好地滤除。由于中值滤波进行N次采样才输出一次有效值(即采样输出比N:1),抗突发干扰能力比限幅滤波要提高很多,能够在干扰比较频繁的场合正常工作。另外,在N个数据样本中,中值样本通常受到的噪声干扰也比较小,故中值滤波算法也具备一定的抗随机干扰能力(其能力与N正相关)。
中值滤波的效果比限幅滤波提高很多,但必须满足主采样周期远大于子采样周期的条件。而子采样周期受到毛刺型突发干扰持续时间的限制不能太短,故主采样周期必然较长,即被检测物理量的基波频率一定比较低(慢变信号),其应用场合受到一定的限制。

3.算术平均滤波

由于随机干扰(噪声型干扰)随着数据样本的增加其统计平均值区域零,故对被检测物理量进行连续多次采样,然后求其算数平均值作为有效采样值,就可以达到抑制随机干扰的效果。连续采样次数越多,抑制随机干扰的效果越好。这种滤波算法就是算术平均滤波算法。
算术平均滤波C语言代码如下:

#include "stdafx.h"

float adcData[20]={10,12,15,13,14,25,16,16,20,9,               //手动定义ADC采集的值
				13,14,25,16,16,20,9,10,12,15}; 

#define N 5												   	//定义N个数取算术平均

float value_buff[N];                                           //定义算术平均计算缓冲区

int main(int argc, char* argv[])
{
	float neo=0.0;                                                 //定义滤波计算完输出的值
	for(int major_col=0;major_col<20;major_col+=N)                 //定义主采样周期,每个包括N个子采样周期
	{
		for(int minor_col=0;minor_col<N;minor_col++)               //采集每个子采样周期的值
		{
			value_buff[minor_col]=adcData[minor_col+major_col];
			neo+=value_buff[minor_col];
		}
		neo=neo/N;                                                 //输出算数平均
		printf("%0.2f\n",neo);
	}
	return 0;
}

//循环neo输出结果为:12.80 19.76 20.75 17.35
//可见四个主采样周期的值都是子采样周期数据的算数平均

算术平均滤波对随机干扰的抑制效果与连续采样次数N密切相关,当采样次数N增加到一定程度后,被测物理量本身产生的变化量就会超过允许范围,再也不能忽略不计了,因此连续采样次数N是不能任意增加的。其应用场合与中值滤波的应用场合类似,必须满足主采样周期远大于子采样周期的条件。而子采样周期受到毛刺型突发干扰持续时间的限制不能太短,故主采样周期必然较长,即被检测物理量的基波频率一定比较低(慢变信号),其应用场合受到一定限制。
虽然算术平均滤波对随机干扰的抑制效果比较好,但却不能消除毛刺型突发干扰。只要有一个采样数据样本受到毛刺型突发干扰,算术平均值将明显偏离真实值,所以一般需要结合其他限制条件去对算术平均滤波算法进行优化。

4.去极值平均滤波

算术平均滤波不能消除毛刺型突发干扰,只是通过平均操作将其影响削弱。因毛刺型突发干扰使采样值远离真实值,针对毛刺型突发干扰这一特点,可以比较容易地将其剔除,不参加平均值计算,从而使平均滤波的输出值更接近真实值。算法原理如下:连续采集N次,将其累加求和,同时找出其中的最大值和最小值,再从累加和中减去最大值和最小值,将剩余的N-2个采样值求平均,即得有效采样值。这种滤波算法就是去极值平均滤波算法。
算术平均滤波C语言代码如下:

#include "stdafx.h"

float adcData[20]={10,12,15,13,14,25,16,16,20,9,               //手动定义ADC采集的值
				13,14,25,16,16,20,9,10,12,15}; 

#define N 5												   	//定义N个数取算术平均

float value_buff[N];                                           //定义算术平均计算缓冲区
float nvalue_buff[N-2];                                        //定义去极值之后的缓冲区
int main(int argc, char* argv[])
{
	float neo=0.0;                                                 //定义滤波计算完输出的值
	float temp;
	for(int major_col=0;major_col<20;major_col+=N)           //定义主采样周期,每个包括N个子采样周期
	{
		for(int minor_col=0;minor_col<N;minor_col++)         //采集每个子采样周期的值
		{
			value_buff[minor_col]=adcData[minor_col+major_col];
		}
		//冒泡排序法
		for(int i=0;i<N-1;i++)
		{
			for(int j=0;j<N-i-1;j++)
			{
				if(value_buff[j]>value_buff[j+1])
				{
					temp=value_buff[j];
					value_buff[j]=value_buff[j+1];
					value_buff[j+1]=temp;
				}
			}
		}
		for(int k=0;k<N-2;k++)                                //去极值并且放入缓冲区
		{
			nvalue_buff[k]=value_buff[k+1];
			neo+=nvalue_buff[k];
		}
		neo=neo/(N-2);                                        //输出值为去极值之后的算数平均值
		printf("%0.2f\n",neo);
	}
	return 0;
}

//循环neo输出结果为:13.00 21.67 22.56 19.85
//可见四个主采样周期的值都是子采样周期数据去极值后的算数平均

去极值平均滤波同时具有消除毛刺型突发干扰和噪声型随机干扰的能力,在低频信号采集系统中被广泛运用。比如在各种文艺表演大赛的评奖计分中经常听到主持人所说的“去掉一个最高分,去掉一个最低分,最终的得分是xxx”,这实际上就是采用了去极值平均滤波算法。
如果连续N次采样中没有受到毛刺型干扰的数据样本,被剔除的将是两个随机误差最大的数据样本,滤波效果仍然很好。去极值平均滤波算法也有效果不佳的时候,如果连续N次采样中有两个以上的正毛刺数据样本或者两个以上的负毛刺数据样本,将至少有一个毛刺数据样本不能剔除,最终平均值必然与真实值存在明显偏差。
去极值平均滤波的应用条件与算术平均滤波的应用条件相同,主要用来对低频信号进行软件滤波。

5.滑动平均滤波

前面介绍的两种平均滤波算法有一个共同点,即每个主采样周期取得的一个有效采样值是由连续若干个子采样值计算出来的,为此,这些算法的主采样周期都是比较长的。当被检测物理量变化快时,较长的主采样周期不能及时采集到被检测物理量中的高频信息,致使系统反应迟钝,实时性难以保证。要保证系统的实时性,必须要按技术指标的要求相应缩短主采样周期,而子采样周期不能随意缩短(受干扰持续时间的制约),只好减少连续采样次数,连续采样次数的减少又直接降低了滤波效果。既然如此,干脆直接按技术指标的要求确定一个合理的采样周期,每个采样周期只进行一次采样操作(即采样输出比1:1),然后将当前的采样值和之前连续的若干次采样值(最近历史采样值)一起进行平均,将得到的平均值作为当前有效采样值投入使用。由于参与平均运算的历史采样值个数固定且内容不断更新,相当于一个滑动的时间窗口,故将这种平均滤波方式称为“滑动平均滤波”,窗口的大小用采样数据样本个数m来表示。按这种方式进行采样就不再存在主采样周期和子采样周期的问题。
在这里插入图片描述
滑动平均滤波C语言代码如下:

#include "stdafx.h"

float adcData[20]={10,12,15,13,14,25,16,16,20,9,               //手动定义ADC采集的值
				13,14,25,16,16,20,9,10,12,15}; 

#define N 5												   	//定义N个数取算术平均

float value_buff[N];                                           //定义算术平均计算缓冲区

int main(int argc, char* argv[])
{
	float neo=0.0;                                           //定义滤波计算完输出的值
	for(int step=0;step<20-N;step++)                         //缓冲区的循环
	{
		for(int count=0;count<N;count++)                     //缓冲区内N个数的赋值
		{
			value_buff[count]=adcData[count+step];
			neo+=value_buff[count];
		}
		neo=neo/N;                                           //输出滑动平均后的值,一共20-N个
		printf("%0.2f\n",neo);
	}

	return 0;
}

//循环neo输出结果为:12.80 18.36 20.27 20.85 22.37 21.67 19.13 18.23
//                   19.85 19.37 20.67 22.33 21.67 18.53 17.11
//可见添加滑动窗之后会更加平滑
//理应输入输出是1:1,这里为了简便代码,故这样输出,只要知道思想就可以了,具体算法具体使用

6.滑动加权滤波

在滑动平均滤波算法中,窗口中的m个采样数据样本以平等身份参与运算,这对抑制随机干扰比较有利,但将有超时严重的滞后效果,降低系统反应速度。为了提高系统的反应速度,滤波算法的输出应该及时反映当前采样值中包含的有效信息,即增加即时数据样本和近期数据样本的权重,降低早期数据样本的权重。为此,为滑动窗口中的各个数据样本分配不同的“加权系数”,进行加权平均运算。这种滤波算法称为“滑动加权滤波”
在这里插入图片描述
滑动加权滤波C语言代码如下:

#include "stdafx.h"

float adcData[20]={10,12,15,13,14,25,16,16,20,9,               //手动定义ADC采集的值
				13,14,25,16,16,20,9,10,12,15}; 

#define N 5												   	//定义N个数取算术平均

float value_buff[N];                                           //定义算术平均计算缓冲区
float perc_buff[N]={0.1,0.2,0.1,0.3,0.3};                  //定义缓冲区权重


int main(int argc, char* argv[])
{
	for(int step=0;step<20-N;step++)                         //缓冲区的循环
	{
		float neo=0.0;                                                 //定义滤波计算完输出的值
		for(int count=0;count<N;count++)                     //缓冲区内N个数的赋值
		{
			value_buff[count]=adcData[count+step];    
			value_buff[count]*=perc_buff[count];              //每个值乘对应的权重
			neo+=value_buff[count];							//累加
		}
		printf("%0.2f\n",neo);
	}
	return 0;
}

//循环neo输出结果为:13.00 17.20 17.80 16.20 18.80 16.00 13.40 14.60
//                   16.80 17.20 16.20 18.80 16.00 12.50 13.10
//可见添加滑动窗之后会更加平滑

7.一阶滞后滤波

将一阶滞后滤波器的微分方程用差分方程来表示,便可以用软件算法来模拟硬件一阶滞后滤波器(RC低通滤波器)的功能
在这里插入图片描述

由上式可以看出,本次滤波的输出值主要取决于上次滤波的输出值,本次采样值对本次滤波输出的贡献是比较小的,但多少有些修正作用。这种算法便模拟了具有较大惯性的一阶滞后滤波器的功能。
当目标参数为变化很慢的物理量时(如大型储水池的水位信号),采用一阶滞后滤波算法是很有效的。
另一方面,他不能滤除高于二分之一采样频率的干扰信号。一阶滞后滤波算法程序流程与加权平均滤波相似,而加权系数只有两个:a和(1-a)。
一阶滞后滤波C语言代码如下:

#include "stdafx.h"

float adcData[10]={10,12,15,13,14,25,16,16,20,9};            //手动定义ADC采集的值

#define D 10                                               //相邻两次采样值之间最大允许变化值
#define A 0.85                                             //滤波系数
float history=0.0;                                               //上次采样值

int main(int argc, char* argv[])
{
	float neo=0.0;                                               //定义本次采样值
	history=adcData[0];                                    //定义上次采样值初值
	for(int i=0;i<10;i++)                                  //循环访问数组adcData
	{
		neo=adcData[i];                                    //将数组里的元素作为本次采样值
		neo=A*neo+(1-A)*history;                           //滤波加权
		printf("%0.2f\n",neo);                                //输出滤波后的值
 	}
	return 0;
}

//循环neo输出结果为:10.00 11.70 14.25 12.55 13.40 22.75 15.10 15.10 18.50 9.15
//可见滤波系数的取值对滤波效果尤为重要

在设置滤波系数时需要同时兼顾系统的平稳性和灵敏性,而两者在一阶滞后滤波算法中属于不能同事达到最优,只能取得相对最优解,所以找到一个平衡点很重要,这也需要具体工程具体应用。当数据变化较为快速时需要以灵敏性优先考虑,当数据趋于稳定时需要以平稳性优先考虑。


三、数字滤波小结

下面将从采样输出比,康毛刺干扰能力和抗噪声干扰能力三个方面进行对比,如下表所示:
在这里插入图片描述

每种数字滤波算法都有自己的特点和应用条件,应该根据实际应用场合来合理选择数字滤波算法,并根据技术参数要求来确定采样周期。以上这些也只算是比较基础的滤波方式,可以相互结合使用,但也要考虑采集数据的类型。读者掌握这些之后可以在学习一些更为升入的滤波方式,比如卡尔曼,维纳等,技多不压身。

PS:最最最重要的,码字不易,求各位大佬看完点个赞,感谢!!!


在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【嵌入式算法】学习笔记(一):数字滤波算法 的相关文章

  • 学习记录--PID(角度双环)

    一 xff0c 理论理解 参考 xff1a 从不懂到会用 xff01 PID从理论到实践 哔哩哔哩 bilibili 1 三个参数 Kp xff1a 比例系数 xff1a pid gt p out 61 pid gt kp pid gt e
  • FreeRTOS多任务调度器原理

    1 xff1a 多任务启动 1 xff1a 创建空闲任务 2 xff1a 配置SysTick和PendSV为最低优先级 3 xff1a 配置SysTick寄存器 4 xff1a 调用SVC中断 2 xff1a SVC业务流程 1 xff1a
  • 立创EDA使用教程

    1 xff1a 绘制原理图 1 1 放置元件 立创EDA可以在线编辑 xff0c 不同于AD和PADS需要自己绘制或者导入封装 立创可以直接在线拉取别人的封装过来使用 xff0c 当然也可以自己绘制 1 2添加导线和网络 W是连线 xff0
  • ubuntu电脑共享文件夹给另一台windows电脑

    1 xff1a 安装samba工具 sudo apt get install samba samba version 2 xff1a 配置共享文件夹路径 vi etc samba smb conf 在文件末尾添加 share comment
  • FreeRTOS 学习(一)

    一 使用FreeRTOS点亮LED灯 在STM32有一定基础 xff0c 在开始学习操作系统的小白 xff0c 介绍使用STM32用操作系统点亮第一盏灯 xff0c 这也是学习单片机最开始的地方 xff1b 下面来图文配置 xff0c 我这
  • FreeRTOS的启动流程,编码风格与调试方法

    一 启动流程 RTOS主要有两种比较流行的启动方式 xff0c 下面会通过伪代码讲解两种启动方式的区别 xff0c 然后看看STM32cubeMX集成的FreeRTOS采用哪种启动方式 1 方法一 xff1a 在main函数中将硬件初始化
  • 2021AIOps挑战赛|基于移动通信网络运维中的多指标时空序列预测

    2021国际AIOps挑战赛决赛暨AIOps创新高峰论坛于2021年5月13日在北京成功举行 本文根据中国移动研究院首席科学家 人工智能与智慧运营中心总经理冯俊兰博士现场发言纪要整理而成 演讲内容 各位领导 xff0c 各位老师 xff0c
  • python架构之Django学习------基础篇二

    学习环境 xff1a ubuntu16 0 4 1 创建项目 django admin startproject studypy studypy为项目名称 注意 xff1a 项目创建完成之后 xff0c 会有一个文件夹和项目名称一样 xff
  • VNC配置端口占用

    问题描述 xff1a 配置VNC环境时 执行systemctl配置端口发现有些端口被占用 systemctl status vncserver span class token operator span user 64 span clas
  • SNMP概述

    目录 SNMP的架构 SNMP的版本 SNMPv1 v2c 报文结构 操作类型 工作原理 SNMPv3 报文结构 SNMPv3体系结构 工作原理 用户组和用户名 SNMP的配置 基本配置 v2c配置 SNMPv3配置 xff08 USM用户
  • (18)ROS学习-TF坐标变换之静态坐标变换

    1 坐标msg消息 xff1a 订阅发布模型中数据载体 msg 是一个重要实现 xff0c 首先需要了解一下 xff0c 在坐标转换实现中常用的 msg geometry msgs TransformStamped和geometry msg
  • CentOS8.4 Samba服务配置

    目录 Samba服务简介 基本操作 Samba服务主配置文件 全局配置参数 局部配置参数 题一 创建共享资源 创建系统用户组和系统用户并查看 对系统用户设置Samba密码 查看已设置Samba密码的用户 建立共享资源目录并分配权限 修改主配
  • X86汇编语言从实模式到保护模式(Linux环境搭建)

    前言 在学完了计算机组成原理和王爽的汇编语言后 xff0c 虽然操作系统的理论知识能看懂了 xff0c 但做起xv6和ucore实验还是有一定难度 xff0c 所以还是得补一补x86汇编的知识 环境搭建 xff1a 因为书中的工具包和环境都
  • 【机器学习】二分类算法实现及算法精度比较

    文章目录 一 数据集选择1 感知机2 K近邻 xff08 knn xff09 3 朴素贝叶斯4 决策树id35 逻辑斯蒂回归总结 一 数据集选择 鸢尾花数据集 iris data Iris数据集是常用的分类实验数据集 xff0c 由Fish
  • OpenStack实战

    开源OpenStack实战 公有云 一个用户就是一个VPC虚拟私有云 在同一个VPC中的不同子网可以互通 不同VPC之间不能互通 一个VPC 就属于regin一个路由器 VPC不可以跨Regin 两个租户是不可以打通的 Regin xff1
  • VScode怎样从gitee上拉取项目?很简单,赶快学起来

    1 xff0c 在你写项目的磁盘里新建文件夹 2 xff0c 登录Gitee 3 xff0c 复制克隆 下载处的地址 4 xff0c 打开VScode xff0c 在新建的文件夹下 xff0c 打开终端 5 xff0c 运行 git clo
  • 《操作系统》-进程的定义组成和特征

    进程的定义组成和特征 进程的定义 程序 xff1a 就是一个指令序列 早期的计算机只支持单道程序 引用多道程序技术 xff1a 为了方便操作系统管理完成各程序并发执行 xff0c 引入了进程和进程实体的概念 进程实体 xff08 进程映像
  • 【完整教程】在win10平台下使用d435i深度相机读取数据并保存到本地,以便进行后续3D点云处理

    1 下载RealSense SDK 2 0 进入网址 xff1a RealSense SDK 2 0 直接拉到网站最下端 xff0c 在Asset下可以看到很多exe可执行软件 xff0c 由于我的电脑是win10 xff0c 所以选择第三
  • python架构之Django学习(管理站点)------基础篇三

    学习环境 xff1a ubuntu16 0 4 1 创建管理员 http 127 0 0 1 8000 admin python manage py createsuperuser 创建用户名密码 注册
  • VMware虚拟机安装Linux教程(超详细)

    一 安装 VMware 官方正版VMware下载 xff08 16 pro xff09 xff1a https www aliyundrive com s wF66w8kW9ac 下载Linux系统镜像 xff08 阿里云盘不限速 xff0

随机推荐

  • WIFI模块——ESP8266

    1 ESP8266简介 ESP8266是一款高性能的WIFI串口模块 xff0c 内部集成MCU能实现单片机之间串口通信 xff0c 是目前使用最广泛的一种WIFI模块之一 可以简单理解为一个WIFI转串口的设备 xff0c 不用知道太多W
  • 姿态传感器——MPU6050

    1 MPU6050介绍 MPU6050是由三个陀螺仪和三个加速度传感器组成的6轴运动处理组件 xff0c 是一款六轴 xff08 三轴加速度 43 三轴角速度 xff08 陀螺仪 xff09 xff09 传感器 内部主要结构 陀螺仪 加速度
  • Arch | Nodejs 配置

    今天在使用 npm 时出现了一些错误 xff0c 之前那个文章内容有点多 xff0c 找起来比较麻烦 xff0c 所以这里单独把一些软件的配置单独拉出来写一个文章 参考 ArchWiki Node js 安装 如果没有多版本需求的话 xff
  • 基于I2C协议利用STM32进行温湿度传感器的数据采集

    目录 一 I2C总线通信协议的介绍1 I2C简介2 I2C总线时序图3 五种速率4 四种信号5 I2C的优缺点6 软件IIC和硬件IIC 二 创建工程1 实验目的2 工具的选择3 相关代码分析 三 线路的连接四 结果实现五 总结参考文献 一
  • 海康嵌入式软件面试经验(已拿offer)

    本科双非 xff0c 计算机类专业学渣 xff0c 0实习经历 xff0c 复习考研的时候学了一遍408 xff0c 强化阶段学的心态崩了就边复习边投简历 xff0c 之前投了好几次体面厂的测试岗都没进面试 xff0c 投开发岗反而进了 7
  • 前端浏览器渲染原理及优化

    文章目录 一 浏览器组成1 对浏览器内核的理解2 浏览器的主要组成部分 二 浏览器渲染原理1 浏览器的渲染过程步骤一 xff1a 步骤二 xff1a 步骤三 xff1a 步骤四 xff1a 步骤五 xff1a 2 相关概念 重排 更新元素的
  • Docker+github actions部署前端项目

    Docker 43 github actions部署前端项目 文章目录 Docker 43 github actions部署前端项目前言1 Docker相关文件配置2 创建自己的dokcer hub仓库3 yml文件配置 前言 在进行本篇实
  • pytorch可视化之:可视化网络结构+CNN可视化+TensorBorad使用

    Pytorch学习第五部分 xff1a pytorch可视化 Let 39 s go 一 可视化网络结构1 1 Resnet18结构1 2 使用torchinfo可视化网络结构1 2 1 torchinfo安装1 2 2 torchinfo
  • spring中用到的设计模式及应用场景

    spring中用到的设计模式及应用场景 1 工厂模式 xff1a 在Beanfactory和applicationContext创建中都用到了 2 单例模式 xff1a Bean默认就是单例模式 单例模式只允许创建一个对象 xff0c 获取
  • python架构之Django学习------流程总结

    python架构之Django学习 一 二 三 开发流程 xff1a step1 创建虚拟环境 mkvirtrualenv step2 安装django pip install django step3 创建项目 python manage
  • PDU 发送短信3

    T指令收发短信主要有两种模式 xff1a Text模式和PDU xff08 Protocol Data Unit xff0c 协议数据单元 xff09 模式 使用Text模式收发短信代码简单 xff0c 很容易实现 xff0c 最大缺点不支
  • Linux驱动---休眠与唤醒

    Linux 休眠与唤醒 文章目录 Linux 休眠与唤醒前言一 休眠 唤醒 机制二 重要的函数及其数据结构wait内核函数唤醒函数 三 驱动编程步骤附录 xff08 源码 xff09 前言 当应用程序必须等待某个时间发生 xff0c 比如必
  • 序列化Writable接口

    基本序列化类型往往不能满足所有需求 xff0c 比如在Hadoop框架内部传递一个自定义bean对象 xff0c 那么该对象就需要实现Writable序列化接口 实现Writable序列化步骤如下 xff08 1 xff09 必须实现Wri
  • MapReduce读取数据

    1 InputFormat 运行MapReduce程序时 xff0c 输入的文件格式包括 基于行的日志文件 二进制格式文件 数据库表等 那么 xff0c 针对不同的数据类型 xff0c MapReduce是如何读取这些数据的呢 InputF
  • Git的安装与配置,VScode如何连接Gitee?

    什么是gitee 要学gitee 你首先得知道gitee是什么 而且你得知道它的好处 首先它是国内最大的代码托管平台 国外GitHub的弟弟 然后 它能帮你 管理 昨天和今天 改动的文件 xff0c 还给你做 备份 xff1b 它能管理让你
  • 下载并使用Maven创建运行项目(配置Maven、tomcat、含idea实例)【精细教程】

    前言 xff08 重点 xff01 xff01 xff09 xff1a 很多人在安装好maven后 xff0c 遇到idea与maven版本不匹配的问题 xff0c 首先要根据自己的idea版本来选择maven版本 xff01 IDEA 2
  • 将本地项目commit到gitee上

    在新建的项目路径中 xff0c shift 43 右键 xff0c 打开powershell窗口 查看状态 xff1a git status 再执行 xff1a git add git commit m 34 add files 34 再次
  • docker搭建私有仓库

    一 宿主机安装 1 extras源中下载安装distributon包 编写源 extras name 61 extra baseurl 61 https mirrors aliyun com centos vault 7 9 2009 ex
  • HBase-API

    目录 引入的依赖 创建连接 命名空间 表 引入的依赖 lt dependencies gt lt dependency gt lt groupId gt org apache hbase lt groupId gt lt artifactI
  • 【嵌入式算法】学习笔记(一):数字滤波算法

    文章目录 摘要一 数字滤波简介二 常用数字滤波算法1 限幅滤波2 中值滤波3 算术平均滤波4 去极值平均滤波5 滑动平均滤波6 滑动加权滤波7 一阶滞后滤波 三 数字滤波小结 摘要 最近在做直流电机的毕设中 xff0c 由于需要采集转速 x