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

RT-Thread+STM32L475VET6——USB鼠标模拟


文章目录

  • 前言
  • 一、板载资源
  • 二、具体步骤
    • 1.配置icm20608传感器
    • 2.打开CubeMX进行USB配置
    • 3. 配置USB
      • 3.1 打开USB驱动
      • 3.2 声明USB
      • 3.3 剪切stm32xxxx_hal_msp.c中的void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)和void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)函数至board.c
      • 3.4 使能USB
    • 4. 编译,烧录


前言

本文采用开发板为STM32L475VET6(潘多拉开发板),使用RT_Thread Studio基于芯片开发模式,系统版本为4.0.3,完成模拟鼠标实验,实现鼠标功能,左键为KEY0,右键为KEY2


一、板载资源

icm20608传感器采用I2C协议,本文采用软件模拟I2C
查阅数据手册:开发板使用的是 PC0 模拟时钟线SCL、PC1 模拟数据线 SDA,
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、具体步骤

1.配置icm20608传感器

RT-Thread+STM32L475VET6——icm20608传感器

2.打开CubeMX进行USB配置

在这里插入图片描述
生成工程

3. 配置USB

按照官方步骤配置
在这里插入图片描述

3.1 打开USB驱动

在这里插入图片描述

3.2 声明USB

在这里插入图片描述

3.3 剪切stm32xxxx_hal_msp.c中的void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)和void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)函数至board.c

在这里插入图片描述

3.4 使能USB

一般默认开启
在这里插入图片描述

4. 编译,烧录

