BWS2000倾角传感器c++测试代码【2】

news2024/12/24 20:18:22

问题一:串口频率的初始化

由于本次项目之中使用的线长为40米的倾角传感器,需要对于其频率输出存在要求,如何测试其频率如下所示:

如上所示相应的软件,软件中存在一句如果设置后不保存,则存在传感器断电后设置还原。在实际设计接口的时候,发现这款软件即便是设置后进行了保存,如果连续开关断电时间过长,还是会存在断电还原的情况,因此,在测试代码之中需要写出对于初始状态的判断。
初始状态的时候,假设波特率为9600,当然也可能开始的时候已经设置为115200,

协议如下所示,首先需要设置为00应答模式,才可以需要重新设置串口的信息。

下面是对于初始波特率是否为9600进行判断,我这个地方是进行了8次判断,看看是否能够写入输出,如果不是重新设置为115200。

//默认为9600的时候,进行对话模式
	char command_R4[] = { 0x77, 0x05, 0x00, 0x0C, 0x00, 0x11 };
	if (!WriteFile(hSerial, command_R4, sizeof(command_R4), &bytesWritten4, NULL)) {
		std::cout << "Error writing to serial port." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}
	if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {
		std::cout << "Error reading from serial port." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}
	for (int i = 0; i < sizeof(dataReceived); i++) {
		printf("%02X ", dataReceived[i]);
	}


	bool exists = false; // 标志位,记录元素是否存在
	int falsecount = 0;
   // 循环遍历数组
	while (!exists) {
		for (int i = 0; i < sizeof(dataReceived); i++) {
			printf("%02X ", dataReceived[i]);
		}
		for (int i = 0; i < sizeof(dataReceived); i++) {
			if (dataReceived[i] == 0xFFFFFF8C) {
				exists = true; // 元素存在,设置标志位为true
				std::cout << "应答模式配置成功!" << std::endl;
				//std::this_thread::sleep_for(std::chrono::milliseconds(400000));
				break; // 跳出for循环
			}
		}

		if (!exists) {
			falsecount++;
			if (falsecount >= 8)//说明原有配置是115200波特率
			{

				dcbSerialParams.BaudRate = CBR_115200;
				dcbSerialParams.ByteSize = 8;
				dcbSerialParams.StopBits = ONESTOPBIT;
				dcbSerialParams.Parity = NOPARITY;

				if (!SetCommState(hSerial, &dcbSerialParams)) {
					std::cout << "Error setting serial port state." << std::endl;
					CloseHandle(hSerial);
					return 1;
				}

				timeouts.ReadIntervalTimeout = 500;
				timeouts.ReadTotalTimeoutConstant = 500;
				timeouts.ReadTotalTimeoutMultiplier = 100;
				timeouts.WriteTotalTimeoutConstant = 500;
				timeouts.WriteTotalTimeoutMultiplier = 100;

				if (!SetCommTimeouts(hSerial, &timeouts))
				{
					std::cout << "Error setting timeouts." << std::endl;
					CloseHandle(hSerial);
					return 1;
				}

			}
			if (!WriteFile(hSerial, command_R4, sizeof(command_R4), &bytesWritten4, NULL)) {
				std::cout << "Error writing to serial port." << std::endl;
				CloseHandle(hSerial);
				return 1;
			}
			if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {
				std::cout << "Error reading from serial port." << std::endl;
				CloseHandle(hSerial);
				return 1;
			}
			std::cout << "元素不存在,继续执行某条语句..." << std::endl;
			// 可以在这里添加需要执行的语句
		}

	}

问题二:重复写入判断

上面代码为什么要进行反复的输入,判断输出的原因是因为在实际的测试的情况下,写入一次可能会出现返回数据不正确的情况,因此需要一个标志位去表明协议已经写入正确。

在给定的配套软件之中,设置的这个位置按钮就是进行协议的写入,但是按一次偶尔会出现没有生效,因此,这个地方进行反复判断功能。

问题三:自动输出的判断

一个准确的报文帧数据应该是如下所示:

正常的报文帧数据应该是0x77 0x10 0x00 0xFFFF84开头,一个数据的大小是17bytes,
那就以一个实际的案例进行读出,设置波特率为115200,应答模式为100Hz输出。

可以见到并不是0x77 0x10 0x00 0xFFFF84开头,原因在于当设置完成自动输出模式之后,其将返回的帧数据与角度数据结合到了一起。

