当前位置: 首页 > news >正文

结课作业01. 用户空间 MPU6050 体感鼠标驱动程序

目录

一. qt界面实现

二. 虚拟设备模拟模拟鼠标实现体感鼠标

2.1 函数声明

2.2 虚拟鼠标实现

2.2.1 虚拟鼠标创建函数

2.2.2 鼠标移动函数

2.2.3 鼠标点击函数

2.3 mpu6050相关函数实现

2.3.1 i2c设备初始化

2.3.2 mpu6050寄存器写入

2.3.3 mpu6050寄存器读取

2.3.4 mpu6050初始化

2.3.5 read_accel 加速度数据获取及处理函数

2.4 按键模拟鼠标点击功能实现

2.4.1 导出export按键对应的gpio

2.4.2 将gpio方向direction设置为输入

2.4.3 读取按键gpio状态,来控制鼠标按键

2.5 资源清理函数

2.6 主函数实现(伪代码)

2.7 源代码及执行步骤


        使用uinput虚拟设备实现体感鼠标,通过用户空间 input 设备测试程序读取/dev/event*文件获取鼠标状态,鼠标移动数据能随开发板倾角运动改变。

        鼠标按键可以使用 Key_DOWN、Key_RIGHT、Key_LEFT、Key_UP 四个按键中任选两个 实现,四个按键的 GPIO 编号为 960 – 963.(本实验使用Key_RIGHT、Key_LEFT分别实现鼠标的右键和左键)

一. qt界面实现

        为了测试虚拟鼠标的功能,使用qt软件画了一个窗口,通过以下指令将 .ui文件 转换成python可执行文件。

pyuic5 -x windows_mouse.ui -o windows_mouse.py

         qt完整python代码如下

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'windows_mouse.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!
# windows_mouse.pyfrom PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(480, 272)  # 调整窗口高度以容纳新控件self.verticalLayout = QtWidgets.QVBoxLayout(Form)self.verticalLayout.setObjectName("verticalLayout")# 原有的 right 按钮和进度条self.right = QtWidgets.QPushButton(Form)self.right.setObjectName("right")self.verticalLayout.addWidget(self.right)self.progressBarRight = QtWidgets.QProgressBar(Form)self.progressBarRight.setProperty("value", 0)  # 初始值设为 0self.progressBarRight.setObjectName("progressBarRight")self.verticalLayout.addWidget(self.progressBarRight)# 新增的 left 按钮和进度条self.left = QtWidgets.QPushButton(Form)self.left.setObjectName("left")self.verticalLayout.addWidget(self.left)self.progressBarLeft = QtWidgets.QProgressBar(Form)self.progressBarLeft.setProperty("value", 0)  # 初始值设为 0self.progressBarLeft.setObjectName("progressBarLeft")self.verticalLayout.addWidget(self.progressBarLeft)self.Exit = QtWidgets.QPushButton(Form)self.Exit.setObjectName("Exit")self.verticalLayout.addWidget(self.Exit)self.retranslateUi(Form)self.Exit.clicked.connect(Form.close)# 设置 right 按钮右键菜单self.right.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)self.right.customContextMenuRequested.connect(self.right_button_clicked)# 设置 left 按钮左键点击事件self.left.clicked.connect(self.left_button_clicked)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.right.setText(_translate("Form", "right"))self.left.setText(_translate("Form", "left"))self.Exit.setText(_translate("Form", "left - Exit"))def right_button_clicked(self, pos):# right 按钮右键点击事件处理if self.progressBarRight.value() == 0:self.progressBarRight.setValue(100)  # 进度条加满else:self.progressBarRight.setValue(0)  # 进度条变为 0def left_button_clicked(self):# left 按钮左键点击事件处理if self.progressBarLeft.value() == 0:self.progressBarLeft.setValue(100)  # 进度条加满else:self.progressBarLeft.setValue(0)  # 进度条变为 0if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)Form = QtWidgets.QWidget()ui = Ui_Form()ui.setupUi(Form)Form.show()sys.exit(app.exec_())

        运行python windows_mouse.py出现以下界面。其中right按键只能鼠标右键点击,left按键只能鼠标左键点击,left-Exit为鼠标左键点击的退出按键。

二. 虚拟设备模拟模拟鼠标实现体感鼠标

2.1 函数声明

        总共分为四个部分,分别是mpu6050设备初始化及信息获取、虚拟鼠标实现、gpio设备初始化及按键gpio信息获取、资源清理clean。