示例代码

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>#include "icm20608.h"
#include <math.h>#define DBG_SECTION_NAME "3D_mouse"
#define DBG_LEVEL DBG_LOG
#include <rtdbg.h>#define PIN_KEY0 GET_PIN(D,10)
#define PIN_KEY2 GET_PIN(D,8)static rt_sem_t mouse_sem = RT_NULL;static struct rt_thread usb_thread;
ALIGN(RT_ALIGN_SIZE)
static char usb_thread_stack[0x1000];static struct rt_thread icm_thread;
ALIGN(RT_ALIGN_SIZE)
static char icm_thread_stack[0x1000];static struct rt_thread key_thread;
ALIGN(RT_ALIGN_SIZE)
static char key_thread_stack[0x1000];/* 变动识别值 */
const static float mouse_rang_scope = 6.0f;
/* 读取角度有效角度 */
const static float mouse_angle_range = 80.0f;
/* 移动值的最大值 */
const static float mouse_move_range = 127.0f;
/* 角度移动比 */
#define mouse_ratio (mouse_move_range / mouse_angle_range)
/* 移动步长 */
const static rt_uint8_t mouse_pixel_len = 5;
/* 鼠标响应时间 */
const static rt_uint32_t mouse_sample_times = 0;static float mouse_cmp_last_x, mouse_cmp_last_y;#define Gyro_Gr 0.0010653f
#define pi 3.141593f
#define Kp 10.0f
#define Ki 0.008f
#define halfT 0.01fstatic float q0 = 1, q1 = 0, q2 = 0, q3 = 0;
static float exInt = 0, eyInt = 0, ezInt = 0;struct icm_position
{icm20608_device_t icm20608_device;rt_mutex_t lock;float x;           // 传感器 x 位置float y;           // 传感器 y 位置float z;           // 传感器 z 位置rt_int8_t buff[4]; // 发送鼠标的值
};
typedef struct icm_position *icm_position_t;icm_position_t icm_device = RT_NULL;static void mouse_meas_check(float *temp)
{if (*temp > mouse_angle_range){*temp = mouse_angle_range;}else if (*temp < -mouse_angle_range){*temp = -mouse_angle_range;}
}#ifdef __GNUC__const float __atan2f_lut[4] = {-0.0443265554792128, //p7-0.3258083974640975, //p3+0.1555786518463281, //p5+0.9997878412794807  //p1
};
const float __atan2f_pi_2 = 1.5707963;/* 求平方根 */
static float _sqrt(float x)
{float xhalf = 0.5f * x;int i = *(int *)&x;i = 0x5f375a86 - (i >> 1);x = *(float *)&i;x = x * (1.5f - xhalf * x * x);return 1.0 / x;
}/* 求绝对值 */
static float _fabs(float x)
{return (x >= 0 ? x : (-x));
}/* 求x / y的反正切值 */
static float _atan2f(float y, float x)
{float a, b, c, r, xx;int m;union {float f;int i;} xinv;xx = _fabs(x);xinv.f = xx;m = 0x3F800000 - (xinv.i & 0x7F800000);xinv.i = xinv.i + m;xinv.f = 1.41176471f - 0.47058824f * xinv.f;xinv.i = xinv.i + m;b = 2.0 - xinv.f * xx;xinv.f = xinv.f * b;b = 2.0 - xinv.f * xx;xinv.f = xinv.f * b;c = _fabs(y * xinv.f);xinv.f = c;m = 0x3F800000 - (xinv.i & 0x7F800000);xinv.i = xinv.i + m;xinv.f = 1.41176471f - 0.47058824f * xinv.f;xinv.i = xinv.i + m;b = 2.0 - xinv.f * c;xinv.f = xinv.f * b;b = 2.0 - xinv.f * c;xinv.f = xinv.f * b;xinv.f = xinv.f + c;a = (c > 1.0f);c = c - a * xinv.f;r = a * __atan2f_pi_2;xx = c * c;a = (__atan2f_lut[0] * c) * xx + (__atan2f_lut[2] * c);b = (__atan2f_lut[1] * c) * xx + (__atan2f_lut[3] * c);xx = xx * xx;r = r + a * xx;r = r + b;b = M_PI;b = b - 2.0f * r;r = r + (x < 0.0f) * b;b = (_fabs(x) < 0.000001f);c = !b;r = c * r;r = r + __atan2f_pi_2 * b;b = r + r;r = r - (y < 0.0f) * b;return r;
}static double _asin(double x)
{return _atan2f(x, _sqrt(1.0 - x * x));
}
#endif /* __GNUC__ *//* 获取俯仰角、偏航角、翻滚角 */
static void get_angle(icm_position_t dev, float ax, float ay, float az, float gx, float gy, float gz)
{float pitch = 0, roll = 0, yaw = 0;float norm;float vx, vy, vz;float ex, ey, ez;float q0q0 = q0 * q0;float q0q1 = q0 * q1;float q0q2 = q0 * q2;float q1q1 = q1 * q1;float q1q3 = q1 * q3;float q2q2 = q2 * q2;float q2q3 = q2 * q3;float q3q3 = q3 * q3;gx *= Gyro_Gr;gy *= Gyro_Gr;gz *= Gyro_Gr;if (az == 0)return;#ifdef __GNUC__norm = _sqrt(ax * ax + ay * ay + az * az);
#elsenorm = sqrt(ax * ax + ay * ay + az * az);
#endif /* __GNUC__ */ax = ax / norm;ay = ay / norm;az = az / norm;vx = 2 * (q1q3 - q0q2);vy = 2 * (q0q1 + q2q3);vz = q0q0 - q1q1 - q2q2 + q3q3;ex = (ay * vz - az * vy);ey = (az * vx - ax * vz);ez = (ax * vy - ay * vx);exInt = exInt + ex * Ki;eyInt = eyInt + ey * Ki;ezInt = ezInt + ez * Ki;gx = gx + Kp * ex + exInt;gy = gy + Kp * ey + eyInt;gz = gz + Kp * ez + ezInt;q0 = q0 + (-q1 * gx - q2 * gy - q3 * gz) * halfT;q1 = q1 + (q0 * gx + q2 * gz - q3 * gy) * halfT;q2 = q2 + (q0 * gy - q1 * gz + q3 * gx) * halfT;q3 = q3 + (q0 * gz + q1 * gy - q2 * gx) * halfT;#ifdef __GNUC__norm = _sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
#elsenorm = sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
#endif /* __GNUC__ */q0 = q0 / norm;q1 = q1 / norm;q2 = q2 / norm;q3 = q3 / norm;#ifdef __GNUC__pitch = -_asin(2 * (q0 * q2 - q1 * q3)) * 57.2957795f;roll = _asin(2 * (q0 * q1 + q2 * q3)) * 57.2957795f;yaw = -_atan2f(2 * (q1 * q2 + q0 * q3), (q0q0 + q1q1 - q2q2 - q3q3)) * 57.29578f;
#elsepitch = -asin(2 * (q0 * q2 - q1 * q3)) * 57.2957795f;roll = asin(2 * (q0 * q1 + q2 * q3)) * 57.2957795f;yaw = -atan2f(2 * (q1 * q2 + q0 * q3), (q0q0 + q1q1 - q2q2 - q3q3)) * 57.29578f;
#endif /* __GNUC__ */mouse_meas_check(&pitch);dev->x = pitch * mouse_ratio;mouse_meas_check(&roll);dev->y = roll * mouse_ratio;mouse_meas_check(&yaw);dev->z = yaw * mouse_ratio;
}static void mouse_get_pos(icm_position_t dev)
{rt_err_t result;rt_int16_t accel_x, accel_y, accel_z;rt_int16_t gyros_x, gyros_y, gyros_z;RT_ASSERT(dev);result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);if (result != RT_EOK){goto __exit;}result = icm20608_get_accel(dev->icm20608_device, &accel_x, &accel_y, &accel_z);if (result != RT_EOK){rt_mutex_release(dev->lock);goto __exit;}result = icm20608_get_gyro(dev->icm20608_device, &gyros_x, &gyros_y, &gyros_z);if (result != RT_EOK){rt_mutex_release(dev->lock);goto __exit;}get_angle(dev, (float)accel_x, (float)accel_y, (float)accel_z, (float)gyros_x, (float)gyros_y, (float)gyros_z);rt_mutex_release(dev->lock);__exit:if (result != RT_EOK){LOG_E("The sensor does not work");return;}
}static icm_position_t mouse_init_icm(void)
{rt_err_t result;rt_thread_mdelay(1000);icm_device = rt_calloc(1, sizeof(struct icm_position));if (icm_device == RT_NULL){LOG_E("Can't allocate memory for three-dimensional mouse ");return RT_NULL;}/* 初始化传感器 icm20608 */icm_device->icm20608_device = icm20608_init("i2c3");if (icm_device->icm20608_device == RT_NULL){LOG_E("The sensor initializes failure");rt_free(icm_device);return RT_NULL;}else{LOG_D("The 3D mouse initializes success");}icm_device->lock = rt_mutex_create("mutex_mouse", RT_IPC_FLAG_FIFO);if (icm_device->lock == RT_NULL){LOG_E("Can't create mutex for three-dimensional mouse");rt_free(icm_device);return RT_NULL;}mouse_sem = rt_sem_create("mouse_sem", 0, RT_IPC_FLAG_FIFO);if (mouse_sem == RT_NULL){LOG_E("Can't create sem for mouse device");rt_mutex_delete(icm_device->lock);rt_free(icm_device);return 0;}/* 传感器零值校准 */result = icm20608_calib_level(icm_device->icm20608_device, 10);if (result != RT_EOK){LOG_E("The sensor calibrates failure");rt_mutex_delete(icm_device->lock);rt_sem_delete(mouse_sem);rt_free(icm_device);return RT_NULL;}return icm_device;
}static void mouse_go_release_status(void)
{/* 初始状态值 */rt_int8_t buff[4] = {0x08, 0, 0, 0};icm_device->buff[0] = buff[0];icm_device->buff[1] = buff[1];icm_device->buff[2] = buff[2];icm_device->buff[3] = buff[3];
}static void mouse_send_data(rt_device_t device)
{RT_ASSERT(device != RT_NULL);rt_device_write(device, HID_REPORT_ID_MOUSE, icm_device->buff, 4);mouse_go_release_status();
}/* 负值表示向左移动,正值表示向右移动 */
static void mouse_move_x(rt_device_t device, float ratio_x)
{RT_ASSERT(device != RT_NULL);if (icm_device->x < 0){icm_device->buff[1] = (rt_int8_t)(-mouse_pixel_len * ratio_x);}else{icm_device->buff[1] = (rt_int8_t)(mouse_pixel_len * ratio_x);}mouse_send_data(device);
}/* 正值表示向下移动,负值表示向上移动 */
static void mouse_move_y(rt_device_t device, float ratio_y)
{RT_ASSERT(device != RT_NULL);if (icm_device->y < 0){icm_device->buff[2] = (rt_int8_t)(-mouse_pixel_len * ratio_y);}else{icm_device->buff[2] = (rt_int8_t)(mouse_pixel_len * ratio_y);}mouse_send_data(device);
}static void mouse_move_xy(rt_device_t device, float ratio_x, float ratio_y)
{RT_ASSERT(device != RT_NULL);if (icm_device->x < 0){icm_device->buff[1] = (rt_int8_t)(-mouse_pixel_len * ratio_x);}else{icm_device->buff[1] = (rt_int8_t)(mouse_pixel_len * ratio_x);}if (icm_device->y < 0){icm_device->buff[2] = (rt_int8_t)(-mouse_pixel_len * ratio_y);}else{icm_device->buff[2] = (rt_int8_t)(mouse_pixel_len * ratio_y);}mouse_send_data(device);
}static void usb_thread_entry(void *parameter)
{rt_device_t device = (rt_device_t)parameter;rt_uint8_t i = 0;while (1){if (rt_sem_take(mouse_sem, RT_WAITING_FOREVER) == RT_EOK){rt_uint8_t temp_x = 0, temp_y = 0, move_max = 0;float move_distance = 0.0f;rt_mutex_take(icm_device->lock, RT_WAITING_FOREVER);#ifdef __GNUC__temp_x = (rt_uint8_t)_fabs(icm_device->x);temp_y = (rt_uint8_t)_fabs(icm_device->y);move_distance = _sqrt(temp_x * temp_x + temp_y * temp_y);
#elsetemp_x = (rt_uint8_t)fabs(icm_device->x);temp_y = (rt_uint8_t)fabs(icm_device->y);move_distance = sqrt(temp_x * temp_x + temp_y * temp_y);
#endifmove_max = temp_x > temp_y ? temp_x : temp_y;/* 根据倾斜程度获取移动值 */for (i = 0; i < move_max / mouse_pixel_len; i++){LOG_D("move_max :%4d, x: %4d, y :%4d ", move_max, temp_x, temp_y);if (i < temp_x && i < temp_y){mouse_move_xy(device, temp_x / move_distance, temp_y / move_distance);}else if (i < temp_x && i >= temp_y){mouse_move_x(device, temp_x / move_distance);}else if (i >= temp_x && i < temp_y){mouse_move_y(device, temp_y / move_distance);}else{break;}}rt_mutex_release(icm_device->lock);}rt_thread_mdelay(mouse_sample_times);}
}static void icm_thread_entry(void *parameter)
{while (1){float temp_x = 0.0, temp_y = 0.0;rt_mutex_take(icm_device->lock, RT_WAITING_FOREVER);/* 获取鼠标移动范围 */mouse_get_pos(icm_device);/* 获取差值 */temp_x = icm_device->x - mouse_cmp_last_x;temp_y = icm_device->y - mouse_cmp_last_y;/* 避免抖动 */if (temp_x > mouse_rang_scope || temp_x < -mouse_rang_scope || temp_y > mouse_rang_scope || temp_y < -mouse_rang_scope){/* 存储这次鼠标位移值 */mouse_cmp_last_x = icm_device->x;mouse_cmp_last_y = icm_device->y;rt_sem_release(mouse_sem);}rt_mutex_release(icm_device->lock);rt_thread_mdelay(mouse_sample_times);}
}static void key_thread_entry(void *parameter)
{int mouse_key_2, mouse_key_0;rt_device_t device = (rt_device_t)parameter;rt_err_t result = -RT_ERROR;while (1){if (rt_pin_read(PIN_KEY0) == PIN_LOW){mouse_key_0 = 1;}else if (rt_pin_read(PIN_KEY2) == PIN_LOW){mouse_key_2 = 1;}else{mouse_key_2 = 0;mouse_key_0 = 0;}if (mouse_key_2 | mouse_key_0){result = rt_mutex_take(icm_device->lock, RT_WAITING_FOREVER);if (result == RT_EOK){/* 获取鼠标键值,默认为 0 */icm_device->buff[0] = 0x08 | mouse_key_2 | mouse_key_0 << 1;if (mouse_key_2 & mouse_key_0){LOG_D("left & right down");}else if (mouse_key_2){LOG_D("left down");}else if (mouse_key_0){LOG_D("right down");}mouse_send_data(device);rt_mutex_release(icm_device->lock);rt_thread_mdelay(50);}}rt_thread_mdelay(mouse_sample_times / 5);}
}static void mouse_init_key(void)
{/* 鼠标左键 */rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT);/* 鼠标右键 */rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT);
}int main(void)
{return 0;
}static int application_usb_init(void)
{/* 查找名称为 hidd 的设备 */rt_device_t device = rt_device_find("hidd");/* 初始化六轴传感器设备 */icm_device = mouse_init_icm();/* 初始化按键 */mouse_init_key();RT_ASSERT(device != RT_NULL);RT_ASSERT(icm_device != RT_NULL);/*打开查找到的 hid 设备 */rt_device_open(device, RT_DEVICE_FLAG_WRONLY);/* 初始化 USB 线程*/rt_thread_init(&usb_thread,"hidd",usb_thread_entry, device,usb_thread_stack, sizeof(usb_thread_stack),10, 20);rt_thread_startup(&usb_thread);/* 初始化六轴传感器线程 */rt_thread_init(&icm_thread,"icm20608",icm_thread_entry, RT_NULL,icm_thread_stack, sizeof(icm_thread_stack),10, 20);rt_thread_startup(&icm_thread);/* 初始化按键线程 */rt_thread_init(&key_thread,"key",key_thread_entry, device,key_thread_stack, sizeof(key_thread_stack),10, 20);rt_thread_startup(&key_thread);return 0;
}
INIT_APP_EXPORT(application_usb_init);

