基于RFbeam的V-LD1-60GHz毫米波雷达传感器数据获取(通过UART串口来控制模块)

基于RFbeam的V-LD1-60GHz毫米波雷达传感器数据获取(通过UART串口来控制模块)

文章目录

  • V-LD1
  • 命令发送
  • 消息回复
  • 通信示例
  • 雷达数据获取
  • 宏定义
  • 通信代码
  • 运行效果
  • 附录:压缩字符串、大小端格式转换
    • 压缩字符串
      • 浮点数
      • 压缩Packed-ASCII字符串
    • 大小端转换
      • 什么是大端和小端
      • 数据传输中的大小端
      • 总结
      • 大小端转换函数

V-LD1

该模块是由串口进行控制的
在这里插入图片描述
串口协议结构体如下:

#pragma pack(1)
typedef struct
{
	char Header[4];
	uint32_t Length;
	uint8_t DATA[43];
}V_LD1_Struct;
#pragma pack()

头文字是ASCII码字符串格式
然后四字节的Length表示DATA数据长度
数据位小端格式
在这里插入图片描述
通信方式就是先发一个命令 然后等待RESP返回 随后就是命令对应的数据

INIT命令支持修改波特率 但第一次发的时候必须用115200
在这里插入图片描述修改波特率后 直到GBYE命令或复位、断电之前 都是修改后的波特率

命令发送

读取雷达命令就是GNFD 另外配置雷达参数则是SRPS
在这里插入图片描述
在这里插入图片描述

消息回复

发什么命令 就按什么格式回复 但RESP是肯定会最先回复的
另外 读雷达参数用GRPS命令
在这里插入图片描述

通信示例

在这里插入图片描述

雷达数据获取

通过GNFD命令获取雷达数据
如果不需要读大量数据 可以只使用115200
在这里插入图片描述
在这里插入图片描述

宏定义

#ifndef __V_LD1_H__
#define __V_LD1_H__
#include "main.h"

#pragma pack(1)
typedef struct
{
	char Header[4];
	uint32_t Length;
	uint8_t DATA[43];
}V_LD1_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	char Version[19];
	char Unique_ID[12];
	uint8_t Distance_Range;
	uint8_t Threshold_Offset;
	uint16_t Min_Range_Filter;
	uint16_t Max_Range_Filter;
	uint8_t Distance_Average_Count;
	uint8_t Target_Filter;
	uint8_t Distance_Precision;
	uint8_t TX_Power;
	uint8_t Chirp_Integration_Count;
	uint8_t Short_Range_Distance_Filter;
}V_LD1_Radar_Parameter_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	uint16_t ADC_Value[1024];
}V_LD1_RADC_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	uint16_t Spectrum_Point[512];
	uint16_t Threshold_Point[512];
}V_LD1_RFFT_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	float Distance;
	uint16_t Magnitude_Of_Target;
}V_LD1_PDAT_Struct;
#pragma pack()

#pragma pack(1)
typedef struct
{
	uint32_t Frame_ID;
}V_LD1_DONE_Struct;
#pragma pack()

typedef enum
{
	V_LD1_GNFD_RADC = (1<<0),
	V_LD1_GNFD_RFFT = (1<<1),
	V_LD1_GNFD_PDAT = (1<<2),
	V_LD1_GNFD_DONE = (1<<5),
}V_LD1_GNFD_Enum;

typedef enum
{
	V_LD1_RESP_OK			 									= 0,
	V_LD1_RESP_Unknown_CMD			 				= 1,
	V_LD1_RESP_Invalid_Parameter_Value	= 2,
	V_LD1_RESP_Invalid_RPST_Version			= 3,
	V_LD1_RESP_UART_Error								= 4,
	V_LD1_RESP_No_Calibration_Value			= 5,
	V_LD1_RESP_Timeout									= 6,
	V_LD1_RESP_NO_Programmed						= 7,
}V_LD1_RESP_Enum;

extern uint8_t V_LD1_Status;
extern uint8_t V_LD1_RxBit;
extern uint8_t V_LD1_RxBuffer[1024];
extern uint8_t V_LD1_RxFlag;
extern V_LD1_Radar_Parameter_Struct V_LD1_Radar_Parameter_Global;

void Init_V_LD1(void);

void Read_V_LD1_Radar(void);
#endif

通信代码

# include "V_LD1.h"

uint8_t V_LD1_RxBit=0;
uint8_t V_LD1_RxBuffer[1024]={0};
uint8_t V_LD1_RxFlag=0;
uint8_t V_LD1_Status=0;

V_LD1_Radar_Parameter_Struct V_LD1_Radar_Parameter_Global={0};