/* 函数声明 */
// mpu6050和i2c的初始化和功能函数
int i2c_init(const char* i2c_dev);
void mpu6050_write(int fd, uint8_t reg, uint8_t val);
void mpu6050_read(int fd, uint8_t reg, uint8_t* buf, int len);
void mpu6050_init(int fd);
void read_accel(int fd, float* accel);
// 清理
void cleanup_handler(int sig);
// 虚拟鼠标创建及移动、点击
int create_virtual_mouse(const char* dev_name);
void send_mouse_move(int fd, int dx, int dy);
int send_mouse_click(int fd, int button_code);// 按键对应鼠标点击
void set_gpio_direction(int gpio, const char *direction);
char read_gpio_value(int gpio);
void export_gpio(int gpio);
void unexport_gpio(int gpio);

2.2 虚拟鼠标实现

2.2.1 虚拟鼠标创建函数

        1. 创建虚拟鼠标需要:配置鼠标移动按键事件、初始化设备信息、提交设备配置 三个步骤。

int create_virtual_mouse(const char* dev_name) {struct uinput_user_dev uidev;int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);/* 配置基础事件类型 */    // 此处没有错误处理,代码里有// 鼠标移动事件ioctl(fd, UI_SET_EVBIT, EV_REL);ioctl(fd, UI_SET_RELBIT, REL_X);ioctl(fd, UI_SET_RELBIT, REL_Y);// 鼠标按键事件ioctl(fd, UI_SET_EVBIT, EV_KEY);ioctl(fd, UI_SET_KEYBIT, BTN_LEFT);ioctl(fd, UI_SET_KEYBIT, BTN_RIGHT);/* 初始化设备信息 */memset(&uidev, 0, sizeof(uidev));snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "%s", dev_name);uidev.id.bustype = BUS_USB;uidev.id.version = 4;/* 提交设备配置 */ioctl(fd, UI_DEV_SETUP, &uidev);    // 提交设备配置ioctl(fd, UI_DEV_CREATE);           // 创建设备
}

2.2.2 鼠标移动函数

void send_mouse_move(int fd, int dx, int dy) {struct input_event ev[3];struct timeval tv;gettimeofday(&tv, NULL);    // 此函数是获取时间戳// X轴移动memset(&ev[0], 0, sizeof(ev[0]));	// 初始化ev[0]的所有成员为0ev[0].type = EV_REL;ev[0].code = REL_X;ev[0].value = dx;ev[0].time = tv;// Y轴移动memset(&ev[1], 0, sizeof(ev[1]));ev[1].type = EV_REL;ev[1].code = REL_Y;ev[1].value = dy;ev[1].time = tv;// 同步事件memset(&ev[2], 0, sizeof(ev[2]));ev[2].type = EV_SYN;ev[2].code = SYN_REPORT;ev[2].value = 0;ev[2].time = tv;
}

        1. 使用到的结构体 input_event 结构体介绍

#include <linux/input.h>struct input_event {struct timeval time;  // 时间戳__u16 type;           // 事件类型__u16 code;           // 事件代码__s32 value;          // 事件值
};
变量名类型功能
timestruct timeval记录输入事件发生的时间戳,包含秒(tv_sec)和微秒(tv_usec),通常用于事件排序或性能分析
type__u16

表示输入事件的类型,如按键事件(EV_KEY)、相对位置事件(EV_REL)

、(EV_SYN)同步事件(标记批次结束)

code__u16

与 type 结合,具体化事件含义,如具体按键、轴或输入元素

EV_KEY 类型

BTN_LEFT  // 鼠标左键(0x110)、

BTN_RIGHT // 鼠标右键(0x111)、

KEY_ENTER  // 回车键(0x1c)

EV_REL 类型

REL_X  // X轴相对移动、

(0x00)REL_Y  // Y轴相对移动(0x01)、

REL_WHEEL  // 滚轮滚动(0x08)

EV_ABS 类型

ABS_X  // X轴绝对坐标、(

0x00)ABS_Y  // Y轴绝对坐标(0x01)

value__s32

表示与事件相关的具体值,含义取决于 event 的 type 和 code

EV_KEY 事件:

value = 1:按键按下

value = 0:按键释放

value = 2:按键长按(部分设备支持)

EV_REL 事件:

value = 10:X轴向右移动10像素

value = -5:Y轴向下移动5像素

EV_ABS 事件:

value = 500:触摸屏X轴坐标为500

         2. 注意:每次事件完成都要调用同步事件,将鼠标位置和按键状态更新。

2.2.3 鼠标点击函数

        和鼠标移动函数类似,只是将鼠标移动函数中的input_event结构体的参数值给鼠标按键相关的参数即可。

2.3 mpu6050相关函数实现

2.3.1 i2c设备初始化

/* I2C设备初始化 */
int i2c_init(const char* i2c_dev) {int fd = open(i2c_dev, O_RDWR);if (fd < 0) {perror("Failed to open I2C device");return -1;}// 因为ioctl的数据结构体有“从机地址”参数,所以不用单独设置从机地址return fd;
}

