DomoticsCore:面向生产的ESP32/ESP8266嵌入式智能家居框架

news2026/3/21 19:01:31
1. DomoticsCore 框架深度解析面向生产环境的 ESP32/ESP8266 智能家居底层架构DomoticsCore 并非一个简单的 Arduino 库集合而是一个为嵌入式物联网设备量身打造的、具备工业级鲁棒性的系统级框架。其设计哲学直指嵌入式开发中最棘手的痛点资源受限下的可靠性、无调试接口时的状态可见性、组件间的松耦合与可测试性以及从原型到量产的平滑演进路径。本文将基于其 v1.6.0 版本的官方文档与源码结构以一名嵌入式固件工程师的视角系统性地拆解其核心机制、关键 API 及工程实践细节。1.1 系统定位与核心价值主张在 ESP32 生态中开发者常面临两种极端一是使用裸机 SDK 或 FreeRTOS 原生 API获得极致控制权但需自行构建整个软件栈二是依赖高度封装的平台如 ESPHome虽上手极快却丧失底层干预能力且难以进行深度定制与故障排查。DomoticsCore 正是介于二者之间的“黄金中间层”。其核心价值并非提供某个单一功能而是定义了一套可组合、可观测、可恢复的嵌入式系统构建范式可组合Composable通过Core类作为运行时容器所有功能模块WiFi、LED、MQTT均以IComponent接口实现通过addComponent()动态注入。这使得一个 300KB 的最小系统仅含 Core LED与一个 900KB 的全功能系统共享同一套初始化、调度与生命周期管理逻辑。可观测Observable视觉状态指示器LED是其最具匠心的设计。它不依赖串口或网络而是直接映射到 GPIO在系统崩溃、WiFi 连接失败、OTA 升级等关键状态下以精确的时序如 ERROR 状态下 300ms 快闪向开发者传递信息。这在部署于配电箱、天花板等“黑盒”场景的设备中是无可替代的诊断手段。可恢复Recoverable框架内置的错误处理不是简单的while(1)死循环而是domotics-loop()的持续调用。这意味着即使主系统初始化失败LED 状态动画、Telnet 远程控制台RemoteConsole等关键服务依然保持活跃为现场调试提供了最后一道防线。这种设计思想深刻体现了嵌入式开发的工程本质系统必须在已知的、未知的、以及完全不可预测的故障模式下始终提供一种确定性的、可理解的反馈。1.2 分层架构与硬件抽象层HALDomoticsCore 的项目结构清晰地反映了其分层设计理念整个代码库采用单体仓库Monorepo管理包含 12 个独立的组件包Component Package。这种组织方式既保证了模块的物理隔离又便于统一版本控制与 CI/CD 流水线。DomoticsCore/ ├── DomoticsCore-Core/ # 核心框架EventBus、MemoryManager、HeapTracker、日志系统 ├── DomoticsCore-System/ # 高阶编排System 类提供“开箱即用”的完整体验 ├── DomoticsCore-Wifi/ # WiFi 组件支持 STAAP 双模、自动重连、连接状态事件 ├── DomoticsCore-LED/ # LED 组件6 种预设效果Blink, Pulse, Breathing... ├── DomoticsCore-Storage/ # 存储组件统一 NVSESP32与 LittleFSESP8266API ├── DomoticsCore-RemoteConsole/ # Telnet 控制台支持命令注册、WebUI 集成 ├── DomoticsCore-WebUI/ # WebUI 组件基于 ESPAsyncWebServer支持 WebSocketSSE 双通道 ├── DomoticsCore-MQTT/ # MQTT 客户端基于 PubSubClient集成自动重连与 HA 发现 ├── DomoticsCore-NTP/ # NTP 时间同步统一 SNTPESP32与 configTimeESP8266接口 ├── DomoticsCore-OTA/ # OTA 更新支持 HTTP/HTTPS 固件升级 ├── DomoticsCore-HomeAssistant/ # Home Assistant 集成自动生成 MQTT Discovery 主题 ├── DomoticsCore-SystemInfo/ # 系统监控实时内存、CPU、Uptime 数据采集与图表所有组件均遵循统一的硬件抽象层HAL规范其头文件位于DomoticsCore-Core/include/DomoticsCore/HAL/目录下。HAL 是实现跨平台兼容性的基石它将平台特定的实现细节完全封装对外暴露一致的 C 接口。例如HAL/WiFi.h定义了WiFi.begin(),WiFi.status()等函数其内部在 ESP32 上调用esp_wifi_start()在 ESP8266 上则调用WiFi.begin()对上层组件完全透明。HAL/Storage.h提供storage::putString(key, value)和storage::getString(key)等通用 KV 操作。在 ESP32 上它最终调用nvs_set_str()在 ESP8266 上则调用LittleFS.open().write()。组件开发者只需关心“存什么”无需关心“怎么存”。这种 HAL 设计不仅支撑了当前对 ESP32/ESP32-C3/ESP8266 的支持也为未来扩展至其他平台如 RP2040铺平了道路。其Platform.h头文件通过宏定义如#ifdef ESP32进行条件编译是嵌入式 C 中实现多平台支持的标准且高效的做法。2. 核心运行时机制EventBus 与组件生命周期管理DomoticsCore 的灵魂在于其EventBus事件总线架构。它彻底摒弃了传统嵌入式开发中常见的全局变量、回调函数指针或紧耦合的类成员调用转而采用发布-订阅Publish-Subscribe模式实现了组件间真正的解耦。2.1 EventBus 的设计原理与实现逻辑EventBus的核心是一个轻量级的、类型安全的内存内消息队列。其设计目标是零拷贝、低延迟和高可靠性。在DomoticsCore-Core的源码中EventBus类通常包含以下关键数据结构一个std::vectorstd::pairString, std::functionvoid(const void*)类型的订阅者列表其中String是主题Topicstd::function是回调函数。一个std::queuestd::pairString, const void*类型的待处理事件队列用于在loop()中批量分发。其工作流程如下发布Publish当一个组件如WifiComponent检测到 WiFi 已连接它会调用eventBus().publish(wifi.connected, nullptr)。此时nullptr是一个空载荷仅表示事件发生。分发Dispatch在Core::loop()的主循环中框架会遍历事件队列对于每个事件查找所有订阅了该主题的回调函数并依次调用它们。订阅Subscribe另一个组件如LEDComponent在begin()中调用eventBus().subscribe(wifi.connected, [](const void*) { /* 设置LED为PULSE状态 */ }, this)。这个this指针确保了回调函数可以安全地访问订阅者的私有成员。这种模式的优势是革命性的可测试性LEDComponent的单元测试无需启动真实的 WiFi 模块。测试框架可以直接调用eventBus().publish(wifi.connected)然后断言 LED 的内部状态是否正确更新。可维护性添加一个新的“通知用户 WiFi 已连接”的功能只需创建一个新组件并订阅wifi.connected主题完全无需修改WifiComponent的任何一行代码。健壮性一个组件的崩溃不会导致整个事件分发链路中断。框架会在try-catch块中执行每个回调捕获异常并记录日志确保其他组件不受影响。2.2 组件IComponent的标准化生命周期所有功能模块都必须继承自抽象基类IComponent该类强制定义了四个虚函数构成了组件的标准化生命周期函数名调用时机工程目的典型实现begin()Core::begin()期间被调用初始化分配内存、配置外设、注册事件监听器、建立网络连接WiFi.begin(ssid, password); eventBus().subscribe(...);loop()Core::loop()的每一次迭代中被调用主循环处理网络收发、传感器读取、状态机更新等非阻塞任务WiFiClient client server.available(); if(client) handleClient(client);shutdown()Core::shutdown()时被调用如 OTA 前优雅关闭释放网络连接、保存关键状态、关闭外设WiFi.disconnect(); storage::putInt(last_uptime, uptime);getDependencies()Core::begin()的初始化排序阶段被调用依赖声明声明本组件所依赖的其他组件名称确保初始化顺序正确return {Storage, NTP}; // Storage 必须在本组件之前初始化getDependencies()是一个精妙的设计。它允许框架在begin()阶段根据所有组件的依赖关系自动生成一个有向无环图DAG并据此对组件进行拓扑排序。这意味着开发者永远不必担心“先初始化 WiFi 还是先初始化 MQTT”框架会自动确保WifiComponent在MQTTComponent之前完成初始化从而避免了因初始化顺序错误导致的空指针或连接失败等隐蔽 Bug。3. 关键组件深度剖析与 API 实战3.1 System 类开箱即用的“全栈”体验System类是为初学者和快速原型开发设计的最高层封装。它将Core、WifiComponent、LEDComponent、RemoteConsole等常用组件预先打包并提供了一个简洁的SystemConfig结构体来配置所有参数。其核心 API 如下表所示API参数说明返回值作用System(SystemConfig config)构造函数传入配置结构体无创建 System 实例但不执行初始化bool begin()无true表示成功false表示失败执行所有组件的begin()启动整个系统void loop()无无执行所有组件的loop()是main loop()中唯一需要调用的函数void registerCommand(String cmd, std::functionString(const String) handler)cmd: 命令名handler: 处理函数无向 RemoteConsole 注册一个自定义命令例如helloSystemConfig结构体是配置的中心枢纽其关键字段包括字段类型默认值说明deviceNameStringDomoticsCore设备在局域网中的主机名影响 MQTT 主题前缀和 WebUI 标题wifiSSID/wifiPasswordStringWiFi 连接凭据ledPinint-1用于状态指示的 GPIO 引脚号若为-1则禁用 LEDconsolePortuint16_t23Telnet 控制台监听端口webUIPortuint16_t80WebUI HTTP 服务监听端口一个典型的setup()函数其背后隐藏着复杂的初始化序列void setup() { Serial.begin(115200); SystemConfig config SystemConfig::fullStack(); // 获取一个预设的全功能配置 config.deviceName MyDevice; config.wifiSSID YOUR_WIFI; config.wifiPassword YOUR_PASSWORD; config.ledPin 2; domotics new System(config); // 注册自定义命令这是对 RemoteConsole 的扩展 domotics-registerCommand(uptime, [](const String args) { return String(Uptime: ) millis() / 1000 s; }); // 执行初始化。如果失败进入错误处理循环。 if (!domotics-begin()) { DLOG_E(LOG_APP, System initialization failed!); while (1) { domotics-loop(); // 关键在此循环中LED 仍会闪烁Console 仍可访问 yield(); } } DLOG_I(LOG_APP, System ready!); }System::begin()的内部逻辑是首先调用Core::begin(config)然后Core会根据System的依赖声明依次调用WifiComponent::begin()、LEDComponent::begin()、RemoteConsole::begin()等。整个过程对用户完全透明体现了“约定优于配置”的设计哲学。3.2 LEDComponent嵌入式系统的“生命体征监护仪”LEDComponent是 DomoticsCore 中最具人文关怀的设计。它将一个简单的 GPIO 输出升华为一个承载丰富语义信息的“状态显示器”。其核心在于LEDState枚举和一套精确的定时器驱动的状态机。LEDState定义了 6 种标准状态每种状态对应一个独特的视觉模式状态枚举视觉效果触发条件时序参数BOOTING快速闪烁200ms on / 200ms offSystem::begin()开始执行时blinkPeriod 400msWIFI_CONNECTING缓慢闪烁1000ms on / 1000ms offWifiComponent进入连接尝试状态blinkPeriod 2000msWIFI_CONNECTED脉冲2000ms 周期占空比 30%WifiComponent报告WL_CONNECTEDpulsePeriod 2000msREADY呼吸3000ms 周期正弦波亮度变化System::begin()成功返回后breathPeriod 3000msERROR快速闪烁300ms on / 300ms off任何组件begin()失败或loop()中抛出未捕获异常blinkPeriod 600msOTA_UPDATE常亮OTAComponent开始下载固件时brightness 255其实现逻辑非常精炼。LEDComponent内部维护一个millis()计时器和一个currentBrightness变量。在loop()中它根据当前LEDState计算出下一个毫秒时刻应设置的 PWM 占空比并通过analogWrite(ledPin, currentBrightness)输出。整个过程不使用delay()完全是非阻塞的确保了与其他组件如 WiFi、MQTT的并发执行。对于高级用户LEDComponent还提供了setCustomEffect()接口允许传入一个自定义的std::functionuint8_t(uint32_t)函数该函数接收一个单调递增的时间戳ms并返回一个 0-255 的亮度值。这为实现彩虹渐变、心跳模拟等复杂效果提供了无限可能。3.3 StorageComponent统一的持久化存储抽象在 ESP32/ESP8266 上持久化存储方案五花八门ESP32 原生推荐 NVSNon-Volatile Storage而 ESP8266 社区则普遍采用 LittleFS。StorageComponent的使命就是抹平这些差异为上层应用提供一个统一的、类似数据库的 KV键值对操作接口。其核心 API 是一组模板化的put和get函数// 存储数据 bool storage::putString(const String key, const String value); bool storage::putInt(const String key, int32_t value); bool storage::putFloat(const String key, float value); bool storage::putBytes(const String key, const uint8_t* data, size_t len); // 读取数据 String storage::getString(const String key, const String defaultValue ); int32_t storage::getInt(const String key, int32_t defaultValue 0); float storage::getFloat(const String key, float defaultValue 0.0f); size_t storage::getBytes(const String key, uint8_t* buffer, size_t bufferSize);这些 API 的底层实现是平台相关的ESP32/NVSputString最终调用nvs_set_str(handle, key.c_str(), value.c_str())getFloat则调用nvs_get_blob(handle, key.c_str(), buffer, length)并进行memcpy解析。ESP8266/LittleFSputString会打开一个以key命名的文件将value写入getFloat则打开同名文件读取内容并调用atof()转换。这种抽象带来的好处是巨大的。一个为 ESP32 编写的传感器节点固件如果只使用StorageComponent的 API那么只需重新编译即可无缝迁移到 ESP8266 平台上而无需修改任何一行业务逻辑代码。这正是 HAL 层价值的完美体现。4. 生产就绪特性内存管理、错误处理与远程调试4.1 MemoryManager 与 HeapTracker对抗内存泄漏的利器对于一个长期运行的 IoT 设备“内存泄漏”是比功能缺陷更致命的敌人。DomoticsCore v1.6.0 引入的MemoryManager和HeapTracker是一套完整的内存治理工具链。MemoryManager它不是一个全新的内存分配器而是对malloc/free的一层智能包装。它会记录每一次分配的调用栈通过__builtin_return_address(0)、大小和时间戳。当系统内存低于阈值时它可以触发一个memory.low事件通知SystemInfoComponent记录日志或通知WebUI显示警告。HeapTracker这是一个运行时内存分析器。它提供了一个heapTracker::start()和heapTracker::stop()API。在start()和stop()之间它会记录所有malloc和free的调用并在stop()时生成一份详细的报告列出所有未被free的内存块及其分配位置。这对于在 CI 流水线中自动化检测内存泄漏至关重要。在examples/目录下的MemoryLeakTest示例中展示了如何使用HeapTrackervoid setup() { heapTracker::start(); // 开始跟踪 // ... 执行一系列可能产生泄漏的操作 ... heapTracker::stop(); // 停止跟踪并打印报告到 Serial }报告输出类似于[HEAP] Leak detected! 3 blocks, total 128 bytes. [HEAP] Block #1: 64 bytes 0x3ffae000, allocated in WifiComponent.cpp:142 [HEAP] Block #2: 32 bytes 0x3ffae040, allocated in MQTTComponent.cpp:87 [HEAP] Block #3: 32 bytes 0x3ffae060, allocated in CustomSensor.cpp:55这种精准的定位能力将原本需要数小时甚至数天的手动排查缩短到了几分钟之内。4.2 RemoteConsole 与 WebUI双模远程调试体系DomoticsCore 提供了业界领先的远程调试体验其核心是RemoteConsole组件与WebUI组件的深度集成。RemoteConsole它是一个轻量级的 Telnet 服务器监听在 TCP 端口 23可配置。它支持命令行历史、Tab 键自动补全并且最关键的是它完全独立于主应用逻辑。即使System::begin()失败RemoteConsole依然可以接受连接让开发者能够输入log level debug来提升日志级别或输入wifi scan来手动扫描周围的 WiFi 网络从而找到初始化失败的根本原因。WebUI它基于ESPAsyncWebServer提供了现代化的 Web 界面。其最大创新在于WebSocket SSEServer-Sent Events双模式传输。对于需要实时双向通信的场景如控制台输入输出使用 WebSocket对于只需要服务器向客户端单向推送状态更新的场景如系统监控图表则使用更轻量的 SSE。这种设计在带宽和 CPU 占用上取得了最佳平衡。RemoteConsole与WebUI的集成体现在WebUI的/console页面。该页面本质上是一个 WebSocket 客户端它连接到RemoteConsole的 WebSocket 服务端。这意味着开发者可以在浏览器中获得与 Telnet 客户端完全一致的交互体验同时还能享受 Web 界面的便利性如复制粘贴、字体缩放。4.3 HomeAssistantComponent零配置的智能家居生态接入HomeAssistantComponent是 DomoticsCore 与智能家居生态对接的桥梁。它实现了 MQTT Auto-Discovery 协议使得设备在首次连接到 Home Assistant 的 MQTT Broker 后无需任何手动配置即可自动在 HA 的 UI 中出现。其工作原理是HomeAssistantComponent在begin()时会向 MQTT Broker 的特定主题如homeassistant/sensor/mydevice/temperature/config发布一条 JSON 格式的配置消息。这条消息包含了该传感器的名称、单位、图标、状态主题等元数据。Home Assistant 的 MQTT 集成模块会监听这个主题一旦收到消息便自动创建一个对应的实体Entity。其核心 API 是ha::registerSensor()和ha::registerSwitch()等系列函数// 注册一个温度传感器 ha::registerSensor(temperature, Temperature, °C, mdi:thermometer); // 之后只需定期发布状态mqtt.publish(homeassistant/sensor/mydevice/temperature/state, 22.5); // 注册一个开关 ha::registerSwitch(light, Living Room Light, mdi:lightbulb); // 之后HA 会向 homeassistant/switch/mydevice/light/set 主题发送 ON/OFF 命令这种“发布即发现”的模式极大地简化了设备的配网流程是 DomoticsCore “Production Ready” 定位的又一有力佐证。5. 工程实践指南从最小核心到全功能系统5.1 最小核心Core-Only的构建与裁剪对于资源极度敏感的应用如使用 ESP8266 的电池供电设备System类的 900KB 二进制尺寸是不可接受的。此时应采用Core类的最小化构建方式。一个典型的Core-Only项目结构如下#include DomoticsCore/Core.h #include DomoticsCore/LED.h #include DomoticsCore/Wifi.h using namespace DomoticsCore; Core core; void setup() { // 只添加必需的组件 core.addComponent(std::make_uniqueComponents::LEDComponent(2)); // GPIO2 core.addComponent(std::make_uniqueComponents::WifiComponent(SSID, PASS)); CoreConfig config; config.deviceName MinimalDevice; core.begin(config); // 自动解析依赖先初始化 LED再初始化 WiFi } void loop() { core.loop(); // 所有组件的 loop() 都在此被调用 }此方案的二进制尺寸约为 300KB相比全功能系统减少了 60%。其裁剪的关键在于移除 WebUI 和 AsyncTCP这两个库是内存消耗大户Core-Only方案完全不链接它们。禁用 JSON 解析HomeAssistantComponent和WebUI重度依赖ArduinoJson移除它们后ArduinoJson库也不会被链接。使用CoreConfig替代SystemConfigCoreConfig不包含webUIPort、consolePort等字段编译器会将其优化掉。5.2 PlatformIO 集成与依赖管理DomoticsCore 对 PlatformIO 的支持是其易用性的基石。在platformio.ini中有三种推荐的集成方式Registry 方式推荐最简单适用于大多数用户。[env:esp32dev] platform espressif32 board esp32dev framework arduino lib_deps jn0v/DomoticsCore^1.6.0GitHub 方式适用于需要最新开发版或特定分支的用户。lib_deps https://github.com/JN0V/DomoticsCore.git#v1.6.0符号链接方式Symlink适用于深度定制和组件开发。lib_deps symlink://path/to/DomoticsCore/DomoticsCore-Core symlink://path/to/DomoticsCore/DomoticsCore-LED symlink://path/to/DomoticsCore/DomoticsCore-Wifi这种方式允许开发者在本地修改某个组件如DomoticsCore-LED的源码并立即在项目中看到效果无需重新发布库。PlatformIO 的强大之处在于它能自动解析library.json文件中的dependencies字段。例如DomoticsCore-WebUI的library.json中声明了dependencies: {jn0v/DomoticsCore-Core: ^1.5.0}PlatformIO 会自动下载并链接Core库确保了整个依赖树的一致性。5.3 版本管理与语义化发布DomoticsCore 采用了一套严谨的语义化版本管理Semantic Versioning策略其独特之处在于组件级版本与根框架版本的联动。根框架版本由顶层library.json的version字段定义代表整个DomoticsCore项目的发布版本。组件版本每个子目录如DomoticsCore-Wifi/都有自己的library.json其version字段定义了该组件的独立版本。版本联动规则Model B确保了向后兼容性如果DomoticsCore-Wifi的 patch 版本如1.4.1-1.4.2被更新则根框架的 patch 版本也必须更新如1.6.0-1.6.1。如果DomoticsCore-Wifi的 minor 版本如1.4.1-1.5.0被更新则根框架的 minor 版本也必须更新如1.6.0-1.7.0且 patch 重置为0。major 版本的更新同理会重置 minor 和 patch。这套规则由tools/bump_version.py脚本自动化执行。例如执行python tools/bump_version.py Wifi minor脚本会读取DomoticsCore-Wifi/library.json的当前版本1.4.1。计算新版本1.5.0。更新DomoticsCore-Wifi/library.json和DomoticsCore-Wifi/include/DomoticsCore/Wifi/WifiComponent.h中的metadata.version字符串。更新根目录library.json的版本为1.7.0。这种精细化的版本控制使得大型团队协作开发成为可能。不同小组可以并行开发MQTT和Display组件只要它们遵守各自的版本规则最终集成时就不会出现兼容性问题。DomoticsCore 的设计处处体现着一位资深嵌入式工程师对“生产就绪”Production-Ready这一目标的深刻理解。它不追求炫酷的新特性而是将全部精力投入到解决那些在深夜调试一个离线设备时才会真正痛彻心扉的问题上如何让一个没有屏幕的设备告诉你它正在做什么如何在内存耗尽前预警如何让一个崩溃的组件不影响其他服务的运行。当你在配电箱里安装好一个基于 DomoticsCore 的设备并在数月后第一次打开手机上的 Home Assistant看到那个熟悉的设备图标和实时更新的传感器数据时你所感受到的正是这套框架所承诺的——稳定、可靠、以及那份无需解释的安心。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

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

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

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

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

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

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…