可以见到返回数据帧的大小为6bytes,因此这个地方需要将返回数据帧大小设置为6bytes+17bytes = 23bytes。

读取数据是从6 + 5  = 11byte开始读取。也就是FFFFFF84后面的一位开始读取。也就是response_R[11-1]位开始读取。

进行输出

可以见到数据正常。

问题四:自动输出的频率如何判断

一开始我是想要在页面上写一个读写的功能进行频率的输出,但是存在问题,发现写一帧然后读一帧的数据是非常慢的,因为BWS2000系列倾角传感器是半双工的倾角传感器,不建议那样用,但是我看给的官方软件上存在这样一句话:
 

我不是特别的理解,既然是半双工的倾角传感器,自动输出模式不是更好一些吗????但是我还是用自动输出模式吧。

注意:设置好之后,不能够直接进行读取,否则会出现问题,也就是出现频率不正确。

原因是因为设置好之后,传感器并不是处于稳定的状态,导致读出频率与设置频率不一致,在采集之前需要加入一个延时函数:

然后在代码之中,通过对比前后输出的时间差别,查看是否输出的频率正确。

可以见到是正确的,也就是说倾角传感器40米线长的情况下,115200波特率的情况下,可以正常输出,打完收工,接下来就是设计线程的过程。

测试代码如下所示:

#include <Windows.h>