V_LD1_Struct Read_V_LD1_Stu(void)
{
	V_LD1_Struct V_LD1_Stu;
	memset(&V_LD1_Stu,0,sizeof(V_LD1_Stu));
	uint8_t i=0;
	while(V_LD1_Status<2)
	{
		i++;
		delay_ms(10);
		if(i>=50)
		{
			V_LD1_RxBit=0;
			V_LD1_Status=0;
			V_LD1_RxFlag=0;
			return V_LD1_Stu;
		}
	}
	
	memcpy(&V_LD1_Stu.Header[0],&V_LD1_RxBuffer[0],4);
	memcpy(&V_LD1_Stu.Length,&V_LD1_RxBuffer[4],4);
	memcpy(&V_LD1_Stu.DATA[0],&V_LD1_RxBuffer[8],V_LD1_Stu.Length);
	V_LD1_RxBit=0;
	V_LD1_Status=0;
	V_LD1_RxFlag=0;
	
	return V_LD1_Stu;
}

void Send_V_LD1_Stu(V_LD1_Struct V_LD1_Stu)
{
	uint8_t buf[51]={0};
	memcpy(buf,&V_LD1_Stu,V_LD1_Stu.Length+8);
	V_LD1_RxBit=0;
	V_LD1_Status=0;
	V_LD1_RxFlag=0;
	HAL_UART_Transmit(&V_LD1_UART_Handle,buf,V_LD1_Stu.Length+8,0xFFFF);
}

int Read_V_LD1_RESP(void)
{
	V_LD1_Struct V_LD1_Stu=Read_V_LD1_Stu();
	if (V_LD1_Stu.Header[0]=='R' && V_LD1_Stu.Header[1]=='E' && V_LD1_Stu.Header[2]=='S' && V_LD1_Stu.Header[3]=='P' && V_LD1_Stu.Length==1)
	{
		return V_LD1_Stu.DATA[0];
	}
	else
	{
		return -1;
	}
}

int Read_V_LD1_VERS(V_LD1_Struct* V_LD1)
{
	V_LD1_Struct V_LD1_Stu=Read_V_LD1_Stu();
	if (V_LD1_Stu.Header[0]=='V' && V_LD1_Stu.Header[1]=='E' && V_LD1_Stu.Header[2]=='R' && V_LD1_Stu.Header[3]=='S' && V_LD1_Stu.Length==19)
	{
		memcpy(V_LD1,&V_LD1_Stu,27);
		return 0;
	}
	else
	{
		return -1;
	}
}

void Read_V_LD1_Radar(void)
{
	V_LD1_Struct V_LD1_Stu={0};
	V_LD1_PDAT_Struct PDAT_Stu = {0};
	GUI_Struct Stu={0};
	uint8_t RESP_Code=0;
	
	memcpy(&V_LD1_Stu.Header[0],"GNFD",4);
	V_LD1_Stu.Length=1;
	V_LD1_Stu.DATA[0]=0|V_LD1_GNFD_PDAT;	
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] GNFD PDAT RESP: %d\n",RESP_Code);
	
	V_LD1_Stu=Read_V_LD1_Stu();
	
	if (V_LD1_Stu.Header[0]=='P' && V_LD1_Stu.Header[1]=='D' && V_LD1_Stu.Header[2]=='A' && V_LD1_Stu.Header[3]=='T' && V_LD1_Stu.Length==6)
	{
		memcpy(&PDAT_Stu,&V_LD1_Stu.DATA[0],6);
		printf("[INFO] PDAT: %f %d\n",PDAT_Stu.Distance,PDAT_Stu.Magnitude_Of_Target);
		Stu.COM=0x00;
		Stu.BCNT[0]=0;
		Stu.BCNT[1]=6;
		memcpy(&Stu.DATA[0],&PDAT_Stu,6);
		GUI_Slave_Send(Stu);
	}
}

void Init_Radar_Parameter(void)
{
	V_LD1_Radar_Parameter_Global.Distance_Range=0;
	V_LD1_Radar_Parameter_Global.Threshold_Offset=60;
	V_LD1_Radar_Parameter_Global.Min_Range_Filter=5;
	V_LD1_Radar_Parameter_Global.Max_Range_Filter=460;
	V_LD1_Radar_Parameter_Global.Distance_Average_Count=5;
	V_LD1_Radar_Parameter_Global.Target_Filter=0;
	V_LD1_Radar_Parameter_Global.Distance_Precision=1;
	V_LD1_Radar_Parameter_Global.TX_Power=31;
	V_LD1_Radar_Parameter_Global.Chirp_Integration_Count=20;
	V_LD1_Radar_Parameter_Global.Short_Range_Distance_Filter=0;
}

