BWS2000倾角传感器c++测试代码_时间延迟与时间同步问题【3】

详见昨天做的测试代码,代码网址:
BWS2000倾角传感器c++测试代码【2】-CSDN博客文章浏览阅读268次,点赞7次,收藏8次。倾角传感器测试与编写思路https://blog.csdn.net/m0_47489229/article/details/135128748

问题一:新的问题出现---存在时间延缓的问题

昨天的代码今天打开之后,再进行测试出现了一个问题,就是当移动倾角传感器之后,可以见到传感器显示的数值变化是比实际慢很多的,可以明显看出来。

由于昨天的代码存在相应的时间延迟,不方便后面进行传感器的时间同步。我的思路是搞个多线程

由于倾角传感器存在时间延迟的问题,但是厂家给出的软件之中并不存在时间延迟的问题。所以为了解决这个问题我的想法是创建一个线程,进行实时处理传输的接口信息,对于通信接口进行连接判断。连接的瞬间就进行数据处理。

写个测试案例:
首先创建一个线程,实时监督接口与进行数据处理:


void sensorThread()
{std::cout << " " << std::endl;std::cout << "开始采集 " << std::endl;int i = 0;while (1){ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL);auto startTime = std::chrono::high_resolution_clock::now();for (int i = 0; i < sizeof(dataReceived); i++) {printf("%02X ", dataReceived[i]);}bool flag1 = false;int flag;for (int i = 0; i < sizeof(dataReceived); i++) {if (dataReceived[i] == 0x77 && dataReceived[i + 1] == 0x10 && dataReceived[i + 2] == 0x00 && dataReceived[i + 3] == 0xFFFFFF84){flag1 = true;flag = i;break;}}std::cout << "" << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(4000));if (flag1 == true){//x轴// Given hexadecimal valuesint 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)***************************************:" << delay << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(200000000));}}}//std::this_thread::sleep_for(std::chrono::milliseconds(2000));}

在主函数函数之中对于接口进行初步的数据处理:


int main()
{// 创建传感器数据读取线程std::thread sensorThreadObj(sensorThread);//CString str123 = strValue1;//CString strA("COM10");//CString strB("\\\\.\\");//strB += strA;//const char* portName = strB.GetString();//strB.ReleaseBuffer();//strA.ReleaseBuffer();wchar_t portName[] = L"\\\\.\\COM10"; // Note the 'L' before the stringhSerial = CreateFile("\\\\.\\COM10", 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 << "第一次9600的对话模式配置失败" << std::endl;CloseHandle(hSerial);return 1;}if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {std::cout << "第一次9600的对话模式数据读取失败." << std::endl;CloseHandle(hSerial);return 1;}std::cout << "第一次初始波特率:" << dcbSerialParams.BaudRate << std::endl;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] == 0x77 && dataReceived[i + 3] == 0xFFFFFF8C) {exists = true; // 元素存在,设置标志位为truestd::cout << falsecount << std::endl;std::cout << "应答模式配置成功!" << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(400000));break; // 跳出for循环}}if (exists){break;}if (!exists) {falsecount++;if (falsecount >= 2)//说明原有配置是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 << "115200的对话模式配置失败." << std::endl;CloseHandle(hSerial);return 1;}if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {std::cout << "115200的对话模式回复失败." << std::endl;CloseHandle(hSerial);return 1;}}}//设置频率为115200char 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] == 0x77 && dataReceived[i + 3] == 0xFFFFFF8B) {//设置成功exists = true; // 元素存在,设置标志位为truestd::cout << "115200波特率配置成功!" << std::endl;break; // 跳出for循环}}if (exists){break;}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 << "重复配置115200波特率" << std::endl;// 可以在这里添加需要执行的语句std::this_thread::sleep_for(std::chrono::milliseconds(4000));}}//00-11:应答模式 05-50Hz 04-25Hz//06-100     05-50     04-25    char command_R3[] = { 0x77, 0x05, 0x00, 0x0C, 0x03, 0x14 };//50Hzif (!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] == 0x77 && dataReceived[i+3] == 0xFFFFFF8C) {//设置成功exists = true; // 元素存在,设置标志位为truestd::cout << "50Hz配置成功!" << std::endl;break; // 跳出for循环}}if (exists){break;}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;// 可以在这里添加需要执行的语句}}//sensorThreadObj.join();return 0;
}

完整代码段:

#include <Windows.h>#include <iostream>
#include <iomanip>
#include <iostream>
#include <chrono>
#include <thread>
#include <iostream>
#include <iomanip> 
#include <iostream>
#include <sstream> 
#include <iomanip>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[34];
double Sensor_Angle_RX0;
double Sensor_Angle_RY0;char dataReceived[34];
const int interval = 100;void sensorThread()
{std::cout << " " << std::endl;std::cout << "开始采集 " << std::endl;int i = 0;while (1){auto startTime = std::chrono::high_resolution_clock::now();ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL);for (int i = 0; i < sizeof(dataReceived); i++) {printf("%02X ", dataReceived[i]);}bool flag1 = false;int flag;for (int i = 0; i < sizeof(dataReceived); i++) {if (dataReceived[i] == 0x77 && dataReceived[i + 1] == 0x10 && dataReceived[i + 2] == 0x00 && dataReceived[i + 3] == 0xFFFFFF84){flag1 = true;flag = i;break;}}std::cout << "" << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(4000));if (flag1 == true){//x轴// Given hexadecimal valuesint 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)***************************************:" << delay << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(200000000));}}}//std::this_thread::sleep_for(std::chrono::milliseconds(2000));}int main()
{// 创建传感器数据读取线程std::thread sensorThreadObj(sensorThread);//CString str123 = strValue1;//CString strA("COM10");//CString strB("\\\\.\\");//strB += strA;//const char* portName = strB.GetString();//strB.ReleaseBuffer();//strA.ReleaseBuffer();wchar_t portName[] = L"\\\\.\\COM10"; // Note the 'L' before the stringhSerial = CreateFile("\\\\.\\COM10", 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 << "第一次9600的对话模式配置失败" << std::endl;CloseHandle(hSerial);return 1;}if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {std::cout << "第一次9600的对话模式数据读取失败." << std::endl;CloseHandle(hSerial);return 1;}std::cout << "第一次初始波特率:" << dcbSerialParams.BaudRate << std::endl;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] == 0x77 && dataReceived[i + 3] == 0xFFFFFF8C) {exists = true; // 元素存在,设置标志位为truestd::cout << falsecount << std::endl;std::cout << "应答模式配置成功!" << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(400000));break; // 跳出for循环}}if (exists){break;}if (!exists) {falsecount++;if (falsecount >= 2)//说明原有配置是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 << "115200的对话模式配置失败." << std::endl;CloseHandle(hSerial);return 1;}if (!ReadFile(hSerial, dataReceived, sizeof(dataReceived), &bytesRead, NULL)) {std::cout << "115200的对话模式回复失败." << std::endl;CloseHandle(hSerial);return 1;}}}//设置频率为115200char 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] == 0x77 && dataReceived[i + 3] == 0xFFFFFF8B) {//设置成功exists = true; // 元素存在,设置标志位为truestd::cout << "115200波特率配置成功!" << std::endl;break; // 跳出for循环}}if (exists){break;}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 << "重复配置115200波特率" << std::endl;// 可以在这里添加需要执行的语句std::this_thread::sleep_for(std::chrono::milliseconds(4000));}}//00-11:应答模式 05-50Hz 04-25Hz//06-100     05-50     04-25    char command_R3[] = { 0x77, 0x05, 0x00, 0x0C, 0x03, 0x14 };//50Hzif (!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] == 0x77 && dataReceived[i+3] == 0xFFFFFF8C) {//设置成功exists = true; // 元素存在,设置标志位为truestd::cout << "50Hz配置成功!" << std::endl;break; // 跳出for循环}}if (exists){break;}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;// 可以在这里添加需要执行的语句}}//sensorThreadObj.join();return 0;
}

我不知道为啥,程序可以正常运行,但是时间过长的情况下,偶尔会出现下面的这个问题(如果哪个大佬要是知道可以告诉我一下,学习学习):

问题二:界面化设计(简化版)

前面已经完成了对于倾角传感器初步的设定与时间延缓问题的补偿,下一步需要对于倾角传感器的界面进行设计了。不写那么复杂,直接就是连接之后实时显示。

其中,Combo Box的ID我设置为IDC_COMBO1。x轴、y轴控件之间添加变量为m_x11、x_x22。可以见到在.h文件之中生成绑定变量。

在.h之中添加自己想要的变量。

HANDLE hSerial_L;DCB dcbSerialParams_L = { 0 };COMMTIMEOUTS timeouts_L = { 0 };DWORD bytesRead_L, bytesRead_L1, bytesWritten, bytesWritten1, bytesWritten2, bytesWritten3, bytesWritten4, bytesWritten5, response_R1;char dataReceived[34];const int interval = 100;char dataReceived_L[23];

在.cpp的初始化函数OnInit之中添加线程监控与按钮初始化

AfxBeginThread(ReadCom1Thread, this);CComboBox* pCombo_S_L = (CComboBox*)GetDlgItem(IDC_COMBO1);pCombo_S_L->AddString(_T("断开连接"));pCombo_S_L->AddString(_T("COM1"));pCombo_S_L->AddString(_T("COM2"));pCombo_S_L->AddString(_T("COM3"));pCombo_S_L->AddString(_T("COM4"));pCombo_S_L->AddString(_T("COM5"));pCombo_S_L->AddString(_T("COM6"));pCombo_S_L->AddString(_T("COM7"));pCombo_S_L->AddString(_T("COM8"));pCombo_S_L->AddString(_T("COM9"));pCombo_S_L->AddString(_T("COM10"));pCombo_S_L->AddString(_T("COM11"));pCombo_S_L->AddString(_T("COM12"));pCombo_S_L->AddString(_T("COM13"));pCombo_S_L->AddString(_T("COM14"));pCombo_S_L->AddString(_T("COM15"));pCombo_S_L->AddString(_T("COM16"));pCombo_S_L->AddString(_T("COM17"));pCombo_S_L->AddString(_T("COM18"));pCombo_S_L->AddString(_T("COM19"));pCombo_S_L->AddString(_T("COM20"));pCombo_S_L->SetCurSel(0);

线程函数如下所示:


volatile bool bThreadRunning1 = false; // 线程1运行标志
//UINT CMFCApplication1Dlg::ReadCom1Thread(LPVOID pParam)
UINT ReadCom1Thread(LPVOID pParam)
{CMFCApplication1Dlg* pDlg = (CMFCApplication1Dlg*)pParam;CString strText;bThreadRunning1 = true;double LX, LY;std::cout << " " << std::endl;std::cout << "开始采集 " << std::endl;int i = 0;while (1){auto startTime = std::chrono::high_resolution_clock::now();ReadFile(pDlg->hSerial_L, pDlg->dataReceived, sizeof(pDlg->dataReceived), &(pDlg->bytesRead_L), NULL);for (int i = 0; i < sizeof(pDlg->dataReceived); i++) {printf("%02X ", pDlg->dataReceived[i]);}bool flag1 = false;int flag;for (int i = 0; i < sizeof(pDlg->dataReceived); i++) {if (pDlg->dataReceived[i] == 0x77 && pDlg->dataReceived[i + 1] == 0x10 && pDlg->dataReceived[i + 2] == 0x00 && pDlg->dataReceived[i + 3] == 0xFFFFFF84){flag1 = true;flag = i;break;}}std::cout << "" << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(4000));if (flag1 == true){//x轴// Given hexadecimal valuesint hexValues[] = { pDlg->dataReceived[flag + 5] & 0xFF, pDlg->dataReceived[flag + 6] & 0xFF, pDlg->dataReceived[flag + 7] & 0xFF };int hexValues1[] = { pDlg->dataReceived[flag + 9] & 0xFF, pDlg->dataReceived[flag + 10] & 0xFF, pDlg->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 (pDlg->dataReceived[flag + 4] == 0x00){LX = resultDouble;}else{LX = -resultDouble;}//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 (pDlg->dataReceived[flag + 8] == 0x00){LY = resultDouble1;}else{LY = -resultDouble1;}CString strValue;strValue.Format(_T("%.4f°"), LX); // 将 double 值转换成字符串,保留四位小数pDlg->m_x11.ResetContent();pDlg->m_x11.AddString(strValue); // 将字符串添加到 ListBox 中CString strValue1;strValue1.Format(_T("%.4f°"), LY); // 将 double 值转换成字符串,保留四位小数pDlg->m_x22.ResetContent();pDlg->m_x22.AddString(strValue1); // 将字符串添加到 ListBox 中// 计算执行代码所花费的时间auto endTime = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);// 计算需要延迟的时间int delay = pDlg->interval - duration.count();//std::cout << delay << std::endl;if (delay == pDlg->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)***************************************:" << delay << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(200000000));}}}//// 关闭串口1CloseHandle(pDlg->hSerial_L);return 0;
}

双击COM口选择控件,添加如下函数


void CMFCApplication1Dlg::OnCbnSelchangeCombo1()
{// TODO: 在此添加控件通知处理程序代码// TODO: 在此添加控件通知处理程序代码CComboBox* pCombo12 = (CComboBox*)GetDlgItem(IDC_COMBO1);CString strValue1;pCombo12->GetLBText(pCombo12->GetCurSel(), strValue1);CString vl11 = strValue1;CStringA strA(strValue1);CStringA strB("\\\\.\\");strB += strA;const char* portName = strB.GetString();// 释放 portName 的资源strB.ReleaseBuffer();strA.ReleaseBuffer();CString duankai("断开连接");if (vl11 == duankai){MessageBox(L"断开与倾角传感器的连接");}else{CStringW widePortName(portName);hSerial_L = CreateFile(widePortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);//hSerial = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hSerial_L == INVALID_HANDLE_VALUE) {if (GetLastError() == ERROR_FILE_NOT_FOUND) {std::cout << "Serial port not available." << std::endl;}}dcbSerialParams_L.DCBlength = sizeof(dcbSerialParams_L);if (!GetCommState(hSerial_L, &dcbSerialParams_L)) {std::cout << "Error getting serial port state." << std::endl;CloseHandle(hSerial_L);}dcbSerialParams_L.BaudRate = CBR_9600;dcbSerialParams_L.ByteSize = 8;dcbSerialParams_L.StopBits = ONESTOPBIT;dcbSerialParams_L.Parity = NOPARITY;if (!SetCommState(hSerial_L, &dcbSerialParams_L)) {std::cout << "Error setting serial port state." << std::endl;CloseHandle(hSerial_L);}timeouts_L.ReadIntervalTimeout = 500;timeouts_L.ReadTotalTimeoutConstant = 500;timeouts_L.ReadTotalTimeoutMultiplier = 100;timeouts_L.WriteTotalTimeoutConstant = 500;timeouts_L.WriteTotalTimeoutMultiplier = 100;if (!SetCommTimeouts(hSerial_L, &timeouts_L)){std::cout << "Error setting timeouts." << std::endl;CloseHandle(hSerial_L);}//默认为9600的时候,进行对话模式char command_R4[] = { 0x77, 0x05, 0x00, 0x0C, 0x00, 0x11 };if (!WriteFile(hSerial_L, command_R4, sizeof(command_R4), &bytesWritten4, NULL)) {std::cout << "第一次9600的对话模式配置失败" << std::endl;CloseHandle(hSerial_L);}if (!ReadFile(hSerial_L, dataReceived_L, sizeof(dataReceived_L), &bytesRead_L, NULL)) {std::cout << "第一次9600的对话模式数据读取失败." << std::endl;CloseHandle(hSerial_L);}std::cout << "第一次初始波特率:" << dcbSerialParams_L.BaudRate << std::endl;for (int i = 0; i < sizeof(dataReceived_L); i++) {printf("%02X ", dataReceived_L[i]);}bool exists = false; // 标志位,记录元素是否存在int falsecount = 0;// 循环遍历数组while (!exists) {for (int i = 0; i < sizeof(dataReceived_L); i++) {printf("%02X ", dataReceived_L[i]);}for (int i = 0; i < sizeof(dataReceived_L); i++) {if (dataReceived_L[i] == 0x77 && dataReceived_L[i + 3] == 0xFFFFFF8C) {exists = true; // 元素存在,设置标志位为truestd::cout << falsecount << std::endl;std::cout << "应答模式配置成功!" << std::endl;//std::this_thread::sleep_for(std::chrono::milliseconds(400000));break; // 跳出for循环}}if (exists){break;}if (!exists) {falsecount++;if (falsecount >= 2)//说明原有配置是115200波特率{dcbSerialParams_L.BaudRate = CBR_115200;dcbSerialParams_L.ByteSize = 8;dcbSerialParams_L.StopBits = ONESTOPBIT;dcbSerialParams_L.Parity = NOPARITY;if (!SetCommState(hSerial_L, &dcbSerialParams_L)) {std::cout << "Error setting serial port state." << std::endl;CloseHandle(hSerial_L);}timeouts_L.ReadIntervalTimeout = 500;timeouts_L.ReadTotalTimeoutConstant = 500;timeouts_L.ReadTotalTimeoutMultiplier = 100;timeouts_L.WriteTotalTimeoutConstant = 500;timeouts_L.WriteTotalTimeoutMultiplier = 100;if (!SetCommTimeouts(hSerial_L, &timeouts_L)){std::cout << "Error setting timeouts." << std::endl;CloseHandle(hSerial_L);}}if (!WriteFile(hSerial_L, command_R4, sizeof(command_R4), &bytesWritten4, NULL)) {std::cout << "115200的对话模式配置失败." << std::endl;CloseHandle(hSerial_L);}if (!ReadFile(hSerial_L, dataReceived_L, sizeof(dataReceived_L), &bytesRead_L, NULL)) {std::cout << "115200的对话模式回复失败." << std::endl;CloseHandle(hSerial_L);}}}//设置频率为115200char command_R1[] = { 0x77, 0x05, 0x00, 0x0B, 0x04, 0x14 };//115200 if (!WriteFile(hSerial_L, command_R1, sizeof(command_R1), &bytesWritten1, NULL)){std::cout << "Error writing to serial port." << std::endl;CloseHandle(hSerial_L);}if (!ReadFile(hSerial_L, dataReceived_L, sizeof(dataReceived_L), &bytesRead_L, NULL)){std::cout << "Error reading from serial port." << std::endl;CloseHandle(hSerial_L);}exists = false;while (!exists){for (int i = 0; i < sizeof(dataReceived_L); i++) {printf("%02X ", dataReceived_L[i]);}for (int i = 0; i < sizeof(dataReceived_L); i++) {if (dataReceived_L[i] == 0x77 && dataReceived_L[i + 3] == 0xFFFFFF8B) {//设置成功exists = true; // 元素存在,设置标志位为truestd::cout << "115200波特率配置成功!" << std::endl;break; // 跳出for循环}}if (exists){break;}if (!exists) {if (!WriteFile(hSerial_L, command_R1, sizeof(command_R1), &bytesWritten1, NULL)) {std::cout << "Error writing to serial port." << std::endl;CloseHandle(hSerial_L);}if (!ReadFile(hSerial_L, dataReceived_L, sizeof(dataReceived_L), &bytesRead_L, NULL)) {std::cout << "Error reading from serial port." << std::endl;CloseHandle(hSerial_L);}std::cout << "重复配置115200波特率" << std::endl;// 可以在这里添加需要执行的语句}}//00-11:应答模式 05-50Hz 04-25Hz//06-100     05-50     04-25    char command_R3[] = { 0x77, 0x05, 0x00, 0x0C, 0x03, 0x14 };//50Hzif (!WriteFile(hSerial_L, command_R3, sizeof(command_R3), &bytesWritten3, NULL)) {std::cout << "Error writing to serial port." << std::endl;CloseHandle(hSerial_L);}if (!ReadFile(hSerial_L, dataReceived_L, sizeof(dataReceived_L), &bytesRead_L, NULL)) {std::cout << "Error reading from serial port." << std::endl;CloseHandle(hSerial_L);}for (int i = 0; i < sizeof(dataReceived_L); i++) {printf("%02X ", dataReceived_L[i]);}exists = false;while (!exists) {for (int i = 0; i < sizeof(dataReceived_L); i++) {printf("%02X ", dataReceived_L[i]);}for (int i = 0; i < sizeof(dataReceived_L); i++) {if (dataReceived_L[i] == 0x77 && dataReceived_L[i + 3] == 0xFFFFFF8C) {//设置成功exists = true; // 元素存在,设置标志位为truestd::cout << "50Hz配置成功!" << std::endl;break; // 跳出for循环}}if (exists){break;}if (!exists) {if (!WriteFile(hSerial_L, command_R3, sizeof(command_R3), &bytesWritten3, NULL)) {std::cout << "Error writing to serial port." << std::endl;CloseHandle(hSerial_L);;}if (!ReadFile(hSerial_L, dataReceived_L, sizeof(dataReceived_L), &bytesRead_L, NULL)) {std::cout << "Error reading from serial port." << std::endl;CloseHandle(hSerial_L);}std::cout << "元素不存在,继续执行某条语句..." << std::endl;// 可以在这里添加需要执行的语句}}}}

实时读取界面完成。

问题三:时间同步问题

因为在实际的使用过程之中,需要用到的数据不可能只是一个倾角传感器的数据,如何进行多传感器的时间的同步是一个比较重要的问题。

针对于这个时间帧对齐方式,当存在多个传感器的时候,多个传感器的输出频率是不一致的情况下,最佳的方式是将其频率调节到整数倍的情况下。然后使用插值的方式使得其帧率变为一致的情况。

以相机而言,如下所示,可以调用相机的SDK进行人为设置相机的帧率。

可以见到相应的相机的帧率是稳定不变的,以将相机与倾角传感器时间帧进行对齐为例。首先,选定一个参考物也就是所谓的时间的参考物,我是以相机为参考时间的,将倾角传感器的频率设置为100Hz,由于此处我是将receive的长度设置为34,也就是采集长度的二倍,因此实际输出的频率为原来的1/2,也就是50Hz。(这样做的目的是方式出现丢帧的问题)

我的想法是使用时间戳的方式进行对齐,首先将相机的帧率设置为10FPS,需要进行注意的是相机设置为10FPS的过程,相机是逐渐成为10FPS的,有一个时间延迟,延迟一段时间并且记录下此时的时间戳t1。同理,倾角传感器在进行采集的过程之中也是存在相应的时间延迟,延迟之后记录下此时的时间戳t2。

其含义为相机在t1时刻以后以10Hz的频率进行采集,倾角传感器在t2时刻以后以50Hz的频率进行采集。其中10Hz对应100ms/次,50Hz对应20ms/次。其中如何对齐,后面再想。

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

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

相关文章

NVIDIA NCCL 源码学习(十二)- double binary tree

上节我们以ring allreduce为例看到了集合通信的过程&#xff0c;但是随着训练任务中使用的gpu个数的扩展&#xff0c;ring allreduce的延迟会线性增长&#xff0c;为了解决这个问题&#xff0c;NCCL引入了tree算法&#xff0c;即double binary tree。 double binary tree 朴素…

八:爬虫-MySQL基础

一&#xff1a;MySQL数据库基础 1.MySQL数据库介绍 MySQL是一个[关系型数据库管理系统]&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Rela…

数据结构 | 北京大学期末试卷查漏补缺

目录 顺序存储 优点 缺点 适用于&#xff1a; 链式存储 优点 缺点 适用于&#xff1a; 折半查找为什么要使用顺序存储结构 树的存储结构​编辑 对于一个数据结构&#xff0c;一般包括 DFS&BFS 什么是递归程序 C语言不带头结点的单链表逆置 检测字符…

window10下载与安装Dubbo Admin,图文说明

0&#xff0c;前言 在学习这篇文章之前&#xff0c;可以先把zookeeper安装一下 安装教程指路&#xff1a;window10下载与安装zookeeper&#xff0c;图文说明 1&#xff0c;下载 拉取代码&#xff0c;一般教程都会让我去github官网拉取&#xff0c;但是因为该网站经常打不开…

如何在小程序中添加字符

随着移动互联网的普及&#xff0c;微信小程序已经成为众多商家的首选。通过微信小程序&#xff0c;商家可以展示产品、服务和品牌形象。那么如何在微信小程序中添加视频内容呢&#xff1f;本文将详细介绍操作步骤。 首先&#xff0c;商家需要登录乔拓云平台&#xff0c;进入门店…

MongoDB 单机安装部署

文章目录 说明1. 下载安装包2. 安装数据库3. 配置 systemctl4. 创建 root 用户 说明 本篇文章介绍 MongoDB 二进制安装的步骤&#xff0c;整个过程还是比较简单。 1. 下载安装包 进入 MongoDB 官网&#xff0c;获取安装包的下载链接&#xff1a; https://www.mongodb.com/tr…

安全运维是做什么的,主要工作内容是什么

安全运维&#xff0c;简称SecOps&#xff0c;是一种集成安全措施和流程到信息技术运维的实践。它的目的是确保在日常运维活动中&#xff0c;如网络管理、系统维护、软件更新等&#xff0c;均考虑并融入安全策略。安全运维的核心是实现安全和运维团队的密切协作&#xff0c;以快…

【自动化测试】selenium元素定位方式大全!

前言 当我们在使用selenium进行自动化测试工作时&#xff0c;元素定位是非常重要的一环&#xff0c;因为我们是借助脚本模拟我们通过鼠标和键盘对元素进行点击、输入内容和滑动操作的&#xff0c;所以准确的元素定位是我们执行测试脚本的重要一环。本文就来给大家介绍一下sele…

竞赛保研 基于CNN实现谣言检测 - python 深度学习 机器学习

文章目录 1 前言1.1 背景 2 数据集3 实现过程4 CNN网络实现5 模型训练部分6 模型评估7 预测结果8 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于CNN实现谣言检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&am…

百分比-保留2位小数

有时候工作中有这样的需求&#xff0c;统计各种类型的占比&#xff0c;因此记录一下求百分比的小工具&#xff0c;以后方便自己用到随时来查 /*** 转成百分数* 当前数除以总数* param num1-当前数 ,num2-总数 num1/num2* return rate 保留2位小数的*/public static String …

4.使用 Blazor 构建 Web 应用程序

微软官方培训 了解如何通过 Blazor Web 用户界面框架构建你的第一个 Web 应用程序。 https://learn.microsoft.com/zh-cn/training/paths/build-web-apps-with-blazor/?viewaspnetcore-8.0 8个模块 目录 微软官方培训 1.使用 Blazor 进行 Web 开发的简介 2.使用 Blazor…

Vue中为什么data属性是一个函数而不是一个对象?(看完就会了)

文章目录 一、实例和组件定义data的区别二、组件data定义函数与对象的区别三、原理分析四、结论 一、实例和组件定义data的区别 vue实例的时候定义data属性既可以是一个对象&#xff0c;也可以是一个函数 const app new Vue({el:"#app",// 对象格式data:{foo:&quo…

安装 PyCharm 2021.1 保姆级教程

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 目前能下载到的最新版本是 PyCharm 2021.1。 请注意对应 Python 的版本&#xff1a; Python 2: 2.7Python 3: >3.6, <3.11…

22 3GPP在SHF频段基于中继的5G高速列车场景中的标准化

文章目录 信道模型实验μ参考信号初始接入方法波形比较 RRH&#xff1a;remote radio head 远程无线头 HTS&#xff1a;high speed train 高速移动列车 信道模型 考虑搭配RRH和车载中继站之间的LOS路径以及各种环境&#xff08;开放或峡谷&#xff09;&#xff0c;在本次实验场…

分享5款为你生活带来便捷的小工具

​ 生活需要一些小巧而贴心的工具&#xff0c;它们能够在细节处为我们带来便捷。这五款工具简洁而实用&#xff0c;看看它们是否适合融入你的生活。 1.图片压缩——TinyPNG ​ TinyPNG是一款图片压缩工具&#xff0c;可以智能地减少WebP、PNG和JPEG图片的文件大小。TinyPNG通…

Jenkins持续集成自动化测试

执行集成构建 持续&#xff0c;自动地构建&测试软件项目代码管理&#xff08;git/svn&#xff09;>编译&#xff08;maven/ant/gradle&#xff09;>打包>测试环境部署>自动化测试 研发体系中的迭代流程 1 源码分支管理&#xff1a; git或者svn, 将不同开发编…

【限时Free】新增普刊!计算机/社科/医学等多领域,1个月见刊!

普刊极速发表 1 计算机类 World Journal of Information Technology 【Print ISSN】2959-9903&#xff1b; 【Online ISSN】2959-9911&#xff1b; 【出版社】Upubscience Publisher出版社 【发表周期】1-2个月左右出刊&#xff1b; 【接收领域】专注于涉及技术和IT管理的…

用于从未配对的3D医学图像中进行多模式分割的统一生成对抗性网络

Unified generative adversarial networks for multimodal segmentation from unpaired 3D medical images 用于从未配对的3D医学图像中进行多模式分割的统一生成对抗性网络背景积累 贡献难点&#xff1a;贡献&#xff1a; 实验Effect of the weight λshape&#xff08;形状损…

Android MVI架构之UI开发指南

Android MVI架构之UI开发指南 在整个应用程序架构中&#xff0c;UI层并不是唯一的层级。除了UI层之外&#xff0c;您还可以找到数据层&#xff0c;有时还有领域层。根据Android架构文档&#xff1a; UI层在屏幕上显示数据。数据层暴露应用程序数据&#xff0c;并包含大部分业…

自动评估作业,支持订正最终得分、查看关联代码|ModelWhale 版本更新

冬至时节&#xff0c;2023 已进入尾声&#xff0c;ModelWhale 于今日迎来新一轮的版本更新&#xff0c;与大家一起静候新年的到来。 本次更新中&#xff0c;ModelWhale 主要进行了以下功能迭代&#xff1a; 自动评估作业 新增 提交代码&#xff08;团队版✓ &#xff09;新增…