2.3.2 mpu6050寄存器写入

/* MPU6050寄存器写操作 */
void mpu6050_write(int fd, uint8_t reg, uint8_t val) {struct i2c_msg msg;uint8_t buf[2] = {reg, val};msg.addr  = MPU6050_ADDR;	// 设备地址msg.flags = 0;		// 写操作msg.len   = 2;		// 数据长度(寄存器地址 + 值)msg.buf   = buf;		// 数据缓冲区struct i2c_rdwr_ioctl_data ioctl_data;ioctl_data.msgs = &msg;	// 消息数组ioctl_data.nmsgs = 1;	// 消息数量if (ioctl(fd, I2C_RDWR, &ioctl_data) < 0)perror("MPU6050 write failed");
}

        1. struct i2c_rdwr_ioctl_data结构体详解

struct i2c_rdwr_ioctl_data {struct i2c_msg* msgs;  /* I2C 消息数组的指针 */int nmsgs;             /* 消息数组的元素个数 */
};
参数名类型功能
msgsstruct i2c_msg*指向一个 i2c_msg 结构体数组的指针,每个数组元素描述了一次 I2C 传输操作(消息)。
nmsgsint表示 msgs 数组中元素的个数,即要执行的 I2C 消息传输操作的次数。

        2.  struct i2c_msg结构体详解

struct i2c_msg {__u16 addr;        /* I2C从设备地址 */__u16 flags;       /* 消息标志 */__u16 len;         /* 数据缓冲区长度 */__u8 *buf;         /* 数据缓冲区指针 */
};
参数名类型功能说明
addr__u16I2C从设备地址,用于指定要通信的从设备的7位或10位地址
flags__u16消息标志,用于指定传输方向等信息,如I2C_M_RD(读取操作),flags=0(写入操作)等
len__u16要传输的数据长度,即buf数组中数据的字节数
buf__u8 *指向数据缓冲区的指针,用于存储要发送的数据或接收到的数据

2.3.3 mpu6050寄存器读取

        将 i2c_msg 的flags标志换成读取操作即可。

        注意:在读取数据之前,主设备(linux开发板)需要先指定要读取的从设备(mpu6050)寄存器地址。所以在读取数据之前需要先进行一次写入。这个写入操作的作用是将寄存器地址发送给 MPU6050,告诉它接下来要从哪个寄存器开始读取数据。

2.3.4 mpu6050初始化

/* MPU6050初始化 (关闭睡眠模式)*/
void mpu6050_init(int fd) {mpu6050_write(fd, ACCEL_CONFIG, 0x00); // ±2g量程mpu6050_write(fd, PWR_MGMT_1, 0x00);   // 退出睡眠模式usleep(100000); // 等待稳定100ms
}

2.3.5 read_accel 加速度数据获取及处理函数

        调用mpu6050_read函数读取加速度数据,并进行处理,转换为m/s²的加速度。

/* 读取加速度数据 (XYZ 三轴)*/
void read_accel(int fd, float* accel) {uint8_t buf[6];mpu6050_read(fd, ACCEL_XOUT_H, buf, 6);// 合并原始数据并转换单位int16_t raw_x = (int16_t)((buf[0] << 8) | buf[1]);	// X 轴int16_t raw_y = (int16_t)((buf[2] << 8) | buf[3]);	// Y 轴int16_t raw_z = (int16_t)((buf[4] << 8) | buf[5]);	// Z 轴// 转换为 m/s²accel[0] = (raw_x / ACCEL_SCALE_2G) * GRAVITY_CM_S2;accel[1] = (raw_y / ACCEL_SCALE_2G) * GRAVITY_CM_S2;accel[2] = (raw_z / ACCEL_SCALE_2G) * GRAVITY_CM_S2;
}

2.4 按键模拟鼠标点击功能实现

2.4.1 导出export按键对应的gpio

        还有对应的撤销导出unexport函数同理。

// 导出gpio
void export_gpio(int gpio) {FILE *fp = fopen(GPIO_EXPORT, "w");if (fp == NULL) {perror("Failed to open export file");fprintf(stderr, "Error code: %d\n", errno);exit(EXIT_FAILURE);}fprintf(fp, "%d", gpio);fclose(fp);
}

2.4.2 将gpio方向direction设置为输入

// 设置gpio方向为输入
void set_gpio_direction(int gpio, const char *direction) {char path[64];snprintf(path, sizeof(path), GPIO_DIRECTION, gpio);FILE *fp = fopen(path, "w");if (fp == NULL) {perror("Failed to open direction file");fprintf(stderr, "Error code: %d\n", errno);exit(EXIT_FAILURE);}fprintf(fp, "%s", direction);fclose(fp);
}