#include <iostream>
#include <iomanip>
#include <iostream>
#include <chrono>
#include <thread>
#include <iostream>
#include <iomanip> 
#include <iostream>
#include <sstream> 
#include <iomanip>
double convertStringToDouble(const std::string& str) {
	double result;
	std::istringstream stream(str);
	stream >> result;
	return result;
}
int main() {
	HANDLE hSerial;
	DCB dcbSerialParams = { 0 };
	COMMTIMEOUTS timeouts = { 0 };
	DWORD bytesRead, bytesRead1, bytesWritten, bytesWritten1, bytesWritten2, bytesWritten3, bytesWritten4, bytesWritten5, response_R1;
	char command_R[] = { 0x77, 0x04, 0x00, 0x04, 0x08 };//读X、Y轴角度 发送命令: 77 04 00 04 08
	char response_R[23];
	double Sensor_Angle_RX0;
	double Sensor_Angle_RY0;


	char dataReceived[20];
	wchar_t portName[] = L"\\\\.\\COM10"; // Note the 'L' before the string
	hSerial = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if (hSerial == INVALID_HANDLE_VALUE) {
		if (GetLastError() == ERROR_FILE_NOT_FOUND) {
			std::cout << "Serial port not available." << std::endl;
		}
		return 1;
	}
	
	dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

	if (!GetCommState(hSerial, &dcbSerialParams)) {
		std::cout << "Error getting serial port state." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}

	dcbSerialParams.BaudRate = CBR_9600;
	dcbSerialParams.ByteSize = 8;
	dcbSerialParams.StopBits = ONESTOPBIT;
	dcbSerialParams.Parity = NOPARITY;

	if (!SetCommState(hSerial, &dcbSerialParams)) {
		std::cout << "Error setting serial port state." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}

	timeouts.ReadIntervalTimeout = 500;
	timeouts.ReadTotalTimeoutConstant = 500;
	timeouts.ReadTotalTimeoutMultiplier = 100;
	timeouts.WriteTotalTimeoutConstant = 500;
	timeouts.WriteTotalTimeoutMultiplier = 100;

	if (!SetCommTimeouts(hSerial, &timeouts))
	{
		std::cout << "Error setting timeouts." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}

	//默认为9600的时候,进行对话模式
	char command_R4[] = { 0x77, 0x05, 0x00, 0x0C, 0x00, 0x11 };
	if (!WriteFile(hSerial, command_R4, sizeof(command_R4), &bytesWritten4, NULL)) {
		std::cout << "Error writing to serial port." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}
	if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {
		std::cout << "Error reading from serial port." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}
	for (int i = 0; i < sizeof(dataReceived); i++) {
		printf("%02X ", dataReceived[i]);
	}


	bool exists = false; // 标志位,记录元素是否存在
	int falsecount = 0;
	// 循环遍历数组
	while (!exists) {
		for (int i = 0; i < sizeof(dataReceived); i++) {
			printf("%02X ", dataReceived[i]);
		}
		for (int i = 0; i < sizeof(dataReceived); i++) {
			if (dataReceived[i] == 0xFFFFFF8C) {
				exists = true; // 元素存在,设置标志位为true
				std::cout << "应答模式配置成功!" << std::endl;
				//std::this_thread::sleep_for(std::chrono::milliseconds(400000));
				break; // 跳出for循环
			}
		}

		if (!exists) {
			falsecount++;
			if (falsecount >= 8)//说明原有配置是115200波特率
			{

				dcbSerialParams.BaudRate = CBR_115200;
				dcbSerialParams.ByteSize = 8;
				dcbSerialParams.StopBits = ONESTOPBIT;
				dcbSerialParams.Parity = NOPARITY;

				if (!SetCommState(hSerial, &dcbSerialParams)) {
					std::cout << "Error setting serial port state." << std::endl;
					CloseHandle(hSerial);
					return 1;
				}

				timeouts.ReadIntervalTimeout = 500;
				timeouts.ReadTotalTimeoutConstant = 500;
				timeouts.ReadTotalTimeoutMultiplier = 100;
				timeouts.WriteTotalTimeoutConstant = 500;
				timeouts.WriteTotalTimeoutMultiplier = 100;

				if (!SetCommTimeouts(hSerial, &timeouts))
				{
					std::cout << "Error setting timeouts." << std::endl;
					CloseHandle(hSerial);
					return 1;
				}

			}
			if (!WriteFile(hSerial, command_R4, sizeof(command_R4), &bytesWritten4, NULL)) {
				std::cout << "Error writing to serial port." << std::endl;
				CloseHandle(hSerial);
				return 1;
			}
			if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {
				std::cout << "Error reading from serial port." << std::endl;
				CloseHandle(hSerial);
				return 1;
			}
			std::cout << "元素不存在,继续执行某条语句..." << std::endl;
			// 可以在这里添加需要执行的语句
		}

	}

	//设置频率为115200
	char command_R1[] = { 0x77, 0x05, 0x00, 0x0B, 0x04, 0x14 };//115200
	if (!WriteFile(hSerial, command_R1, sizeof(command_R1), &bytesWritten1, NULL))
	{
		std::cout << "Error writing to serial port." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}
	if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL))
	{
		std::cout << "Error reading from serial port." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}
	exists = false;
	while (!exists)
	{
		for (int i = 0; i < sizeof(dataReceived); i++) {
			printf("%02X ", dataReceived[i]);
		}
		for (int i = 0; i < sizeof(dataReceived); i++) {
			if (dataReceived[i] == 0xFFFFFF8B) {//设置成功
				exists = true; // 元素存在,设置标志位为true
				std::cout << "115200波特率配置成功!" << std::endl;
				break; // 跳出for循环
			}
		}

		if (!exists) {
			if (!WriteFile(hSerial, command_R1, sizeof(command_R1), &bytesWritten1, NULL)) {
				std::cout << "Error writing to serial port." << std::endl;
				CloseHandle(hSerial);
				return 1;
			}
			if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {
				std::cout << "Error reading from serial port." << std::endl;
				CloseHandle(hSerial);
				return 1;
			}
			std::cout << "元素不存在,继续执行某条语句..." << std::endl;
			// 可以在这里添加需要执行的语句
		}

	}

	//00-11:应答模式 05-50Hz 04-25Hz
	//06-100     05-50     04-25    
	char command_R3[] = { 0x77, 0x05, 0x00, 0x0C, 0x06, 0x17 };//50Hz
	if (!WriteFile(hSerial, command_R3, sizeof(command_R3), &bytesWritten3, NULL)) {
		std::cout << "Error writing to serial port." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}
	if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {
		std::cout << "Error reading from serial port." << std::endl;
		CloseHandle(hSerial);
		return 1;
	}
	for (int i = 0; i < sizeof(dataReceived); i++) {
		printf("%02X ", dataReceived[i]);
	}
	exists = false;
	while (!exists) {
		for (int i = 0; i < sizeof(dataReceived); i++) {
			printf("%02X ", dataReceived[i]);
		}
		for (int i = 0; i < sizeof(dataReceived); i++) {
			if (dataReceived[i] == 0xFFFFFF8C) {//设置成功
				exists = true; // 元素存在,设置标志位为true
				std::cout << "50Hz配置成功!" << std::endl;
				break; // 跳出for循环
			}
		}

		if (!exists) {
			if (!WriteFile(hSerial, command_R3, sizeof(command_R3), &bytesWritten3, NULL)) {
				std::cout << "Error writing to serial port." << std::endl;
				CloseHandle(hSerial);
				return 1;
			}
			if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {
				std::cout << "Error reading from serial port." << std::endl;
				CloseHandle(hSerial);
				return 1;
			}
			std::cout << "元素不存在,继续执行某条语句..." << std::endl;
			// 可以在这里添加需要执行的语句
		}

	}

	//std::this_thread::sleep_for(std::chrono::milliseconds(400000));

	std::cout << "波特率:" << dcbSerialParams.BaudRate << std::endl;

	// 设置角度输出频率模式  77 05 00 0C 06(100Hz 05 50Hz 04 25Hz) 11 100Hz 


	std::cout << " " << std::endl;
	std::cout << "开始采集 " << std::endl;
	int i = 0;

	const int interval = 10;

	while (1)
	{
		auto startTime = std::chrono::high_resolution_clock::now();
		if (!ReadFile(hSerial, response_R, sizeof(response_R), &response_R1, NULL)) {
			std::cout << "Error reading from serial port." << std::endl;
			CloseHandle(hSerial);
			return 1;
		}

		for (int i = 0; i < sizeof(dataReceived); i++) {
			printf("%02X ", dataReceived[i]);
		}
		std::cout << "" << std::endl;

		int flag;
		for (int i = 0; i < sizeof(response_R); i++) {
			if (dataReceived[i] == 0x77 && dataReceived[i + 1] == 0x10 && dataReceived[i + 2] == 0x00 && dataReceived[i + 3] == 0xFFFFFF84)
			{
				flag = i;
				break;
			}
		}

		//x轴
			// Given hexadecimal values
		int hexValues[] = { dataReceived[flag + 5] & 0xFF, dataReceived[flag + 6] & 0xFF, dataReceived[flag + 7] & 0xFF };
		int hexValues1[] = { dataReceived[flag + 9] & 0xFF, dataReceived[flag + 10] & 0xFF, dataReceived[flag + 11] & 0xFF };
		int numValues = sizeof(hexValues) / sizeof(hexValues[0]);
	
		std::stringstream ss;
		ss << std::setfill('0') << std::setw(2) << std::hex << hexValues[0];
		
		for (int i = 1; i < numValues; i++) {
			ss << "." << std::setw(2) << std::hex << hexValues[i];
		}
		std::string resultString = ss.str();
		
		std::string inputString = resultString;
		std::string outputString;
		size_t firstDotIndex = inputString.find('.');
		size_t secondDotIndex = inputString.find('.', firstDotIndex + 1);
		if (firstDotIndex != std::string::npos && secondDotIndex != std::string::npos) {
			outputString = inputString.substr(0, secondDotIndex) + inputString.substr(secondDotIndex + 1);
		}
		else {
			outputString = inputString;
		}
		
		double resultDouble = std::stod(outputString);
		if (dataReceived[flag + 4] == 0x00)
		{
			Sensor_Angle_RX0 = resultDouble;
		}
		else
		{
			Sensor_Angle_RX0 = -resultDouble;
		}
		std::cout << "x轴角度" << Sensor_Angle_RX0 << std::endl;



		//Y轴
		int numValues1 = sizeof(hexValues1) / sizeof(hexValues1[0]);

		std::stringstream ss1;
		ss1 << std::setfill('0') << std::setw(2) << std::hex << hexValues1[0];
	
		for (int i = 1; i < numValues1; i++) {
			ss1 << "." << std::setw(2) << std::hex << hexValues1[i];
		}
		std::string resultString1 = ss1.str();
		
		std::string inputString1 = resultString1;
		std::string outputString1;
		size_t firstDotIndex1 = inputString1.find('.');
		size_t secondDotIndex1 = inputString1.find('.', firstDotIndex1 + 1);
		if (firstDotIndex1 != std::string::npos && secondDotIndex1 != std::string::npos) {
			outputString1 = inputString1.substr(0, secondDotIndex1) + inputString1.substr(secondDotIndex1 + 1);
		}
		else {
			outputString1 = inputString1;
		}
		double resultDouble1 = std::stod(outputString1);
		if (dataReceived[flag + 8] == 0x00)
		{

			Sensor_Angle_RY0 = resultDouble1;
		}
		else
		{
			Sensor_Angle_RY0 = -resultDouble1;
		}
		std::cout << "y轴: " << Sensor_Angle_RY0 << std::endl;
		

		// 计算执行代码所花费的时间
		auto endTime = std::chrono::high_resolution_clock::now();
		auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);

		// 计算需要延迟的时间
		int delay = interval - duration.count();
		//std::cout << delay << std::endl;
		if (delay == interval)
		{
			std::cout << "频率正确" << std::endl;
		}
		else if (delay > 0) {
			// 延迟执行
			std::this_thread::sleep_for(std::chrono::milliseconds(delay));
			std::cout << "频率正确" << std::endl;
		}
		else if (delay < 0)
		{
			std::cout << "时间不够:(ms)***************************************:" << duration.count() << std::endl;
		}
	}
		getchar();
		CloseHandle(hSerial);
		return 0;
	
}




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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

