Qt之CAN设计(十三)
Qt开发 系列文章 - CAN(十三)
目录
前言
一、CAN
二、实现方式
1.创建类
2.相关功能函数
3.用户使用
4.效果演示
5.拓展应用-实时刷新
总结
前言
Qt框架中并没有提供关于CAN接口的相关模块,需要用户自己根据CAN接口硬件模块,例如周立功CAN分析仪,编写底层接口功能函数,然后调用它。一般用户买的CAN分析仪工具都自带二次开发功能,即对于can接口的底层函数都已编写好,且封装完成,用户只需要根据头文件调用相关功能即可,完成对他的二次开发。
一、CAN
CAN(Controller Area Network)是一种用于连接微控制器和设备的串行总线标准,主要用于实时数据交换,它支持分布式控制或实时控制的串行通信系统,特别适用于那些对时间延迟敏感的应用。CAN通信基于广播模式,任何节点发送的数据可以被网络上所有其他节点接收,每个节点都可以通过发送具有唯一标识符的消息来与其他节点通信。与传统的点对点通信相比,CAN总线具有更高的可靠性和灵活性,它能够自动检测错误并采取相应措施,如重新发送数据包,确保数据的完整性和准确性。
CAN总线标准由ISO/IEC 11898和ISO/IEC 11519定义,广泛应用于汽车工业、工业自动化、楼宇自动化、医疗设备、机器人等领域。在工业自动化中,CAN总线用于连接传感器、执行器和控制单元,实现设备的互联和监控。
二、实现方式
要实现CAN上位机通讯,通过相关工具,一般是CAN分析仪板,市场都有卖的,连接到你的上位机电脑上面。然后根据卖家提供的CAN硬件底层接口源文件或库文件,导入到你的项目中,进行二次开发。
本文使用的是周立功的分析仪工具,首先将厂家提供的底层CAN接口库和头文件添加到项目中,然后使用开发!
1.创建类
在Qt项目上创建一个串口类,属于线程public QThread,具体实现如下。
#include <QThread>
#include "ControlCAN.h"#define CANalyst_II 4 //CAN卡设备类型 USBCAN-2A或USBCAN-2C或CANalyst-II类型均为4
#define CAN_Channel 0 //CAN卡通道 0和1
#define CAN_Reserve 0 //保留参数
#define CAN_MSG_TYPE_FILTER 0x4
#define CAN_MSG_LEN sizeof(CAN_Message) //13字节
#define ID_IGNORE_CAN_BUS(id) ((id) & 0x1FFFFCFFUL) // 扩展帧有效位29位标识位去掉bus位class CANThread:public QThread
{Q_OBJECT
public:CANThread();~CANThread();bool openCAN();void closeCAN();bool creatdbtable();void closedbtable(void);void ClearCANmsgsData();void PushSendData(CAN_Message);quint32 deviceType; //设备类型quint32 deviceIndex; //设备索引quint32 baundRate; //波特率quint32 devicCom; //CAN通道QString isonline;bool stopped;bool savefile;QList<CAN_Message> CANmsgs;
signals:void getProtocolData(QString);
protected:void run();void SendCANMsgs(void);void RecvCANMsgs(void);//void sleep(unsigned int msec);void ProcessCANMsg(CAN_Message);QDateTime m_zerot;qint64 getSystemTimeGap(){QDateTime nowTime = QDateTime::currentDateTime();return m_zerot.msecsTo(nowTime);}
private:QSqlDatabase db; //数据库对象QSqlQuery sql;mutable QMutex DataLock;
};
2.相关功能函数
该线程类的实现:首先在构造函数初始化相关变量;然后通过openCAN函数完成对CAN口的一系列设置;最后启动线程run后,在while循环中实现对CAN口的收(SendCANMsgs函数)、发(RecvCANMsgs函数)。代码如下(示例):
CANThread::CANThread()
{stopped = true;savefile = false;isonline = "";//sql = new QSqlQuery();qRegisterMetaType<VCI_CAN_OBJ>("VCI_CAN_OBJ");qRegisterMetaType<DWORD>("DWORD");
}
CANThread::~CANThread()
{if(isRunning()){exit();wait(100);}db.close();
}
void CANThread::closedbtable(void)
{// 提交事务并保存更改if (!db.commit())qDebug() << "Failed to commit transaction";db.close();
}
bool CANThread::openCAN()
{//**1**打开设备 注意一个设备只能打开一次if(1 != VCI_OpenDevice(deviceType, deviceIndex, CAN_Reserve)){emit getProtocolData("CAN device open fail.");return false;}//**2**清空指定CAN通道接收和发送缓冲区if(1 != VCI_ClearBuffer(deviceType, deviceIndex, devicCom)){emit getProtocolData("Clear the buffer of 1#CAN channel fail.");}if(1 != VCI_ClearBuffer(deviceType, deviceIndex, devicCom+1)){emit getProtocolData("Clear the buffer of 2#CAN channel fail.");}//**3**配置CAN数据类型VCI_INIT_CONFIG vic;vic.AccCode=0x80000000;vic.AccMask=0xFFFFFFFF;vic.Filter=1;vic.Mode=0;//**4**确定CAN波特率switch (baundRate) {case 10:vic.Timing0=0x31;vic.Timing1=0x1c;break;case 20:vic.Timing0=0x18;vic.Timing1=0x1c;break;case 40:vic.Timing0=0x87;vic.Timing1=0xff;break;case 50:vic.Timing0=0x09;vic.Timing1=0x1c;break;case 80:vic.Timing0=0x83;vic.Timing1=0xff;break;case 100:vic.Timing0=0x04;vic.Timing1=0x1c;break;case 125:vic.Timing0=0x03;vic.Timing1=0x1c;break;case 200:vic.Timing0=0x81;vic.Timing1=0xfa;break;case 250:vic.Timing0=0x01;vic.Timing1=0x1c;break;case 400:vic.Timing0=0x80;vic.Timing1=0xfa;break;case 500:vic.Timing0=0x00;vic.Timing1=0x1c;break;case 666:vic.Timing0=0x80;vic.Timing1=0xb6;break;case 800:vic.Timing0=0x00;vic.Timing1=0x16;break;case 1000:vic.Timing0=0x00;vic.Timing1=0x14;break;case 33:vic.Timing0=0x09;vic.Timing1=0x6f;break;case 66:vic.Timing0=0x04;vic.Timing1=0x6f;break;case 83:vic.Timing0=0x03;vic.Timing1=0x6f;break;default:break;}//**5**初始化指定CAN通道quint8 InitFailCnt = 0;if(1 != VCI_InitCAN(deviceType, deviceIndex, devicCom, &vic)){emit getProtocolData("CAN1 device init fail.");InitFailCnt += 1;}if(1 != VCI_InitCAN(deviceType, deviceIndex, devicCom+1, &vic)){emit getProtocolData("CAN2 device init fail.");InitFailCnt += 1;}if(2 == InitFailCnt)return false;//**6**获取设备信息VCI_BOARD_INFO vbi; //用来存储设备信息的结构指针if(1 != VCI_ReadBoardInfo(deviceType, deviceIndex, &vbi)){emit getProtocolData("Pick up device info fail.");return false;}elseemit getProtocolData(QString("CAN通道数: %1\n硬件版本号: %2\n接口库版本号: %3").arg(vbi.can_Num).arg(vbi.hw_Version).arg(vbi.in_Version));//**7**启动CAN卡某个通道InitFailCnt = 0;if(1 != VCI_StartCAN(deviceType, deviceIndex, devicCom)){emit getProtocolData("Start CAN1 device fail.");InitFailCnt += 1;}if(VCI_StartCAN(deviceType, deviceIndex, devicCom+1) !=1){emit getProtocolData("Start CAN2 device fail.");InitFailCnt += 1;}if(2 == InitFailCnt)return false;return true;
}
void CANThread::closeCAN()
{VCI_CloseDevice(deviceType, deviceIndex);
}
void CANThread::ClearCANmsgsData()
{QMutexLocker locker(&DataLock);CANmsgs.clear();
}
void CANThread::PushSendData(CAN_Message pdata)
{QMutexLocker locker(&DataLock);CANmsgs.push_back(pdata);
}void CANThread::run()
{while(!stopped){// 处理接受数据RecvCANMsgs();// 处理发送数据SendCANMsgs();}
}
void CANThread::SendCANMsgs(void)
{ if(!CANmsgs.isEmpty()){QMutexLocker locker(&DataLock);CAN_Message msg;memcpy(&msg, &CANmsgs.first(), sizeof(msg));DWORD dwRel;VCI_CAN_OBJ vco;vco.ID = msg.ID.id;vco.RemoteFlag = 0;vco.ExternFlag = 1;vco.DataLen = msg.Len;for(uchar j=0;j<msg.Len;j++)vco.Data[j] = msg.Data.b[j];dwRel = VCI_Transmit(deviceType, deviceIndex, devicCom, &vco,1);if(dwRel>0){qDebug()<<"成功发送帧数:" << dwRel;//CAN_Message dealmsg;//dealmsg = CANmsgs.takeFirst(); //移除队头元素并返回该元素,不释放该元素内存CANmsgs.removeFirst(); //删除队头元素不返回,释放该元素内存,更有效率}elseqDebug()<<"发送错误:" << dwRel;}
}
void CANThread::RecvCANMsgs(void)
{static quint8 invalmsg=0,dismsg=0;int cancnt;VCI_CAN_OBJ vco[2500];CAN_Message pData;cancnt = VCI_Receive(deviceType, deviceIndex, devicCom+1, vco,2500,0); //返回CAN2实际读取的帧数if(NULL < cancnt){for(int i=0;i<cancnt;i++){pData.ID.id = vco[i].ID;pData.Len = vco[i].DataLen;for(quint8 j = 0;j<8;j++)pData.Data.b[j] = vco[i].Data[j];ProcessCANMsg(pData);//memset(&pData, 0, CAN_MSG_LEN);}isonline = QString("lightgreen");invalmsg = 0;dismsg = 0;}else if(NULL == cancnt){invalmsg++;if(invalmsg > 70){isonline = QString("lightyellow");invalmsg = 0;}dismsg = 0;}else{//设备不存在或USB掉线 可以调用VCI_CloseDevice并重新VCI_OpenDevice//如此可以达到USB-CAN设备热插拔的效果emit getProtocolData("CAN2 Device not find or USB disconnect.");//VCI_CloseDevice(deviceType, devicIndex);//VCI_OpenDevice(deviceType, devicIndex, CAN_Reserve);dismsg++;if(dismsg > 70){isonline = QString("lightred");dismsg = 0;}}msleep(30);//同时每隔30ms调用一次VCI_Receive为宜.//在满足应用的时效性情况下 尽量降低调用VCI_Receive的频率 只要保证内部缓存不溢出 每次读取并处理更多帧 可以提高运行效率
}
3.用户使用
创建完上面的线程类后,用户需要调用/使用它,首先在构造函数初始化CAN口和CAN的参数设置变量、定时器相关变量,具体含义实现如下。
class MainWindow : public QMainWindow
{Q_OBJECT
public:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();
protected:void timerEvent(QTimerEvent *t);void InitTimerEvent(void);
private slots:private:Ui::MainWindow *ui;CANParamSetting *CANsetting;CANThread *canthread;int m_pluseTimeid;QString StyleSheet;
};MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);/****定时器初始化******/InitTimerEvent();CANsetting = new CANParamSetting();/****CAN线程初始化****/canthread = new CANThread();/****建立信号槽联系****/connect(canthread,&CANThread::getProtocolData,this,&MainWindow::displayText);/****隐藏测试项窗口****/ui->tabWidget->hide();StyleSheet = ui->pushButton_2->styleSheet();//背景测试
// QString ImagePath = qApp->applicationDirPath()+"/images/sss.gif";
// QString ImageSheet = QString("QWidget#widget {border-image: url(%1);}").arg(ImagePath);
// ui->widget->setStyleSheet(ImageSheet);/*首先说明一下background-image、border-image、image三种区别background-image:简单理解就是将图片从部件的左上角开始贴图,部件的大小限制了显示图片范围;好比是我们按照部件的大小来裁剪图片border-image:就是将贴图缩放进到部件里,部件能看到完整图片,但是此时图片会被压缩的变形iamge:部件会按照图片的原始大小进行填充*/
}
MainWindow::~MainWindow()
{delete ui;
}
void MainWindow::on_pushButton_clicked()//参数设置
{CANsetting->show();
}
void MainWindow::on_pushButton_2_clicked()//启动CAN
{if(ui->pushButton_2->text() == tr("CAN设备启动")){ui->pushButton->setEnabled(false);ui->pushButton_2->setText(tr("CAN设备关闭"));canthread->deviceType = CANalyst_II;canthread->deviceIndex = CANsetting->index;canthread->baundRate = CANsetting->baundRate;canthread->devicCom = CAN_Channel;if(canthread->openCAN()){displayText("Open CAN success.");canthread->ClearCANmsgsData();canthread->stopped = false;canthread->start();}}else if(ui->pushButton_2->text() == tr("CAN设备关闭")){ui->pushButton->setEnabled(true);ui->pushButton_2->setText(tr("CAN设备启动"));canthread->stopped = true;canthread->closeCAN();canthread->isonline = StyleSheet;}
}
void MainWindow::on_pushButton_15_clicked()
{if(ui->pushButton_15->text() == tr("开始数据保存")){if(ui->pushButton_2->text() == tr("CAN关闭"))ui->pushButton_2->setEnabled(false);ui->pushButton_15->setText(tr("停止数据保存"));if(canthread->creatdbtable()){qInfo() << "Successfully create database! SQLite Type.";canthread->savefile = true;ui->pushButton_15->setStyleSheet("QPushButton { background-color: lightgreen; }");}}else if(ui->pushButton_15->text() == tr("停止数据保存")){ui->pushButton_2->setEnabled(true);ui->pushButton_15->setText(tr("开始数据保存"));canthread->savefile = false;canthread->closedbtable();ui->pushButton_15->setStyleSheet(StyleSheet);}
}
4.效果演示
上述理解清除后,编译运行,显示窗口如下。
如果需要进行CAN参数设置,点击参数设置按钮,显示如下。
设置完CAN参数后,可以点击设备启动,会出现如下显示。(因为未接CAN设备,提示打开失败)
如果点击保存数据,会出现如下显示。
停止保存数据后,会在项目路劲savefile文件夹下面看到保存的文件,如下所示。(会保存为db类型的数据库,关于其具体详细使用,会在后期更新相关使用方法教程。)
点击开放测试窗口,会出现CAN指令测试项,如下所示。
软件上其它的功能指令,就不一一详细介绍了,具体可以摸索。
5.拓展应用-实时刷新
一般我们工业上使用CAN口,为了实现对数据实时采集、并通过曲线显示出来。这时我们一般采取的是,先在线程中将CAN口收到的数据进行解析处理ProData,然后将解析出来的结果值通过变量传递给主界面上,让其知晓,然后通过主窗口的定时器或者信号槽函数显示在UI界面上。
如果是要绘制曲线,可以参考博文Qt之第三方库QCustomPlot使用(二)-CSDN博客,了解曲线绘制的特性及使用方法。
总结
博文中相应的工程代码Qt-Case.zip 利用Qt开发软件进行编的例程,为博文提供案例-CSDN文库。
相关文章:
Qt之CAN设计(十三)
Qt开发 系列文章 - CAN(十三) 目录 前言 一、CAN 二、实现方式 1.创建类 2.相关功能函数 3.用户使用 4.效果演示 5.拓展应用-实时刷新 总结 前言 Qt框架中并没有提供关于CAN接口的相关模块,需要用户自己根据CAN接口硬件模块&#…...
windows10/windows11运行ps1脚本报错的解决方法,签名错误解决方法
使用win10/win11运行ps1脚本时报错,提示“禁止运行此脚本”,错误如图所示: 此问题通常是由于windows默认的策略导致,解决方法是重新设置权限策略。 1. 设置windows配置 1). 使用管理员权限运行powershell 搜索power…...
在 Mac M2 上安装 PyTorch 并启用 MPS 加速的详细教程与性能对比
1. 安装torch 在官网上可以查看安装教程,Start Locally | PyTorch 作者安装了目前最新的torch版本2.5.1,需要提前安装python3.9及以上版本,作者python版本是python3.11最新版本 使用conda安装torch,在终端进入要安装的环境&…...
vulnhub matrix-breakout靶场
1.搭建靶机 这样就是装好了 获取靶机IP nmap -O 192.168.47.129/24 2.信息收集 dirb http://192.168.47.128 dirb 首页 81端口一个登录页面 gobuster dir -u http://192.168.152.154 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,html gra…...
Hive SQL 窗口函数 `ROW_NUMBER() ` 案例分析
一文彻底搞懂 ROW_NUMBER() 和 PARTITION BY 1. 引言 在处理大规模数据集时,Hive SQL 提供了强大的窗口函数(Window Function),如 ROW_NUMBER(),用于为结果集中的每一行分配唯一的行号。当与 PARTITION BY 和 ORDER …...
windows C++ TCP客户端
demo有一下功能 1、心跳包 2、断开重连 3、非阻塞 4、接受数据单独线程处理 #include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #include <windows.h> #include <string> #include <process.h> // 用于Windows下的线程相…...
【C++】初识C++之C语言加入光荣的进化(上)
写在前面 本篇笔记作为C的开篇笔记,主要是讲解C关键字(C98)连带一点点(C11)的知识。掌握的C新语法新特性,当然C是兼容C的,我们学习C的那套在C中也是受用。 文章目录 写在前面一、命名空间域1.1、命名空间域的定义与使用1.2、命名空间域的细节…...
Linux文件目录 --- 文件时间戳、atime、mtime、ctime、指定格式查看
三、文件时间戳 1. atime 文件最近被访问时间,是在读取文件或者执行文件时更改的,如果只cd进入一个目录然后cd . .不会引起atime的改变,要是使用ll命令进行查看后,再cd . . 离开就不同了。 2. mtime 文件最近内容修改时间,在目录中有文件…...
网页博客风格未完
实现类似的博客风格: 学习前端开发基础: HTML & CSS:掌握网页结构和样式设计的基础知识。JavaScript:增强网页的互动性和动态效果。响应式设计:确保您的博客在不同设备上都有良好的显示效果。 使用开源模板&#x…...
LeetCode 2545.根据第 K 场考试的分数排序:考察编程语言的排序
【LetMeFly】2545.根据第 K 场考试的分数排序:考察编程语言的排序 力扣题目链接:https://leetcode.cn/problems/sort-the-students-by-their-kth-score/ 班里有 m 位学生,共计划组织 n 场考试。给你一个下标从 0 开始、大小为 m x n 的整数…...
软考:系统架构设计师教材笔记(持续更新中)
教材中的知识点都会在。其实就是将教材中的废话删除,语言精练一下,内容比较多,没有标注重点 系统架构概述 定义 系统是指完成某一特定功能或一组功能所需要的组件集,而系统架构则是对所有组件的高层次结构表示,包括各…...
安卓环境配置及打开新项目教程,2024年12月20日最新版
1.去官网下载最新的Android Studio,网址:https://developer.android.com/studio?hlzh-cn 2.下载加速器,注册账号,开启加速器。网址:放在文末。 3.下载安卓代码,项目的路径上不能有中文,特别是…...
基于Spring Boot的电影售票系统
一、系统概述 该系统采用Spring Boot框架开发,充分利用其简化配置、快速部署和生产级别的性能监控等特点,为电影售票业务提供高效、可靠的技术支持。同时,系统采用前后端分离架构,前端使用Vue.js等框架,后端使用Sprin…...
【linux】 unshare -user -r /bin/bash命令详解
命令解析 unshare -user -r /bin/bash 是一个 Linux 命令,它用于在新的用户命名空间中运行一个进程(在这个例子中是 /bin/bash)。以下是这个命令的详细解释: 【1. 命令解析】 unshare: unshare 是一个工具,用于从调用…...
uniappX 移动端单行/多行文字隐藏显示省略号
在手机端不能多行省略使用 -webkit-line-clamp 属性所以移动端多行省略不会生效改为 lines 属性即可 /**单行文本溢出显示省略号*/ .text-ov1 {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;height: auto; } /**APP多行文本溢出显示省略号*/ // #ifdef APP-…...
uniApp打包H5发布到服务器(docker)
使用docker部署uniApp打包后的H5项目记录,好像和VUE项目打包没什么区别... 用HX打开项目,首先调整manifest.json文件 开始用HX打包 填服务器域名和端口号~ 打包完成后可以看到控制台信息 我们可以在web文件夹下拿到下面打包好的静态文件 用FinalShell或…...
谷歌Gemini与Anthropic Claude对比测试引发争议:AI竞赛暗流涌动
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
RAF认证的具体内容是什么?
RAF认证 Responsible Animal Fiber RAF认证,负责任动物纤维标准,是一个致力于确保动物福利、环境可持续性以及产品质量合规性的透明、可追溯和可信赖的认证体系。该体系不仅涵盖了动物纤维的生产和加工环节,还注重从源头到最终产品的整个供应…...
《OpenCV计算机视觉》-对图片的各种操作(均值、方框、高斯、中值滤波处理)及形态学处理
文章目录 《OpenCV计算机视觉》-对图片的各种操作(均值、方框、高斯、中值滤波处理)边界填充阈值处理图像平滑处理生成椒盐图片均值滤波处理方框滤波处理高斯滤波处理中值滤波处理 图像形态学腐蚀膨胀开运算闭运算顶帽和黑帽 《OpenCV计算机视觉》-对图片…...
Java字符串的|分隔符转List实现方案
字符串处理 问题背景代码实现代码优化原因分析实现方案 注意事项异常处理Maven未识别异常 问题背景 在项目组对账流程中,接收对方系统的对账文件,数据以|为分隔符,读取文件内容,分条入库。 代码实现 Java中将字符串转给list&am…...
【机器学习】当教育遇上机器学习:打破传统,开启因材施教新时代
我的个人主页 我的领域:人工智能篇,希望能帮助到大家!!!👍点赞 收藏❤ 教育是人类社会发展的基石,然而传统教育模式往往难以满足每个学生的个性化需求。随着机器学习技术的兴起,教…...
【FastAPI】日志
一、概述 FastAPI 是一个现代的、快速(高性能)的Web框架,用于构建API,基于Python类型提示。 日志记录是任何应用程序中不可或缺的一部分,它允许开发者追踪事件的发生、识别错误并了解系统的运行状态。 在 FastAPI 中&…...
faiss库中ivf-sq(ScalarQuantizer,标量量化)代码解读-7
流程 代码 void IndexIVF::search(idx_t n,const float* x,idx_t k,float* distances,idx_t* labels,const SearchParameters* params_in) const {FAISS_THROW_IF_NOT(k > 0);const IVFSearchParameters* params nullptr;if (params_in) {params dynamic_cast<const I…...
ORA-65198 PDB clone 时 不能新加datafile 以及hang的一个原因
create pluggable database XX from SS keystore identified by "YYY" parallel 32 service_name_convert( _srv, _srv); 20TB 4小时 update /* rule */ undo$ set name:2,file#:3,block#:4,status$:5,user#:6,undosqn:7,xactsqn:8,scnbas:9,scnwrp:10,inst#:11,…...
大秦朝历史
大秦朝是中国历史上一个虚构的朝代,通常被认为是秦朝的后继者。根据一些历史小说和影视作品的描述,大秦朝被描绘为一个强大的中央集权国家,统一了整个中国。大秦朝的帝王被描述为英明神武,开创了繁荣富强的盛世。 根据这些虚构的…...
docker部署工业操作系统基础环境手册
在 Docker 上安装最新的 TDengine 数据库并将数据文件和配置文件映射到宿主机,可以按照以下步骤操作: 一、Tdengine 篇章 1. 拉取最新的 TDengine 镜像 首先,确保你的 Docker 环境已安装并运行。然后,使用以下命令拉取 TDengine…...
算法 class 003
二进制表示数 8位 有符号二进制位,能表示正数128位 ,0 ~ 127(2的7次方减1) ,能表示负数128位 ,-1 ~ -128。 n 位有符号二进制位,一共能表示 2的n次放个数,正数为0 ~ (2的n-1次方) - 1(再减1&…...
gcc和gcc -c区别
gcc 和 gcc -c 之间的主要区别在于编译过程的不同阶段以及最终生成的输出文件类型。理解这两者的区别对于有效地管理和构建项目非常重要。 ### gcc(默认行为) 当你使用 gcc 编译器而没有指定 -c 选项时,GCC 会执行整个编译链的所有步骤&…...
从一次线上故障聊聊接口自动化测试
1、背景 3月初,运营同事配置了个还未上线的页面到网站首页 banner,导致用户点了报错。尽管这次很明确是运营人为操作失误引起的故障,但过往此类核心页面的访问异常,我们已不是第一次遇见。 从平台整体利益触发,我们各…...
工业大数据分析算法实战-day15
文章目录 day15特定数据类型的算法工业分析中的数据预处理工况划分数据缺失时间数据不连续强噪声大惯性系统趋势项消除 day15 今天是第15天,昨日是针对最优化算法、规则推理算法、系统辨识算法进行了阐述,今日主要是针对其他算法中的特定数据类型的算法…...
QLocalServer本地进程通信发送数据丢失部分数据丢失解决方案
问题说明 Qt使用QLocalServer进行本地进程通信,发现数据随机丢失。例如,我需要连续发送7个数据,如果连续调用socket的write接口,会引起数据随机丢失,导致数据不完整。 解决方案 我这里的解决方案是,将7个…...
0.gitlab ubuntu20.04 部署问题解决
安装依赖: ① sudo apt-get update 出现: 解决方式: 去 /etc/apt/sources.list.d 这个目录删除或注释对应的list文件 第三方软件的源一般都以list文件的方式放在 /etc/apt/sources.list.d 这个目录 重新运行sudo apt-get update 安装…...
tomcat temp临时文件不清空,占用硬盘,jdk字体内存泄漏
JSP老旧项目迁移过来的代码,生成海报,会读取图片,读取字体文件,绘制图片,会生成大量临时文件,内存泄漏。 方案一,服务器定时删除temp临时文件夹 方案二,图片、字体改用静态类读取文件…...
元宇宙中的去中心化应用:Web3的未来角色
随着科技的快速发展,元宇宙已经成为了全球关注的焦点,成为一种新型的虚拟世界互动平台。与此同时,Web3作为新一代互联网技术,借助去中心化的理念,为元宇宙的发展提供了技术支撑。从虚拟互动到数字身份管理,…...
中关村科金智能客服机器人如何解决客户个性化需求与标准化服务之间的矛盾?
客户服务的个性化和标准化之间的矛盾一直是一个挑战。一方面,企业需要提供标准化的服务以保持运营效率和成本控制;另一方面,为了提升客户满意度和忠诚度,企业又必须满足客户的个性化需求。为此,中关村科金推出了智能客…...
【ROS2】坐标TF发布(动态)
1、创建目录 mkdir -p ~/ros/src/laoer_tf2、创建包 cd /home/laoer/ros/eg/src/cpp/laoer_tf ros2 pkg create --build-type ament_cmake laoer_tf \--dependencies rclcpp tf2_ros geometry_msgs \--license Apache-2.03、源码 3.1 TF消息TransformStamped 1)消息类型 …...
图解HTTP-HTTP状态码
状态码 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。 类别原因短语1XXInformational(信息状态码)接收的请求正在处理2XXSuccess(成功状态码)请求正常处理完毕4XXRedirection (重定向状态码)需要…...
SAP消息号 FD014 (抬头)没有指定国际标准货币代码 CNY
1、IDOC配置完成后, 2、业务下单-发货-开票(2张) 3、WE02 查看IDOC时发现 从报错看是货币代码设置问题。 4、解决: OY03 RMB和CNY同时勾选导致 RMB不勾选主要。...
GRUtopia:构建虚拟世界中的智能机器人社会
人工智能咨询培训老师叶梓 转载标明出处 人工智能讲师大模型讲师叶梓前沿技术分享:GRUtopia:构建虚拟世界中的智能机器人社会 随着Embodied AI(具身智能)领域的快速发展,对于能够在复杂环境中执行任务的机器人的需求日…...
华为:数字化转型只有“起点”,没有“终点”
上个月,我收到了一位朋友的私信,他询问我是否有关于华为数字化转型的资料。幸运的是,我手头正好收藏了一些,于是我便分享给他。 然后在昨天,他又再次联系我,并感慨:“如果当初我在进行企业数字…...
在开发嵌入式系统时,尤其是处理大数时,会遇到取值范围的问题。51单片机通常没有内建大整数支持,因此我们需要采用不同的方法来解决这一问题
00 两种可行方法分别是: 使用数组存储每一位数据并进行进位运算:通过将大数按位拆分成数组,然后实现逐位加法、进位等操作。使用符号变量进行计算:将数值分成低位和高位,分别用符号变量进行计算。 01:使用…...
STM32 与 AS608 指纹模块的调试与应用
前言 在嵌入式系统中,指纹识别作为一种生物识别技术,广泛应用于门禁系统、考勤机、智能锁等场景。本文将分享如何在 STM32F103C8T6 开发板上使用 AS608 指纹模块,实现指纹的录入和识别功能。 硬件准备 STM32F103C8T6 开发板AS608 指纹模块…...
腾讯PHP经典面试题(附答案)
腾讯PHP经典面试题(附答案) PHP开发工程师笔试试卷 姓名:PHP 一、PHP开发部分 1.合并两个数组有几种方式,试比较它们的异同 答: 1、array_merge() 2、’’ 3、array_merge_recursive array_merge 简单的合并数…...
LightGBM分类算法在医疗数据挖掘中的深度探索与应用创新(上)
一、引言 1.1 医疗数据挖掘的重要性与挑战 在当今数字化医疗时代,医疗数据呈爆炸式增长,这些数据蕴含着丰富的信息,对医疗决策具有极为重要的意义。通过对医疗数据的深入挖掘,可以发现潜在的疾病模式、治疗效果关联以及患者的健康风险因素,从而为精准医疗、个性化治疗方…...
【PCIe 总线及设备入门学习专栏 1.1 -- PCIe 基础知识 lane和link介绍】
文章目录 OverivewLane 和 LinkRC 和 RPPCIe controllerPCIE ControllerPHY模块 Inbound 和 OutboundPCIe transaction modelPIODMAP2P Overivew PCIe,即PCI-Express总线(Peripheral Component Interconnect Express),是一种高速…...
PCDN 适合哪些人群?
家用宽带用户:对于家中有宽带,且宽带闲置时间较多的用户来说,PCDN是一个非常好的赚钱方式。只要你有足够的带宽和一台稳定的设备,就可以轻松参与。 小型网络运营者:如果你是小型网络运营者,拥有大量的闲置带宽资源PCDN 可以帮助你…...
C++之红黑树模拟实现
目录 红黑树的概念 红黑树的性质 红黑树的查找效率 红黑树的实现 红黑树的定义 红黑树节点的插入 红黑树的平衡调整 判断红黑树是否平衡 红黑树整体代码 测试代码 上期我们学习了AVL树的模拟实现,在此基础上,我们本期将学习另一个数据结构-…...
一分钟快速解读LEED绿色建筑认证
一分钟快速解读LEED绿色建筑认证——引领未来建筑绿色革命的风向标 LEED,全称为“Leadership in Energy and Environmental Design”,是美国绿色建筑委员会(USGBC)开发并推广的一套国际公认的绿色建筑评估体系。它如同一座灯塔&am…...
C# 语法糖集锦
文章目录 1、自动属性(Auto - Properties)2、对象和集合初始化器(Object and Collection Initializers)3、匿名类型(Anonymous Types)4、扩展方法(Extension Methods)5、Lambda 表达式(Lambda Expressions)6、空合并运算符(??)和空条件运算符(?.)7、隐式类型数…...
centos制作离线安装包
目录 1.yumdownloader与repotrack怎么选择? yumdownloader --resolve repotrack 总结 2.环境准备 3.安装 1.yumdownloader与repotrack怎么选择? yumdownloader --resolve 和 repotrack 都是与 YUM(Yellowdog Updater Modified…...