2.4.3 读取按键gpio状态,来控制鼠标按键

char read_gpio_value(int gpio) {char path[64];snprintf(path, sizeof(path), GPIO_VALUE, gpio);FILE *fp = fopen(path, "r");if (fp == NULL) {perror("Failed to open value file");fprintf(stderr, "Error code: %d\n", errno);exit(EXIT_FAILURE);}char value[2];fgets(value, sizeof(value), fp);fclose(fp);return value[0] == '1' ? '1' : '0';
}

2.5 资源清理函数

        销毁虚拟设备、关闭i2c、撤销导出按键gpio。

void cleanup_handler(int sig) {if (uinput_fd >= 0) {// 销毁虚拟设备ioctl(uinput_fd, UI_DEV_DESTROY);close(uinput_fd);printf("\n[Cleanup] Virtual mouse device destroyed\n");}if (i2c_fd >= 0) {  // 新增:关闭I2C设备close(i2c_fd);printf("[Cleanup] I2C device closed\n");i2c_fd = -1;     // 重置描述符}int gpios[] = {960, 961, 962, 963, 964};int num_gpios = sizeof(gpios) / sizeof(gpios[0]);for (int i = 0; i < num_gpios; i++) {unexport_gpio(gpios[i]);}printf("all gpio unexported\n");fflush(stdout); // 强制刷新标准输出exit(EXIT_SUCCESS);
}

2.6 主函数实现(伪代码)

int main() {// 1. 注册信号处理(Ctrl+C)/* 2. 创建虚拟鼠标 *//* 3. 初始化MPU6050 */// 4. 导出五个按键的gpio,并设置方向为输入while (1) {// 调整方向// 发送给虚拟鼠标使其移动// 读取当前按钮状态// 键盘左键对应鼠标左键// 键盘右键对应鼠标右键// 按键消抖}//资源清理
}

2.7 源代码及执行步骤

        源代码:用户空间MPU6050体感虚拟鼠标驱动程序资源-CSDN文库

# 代码编译 -lm 是因为使用了数学公式
gcc mpu_mouse.c -o mpu_mouse.out -lm# 功能实现1:添加需要的环境变量,屏幕和鼠标# Qt-embedded需要的环境变量
# • 指定显示设备
export QT_QPA_PLATFORM=linuxfb
# • 指定输入设备(触摸屏)
export QT_QPA_GENERIC_PLUGINS=evdevtouch:/dev/input/event0
export QWS_MOUSE_PROTO=evdevtouch:/dev/input/event0
# • 指定输入设备(鼠标)
export QT_QPA_GENERIC_PLUGINS=evdevmouse:/dev/input/event0
export QWS_MOUSE_PROTO=evdevmouse:/dev/input/event0# 功能实现2 # "&"符号是因为要放在后台运行,然后运行鼠标控制程序
python windows_mouse.py &
./mpu_mouse.c

相关文章:

结课作业01. 用户空间 MPU6050 体感鼠标驱动程序

目录 一. qt界面实现 二. 虚拟设备模拟模拟鼠标实现体感鼠标 2.1 函数声明 2.2 虚拟鼠标实现 2.2.1 虚拟鼠标创建函数 2.2.2 鼠标移动函数 2.2.3 鼠标点击函数 2.3 mpu6050相关函数实现 2.3.1 i2c设备初始化 2.3.2 mpu6050寄存器写入 2.3.3 mpu6050寄存器读取 2.3.…...

Linux操作系统:信号

信号的基本介绍 信号是系统响应某个条件而产生的事件&#xff0c;进程接收到信号会执行响应的操作&#xff1b; &#xff08;1&#xff09;信号的储存位置 vim /usr/include/x86_64-linux-gnu/bits/signum.h 旧版 新版&#xff1a; vim /usr/include/x86_64-linux-gnu/bit…...

OpenCV CUDA模块特征检测与描述------用于创建一个最大值盒式滤波器(Max Box Filter)函数createBoxMaxFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 createBoxMaxFilter()函数创建的是一个 最大值滤波器&#xff08;Maximum Filter&#xff09;&#xff0c;它对图像中每个像素邻域内的像素值取最…...

有没有其他影视app可以像群晖video station一样可以被Windows的本地网络驱动器找到

你是在寻找可以通过Windows本地网络&#xff08;SMB共享&#xff09;访问的影视媒体服务程序&#xff0c;就像群晖的 Video Station 一样&#xff0c;可以浏览、播放或挂载电影资源。以下是一些可选方案&#xff1a; ✅ 具备与 Synology Video Station 类似功能&#xff0c;并支…...

【神经网络与深度学习】流模型的通俗易懂的原理

流模型&#xff08;Flow-based Model&#xff09;简介 引言 流模型是一种强大的生成模型&#xff0c;它通过可逆变换将简单的概率分布转化为复杂的数据分布。相比于扩散模型和生成对抗网络&#xff08;GAN&#xff09;&#xff0c;流模型可以精确计算数据的概率&#xff0c;并…...

OpenCV CUDA模块图像特征检测与描述------图像中快速检测特征点类cv::cuda::FastFeatureDetector

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::FastFeatureDetector 是 OpenCV 的 CUDA 加速模块中的一部分&#xff0c;用于在图像中快速检测特征点。FAST&#xff08;Features fro…...

分享一些多模态文档解析思路

多模态文档解析思路小记 作者&#xff1a;Arlene 原文&#xff1a;https://zhuanlan.zhihu.com/p/1905635679293122466 多模态文档解析内容涉及&#xff1a;文本、表格和图片 解析思路v1 基于mineru框架对pdf文件进行初解析 其具备较完整的布局识别和内容识别&#xff0c;并将…...

【OCCT+ImGUI系列】009-Geom2d-Geom2d_AxisPlacement

一、Geom2d_AxisPlacement 简介 在 OpenCASCADE 的二维几何库中&#xff0c;Geom2d_AxisPlacement 是一个用于定义二维坐标系的几何类&#xff0c;主要包含一个原点&#xff08;gp_Pnt2d&#xff09;和一个方向向量&#xff08;gp_Dir2d&#xff09;。它在构造与控制二维几何对…...

【深度学习:理论篇】--Pytorch之nn.Module详解

目录 1.torch.nn.Module--概述 2.torch.nn.Module--简介 3.torch.nn.Module--实现 3.1.Sequential来包装层 3.2.children和modules 1.torch.nn.Module--概述 1. PyTorch vs. Keras 的设计差异 Keras&#xff08;高层框架&#xff09;&#xff1a; 推荐通过继承 Layer 类…...

SQLMesh 宏操作符详解:@IF 的条件逻辑与高级应用

SQLMesh 的 IF 宏提供了一种在 SQL 查询中嵌入条件逻辑的方法&#xff0c;允许根据运行时条件动态调整查询结构。本文深入探讨 IF 的语法、使用场景及实际案例&#xff0c;帮助开发者构建更灵活、可维护的 SQL 工作流。 1. IF 宏简介 IF 是 SQLMesh 提供的条件逻辑宏&#xff…...

最新版Chrome浏览器调用ActiveX控件之eDrawings Viewer专用包v2.0.42版本发布

背景 eDrawings是一款轻量级的2D和3D浏览/可视化软件&#xff0c;主要用于查看和分享由SolidWorks创建的3D模型和2D工程图。它支持多种CAD文件格式&#xff0c;使得用户能够方便地在不同CAD系统之间转换和查看设计数据。‌适用于设计师和工程师之间的即时协作&#xff0c;通过电…...

人工智能应用时代:个人成长与职业突围的底层逻辑

当人工智能从实验室走向现实场景&#xff0c;从概念热词变为生产力工具&#xff0c;一场静默却深刻的变革正在重塑人类社会的运行规则。无论是算法驱动的智能推荐、语言模型支撑的自动化创作&#xff0c;还是工业机器人对传统生产线的颠覆&#xff0c;人工智能应用已渗透至社会…...

STM32之串口通信蓝牙(BLE)

一、串口通信的原理与应用 通信的方式 处理器与外部设备之间或者处理器与处理器之间通信的方式分两种&#xff1a;串行通信和并行通信。 串行通信 传输原理&#xff1a;数据按位依次顺序传输&#xff08;每一位占据固定的时间长度 MSB or LSB&#xff09; 优点&#xff1a…...

【Spring Boot】配置实战指南:Properties与YML的深度对比与最佳实践

目录 1.前言 2.正文 2.1配置文件的格式 2.2properties 2.2.1基础语法 2.2.2value读取配置文件 2.2.3缺点 2.3yml 2.3.1基础语法 2.3.2配置不同数据类型 2.3.3配置读取 2.3.4配置对象和集合 2.3.5优缺点 2.4综合练习&#xff1a;验证码案例 2.4.1分析需求 2.4.2…...

数据结构篇--优先级队列排序--实验报告

实验简介框架代码实验步骤运行结果实验总结 实验概述 优先队列排序算法的基本思想是&#xff1a; 将所有待排序元素依次插入到优先队列中&#xff0c;然后按照从大到小的顺序&#xff0c;通过重复删除优先队列中的最大元素&#xff0c;取出所有元素&#xff0c;从而实现排序…...

【图像大模型】基于深度对抗网络的图像超分辨率重建技术ESRGAN深度解析

基于深度对抗网络的图像超分辨率重建技术ESRGAN深度解析 一、技术背景与核心创新1.1 图像超分辨率技术演进1.2 核心技术创新对比 二、算法原理深度解析2.1 网络架构设计2.1.1 RRDB模块结构 2.2 损失函数设计2.2.1 对抗损失&#xff08;Adversarial Loss&#xff09;2.2.2 感知损…...

Ubuntu 20.04卸载并重装 PostgreSQL

在 Ubuntu 下彻底卸载并重新安装 PostgreSQL&#xff08;包括所有版本及其数据目录&#xff09;的步骤 下面是一个在 Ubuntu 下彻底卸载并重新安装 PostgreSQL&#xff08;包括所有版本及其数据目录&#xff09;的步骤。 文章目录 在 Ubuntu 下彻底卸载并重新安装 PostgreSQL&…...

debian系统redis-dump安装

1. ​Ruby 环境​ Redis-dump 是一个 Ruby 工具&#xff0c;需先安装 Ruby 和 RubyGems。 安装命令​&#xff1a; sudo apt update sudo apt install ruby-full build-essential[roota29d39f5fd10:/opt/redis-dump/bin# apt install ruby-full build-essential Reading pac…...

AI智能分析网关V4玩手机检测算法精准管控人员手机行为,搭建智慧化安防监管体系

一、背景​ 移动终端普及使随意用机成为常态&#xff0c;在生产车间、加油站、考场、手术室等场景&#xff0c;人员使用手机易引发生产事故、爆炸、作弊、仪器干扰等问题。传统人工巡查存在覆盖不足、响应慢、主观性强等局限&#xff0c;难以满足现代安全管理需求。AI智能分析…...

支持向量存储:PostgresSQL及pgvector扩展详细安装步骤!老工程接入RAG功能必备!

之前文章和大家分享过&#xff0c;将会出一篇专栏&#xff08;从电脑装ubuntu系统&#xff0c;到安装ubuntu的常用基础软件&#xff1a;jdk、python、node、nginx、maven、supervisor、minio、docker、git、mysql、redis、postgresql、mq、ollama等&#xff09;&#xff0c;目前…...

小土堆pytorch--神经网络-非线性激活线性层及其他层介绍

1. 神经网络-非线性激活 1.1 relu与sigmoid 1.1.1 ReLU&#xff08;Rectified Linear Unit&#xff0c;修正线性单元 &#xff09; 定义与数学表达&#xff1a;数学定义为 f ( x ) max ⁡ ( 0 , x ) f(x) \max(0, x) f(x)max(0,x) &#xff0c;即当输入 x > 0 x > …...

【Vue3】数据的返回和响应式处理(ref reactive)

目录 一、拉开序幕的setup 二、ref函数 2.1 访问对象的响应式处理 小结&#xff1a;ref函数 三、reactive函数 3.1 reactive同样也可以修改数组&#xff1a; 3.2 reactive小结&#xff1a; 四、Vue3中的响应式原理 4.1 vue2的响应式&#xff0c;对象属性的添加 4.2…...

【Rust智能指针】Rust智能指针原理剖析与应用指导

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

C++ - 仿 RabbitMQ 实现消息队列(3)(详解使用muduo库)

C - 仿 RabbitMQ 实现消息队列&#xff08;3&#xff09;&#xff08;详解使用muduo库&#xff09; muduo库的基层原理核心概念总结&#xff1a;通俗例子&#xff1a;餐厅模型优势体现典型场景 muduo库中的主要类EventloopMuduo 的 EventLoop 核心解析1. 核心机制&#xff1a;事…...

Java异常处理全解析:从基础到自定义

目录 &#x1f680;前言&#x1f914;异常的定义与分类&#x1f4af;运行时异常&#x1f4af;编译时异常&#x1f4af;异常的基本处理 &#x1f31f;异常的作用&#x1f427;自定义异常&#x1f4af;自定义运行时异常&#x1f4af;自定义编译时异常 ✍️异常的处理方案&#x1…...

C++初阶-vector的模拟实现2

目录 1.vector已经实现的代码总结 2.vector::resize的模拟实现 3.vector::vector(const vector& v)拷贝构造函数的模拟实现 4.vector::operator(const vector& x)的模拟实现&#xff08;原始写法&#xff09; 5.vector::swap的模拟实现 6.vector::operator(const …...

【图数据库】--Neo4j 安装

目录 1.Neo4j --概述 2.JDK安装 3.Neo4j--下载 3.1.下载资源包 3.2.创建环境变量 3.3.运行 Neo4j 是目前最流行的图形数据库(Graph Database)&#xff0c;它以节点(Node)、关系(Relationship)和属性(Property)的形式存储数据&#xff0c;专门为处理高度连接的数据而设计。…...

elementui初学1

当然可以&#xff01;下面是从零开始创建一个最简单的 Element UI 程序的完整流程&#xff0c;基于 Vue 2 Element UI&#xff08;如果你想用 Vue 3&#xff0c;请告诉我&#xff0c;我可以给你 Element Plus 的版本&#xff09;。 ✅ 一、准备环境 确保你已经安装了&#xf…...

lanqiaoOJ 4185:费马小定理求逆元

【题目来源】 https://www.lanqiao.cn/problems/4185/learning/ 【题目描述】 给出 n&#xff0c;p&#xff0c;求 。其中&#xff0c; 指存在某个整数 0≤a<p&#xff0c;使得 na mod p1&#xff0c;此时称 a 为 n 的逆元&#xff0c;即 。数据保证 p 是质数且 n mod p≠0…...

计算机视觉与深度学习 | Python实现CEEMDAN-ISOS-VMD-GRU-ARIMA时间序列预测(完整源码和数据)

以下是结合CEEMDAN、ISOS-VMD、GRU和ARIMA的时间序列预测的Python完整实现方案。本方案包含完整的代码、数据生成逻辑和实现细节说明。 完整代码实现 import numpy as np import pandas as pd from PyEMD import CEEMDAN from vmdpy import VMD from scipy.optimize import di…...

前端开发遇到 Bug,怎么办?如何利用 AI 高效解决问题

前端开发遇到 Bug&#xff0c;怎么办&#xff1f;如何利用 AI 高效解决问题 作为前端开发者&#xff0c;遇到 Bug 几乎是日常。无论是样式错乱、功能异常&#xff0c;还是接口数据不对&#xff0c;Bug 总能让人头疼。但随着人工智能&#xff08;AI&#xff09;技术的发展&…...

博主总结框架

1.博主总结框架 1.1 计算机基础类&#xff08;数据结构、计算机网络、操作系统等&#xff09; &#xff08;1&#xff09;数据结构 &#xff08;2&#xff09;操作系统 &#xff08;3&#xff09;计算机网络 &#xff08;4&#xff09;其他 物联网入门框架 1.2 计算机图形…...

国产化Excel处理组件Spire.XLS for .NET系列教程:通过 C# 将 TXT 文本转换为 Excel 表格

在数据处理和管理场景中&#xff0c;将原始文本文件&#xff08;TXT&#xff09;高效转换为结构化的 Excel 电子表格是一项常见要求。对于那些需要自动生成报表或者处理日志文件的开发人员而言&#xff0c;借助 C# 实现 TXT 到 Excel 的转换工作&#xff0c;可以简化数据组织和…...

网络安全--PHP第一天

目标 熟悉信息传递架构 基于phpstydy-mysql-php 前置条件 需要先在数据库中创建相应的库和表名并配置表的结构 该文件为数据库配置文件 名字为config.php <?php $dbip localhost;//连接数据库的地址 远程连接需要输入ip等 $dbuser root;//连接数据库的用户 $dbpass ro…...

结构型:组合模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 实现案例 3、优缺点分析 4、适用场景 1、核心思想 目的&#xff1a;将总是在重复、迭代地显示的某种自相似性的结构&#xff08;部分与整体结构特征相似&#xff09;&#xff0c;例如树形结构&#xff0c;以统一的方式处…...

Node.js多版本安装工具NVM详细使用教程

一、nvm 简介 nvm&#xff08;Node Version Manager&#xff09;是一个用于管理多个 Node.js 版本的命令行工具&#xff0c;允许开发者在单个系统中轻松切换、安装和卸载不同版本的 Node.js。它是前端和后端开发中处理 Node.js 版本兼容性问题的核心工具之一。 二、nvm 安装 …...

深度解析 Java 中介者模式:重构复杂交互场景的优雅方案

一、中介者模式的核心思想与设计哲学 在软件开发的历史长河中&#xff0c;对象间的交互管理一直是架构设计的核心难题。当多个对象形成复杂的网状交互时&#xff0c;系统会陷入 "牵一发而动全身" 的困境。中介者模式&#xff08;Mediator Pattern&#xff09;作为行…...

(八)深度学习---计算机视觉基础

分类问题回归问题聚类问题各种复杂问题决策树√线性回归√K-means√神经网络√逻辑回归√岭回归密度聚类深度学习√集成学习√Lasso回归谱聚类条件随机场贝叶斯层次聚类隐马尔可夫模型支持向量机高斯混合聚类LDA主题模型 一.图像数字化表示及建模基础 二.卷积神经网络CNN基本原…...

深入剖析原型模式:原理、实现与应用实践

在软件开发的世界里,设计模式如同建筑师手中的蓝图,为复杂系统的构建提供了行之有效的解决方案。其中,原型模式(Prototype Pattern)作为创建型设计模式的重要一员,以其独特的对象创建方式,在提高代码复用性、增强系统灵活性等方面发挥着关键作用。本文将深入剖析原型模式…...

【论文阅读 | CVPR 2024 |RSDet:去除再选择:一种用于 RGB - 红外目标检测的由粗到精融合视角】

论文阅读 | CVPR 2024 |RSDet:去除再选择&#xff1a;一种用于 RGB - 红外目标检测的由粗到精融合视角 1.摘要&&引言2. 方法2.1 “由粗到细”融合策略2.2 冗余光谱去除模块&#xff08;RSR&#xff09;2.3 动态特征选择模块&#xff08;DFS&#xff09;2.4 去除与选择检…...

WinForms 应用中集成 OpenCvSharp 实现基础图像处理

引言 欢迎关注dotnet研习社&#xff0c;今天我们要讨论的主题是WinForms 应用中集成 OpenCvSharp 实现基础图像处理。 在常规的图像处理软件开发中&#xff0c;图像处理功能是这些应用程序的核心组成部分。无论是简单的照片编辑工具&#xff0c;还是复杂的计算机视觉应用&…...

apache http client连接池实现原理

在java开发中我们经常会涉及到http 请求接口&#xff0c;一般有几种方式&#xff1a; java自带的 HttpURLConnectionokHttpClientapache http client 一般我们使用apache http client会比较多点&#xff0c;在代码中会进行如下调用方式&#xff1a; private static class Htt…...

adb抓包

目录 抓包步骤 步骤 1: 获取应用的包名 步骤 2: 查看单个应用的日志 步骤 3: 使用日志级别过滤器 步骤 4: 高级日志过滤 可能的原因&#xff1a; 解决方案&#xff1a; 额外提示&#xff1a; 日志保存 抓包步骤 连接设备 adb devices 步骤 1: 获取应用的包名 首先…...

C语言---结构体 、联合体、枚举

一、初识结构体 1、结构体类型 结构体和数组都是集合&#xff0c;但是结构体有成员&#xff0c;类型可以不同&#xff1b;数组有成员&#xff0c;类型相同。 int main() {struct tag{member--list //一个或者多个成员&#xff0c;成员变量}variable--list;//可以省略&#x…...

Web Workers 使用指南

文章目录 前言基础使用高级特性 使用 ES Modules实际应用场景图像处理大数据处理轮询任务 性能优化技巧现代开发方式使用 worker-loader (Webpack) Vite中的Worker使用 限制与注意事项DOM限制:通信限制:同源策略:最佳实践 前言 Web Workers 是浏览器提供的 JavaScript 多线程解…...

JVM 与容器化部署调优实践(Docker + K8s)

&#x1f4cc; 文章目录 &#x1f4d8; 前言1️⃣ 容器环境下 JVM 面临的新挑战2️⃣ JVM 的容器资源感知机制详解3️⃣ JVM 内存调优&#xff1a;如何正确使用堆内存4️⃣ JVM CPU 调优&#xff1a;GC 与编译线程控制5️⃣ Kubernetes 典型配置误区与对策6️⃣ 实战案例&#…...

Android OkHttp控制链:深入理解网络请求的流程管理

OkHttp作为Android和Java平台上广泛使用的HTTP客户端&#xff0c;其核心设计之一就是"控制链"(Chain)机制。本文将深入探讨OkHttp控制链的工作原理、实现细节以及如何利用这一机制进行高级定制。 一、什么是OkHttp控制链 OkHttp控制链是一种责任链模式的实现&#…...

《易经》的数学表达:初级版和高级版

《易经》的数学表达&#xff0c; 一、初级版&#xff0c;可基于以下框架构建&#xff0c; 涵盖符号系统、结构代数及变换规则&#xff1a; 此框架将《易经》抽象为离散数学结构&#xff0c;兼容符号逻辑、概率论与群论&#xff0c;为算法化占断、卦象拓扑分析及跨文化比较提供…...

卷积神经网络基础(十)

之前我们学习了SGD、Momentum和AdaGrad三种优化方法&#xff0c;今天我们将继续学习Adam方法。 6.1.6 Adam 我们知道Momentum参照的是小球在碗中滚动的物理规则进行移动而实现的&#xff0c;AdaGrad为参数的每个元素适当地调整更新步伐。那如果我们将这两种方法融合在一起会不…...

怎么把cursor(Cursor/ollama)安装到指定路径

使用PowerShell命令 打开电脑开始菜单&#xff0c;输入powerShell&#xff0c;使用管理员权限打开powerShell窗口&#xff0c;使用cd命令到cursor或ollama安装包的下载目录&#xff0c;如我的Cursor所在的目录为D:\environment\cursor\soft&#xff0c;输入以下 cd E:\downloa…...