实现 ESP32-S3 上单摄像头人脸追踪的核心代码骨架,替代 Grove Vision AI V2
模块,通过 UART 发送人脸坐标驱动 RP2040 控制的眼球/YAW 舵机。
## 规划文档(docs/phase-01-face-tracking/)
- GOAL.md Phase 目标与 5 大成功标准
- RESEARCH.md esp-dl v3.2/3.3 + human_face_detect 0.4.1 技术调研
- PLAN.md 15 个原子任务的执行计划(T01-T15)
- PLAN_CHECK.md 计划审查报告(PASS_WITH_NOTES)
- PROGRESS.md 执行进度追踪(批次 1-3 已完成)
## 批次 1:依赖与开关(T01-T03)
- main/idf_component.yml
新增 esp-dl ~3.3.0 + human_face_detect 0.4.1(仅 S3/P4)
esp-sr 从 ~2.2.0 升级到 ~2.3.1,解决 esp-dsp 1.6/1.7 版本冲突
- main/Kconfig.projbuild
新增 CONFIG_XIAOZHI_ENABLE_FACE_TRACKING 开关(默认 y,depends on S3)
新增 CONFIG_XIAOZHI_FACE_TRACKING_FPS_CHOICE(5/10/15)
- main/boards/common/esp32_camera.{h,cc}
新增 ProbeFrameCapture() 最小 V4L2 DQBUF/QBUF 探针(T01)
- main/application.cc
Start() 末尾调用 probe 验证摄像头硬件链路
## 批次 2:人脸检测核心(T04-T06)
- main/boards/common/esp32_camera.{h,cc}
新增 FrameRef 结构体 + CaptureForDetection/ReleaseDetectionFrame
双超时 mutex 策略:face_tracker 10ms timeout 跳帧,Capture() RAII guard
- main/face_tracker.{h,cc}(新建)
Core 0 / 优先级 2 / 栈 8KB 独立任务
集成 esp-dl HumanFaceDetect 推理
坐标归一化 cx*224/W-112,匹配 RP2040 pixel_centre=112
多人脸遍历挑 score 最高,避免多脸时眼球摇摆
三重保护:Kconfig depends on S3 + 源文件 #if 守卫 + CMake 条件排除
- main/CMakeLists.txt
非 S3 目标从 SOURCES 移除 face_tracker.cc
## 批次 3:UART 协议扩展(T07)
- main/uart_component.{h,cc}
新增 uart_send_face(x,y) 发送 face:x,y\r\n 协议
extern "C" 链接名配合 face_tracker 的弱符号声明
全局 TX mutex 保护所有 UART 写入,防并发帧交织
uart_send_string 同步加锁保持一致性
## 编译验证
idf.py build 通过,固件 2.51MB / 剩余 1.46MB (36% free)
当前 face_tracker 未被 application 激活(留到 T11),
UART/摄像头现有功能零影响。
## 未完成(下次继续)
- T01 硬件 probe 实机验证
- T08-T10 RP2040 端 parse_face + facetrack 双数据源改造
- T11-T15 application 接入 + 端到端联调 + 性能调优 + 最终验收
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
33 lines
1.1 KiB
C
33 lines
1.1 KiB
C
#pragma once
|
||
#include "driver/uart.h"
|
||
|
||
// ESP32 → RP2040 的 UART 通信引脚定义
|
||
// ESP32 的 GPIO17(TX) 连接 RP2040 的 GP5(RX)
|
||
// ESP32 的 GPIO18(RX) 连接 RP2040 的 GP4(TX)
|
||
#define TXD_PIN 17
|
||
#define RXD_PIN 18
|
||
#define UART_PORT_NUM UART_NUM_1 // 使用 UART1(UART0 用于调试日志)
|
||
#define BUF_SIZE 1024
|
||
|
||
// 初始化 UART 组件(115200 波特率,8N1)
|
||
void uart_init_component();
|
||
// 发送状态字符串给 RP2040(如 "speaking"、"listening"、"idle" 等)
|
||
// RP2040 收到后驱动 9 个舵机执行对应动画
|
||
void uart_send_string(const char* str);
|
||
// 发送说话开始信号
|
||
void uart_signal_start();
|
||
// 发送说话停止信号
|
||
void uart_signal_stop();
|
||
|
||
// 发送人脸检测坐标,格式:"face:<x>,<y>\r\n"
|
||
// x,y ∈ [-112, +112],RP2040 端 pixel_centre=112 解析(T07)
|
||
// 使用 C 链接名:face_tracker.cc 以 `extern "C" __attribute__((weak))` 前向声明该符号,
|
||
// 链接器用此 strong 实现自动覆盖 weak 版本。不可改为 C++ 名字修饰。
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
void uart_send_face(int x_offset, int y_offset);
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|