void Init_V_LD1(void)
{
	V_LD1_Struct V_LD1_Stu={0};
	V_LD1_RxBit=0;
	V_LD1_Status=0;
	V_LD1_RxFlag=0;
	
	uint8_t RESP_Code=0;
	memset(V_LD1_RxBuffer,0,sizeof(V_LD1_RxBuffer));
	
	memcpy(&V_LD1_Stu.Header[0],"RFSE",4);
	V_LD1_Stu.Length=0;
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] RFSE RESP: %d\n",RESP_Code);
	
	memcpy(&V_LD1_Stu.Header[0],"INIT",4);
	V_LD1_Stu.Length=1;
	V_LD1_Stu.DATA[0]=0;	
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] INIT RESP: %d\n",RESP_Code);
	
	if(RESP_Code==V_LD1_RESP_OK)
	{
		if(Read_V_LD1_VERS(&V_LD1_Stu)==0)
		{
			printf("[INFO] V_LD1_Version: %s\n",V_LD1_Stu.DATA);
			memcpy(&V_LD1_Radar_Parameter_Global.Version[0],&V_LD1_Stu.DATA[0],19);
		}
	}
	
	memcpy(&V_LD1_Stu.Header[0],"TGFI",4);
	V_LD1_Stu.Length=1;	
	V_LD1_Stu.DATA[0]=0	;
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] TGFI RESP: %d\n",RESP_Code);
	
	memcpy(&V_LD1_Stu.Header[0],"INTN",4);
	V_LD1_Stu.Length=1;	
	V_LD1_Stu.DATA[0]=20;
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] INTN RESP: %d\n",RESP_Code);
	
	memcpy(&V_LD1_Stu.Header[0],"SRDF",4);
	V_LD1_Stu.Length=1;	
	V_LD1_Stu.DATA[0]=0;
	Send_V_LD1_Stu(V_LD1_Stu);
	RESP_Code=Read_V_LD1_RESP();
	printf("[INFO] SRDF RESP: %d\n",RESP_Code);
	
	Read_V_LD1_Radar();	
}

运行效果

在这里插入图片描述

附录:压缩字符串、大小端格式转换

压缩字符串

首先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;
}


大小端转换

在串口等数据解析中 难免遇到大小端格式问题

什么是大端和小端

所谓的大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

所谓的小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

简单来说:大端——高尾端,小端——低尾端

举个例子,比如数字 0x12 34 56 78在内存中的表示形式为:

1)大端模式:

低地址 -----------------> 高地址

0x12 | 0x34 | 0x56 | 0x78

2)小端模式:

低地址 ------------------> 高地址

0x78 | 0x56 | 0x34 | 0x12

可见,大端模式和字符串的存储模式类似。

数据传输中的大小端

比如地址位、起止位一般都是大端格式
如:
起始位:0x520A
则发送的buf应为{0x52,0x0A}

而数据位一般是小端格式(单字节无大小端之分)
如:
一个16位的数据发送出来为{0x52,0x0A}
则对应的uint16_t类型数为: 0x0A52

而对于浮点数4.0f 转为32位应是:
40 80 00 00

以大端存储来说 发送出来的buf就是依次发送 40 80 00 00

以小端存储来说 则发送 00 00 80 40

由于memcpy等函数 是按字节地址进行复制 其复制的格式为小端格式 所以当数据为小端存储时 不用进行大小端转换
如:

uint32_t dat=0;
uint8_t buf[]={0x00,0x00,0x80,0x40};
   memcpy(&dat,buf,4);
   float f=0.0f;
   f=*((float*)&dat); //地址强转
   printf("%f",f);

或更优解:

   uint8_t buf[]={0x00,0x00,0x80,0x40};   
   float f=0.0f;
   memcpy(&f,buf,4);

而对于大端存储的数据(如HART协议数据 全为大端格式) 其复制的格式仍然为小端格式 所以当数据为小端存储时 要进行大小端转换
如:

uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};
   memcpy(&dat,buf,4);
   float f=0.0f;
   swap32(&dat); //大小端转换
   f=*((float*)&dat); //地址强转
   printf("%f",f);

或:

uint8_t buf[]={0x40,0x80,0x00,0x00};
   memcpy(&dat,buf,4);
   float f=0.0f;
   swap32(&f); //大小端转换
   printf("%f",f);

或更优解:

uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};
   float f=0.0f;
   dat=(buf[0]<<24)|(buf[0]<<16)|(buf[0]<<8)|(buf[0]<<0)
   f=*((float*)&dat);