烧录完成后,将开发板上的USB OTG 连接PC端的USB接口,即可实现鼠标功能。


相关文章:

RT-Thread+STM32L475VET6——USB鼠标模拟

文章目录 前言一、板载资源二、具体步骤1.配置icm20608传感器2.打开CubeMX进行USB配置3. 配置USB3.1 打开USB驱动3.2 声明USB3.3 剪切stm32xxxx_hal_msp.c中的void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)和void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)函数至board.c3.…...

rust 安全性

Rust 是 静态类型&#xff08;statically typed&#xff09; 语言&#xff0c; 也就是说在编译时就必须知道所有变量的类型&#xff0c; 这一点将贯穿整个章节。 C/C的安全问题 内存的不正确访问引发的内存安全问题 由于多个变量指向同一块内存区域导致的数据一致性问题 由于…...

大模型驱动的围术期质控系统全面解析与应用探索

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与方法 1.3 研究创新点 二、大模型技术与围术期管理概述 2.1 大模型技术原理与发展现状 2.2 围术期管理流程与挑战 三、大模型在术前的应用 3.1 病历内涵质控 3.2 智能医学问答与知识查询 3.3 疾病风险预测与评估 3.…...

中兴B863AV3.2-T/B863AV3.1-T2/B863AV3.1-T2K_电信高安_S905L3A-B_安卓9.0_线刷固件包

