ESP32学习笔记_FreeRTOS(3)——SoftwareTimer
摘要(From AI):
这篇笔记全面介绍了 FreeRTOS 软件定时器的核心概念和使用方法,包括定时器的创建、管理、常用 API 和辅助函数,并通过示例代码演示了如何启动、重置和更改定时器的周期。它强调了软件定时器的灵活性、平台无关性以及与硬件定时器的对比
前言:本文档是本人在依照B站UP:Michael_ee的视频教程进行学习时所做的学习笔记,可能存在疏漏和错误,如有发现,望指正。
上一篇:ESP32学习笔记_FreeRTOS(2)——Queue
文章目录
- Software Timer
- Creating a Software Timer
- xTimerCreate()
- Managing Software Timers
- xTimerStart()
- xTimerStop()
- pcTimerGetName()
- pvTimerGetTimerID()
- xTimerReset()
- xTimerChangePeriod()
- Example Code:Using Software Timers
参考资料:
[Michael_ee视频教程] https://www.bilibili.com/video/BV1Nb4y1q7xz?spm_id_from=333.788.videopod.sections&vd_source=4d8bd0ed3878ef81b239bf69bf38e741
freeRTOS官网
espressif 在线文档
Software Timer
硬件定时器会有数量等方面的限制,使用较不灵活,而软件定时器使用更为灵活,其与硬件、平台无关,在不同的 MCU 都可以使用 FreeRTOS API 进行调用
特性 | 硬件定时器 | 软件定时器 |
---|---|---|
数量 | 固定,受 MCU 硬件资源限制(通常只有几个) | 灵活,可以根据需要动态创建(受内存和任务管理能力限制) |
依赖性 | 依赖具体硬件平台,配置方式和功能因芯片而异 | 与硬件平台无关,可通过 FreeRTOS API 在不同 MCU 上使用 |
精度 | 高精度,直接由硬件计时,通常用于实时性要求高的场景 | 精度依赖于 RTOS 的调度周期(tick 周期),不适合极高实时性场景 |
性能 | 高性能,独立运行,不占用 CPU 资源 | 运行在 RTOS 守护任务上下文中,占用 CPU 资源 |
适用场景 | 适合时间敏感的应用,如 PWM 信号生成、脉冲捕获、输入输出事件计时等 | 适合通用定时功能,如定时任务执行、软件超时处理等 |
灵活性 | 配置固定,功能和用途受限 | 灵活性高,可动态调整超时时间、回调函数等 |
使用复杂度 | 配置复杂,需根据芯片手册手动设置寄存器 | 使用方便,通过 FreeRTOS API 调用 |
移植性 | 差,代码与硬件平台强耦合 | 好,代码与硬件无关,便于跨平台移植 |
所有软件定时器的回调函数都在同一个RTOS守护任务(也称为“定时器服务任务”)的上下文中执行(该任务最初被称为“定时器服务任务”,因为最初它只用于执行软件定时器回调函数。现在同一任务也用于其他用途,因此被改名为更通用的“RTOS 守护任务”)
守护任务是一个标准的FreeRTOS任务,会在调度器启动时自动创建。其优先级和堆栈大小由编译时配置常量configTIMER_TASK_PRIORITY
和configTIMER_TASK_STACK_DEPTH
分别设置,这两个常量在FreeRTOSConfig.h
中定义
需要注意,软件定时器的回调函数是在 RTOS 守护任务的上下文中执行的,而不是在独立的任务中运行。因此,回调函数中不能调用可能使任务进入阻塞状态的 FreeRTOS API 函数,因为这会阻塞整个守护任务,导致系统运行异常
Creating a Software Timer
xTimerCreate()
xTimerCreate()
用于创建一个新的软件定时器,并返回一个句柄以引用创建的定时器
#include “FreeRTOS.h”
#include “timers.h”TimerHandle_t xTimerCreate( const char *pcTimerName,const TickType_t xTimerPeriod,const UBaseType_t uxAutoReload,void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction );
参数
pcTimerName
定时器的名称,仅用于调试xTimerPeriod定时器周期,单位为系统 tick,不能为 0。可以使用
pdMS_TO_TICKS()` 宏将毫秒转换为 tick。例如:- 100 tick直接设置为 100
- 500ms可使用
pdMS_TO_TICKS(500)
,前提是configTICK_RATE_HZ <= 1000
uxAutoReload
设置定时器类型:pdTRUE
自动重载定时器(周期性触发)pdFALSE
一次性定时器(仅触发一次,可手动重新启动)
pvTimerID
定时器标识符,用于在回调函数中区分不同的定时器,或在回调调用之间存储值pxCallbackFunction
:定时器到期时执行的回调函数,需符合TimerCallbackFunction_t
原型:
void vCallbackFunctionExample(TimerHandle_t xTimer);
configTICK_RATE_HZ
是 FreeRTOS 配置文件FreeRTOSConfig.h
中定义的一个宏,它表示 每秒系统 Tick 的次数,即 FreeRTOS 的调度器每秒中断的频率(单位为 Hz)
例如:
如果configTICK_RATE_HZ = 1000
,表示系统每 1 毫秒触发一次 Tick 中断
如果configTICK_RATE_HZ = 100
,表示系统每 10 毫秒触发一次 Tick 中断
返回值:
NULL
定时器创建失败,原因可能是 FreeRTOS 堆内存不足其他值
定时器创建成功,返回的句柄可用于引用该定时器
配置要求(一般不用动)
- 在
FreeRTOSConfig.h
文件中,configUSE_TIMERS
和configSUPPORT_DYNAMIC_ALLOCATION
必须都设置为1
- 如果
configSUPPORT_DYNAMIC_ALLOCATION
未定义,其默认值为1
创建定时器并不会立即启动。可以使用以下函数来启动或管理定时器
// 启动定时器。如果定时器已经在运行,则从当前时间重新开始。
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );// 重置(重新启动)定时器。确保定时器启动或重新计算到期时间。
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );// 从中断上下文启动定时器。等效于 xTimerStart(),用于中断中调用。
BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );// 从中断上下文重置(重新启动)定时器。等效于 xTimerReset(),用于中断中调用。
BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,BaseType_t *pxHigherPriorityTaskWoken );// 更改定时器的周期。如果定时器未运行,则会启动定时器。
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,TickType_t xNewPeriod,TickType_t xTicksToWait );// 从中断上下文更改定时器的周期。等效于 xTimerChangePeriod(),用于中断中调用。
BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,TickType_t xNewPeriod,BaseType_t *pxHigherPriorityTaskWoken );
Managing Software Timers
xTimerStart()
xTimerStart() 用于启动一个软件定时器的运行
- 如果定时器尚未运行,
xTimerStart()
会计算一个到期时间,该时间相对于调用xTimerStart()
的时刻 - 如果定时器已经在运行,则
xTimerStart()
相当于调用了xTimerReset()
,即重置定时器 - 定时器会在定义的周期后(即
xTimerStart()
调用后n
个 tick)触发回调函数,除非定时器在此期间被停止、删除或重置
#include “FreeRTOS.h”
#include “timers.h”BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
参数
xTimer
:要启动、重置或重新启动的定时器句柄xTicksToWait
指定调用任务在timer command queue
队列已满的情况下,等待空间可用的最大时间(单位为 tick)。这是任务在进入 Blocked 状态时的阻塞时间。如果队列已满,任务会被阻塞,直到有足够的空间来发送命令- 设置
xTicksToWait
为portMAX_DELAY
将导致任务无限期等待,直到队列中有空间 - 如果在调度器启动之前调用
xTimerStart()
,则xTicksToWait
会被忽略
- 设置
当任务调用
xTimerStart()
或其他定时器相关 API 时,这些命令并不会立即由任务执行,而是通过一个队列传递给定时器服务任务
如果队列已满,新的命令会被阻塞,直到队列有空间可用。这时,调用xTimerStart()
等 API 的任务会根据指定的阻塞时间(xTicksToWait
)进入阻塞状态,等待队列空间变得可用
timer command queue
的大小由 FreeRTOS 的配置项决定。队列的大小设置影响系统可以同时处理多少个定时器命令。如果队列大小太小,可能会导致命令丢失或任务阻塞:
configTIMER_QUEUE_LENGTH
:定义了timer command queue
队列的最大长度(即可以存放多少个定时器命令)
configUSE_TIMERS
:必须设置为 1,才能启用定时器功能和相关队列
返回值
pdPASS
启动命令成功发送到定时器命令队列。如果指定了阻塞时间(即xTicksToWait
不为零),则可能会因为队列已满,任务进入阻塞状态等待空间释放,直到数据成功写入队列- 定时器命令的处理时间会根据定时器服务任务的优先级而有所不同,但定时器的到期时间是相对于实际调用
xTimerStart()
时刻(从队列中取出命令并实际启动定时器)的 - 定时器命令的处理时间受定时器服务任务优先级的影响,定时器服务任务的优先级由
configTIMER_TASK_PRIORITY
配置常量设置
- 定时器命令的处理时间会根据定时器服务任务的优先级而有所不同,但定时器的到期时间是相对于实际调用
pdFAIL
启动命令未成功发送到定时器命令队列,原因是队列已满。如果指定了阻塞时间,任务会被阻塞等待队列有空间,直到指定的阻塞时间过期,但仍未成功写入数据到队列
注意事项(一般不用动)
在 FreeRTOSConfig.h
中,configUSE_TIMERS
必须设置为 1,才能使用 xTimerStart()
函数
xTimerStop()
xTimerStop()
用于停止一个运行中的软件定时器
- 调用
xTimerStop()
可以停止一个正在运行的定时器。如果定时器已经停止或已过期,则调用xTimerStop()
不会产生影响。 xTimerStop()
向定时器命令队列发送停止命令,定时器服务任务会在稍后处理该命令。
#include “FreeRTOS.h”
#include “timers.h”BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
参数
xTimer
要停止的定时器句柄。xTicksToWait
指定任务在定时器命令队列已满的情况下,最大等待时间(单位为 ticks)
返回值
pdPASS
pdFAIL
pcTimerGetName()
pcTimerGetName()
用于返回在创建定时器时分配的可读文本名称
#include “FreeRTOS.h”
#include “timers.h”const char * pcTimerGetName( TimerHandle_t xTimer );
返回值
- 返回值为一个指向定时器名称的指针。
- 定时器名称是一个标准的以
NULL
结尾的 C 字符串。
pvTimerGetTimerID()
pvTimerGetTimerID()
用于返回与定时器关联的标识符(ID)
- 返回在创建定时器时分配的标识符,该标识符可以通过
vTimerSetTimerID()
API 更新 - 在回调函数中可以使用该标识符区分哪个定时器到期,特别是在多个定时器共享相同的回调函数时
#include “FreeRTOS.h”
#include “timers.h”void *pvTimerGetTimerID( TimerHandle_t xTimer );
返回值
- 返回与指定定时器关联的标识符(指针类型)
xTimerReset()
xTimerReset()
用于重置、启动或重新启动一个软件定时器,能够起到 Watch Dog 的作用
- 如果定时器正在运行,
xTimerReset()
会将定时器的到期时间重新计算为相对于调用时间的周期 - 如果定时器未运行,
xTimerReset()
会启动定时器,并将到期时间计算为相对于调用时间的周期。此时等效于xTimerStart()
- 无论定时器当前是否运行,调用
xTimerReset()
后,定时器都将开始运行
#include “FreeRTOS.h”
#include “timers.h”BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
返回值
pdPASS
pdFAIL
xTimerChangePeriod()
xTimerChangePeriod()
用于更改软件定时器的周期
- 更改运行中定时器的周期
- 如果定时器正在运行,则新周期将用于重新计算到期时间。
- 新的到期时间相对于调用
xTimerChangePeriod()
的时刻,而不是定时器最初启动的时刻。
- 启动未运行的定时器
- 如果定时器未运行,则定时器将使用新的周期值计算到期时间,并开始运行。
#include “FreeRTOS.h”
#include “timers.h”BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,TickType_t xNewPeriod,TickType_t xTicksToWait );
参数
xTimer
需要更改周期的定时器句柄xNewPeriod
定时器的新周期(单位为 tick)。可使用pdMS_TO_TICKS()
将毫秒转换为 tickxTicksToWait
阻塞任务的最大时间(单位为 tick),如果定时器命令队列已满,则等待空间可用
返回值
pdPASS
pdFAIL
Example Code:Using Software Timers
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h" #include "freertos/timers.h" // 定时器头文件 void TimerCallback(TimerHandle_t xTimer)
{ const char *pcTimerName = pcTimerGetName(xTimer);// 获取定时器名称 uint32_t *uiTimerID = (uint32_t *)pvTimerGetTimerID(xTimer);// 获取定时器ID printf("%s expired, ID: %lu.\n", pcTimerName, *uiTimerID);// 打印定时器名称和ID
} int id1 = 0;
int id2 = 1; void app_main(void)
{ TimerHandle_t TimerHandle1 = NULL; TimerHandle1 = xTimerCreate("Timer1", pdMS_TO_TICKS(1000), pdTRUE, (void *)&id1, TimerCallback);// 创建一个周期为1000ms的定时器 xTimerStart(TimerHandle1, 0);// 启动定时器 TimerHandle_t TimerHandle2 = NULL; TimerHandle2 = xTimerCreate("Timer2", pdMS_TO_TICKS(2000), pdTRUE, (void *)&id2, TimerCallback);// 与Timer1公用同一个回调函数,观察pcTimerGetName的输出 xTimerStart(TimerHandle2, 0);// 启动定时器 // for(int i = 0; i < 10; i++) // { // vTaskDelay(pdMS_TO_TICKS(1000)); // xTimerReset(TimerHandle2, 0);// 重置定时器,观察pcTimerGetName的输出,此时Timer2不会被打印 // } vTaskDelay(pdMS_TO_TICKS(5000)); xTimerChangePeriod(TimerHandle2, pdMS_TO_TICKS(1000), 0);// 修改Timer2的周期为1000ms vTaskDelay(pdMS_TO_TICKS(5000)); xTimerStop(TimerHandle1, 0);// 停止定时器 xTimerStop(TimerHandle2, 0);// 停止定时器
}
相关文章:
ESP32学习笔记_FreeRTOS(3)——SoftwareTimer
摘要(From AI): 这篇笔记全面介绍了 FreeRTOS 软件定时器的核心概念和使用方法,包括定时器的创建、管理、常用 API 和辅助函数,并通过示例代码演示了如何启动、重置和更改定时器的周期。它强调了软件定时器的灵活性、平台无关性以及与硬件定时器的对比 …...
文心一言与千帆大模型平台的区别:探索百度AI生态的双子星
随着人工智能技术的迅猛发展,越来越多的公司开始投入资源开发自己的AI解决方案。在中国,百度作为互联网巨头之一,不仅在搜索引擎领域占据重要位置,还在AI领域取得了显著成就。其中,“文心一言”和“千帆大模型平台”便…...
【c语言】文件操作详解 - 从打开到关闭
文章目录 1. 为什么使用文件?2. 什么是文件?3. 如何标识文件?4. 二进制文件和文本文件?5. 文件的打开和关闭5.1 流和标准流5.1.1 流5.1.2 标准流 5.2 文件指针5.3 文件的打开和关闭 6. 文件的读写顺序6.1 顺序读写函数6.2 对比一组…...
Flink Sink的使用
经过一系列Transformation转换操作后,最后一定要调用Sink操作,才会形成一个完整的DataFlow拓扑。只有调用了Sink操作,才会产生最终的计算结果,这些数据可以写入到的文件、输出到指定的网络端口、消息中间件、外部的文件系统或者是…...
pcl::PointCloud<PointType>::Ptr extractedCloud; 尖括号里的值表示什么含义?
在C中,pcl::PointCloud<PointType>::Ptr是一种智能指针,它是Point Cloud Library (PCL)中用于管理pcl::PointCloud对象的智能指针类型。这里的<pcl::PointCloud<PointType>::Ptr>尖括号里的值表示智能指针所指向的对象类型。 让我们分…...
《基于FPGA的便携式PWM方波信号发生器》论文分析(三)——数码管稳定显示与系统调试
一、论文概述 基于FPGA的便携式PWM方波信号发生器是一篇由任青颖、庹忠曜、黄洵桢、李智禺和张贤宇 等人发表的一篇期刊论文。该论文主要研究了一种新型的信号发生器,旨在解决传统PWM信号发生器在移动设备信号调控中存在的精准度低和便携性差的问题 。其基于现场可编…...
VsCode 插件推荐(个人常用)
VsCode 插件推荐(个人常用)...
路由策略与路由控制实验
AR1、AR2、AR3在互联接口、Loopback0接口上激活OSPF。AR3、AR4属于IS-IS Area 49.0001,这两者都是Level-1路由器,AR3、AR4的系统ID采用0000.0000.000x格式,其中x为设备编号 AR1上存在三个业务网段A、B、C(分别用Loopback1、2、3接…...
训练的decoder模型文本长度不一致,一般设置为多大合适,需要覆盖最长的文本长度么
在训练解码器模型时,文本长度不一致是常见的情况,需要根据任务的特性和数据集的长度分布来设置合理的最大长度 (max_length)。以下是一些指导原则,帮助你设置合适的最大长度: 1. 是否需要覆盖最长文本长度 覆盖最长文本长度: 如果任务对完整性要求很高(例如生成数学公式、…...
过滤条件包含 OR 谓词,如何进行查询优化——OceanBase SQL 优化实践
这篇博客涉及两个点,一个是 “OR Expansion 改写”,另一个是 “基于代价的改写”。 背景 在写SQL查询时,难以避免在过滤条件中使用 OR 谓词,但其往往会导致索引利用效率下降的问题 。本文将分享如何通过查询改写的2种方式进行优化…...
通过异步使用消息队列优化秒杀
通过异步使用消息队列优化秒杀 同步秒杀流程异步优化秒杀异步秒杀流程基于lua脚本保证Redis操作原子性代码实现阻塞队列的缺点 同步秒杀流程 public Result seckillVoucher(Long voucherId) throws InterruptedException {SeckillVoucher seckillVoucher iSeckillVoucherServi…...
AI产业告别“独奏”时代,“天翼云息壤杯”高校AI大赛奏响产学研“交响乐”
文 | 智能相对论 作者 | 陈泊丞 人工智能产业正在从“独奏”时代进入“大合奏”时代。 在早期的AI发展阶段,AI应用主要集中在少数几个领域,如语音识别、图像处理等。这些领域的研究和开发工作往往由少数几家公司或研究机构即可独立完成,犹…...
Hot100 - 字母异位词分组
Hot100 - 字母异位词分组 最佳思路:排序 时间复杂度: O(nmlogm),其中 n 为 strs 数组的长度,m 为每个字符串的长度。 代码: class Solution {public List<List<String>> groupAnagrams(String[] strs) …...
力扣hot100-->排序
排序 1. 56. 合并区间 中等 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 示例 1: 输…...
【VRChat 全身动捕】VIVE 手柄改 tracker 定位器教程,低成本光学动捕解决方案(持续更新中2024.11.26)
更新 0.0.1(2024/11/26): 1.解决了内建蓝牙无法识别、“steamVR 蓝牙不可用” 的解决方案 2.解决了 tracker 虽然建立了连接但是在 steamVR 界面上看不到的问题 3.解决了 VIVE 基站1.0 无法被蓝牙识别 && 无法被 steamVR 搜索到 &…...
【Nginx】核心概念与安装配置解释
文章目录 1. 概述2. 核心概念2.1.Http服务器2.2.反向代理2.3. 负载均衡 3. 安装与配置3.1.安装3.2.配置文件解释3.2.1.全局配置块3.2.2.HTTP 配置块3.2.3.Server 块3.2.4.Location 块3.2.5.upstream3.2.6. mine.type文件 3.3.多虚拟主机配置 4. 总结 1. 概述 Nginx是我们常用的…...
Qt界面篇:QMessageBox高级用法
1、演示效果 2、用法注意 2.1 设置图标 用于显示实际图标的pixmap取决于当前的GUI样式。也可以通过设置icon pixmap属性为图标设置自定义pixmap。 QMessageBox::Icon icon(...
【二叉树】【2.1遍历二叉树】【刷题笔记】【灵神题单】
关注二叉树的三个问题: 什么情况适合自顶向下?什么时候适合用自底向上?一般来说,DFS的递归边界是空节点,什么情况下要额外把叶子节点作为递归边界?在什么情况下,DFS需要有返回值?什…...
Mongo数据库 --- Mongo Pipeline
Mongo数据库 --- Mongo Pipeline 什么是Mongo PipelineMongo Pipeline常用的几个StageExplanation with example:MongoDB $matchMongoDB $projectMongoDB $groupMongoDB $unwindMongoDB $countMongoDB $addFields Some Query Examples在C#中使用Aggreagtion Pipeline**方法一: …...
Adobe Illustrator 2024 安装教程与下载分享
介绍一下 下载直接看文章末尾 Adobe Illustrator 是一款由Adobe Systems开发的矢量图形编辑软件。它广泛应用于创建和编辑矢量图形、插图、徽标、图标、排版和广告等领域。以下是Adobe Illustrator的一些主要特点和功能: 矢量绘图:Illustrator使用矢量…...
javax.xml.ws.soap.SOAPFaultException: ZONE_OFFSET
javax.xml.ws.soap.SOAPFaultException 表示 SOAP 调用过程中发生了错误,并且服务端返回了一个 SOAP Fault。 错误信息中提到的 ZONE_OFFSET 可能指的是时区偏移量。在日期和时间处理中,时区偏移量是指格林威治标准时间 (GMT) 的偏移量。如果服务期望特…...
常用的数据结构
队列(FIFO) 栈(LIFO) 链表 hash表 hash冲突处理 开放式寻址 线性探测 表示依次检查索引为 hash(key) + 1、hash(key) + 2 ... 的位置。i 是冲突后的探查步数。公式:hash(i) = (hash(key) + i) % TableSize二次探查 规则:冲突后探查的步长是平方递增的,例如,检查位置为 hash…...
javaweb-day01-html和css初识
html:超文本标记语言 CSS:层叠样式表 1.html实现新浪新闻页面 1.1 标题排版 效果图: 1.2 标题颜色样式 1.3 标签内颜色样式 1.4设置超链接 1.5 正文排版 1.6 页面布局–盒子 (1)盒子模型 (2)页面布局…...
C++11特性(详解)
目录 1.C11简介 2.列表初始化 3.声明 1.auto 2.decltype 3.nullptr 4.范围for循环 5.智能指针 6.STL的一些变化 7.右值引用和移动语义 1.左值引用和右值引用 2.左值引用和右值引用的比较 3.右值引用的使用场景和意义 4.右值引用引用左值及其一些更深入的使用场景分…...
基于Springboot的心灵治愈交流平台系统的设计与实现
基于Springboot的心灵治愈交流平台系统 介绍 基于Springboot的心灵治愈交流平台系统,后端框架使用Springboot和mybatis,前端框架使用Vuehrml,数据库使用mysql,使用B/S架构实现前台用户系统和后台管理员系统,和不同级别…...
初识java(2)
大家好,今天我们来讲讲java中的数据类型。 java跟我们的c语言的数据类型有一些差别,那么接下来我们就来看看。 一.字面常量,其中:199,3.14,‘a’,true都是常量将其称为字面常量。(…...
AIGC--AIGC与人机协作:新的创作模式
AIGC与人机协作:新的创作模式 引言 人工智能生成内容(AIGC)正在以惊人的速度渗透到创作的各个领域。从生成文本、音乐、到图像和视频,AIGC使得创作过程变得更加快捷和高效。然而,AIGC并非完全取代了人类的创作角色&am…...
Wonder3D本地部署到算家云搭建详细教程
Wonder3D简介 Wonder3D仅需2至3分钟即可从单视图图像中重建出高度详细的纹理网格。Wonder3D首先通过跨域扩散模型生成一致的多视图法线图与相应的彩色图像,然后利用一种新颖的法线融合方法实现快速且高质量的重建。 本文详细介绍了在算家云搭建Wonder3D的流程以及…...
【设计模式】【行为型模式(Behavioral Patterns)】之状态模式(State Pattern)
1. 设计模式原理说明 状态模式(State Pattern) 是一种行为设计模式,它允许对象在其内部状态发生变化时改变其行为。这个模式的核心思想是使用不同的类来表示不同的状态,每个状态类都封装了与该状态相关的特定行为。当对象的状态发…...
QML学习 —— 34、视频媒体播放器(附源码)
效果 说明 您可以单独使用MediaPlayer播放音频内容(如音频),也可以将其与VideoOutput结合使用以渲染视频。VideoOutput项支持未转换、拉伸和均匀缩放的视频演示。有关拉伸均匀缩放演示文稿的描述,请参见fillMode属性描述。 播放可能出错问题 出现的问题: DirectS…...
成都住建局官网登陆/上海seo招聘
现实的企业中,对于消息通信的应用一直都非常的火热,而且在J2EE的企业应用中扮演着特殊的角色,所以对于它研究是非常有必要的。 上篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了消息通信的规范JMS,我们这篇博文介绍一…...
亚马逊网站的建设和维护/网络推广法
一:前言 在键盘驱动代码分析的笔记中,接触到了input子系统。键盘驱动,键盘驱动将检测到的所有按键都上报给了input子系统。Input子系统是所有I/O设备驱动的中间层,为上层提供了一个统一的界面。例如,在终端系统中&…...
做网站怎么赚钱 111/五合一网站建设
苹果秋季发布会如期而至,事实上,和之前大家的各种剧透的一样,这次苹果发布会最无悬念,除了传说中的海军蓝跳票外,基本上是对之前的爆料消息库克一次次地点下确定键而已。相反的,苹果这次发布会在系统软件上…...
做网站什么价格/企业网站注册
前几天网易云音乐、喜马拉雅FM、企鹅FM 等音频/直播产品下架的消息,大家应该有所耳闻。其中一个指向就是算法。来源:网信办So,算法做错了什么?好的算法长什么样子?我们以网易云音乐举例展开。听歌、听 FM 都是非常私密…...
python做后台开发移动网站/学计算机哪个培训机构好
背景: 在地图上绘制大量的circleMarker,leaflet能选择使用canvas来渲染,比起默认的svg渲染来说在大量绘制的情况下会更加流畅。但当触发其中某一个circleMarker的tooltip或popup时,浏览器报错“Uncaught RangeError: Maximum call…...
网站设计郑州/建站cms
给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 示例: 输入: [1,2,3,null,5,null,4] 输出: [1, 3, 4] 解释: 1 <--- / \ 2 3 <--- \ \ 5 4 …...