众和策略:大盘涨手中的股票却大跌,到底怎么回事?

大盘涨手中的股票却大跌&#xff0c;究竟怎么回事&#xff1a; 1、大盘上涨是权重股所造成的 大盘上涨可能是受一些权重比较大的工作所影响&#xff0c;比如证券工作、钢铁工作、银行工作等等&#xff0c;这些工作的大涨&#xff0c;可以拉升大盘的上涨&#xff0c;可是其它工…

C++20形式的utf-8字符串转宽字符串,不依赖编译器编码形式

默认的char[]编码都是要看编译器编译选项的&#xff0c;你选了ANSI那它就是ANSI&#xff0c;你选了UTF8那它就是UTF8. 【注意&#xff1a;经典DevC只支持ANSI编码&#xff08;痛苦&#xff09;&#xff1b;上图是小熊猫DevC&#xff0c;则有这个选项】 这一点对我的代码造成了…

20231220将NanoPC-T4(RK3399)开发板的Android10的SDK按照Rockchip官方挖掘机开发板编译打包刷机之后启动跑飞

20231220将NanoPC-T4(RK3399)开发板的Android10的SDK按照Rockchip官方挖掘机开发板编译打包刷机之后启动跑飞 2023/12/20 17:19 简略步骤&#xff1a;rootrootrootroot-X99-Turbo:~/3TB$ tar --use-compress-programpigz -xvpf rk3399-android-10.git-20210201.tgz rootrootro…