中兴B863AV3.2-T&#xff0f;B863AV3.1-T2&#xff0f;B863AV3.1-T2K_电信高安_S905L3A-B_安卓9.0_线刷固件包 B863AV3.2-T B863AV3.1-T2 已知可通刷贵州、江苏、贵州、北京、河南、陕西等省份。 线刷方法&#xff1a;&#xff08;新手参考借鉴一下&#xff09; 1、准备好一…...

Android Binder机制

Binder是IPC&#xff08;进程间通信&#xff09;的一种机制&#xff0c;它允许不同的应用或系统服务在不同的进程中安全地交换数据。Binder的核心原理是基于客户端-服务器模型&#xff08;C/S架构)。 一、Binder的定义 1. Binder是Android中的一个类&#xff0c;它继承了IBind…...

【算法】初等数论

初等数论 模 取余&#xff0c;遵循尽可能让商向0靠近的原则&#xff0c;结果的正负和左操作数相同 取模&#xff0c;遵循尽可能让商向负无穷靠近的原则&#xff0c;结果的正负和右操作数相同 7/&#xff08;-3&#xff09;-2.3&#xff0c;产生了两个商-2和-3&#xff0c;取…...

Spring Boot3+Vue2极速整合:10分钟搭建DeepSeek AI对话系统