总结

固 若数据为小端格式 则可以直接用memcpy函数进行转换 否则通过移位的方式再进行地址强转

对于多位数据 比如同时传两个浮点数 则可以定义结构体之后进行memcpy复制(数据为小端格式)

对于小端数据 直接用memcpy写入即可 若是浮点数 也不用再进行强转

对于大端数据 如果不嫌麻烦 或想使代码更加简洁(但执行效率会降低) 也可以先用memcpy写入结构体之后再调用大小端转换函数 但这里需要注意的是 结构体必须全为无符号整型 浮点型只能在大小端转换写入之后再次强转 若结构体内采用浮点型 则需要强转两次

所以对于大端数据 推荐通过移位的方式来进行赋值 然后再进行个别数的强转 再往通用结构体进行写入

多个不同变量大小的结构体 要主要字节对齐的问题
可以用#pragma pack(1) 使其对齐为1
但会影响效率

大小端转换函数

直接通过对地址的操作来实现 传入的变量为32位的变量
中间变量ptr是传入变量的地址

void swap16(void * p)
{
   uint16_t *ptr=p;
   uint16_t x = *ptr;
   x = (x << 8) | (x >> 8);

   *ptr=x;
}

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;
}

void swap64(void * p)
{
   uint64_t *ptr=p;
   uint64_t x = *ptr;
   x = (x << 32) | (x >> 32);
   x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF0000FFFF);
   x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF00FF00FF);

   *ptr=x;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据知识图谱项目——基于知识图谱的电影问答系统(超详细讲解及源码)

大数据知识图谱项目——基于知识图谱的电影问答系统&#xff08;超详细讲解及源码&#xff09; 一、项目概述 知识图谱是将知识连接起来形成的一个网络。由节点和边组成&#xff0c;节点是实体&#xff0c;边是两个实体的关系&#xff0c;节点和边都可以有属性。知识图谱除了…

【物联网】BDS/GNSS 全星座定位导航模块——ATGM332D-5N

随着科技的不断进步&#xff0c;导航系统已经成为我们日常生活中不可或缺的一部分。传统的导航系统往往只提供基本的地图和路线规划&#xff0c;对于一些特殊需求或个性化定位并不够满足。全星座定位导航模块的出现&#xff0c;为我们带来了全新的导航体验。通过结合星座学说和…

【Liunx】部署WEB服务:Apache

【Liunx】部署WEB服务:Apache 概述Apache1.介绍2.Apache文件路径3.Apache详解(1)安装Apache(2)启动Apache(3)配置文件a.Apache主配置文件&#xff1a;vim /etc/httpd/conf/httpd.conf信息&#xff1a;b.基于主机头的虚拟主机 (4)开始演示&#xff1a;a.新建两个网站根目录b.分别…

JavaScript从入门到精通系列第三十七篇:详解JavaScript中文档的加载顺序

文章目录 一&#xff1a;文档加载说明 1&#xff1a;回顾一个代码 2&#xff1a;问题分析和说明 二&#xff1a;如何给JS换个位置&#xff1f; 1&#xff1a;过程分析 2&#xff1a;代码编写 3&#xff1a;运行结果 4&#xff1a;解释说明 大神链接&#xff1a;作者有幸…

Python机器学习、深度学习提升气象、海洋、水文领域实践应用

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;能够在不同操作系统和平台使用&#xff0c;简洁的语法和解释性语言使其成为理想的脚本语言。除了标准库&#xff0c;还有丰富的第三方库&#xff0c;Python在数据处理、科学计算、数学建模、数据挖…

Latex在图表标题里面引用参考文献时,出现参考文献顺序混乱的解决方案(适用于bibtex)

问题描述 如果你在figure环境的\caption或\captionof中使用\cite&#xff0c;但是参考文献的顺序仍然不正确&#xff0c;可能是因为LaTeX的处理流程导致了这个问题。 比如图片在第二章节但里面引用了参考文献&#xff0c;在文章末尾的参考文献第二章图片的参考文献顺序&#…

微服务基础,分布式核心,常见微服务矿建,SpringCloud概述,搭建SpringCloud微服务项目详细步骤,含源代码

微服务基础 系统架构的演变 随着会联网的发展&#xff0c;网站应用的规模不断扩大&#xff0c;常规的应用架构已经无法应对&#xff0c;分布式服务架构以及微服务架构势在必行&#xff0c;必须一个治理系统确保架构有条不紊的演进 单体应用框架 Web应用程序发展的早期&…

如何把小米路由器刷入OpenWRT系统并通过内网穿透工具实现公网远程访问