Poi实现复杂Excel导出,理解POI操作Excel思路!!!

前言 对于简单excel报表导出&#xff0c;有很多简单的工具如easypoi&#xff0c;而且现在网上已经有很多工具类整合easypoi使用起来非常方便。但是简单的弊端往往无法适配一些负责场景&#xff0c;而我们实际生产中面临的都是客户自定以的一个负责报表导出&#xff0c;这是利用…

【RTOS学习】源码分析(信号量和互斥量 事件组 任务通知)

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《RTOS学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f353;信号量和互斥量&#x1f345;创建&#x1f345;Take&#x1f345;Give &#x…

百川大模型AI对话实战——Python开发一个对话机器人

百川大模型开放提供API体验中心&#xff0c;体验不错&#xff0c;有小伙伴也对搭建自己的对话机器人比较兴趣&#xff0c;今天通过Python来简单介绍下&#xff0c;如何调用百川大模型的API来构建自己的小产品。 在开发环境中安装Python&#xff0c;如何安装&#xff1f;参照网…

(附源码)基于Springboot框架的网络投票系统 计算机毕设42855

基于springboot网络投票系统 摘 要 随着全球Internet的迅猛发展和计算机应用的普及&#xff0c;特别是近几年无线网络的广阔覆盖以及无线终端设备的爆炸式增长&#xff0c;使得人们能够随时随地的访问网络&#xff0c;以获取最新信息、参与网络活动、和他人在线互动。为了能及时…

Python Pandas 多重索引DataFrame数据(第19讲)