前言 在生成式AI技术蓬勃发展的今天&#xff0c;大语言模型已成为企业智能化转型和个人效率提升的核心驱动力。作为国产大模型的优秀代表&#xff0c;DeepSeek凭借其卓越的中文语义理解能力和开发者友好的API生态&#xff0c;正在成为构建本土化AI应用的首选平台。 本文将以S…...

Spring事务原理 二

在上一篇博文《Spring事务原理 一》中&#xff0c;我们熟悉了Spring声明式事务的AOP原理&#xff0c;以及事务执行的大体流程。 本文中&#xff0c;介绍了Spring事务的核心组件、传播行为的源码实现。下一篇中&#xff0c;我们将结合案例&#xff0c;来讲解实战中有关事务的易…...

JVM预热

阿里电商平台每年的各种大促活动&#xff0c;对于Java技术来说&#xff0c;其中重要一个操作环节就是预热操作。 目录 预热是什么&#xff1f;为什么要预热&#xff1f; java 程序不预热和预热的调用对比 预热是什么&#xff1f; 预热是指&#xff0c;在 JVM 启动后&#xff0…...

基于flask+vue框架的的医院预约挂号系统i1616(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能:用户,医生,科室信息,就诊信息,医院概况,挂号信息,诊断信息,取消挂号 开题报告内容 基于FlaskVue框架的医院预约挂号系统开题报告 一、研究背景与意义 随着医疗技术的不断进步和人们健康意识的日益增强&#xff0c;医院就诊量逐年增加。传统的现场…...

DeepSeek掘金——SpringBoot 调用 DeepSeek API 快速实现应用开发

Spring Boot 实现 DeepSeek API 调用 1. 项目依赖 在 pom.xml 中添加以下依赖: <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>&l…...

easelog(1)基础C++日志功能实现

EaseLog(1)基础C日志功能实现 Author: Once Day Date: 2025年2月22日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 注&#xff1a;本简易日志组件代码实现参考了Google …...

epoll_event的概念和使用案例

epoll_event 是 Linux 下 epoll I/O 多路复用机制的核心数据结构&#xff0c;用于描述文件描述符&#xff08;File Descriptor, FD&#xff09;上发生的事件及其关联的用户数据。通过 epoll&#xff0c;可以高效地监控多个文件描述符的状态变化&#xff08;如可读、可写、错误等…...

Leetcode2506:统计相似字符串对的数目

题目描述&#xff1a; 给你一个下标从 0 开始的字符串数组 words 。 如果两个字符串由相同的字符组成&#xff0c;则认为这两个字符串 相似 。 例如&#xff0c;"abca" 和 "cba" 相似&#xff0c;因为它们都由字符 a、b、c 组成。然而&#xff0c;"…...

蓝桥月赛 之 26场

文章目录 好汤圆灯笼猜谜元宵分配摆放汤圆 好汤圆 好汤圆 思路分析&#xff1a;由于2025能够被15整除&#xff0c;所以我们直接输出对应的答案即可 import os import sys# 请在此输入您的代码print(2025//15)灯笼猜谜 灯笼猜谜 思路分析&#xff1a;首先呢&#xff0c;我就考…...

机器学习面试八股文——决战金三银四

大家好&#xff0c;这里是好评笔记&#xff0c;公主 号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本笔记的任务是解读机器学习实践/面试过程中可能会用到的知识点&#xff0c;内容通俗易懂&#xff0c;入门、实习和校招轻松搞定。 公主号合集地址 点击进入优惠地…...

umi: valtio的使用

一、基本用法 import { proxy, useSnapshot } from umijs/max;// 1、定义数据 const state proxy({ count: 33 });export default () > {// 2、使用数据const snap useSnapshot(state);function increaseCount() {state.count 1;}return (<><h1>{snap.count}…...

区块链相关方法-波特五力分析模型

一、定义:波特五力分析模型&#xff08;Porters Five Forces Framework&#xff09;是迈克尔・波特&#xff08;Michael Porter&#xff09;于 1979 年提出的一种用于分析行业竞争态势的工具。它通过考察五种力量的相互作用来评估一个行业的吸引力和竞争环境&#xff0c;这五种…...

纷析云开源版- Vue2-增加字典存储到localStorage

main.js //保存字典数据到LocalStorage Vue.prototype.$api.setting.SystemDictType.all().then(({data}) > {loadDictsToLocalStorage(data) })新增 dictionary.js 放在 Utils文件夹里面 // 获取字典数据 export function getDictByType(dictType) {const dicts JSON.par…...

HTML项目一键打包工具:HTML2EXE 最新版

HTML2EXE 工具可以一键打包生成EXE可执行文件。可以打包任意HTML项目或者是一个网址为单个EXE文件&#xff0c;直接打开即可运行。支持KRPano全景VR项目、WebGL游戏项目、视频播放、,课件打包、网址打包等。 一、功能特点 类别序号功能标题1支持程序图标自定义&#xff08;支持…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...