小米路由器4A千兆版刷入OpenWRT并远程访问 文章目录 小米路由器4A千兆版刷入OpenWRT并远程访问前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理…

【机器学习】决策树算法理论:算法原理、信息熵、信息增益、预剪枝、后剪枝、算法选择

1. 决策树概念 通过不断的划分条件来进行分类&#xff0c;决策树最关键的是找出那些对结果影响最大的条件&#xff0c;放到前面。 我举个列子来帮助大家理解&#xff0c;我现在给我女儿介绍了一个相亲对象&#xff0c;她根据下面这张决策树图来进行选择。比如年龄是女儿择偶更…

vim批量多行缩进调整

网上其他教程&#xff1a; ctrl v 或者 v进行visual模式按方向键<&#xff0c;>调整光标位置选中缩进的行Shift > &#xff08;或者 Shift < &#xff09;进行左右缩进。 我只想说&#xff0c;乱七八糟&#xff0c;根本不管用 本文教程&#xff1a; 增加缩进…

Outlook关闭过去事件的提醒

Outlook关闭过去事件的提醒 故障现象 最近Outlook中推出的新功能让我们可以选择自动关闭过去事件的提醒。 目前这个功能暂时只向当月通道的Office 365 订阅者发布。 这些用户升级到1810版本后&#xff0c;可以在不想收到已发生事件提醒的时候通过下面的步骤自动忽略过去事件…

AIGC ChatGPT4 生成Python可视化分析

使用Python进行数据分析,代码可以通过ChatGPT4来完成。 例如Prompt: 产品 销量 P1 48 P2 53 P3 82 P4 57 P5 89 P6 86 P7 30 P8 79 P9 96 将上述数据用Python通过可视化的图表来进行展示 完整代码如下: import matplotlib.pyplot as pltpr…

神经网络中的量化与蒸馏

本文将深入研究深度学习中精简模型的技术&#xff1a;量化和蒸馏 深度学习模型&#xff0c;特别是那些具有大量参数的模型&#xff0c;在资源受限环境中的部署几乎是不可能的。所以就出现了两种流行的技术&#xff0c;量化和蒸馏&#xff0c;它们都是可以使模型更加轻量级&…

视频推拉流EasyDSS直播点播平台获取指定时间快照的实现方法

视频推拉流直播点播系统EasyDSS平台&#xff0c;可提供流畅的视频直播、点播、视频推拉流、转码、管理、分发、录像、检索、时移回看等功能&#xff0c;可兼容多操作系统&#xff0c;在直播点播领域具有广泛的场景应用。为了便于用户集成、调用与二次开发。 今天我们来介绍下在…

C 语言实现 UDP

广播 发送广播信息&#xff0c;局域网中的客户端都可以接受该信息 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h>int main() {// 1.创建一个通信的socketint fd socket(PF_INET, …

RabbitMQ之消息应答和持久化

文章目录 前言一、消息应答1.概念2.自动应答3.消息应答方法4.Multiple 的解释5.消息自动重新入队6.消息手动应答代码7.手动应答效果演示 二、RabbitMQ持久化1.概念2.队列如何实现持久化3.消息实现持久化4.不公平分发5.预取值 总结 前言 在RabbitMQ中&#xff0c;我们的消费者在…

核心!华为自研系统鸿蒙趋势

鸿蒙系统的推出引起了全球的关注&#xff0c;毕竟这是华为自主研发的操作系统。这个系统有一些特点很独特。首先&#xff0c;它的自主可控性是一大特色。因为是自家研发的&#xff0c;所以更容易适应外界变化。其次&#xff0c;它采用了分布式架构&#xff0c;这样不同设备之间…

三大开源向量数据库大比拼

向量数据库具有一系列广泛的好处&#xff0c;特别是在生成式人工智能方面&#xff0c;更具体地说&#xff0c;是在大语言模型&#xff08;LLM&#xff09;方面。这些好处包括先进的索引和精确的相似度搜索&#xff0c;有助于交付强大的先进项目。 本文将对三种开源向量数据库&…

Linux 关闭对应端口号进程

查看当前的端口号是否在运行 找出端口号端口号进程 netstat -anp | grep 9000 关闭端口号 kill -9 [PID]

Actipro Software WPF Controls 23.1.3

Actipro Software WPF Controls v23.1.3 Actipro Software 为 Microsoft 提供软件组件和 .NET 平台。它位于克利夫兰&#xff0c;重点主要是提供高质量的用户界面软件组件以及客户的过程&#xff0c;以便他们有能力信任&#xff0c;以便为用户应用程序添加强大的功能。自 .NET…