Python Pandas 多重索引DataFrame数据(第19讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

VScode安装C/C++编译器步骤

一、安装C/C插件 二、安装 MinGW-w64 工具链 使用国内源 git clone https://gitee.com/cuihongxi/ubuntu2-mac.git 下载后进入到VScode文件夹下&#xff0c;点击msys2-x86_64-20231026.exe进行安装 完成后&#xff0c;确保选中“立即运行 MSYS2”框&#xff0c;然后选择“完…

董事长陈小华辞职,上市一年半的快狗打车让奇瑞亏掉3.5亿元

近年来&#xff0c;即时货运行业以高速高效的优势&#xff0c;在头部电商的带动下迎来了新一波的流量红利。然而诞生于“58系”的同城货运平台快狗打车&#xff08;HK:02246&#xff09;却起了个大早&#xff0c;赶了个晚集。 12月19日&#xff0c;快狗打车发布公告称&#xf…

本地MinIO存储服务如何创建Buckets并实现公网访问上传文件

文章目录 前言1. 创建Buckets和Access Keys2. Linux 安装Cpolar3. 创建连接MinIO服务公网地址4. 远程调用MinIO服务小结5. 固定连接TCP公网地址6. 固定地址连接测试 前言 MinIO是一款高性能、分布式的对象存储系统&#xff0c;它可以100%的运行在标准硬件上&#xff0c;即X86等…

A股风格因子看板 (2023.12第13期)

该因子看板跟踪A股风格因子&#xff0c;该因子主要解释沪深两市的市场收益、刻画市场风格趋势的系列风格因子&#xff0c;用以分析市场风格切换、组合风格暴 露等。 今日为该因子跟踪第13期&#xff0c;指数组合数据截止日2023-11-30&#xff0c;要点如下 近1年A股风格因子检验…

Actuator内存泄露及利用Swagger未授权自动化测试实现

目录 0x00 前言 0x01 Actuator 泄露及利用 1、Actuator heapdump 内存泄露 2、知道泄露后如何进一步利用 3、如何发现 Actuator 泄露&#xff08;白盒/黑盒&#xff09; 0x02 Swagger自动化测试 1、什么是Swagger&#xff1f; 2、PostmanBurpSuiteXray 联动 3、思考 0x…

【昆明*线上同步】最新ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作

详情点击查看福利&#xff1a;【昆明*线上同步】最新ChatGPT/GPT4科研实践应用与AI绘图技术及论文高效写作 目标&#xff1a; 1、熟练掌握ChatGPT提示词技巧及各种应用方法&#xff0c;并成为工作中的助手。 2、通过案例掌握ChatGPT撰写、修改论文及工作报告&#xff0c;提供…

SparkSQL的编程模型(DataFrame和DataSet)

1.2 SparkSQL的编程模型(DataFrame和DataSet) 1.2.1 编程模型简介 主要通过两种方式操作SparkSQL&#xff0c;一种就是SQL&#xff0c;另一种为DataFrame和Dataset。 SQL SQL不用多说&#xff0c;就和Hive操作一样&#xff0c;但是需要清楚一点的时候&#xff0c;SQL操作的是…

助老理发,寒冬送暖从头开始

为进一步弘扬尊老、敬老、爱老、助老的中华民族传统美德&#xff0c;解决老年人年龄大、冬季出行不便的问题&#xff0c;2023年12月20日&#xff0c;绿萝志愿服务队在翠堤社区开展了“助老理发”志愿活动。 大雪过后天气格外寒冷&#xff0c;但志愿者们依旧早早的来现场做…

Ethernet/IP 之IO 连接简要记录

IO连接 EIP的IO连接提供了在一个生产者和多个消费者之间的特定的通信路径&#xff0c;以达到IO数据在IO连接下传输。 生产者对象产生IO数据通过生产者IO连接管理者对象将连接ID和数据组帧发送给消费者IO连接管理者对象然后将IO数据发送给消费者对象。 显示消息连接 显式消息传…

Seata中AT模式的实现原理03-二阶段提交

全局事务提交 TM提交全局事务 当业务正常处理完毕后 本地事务全部提交完成&#xff0c;TM会将xid提交给TC&#xff0c;TC会返回当前事务状态&#xff0c;status由TC决定&#xff0c;TM最后会将xid从RootContext中解绑&#xff0c;全局事务结束。 TransactionalTemplate priva…

序列化类的高级用法

1.3.3 模型类序列化器 如果我们想要使用序列化器对应的是Django的模型类&#xff0c;DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。 ModelSerializer与常规的Serializer相同&#xff0c;但提供了&#xff1a; 基于模型类自动生成一系列…

ansible的playbook

1、playbook的组成部分 &#xff08;1&#xff09;task任务&#xff1a;在目标主机上执行的操作&#xff0c;使用模块定义这些操作&#xff0c;每个任务都是一个模块的调用 &#xff08;2&#xff09;variables变量&#xff1a;存储和传递数据&#xff08;变量可以自定义&…