主要更改: 1. 新增使用手册: - AI算法更新指南 - HTPA60x40传感器升级指南 - 环境配置教程 2. 传感器模块优化: - HTPA60x40dR1L0.9传感器集成 - HTPAd32x32L1k7传感器更新 - 传感器配置文档完善 3. 项目文档整理: - 删除过期的433MHz使用指南 - 更新README文档结构 - 完善配置教程链接 目标:完善项目文档,优化传感器集成
15 KiB
15 KiB
AI算法更新指南
📋 概述
本文档为后续接手项目的同事提供详细的AI算法更新指导。当客户提供新的AI算法文件时,需要按照本指南进行算法替换和系统集成。
AI算法位置:firefly_esp32/main/AI2/ 目录
当前AI功能:
- 🔥 火灾检测 - 基于热成像的火源识别
- 👤 人员检测 - 基于TensorFlow Lite的人员识别
- 🌡️ 热源分析 - 温度异常和热点扩散检测
🎯 AI算法架构
当前文件结构
AI2/
├── 🔥 火灾检测模块
│ ├── FireDetect.h # 火灾检测类声明
│ ├── FireDetect.cpp # 火灾检测实现
│ ├── thermal_flags.h # 热成像参数配置
│ └── thermal_flags.c # 热成像算法实现
│
├── 👤 人员检测模块
│ ├── PersonDetect.h # 人员检测类声明
│ ├── PersonDetect.cpp # 人员检测实现
│ └── tinycnn_model_data.h # TensorFlow Lite模型数据
│
├── 🌡️ 热源处理模块
│ ├── HeaterPersonProcessor.h # 热源人员处理器
│ ├── HeaterPersonProcessor.cpp # 热源处理实现
│ ├── esp32_thermo_preproc.h # 热成像预处理
│ ├── esp32_thermo_preproc.c # 预处理算法实现
│ └── esp32_thermo_tflm_pipeline.h # TensorFlow Lite管道
│
└── 🔧 辅助模块
├── esp32_preproc_simple.h # 简单预处理
├── esp32_preproc_simple.c # 预处理实现
└── esp32_thermo_tflm_pipeline_stride_u8.h # U8格式管道
🔄 算法更新类型
类型1:TensorFlow Lite模型更新
涉及文件:tinycnn_model_data.h
更新频率:最常见
影响范围:人员检测精度
类型2:火灾检测算法优化
涉及文件:FireDetect.cpp, thermal_flags.h
更新频率:中等
影响范围:火灾检测准确性
类型3:热成像预处理算法
涉及文件:esp32_thermo_preproc.c
更新频率:较少
影响范围:整体算法性能
类型4:完整算法架构升级
涉及文件:所有AI2文件 更新频率:很少 影响范围:整个AI系统
📝 更新步骤详解
步骤1:备份现有算法
1.1 创建备份目录
# 在项目根目录执行
mkdir -p backup/AI2_backup_$(date +%Y%m%d_%H%M%S)
cp -r firefly_esp32/main/AI2/* backup/AI2_backup_$(date +%Y%m%d_%H%M%S)/
1.2 记录当前版本信息
// 在更新前记录当前算法版本
// 查看 FireDetect.cpp 或 PersonDetect.cpp 中的版本信息
ESP_LOGI("AI_UPDATE", "Current AI version: [记录当前版本号]");
ESP_LOGI("AI_UPDATE", "Model size: %d bytes", model_tflite_len);
步骤2:分析新算法文件
2.1 确定更新类型
检查客户提供的文件:
- 如果只有
.tflite或.h模型文件 → 类型1:模型更新 - 如果有
FireDetect.*文件 → 类型2:火灾算法更新 - 如果有
esp32_thermo_preproc.*文件 → 类型3:预处理更新 - 如果提供完整AI2目录 → 类型4:完整更新
2.2 检查兼容性
// 检查新模型的输入输出尺寸
// 在新的 tinycnn_model_data.h 中查找
const unsigned int model_tflite_len = [新的大小];
// 检查是否与当前传感器兼容
// 当前:32x32 (1024像素)
// 新传感器:60x40 (2400像素)
步骤3:执行算法更新
3.1 类型1:TensorFlow Lite模型更新
最常见的更新类型
步骤:
- 替换模型文件
# 备份原文件
cp firefly_esp32/main/AI2/tinycnn_model_data.h firefly_esp32/main/AI2/tinycnn_model_data.h.backup
# 替换为新模型
cp [客户提供的新模型文件] firefly_esp32/main/AI2/tinycnn_model_data.h
- 检查模型大小变化
// 在 tinycnn_model_data.h 文件末尾检查
const unsigned int model_tflite_len = [新的数值];
// 如果模型变大,可能需要调整内存配置
// 在 sdkconfig 中增加:
CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384 // 如果模型>20KB
CONFIG_FREERTOS_HEAP_SIZE_MIN=65536 // 如果模型>50KB
- 验证编译
cd firefly_esp32
idf.py build
- 测试新模型
// 在 PersonDetect.cpp 中添加测试代码
void test_new_model() {
ESP_LOGI("AI_TEST", "Testing new model...");
ESP_LOGI("AI_TEST", "Model size: %d bytes", model_tflite_len);
// 使用测试数据验证模型
uint16_t test_data[1024] = {0}; // 或2400 for 60x40
PERSON_RESULT result = detect(test_data, 32, 32); // 或60, 40
ESP_LOGI("AI_TEST", "Model test result: score=%d, pos=(%d,%d)",
result.score, result.x, result.y);
}
3.2 类型2:火灾检测算法更新
步骤:
- 替换火灾检测文件
# 备份原文件
cp firefly_esp32/main/AI2/FireDetect.h firefly_esp32/main/AI2/FireDetect.h.backup
cp firefly_esp32/main/AI2/FireDetect.cpp firefly_esp32/main/AI2/FireDetect.cpp.backup
# 替换为新文件
cp [客户提供的FireDetect.h] firefly_esp32/main/AI2/
cp [客户提供的FireDetect.cpp] firefly_esp32/main/AI2/
- 检查参数配置变化
// 检查 thermal_flags.h 中的参数是否需要更新
#define TF_T_ABS 50.0f // 热点检测阈值
#define TF_DANGER_T 60.0f // 危险温度阈值
#define TH_W 32 // 传感器宽度
#define TH_H 32 // 传感器高度
// 如果升级到60x40传感器,需要修改:
#define TH_W 60
#define TH_H 40
- 检查API兼容性
// 检查 FIRE_RESULT 结构是否有变化
typedef struct tagFIRE_RESULT {
bool burning_alert;
bool danger_temp_alert;
// ... 检查是否有新增字段
} FIRE_RESULT;
// 检查 detect 方法签名是否变化
FIRE_RESULT detect(uint16_t* data_pixel);
3.3 类型3:热成像预处理更新
步骤:
- 替换预处理文件
# 备份原文件
cp firefly_esp32/main/AI2/esp32_thermo_preproc.h firefly_esp32/main/AI2/esp32_thermo_preproc.h.backup
cp firefly_esp32/main/AI2/esp32_thermo_preproc.c firefly_esp32/main/AI2/esp32_thermo_preproc.c.backup
# 替换为新文件
cp [客户提供的预处理文件] firefly_esp32/main/AI2/
- 检查函数接口变化
// 检查主要预处理函数是否有变化
// 在 esp32_thermo_preproc.h 中查找主要函数声明
void preprocess_thermal_data(uint16_t* input, float* output, int width, int height);
- 验证数据流兼容性
// 确保预处理输出格式与后续算法兼容
// 检查数据类型:uint16_t → float → int8_t 的转换链
3.4 类型4:完整算法架构更新
步骤:
- 完整替换AI2目录
# 备份整个目录
mv firefly_esp32/main/AI2 firefly_esp32/main/AI2_backup_$(date +%Y%m%d)
# 复制新的AI2目录
cp -r [客户提供的AI2目录] firefly_esp32/main/
- 检查CMakeLists.txt更新
# 检查 firefly_esp32/main/CMakeLists.txt 是否需要更新
set(COMPONENT_SRCS
"main.cpp"
# AI2相关文件
"AI2/FireDetect.cpp"
"AI2/PersonDetect.cpp"
"AI2/HeaterPersonProcessor.cpp"
"AI2/esp32_thermo_preproc.c"
"AI2/thermal_flags.c"
"AI2/esp32_preproc_simple.c"
# ... 检查是否有新增或删除的文件
)
- 检查依赖库变化
# 检查是否需要新的依赖库
target_link_libraries(${COMPONENT_LIB}
idf::tflite-micro # TensorFlow Lite
# ... 检查是否有新增依赖
)
步骤4:主程序集成更新
4.1 检查主程序调用
位置:firefly_esp32/main/main.cpp (或相应主文件)
检查AI调用代码:
// 火灾检测调用
FireDetect* fire_detector = FireDetect::Inst();
FireDetect::FIRE_RESULT fire_result = fire_detector->detect(thermal_data);
// 人员检测调用
PersonDetect* person_detector = PersonDetect::Inst();
PersonDetect::PERSON_RESULT person_result = person_detector->detect(thermal_data, 32, 32);
// 检查这些调用是否需要修改参数或处理返回值
4.2 更新传感器适配
如果同时升级传感器到60x40:
// 原代码 (32x32)
PersonDetect::PERSON_RESULT person_result = person_detector->detect(thermal_data, 32, 32);
// 修改为 (60x40)
PersonDetect::PERSON_RESULT person_result = person_detector->detect(thermal_data, 60, 40);
// 或者使用宏定义
#ifdef USE_HTPA60x40
PersonDetect::PERSON_RESULT person_result = person_detector->detect(thermal_data, 60, 40);
#else
PersonDetect::PERSON_RESULT person_result = person_detector->detect(thermal_data, 32, 32);
#endif
4.3 更新网络传输
检查AI结果传输:
// 检查火灾检测结果的网络传输
if (fire_result.burning_alert) {
// 发送火灾报警
send_fire_alert(fire_result.cx, fire_result.cy, fire_result.peak_c);
}
// 检查人员检测结果的传输
if (person_result.score > threshold) {
// 发送人员检测结果
send_person_detection(person_result.x, person_result.y, person_result.score);
}
// 确保这些函数调用与新算法的输出格式兼容
🧪 测试验证步骤
第1步:编译测试
cd firefly_esp32
idf.py clean
idf.py build
# 检查编译输出,确保没有错误
# 特别注意内存使用警告
第2步:功能测试
2.1 AI算法基础测试
void test_ai_algorithms() {
ESP_LOGI("AI_TEST", "=== AI Algorithm Test Start ===");
// 测试火灾检测
FireDetect* fire_detector = FireDetect::Inst();
if (fire_detector->setup()) {
ESP_LOGI("AI_TEST", "✅ Fire detection setup OK");
} else {
ESP_LOGE("AI_TEST", "❌ Fire detection setup failed");
}
// 测试人员检测
PersonDetect* person_detector = PersonDetect::Inst();
if (person_detector->setup()) {
ESP_LOGI("AI_TEST", "✅ Person detection setup OK");
} else {
ESP_LOGE("AI_TEST", "❌ Person detection setup failed");
}
// 测试模型大小
ESP_LOGI("AI_TEST", "Model size: %d bytes", model_tflite_len);
ESP_LOGI("AI_TEST", "Free heap: %d bytes", esp_get_free_heap_size());
ESP_LOGI("AI_TEST", "=== AI Algorithm Test End ===");
}
2.2 实际数据测试
void test_with_real_data() {
ESP_LOGI("AI_TEST", "Testing with real thermal data...");
// 获取真实热成像数据
uint16_t thermal_data[TH_PIX]; // 1024 or 2400
if (thermal_sensor.getData(thermal_data, TH_PIX)) {
// 测试火灾检测
FireDetect::FIRE_RESULT fire_result = fire_detector->detect(thermal_data);
ESP_LOGI("AI_TEST", "Fire detection - Alert: %s, Temp: %.1f°C",
fire_result.burning_alert ? "YES" : "NO", fire_result.peak_c);
// 测试人员检测
PersonDetect::PERSON_RESULT person_result = person_detector->detect(thermal_data, TH_W, TH_H);
ESP_LOGI("AI_TEST", "Person detection - Score: %d, Pos: (%d,%d)",
person_result.score, person_result.x, person_result.y);
}
}
第3步:性能测试
void test_ai_performance() {
ESP_LOGI("PERF_TEST", "=== AI Performance Test ===");
uint16_t test_data[TH_PIX];
memset(test_data, 0, sizeof(test_data));
// 测试火灾检测性能
uint32_t start_time = esp_timer_get_time();
for (int i = 0; i < 10; i++) {
FireDetect::FIRE_RESULT result = fire_detector->detect(test_data);
}
uint32_t fire_time = (esp_timer_get_time() - start_time) / 10;
// 测试人员检测性能
start_time = esp_timer_get_time();
for (int i = 0; i < 10; i++) {
PersonDetect::PERSON_RESULT result = person_detector->detect(test_data, TH_W, TH_H);
}
uint32_t person_time = (esp_timer_get_time() - start_time) / 10;
ESP_LOGI("PERF_TEST", "Fire detection avg time: %d ms", fire_time / 1000);
ESP_LOGI("PERF_TEST", "Person detection avg time: %d ms", person_time / 1000);
ESP_LOGI("PERF_TEST", "Free heap after test: %d bytes", esp_get_free_heap_size());
}
🚨 常见问题解决
问题1:编译错误 - 找不到函数
现象:
error: 'xxx' was not declared in this scope
解决方案:
- 检查新算法的头文件是否正确包含
- 检查函数名称是否有变化
- 检查命名空间或类名是否有变化
问题2:内存不足
现象:
E (xxx) AI: Failed to allocate memory for model
解决方案:
- 检查新模型大小:
model_tflite_len - 增加堆内存配置:
CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384
CONFIG_FREERTOS_HEAP_SIZE_MIN=65536
- 考虑使用PSRAM:
CONFIG_ESP32_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_USE_MALLOC=y
问题3:AI检测结果异常
现象:检测结果明显不正确
解决方案:
- 检查输入数据格式是否匹配
- 验证传感器分辨率配置
- 检查温度转换算法
- 对比算法参数配置
问题4:性能下降
现象:系统响应变慢
解决方案:
- 测量各AI算法的执行时间
- 检查是否有内存泄漏
- 优化算法调用频率
- 考虑使用多任务并行处理
📋 更新检查清单
算法文件更新 ✓
- 备份原有AI2目录
- 确认更新类型和范围
- 替换相应算法文件
- 检查文件完整性
配置参数调整 ✓
- 检查thermal_flags.h参数
- 更新传感器尺寸配置
- 调整内存配置
- 更新CMakeLists.txt
代码集成修改 ✓
- 更新主程序AI调用
- 适配传感器分辨率变化
- 修改网络传输格式
- 更新Android端接收
测试验证完成 ✓
- 编译测试通过
- AI算法基础功能正常
- 实际数据测试正常
- 性能测试满足要求
- 集成测试通过
📞 技术支持
调试技巧
// 启用AI模块详细日志
esp_log_level_set("FireDetect", ESP_LOG_DEBUG);
esp_log_level_set("PersonDetect", ESP_LOG_DEBUG);
// 监控内存使用
ESP_LOGI("AI_DEBUG", "Before AI: Free heap %d", esp_get_free_heap_size());
// ... AI算法调用 ...
ESP_LOGI("AI_DEBUG", "After AI: Free heap %d", esp_get_free_heap_size());
// 性能监控
uint32_t start = esp_timer_get_time();
// ... AI算法执行 ...
ESP_LOGI("AI_PERF", "AI execution time: %d ms", (esp_timer_get_time() - start) / 1000);
文档参考
- AI算法源码:
firefly_esp32/main/AI2/ - 传感器适配:参考传感器升级指南
- TensorFlow Lite文档:ESP32 TensorFlow Lite官方文档
联系信息
- 原开发者:fw kingfun2000@qq.com
- 客户技术支持:[客户提供的联系方式]
- 项目仓库:查看项目根目录README
🎯 总结
AI算法更新主要涉及:
- 模型文件替换 - 最常见的TensorFlow Lite模型更新
- 算法逻辑优化 - 火灾检测和预处理算法改进
- 参数配置调整 - 适配新传感器和优化检测精度
- 性能验证测试 - 确保更新后系统稳定运行
关键提醒:
- 每次更新前必须备份原有算法
- 重点关注内存使用和性能影响
- 充分测试各种场景下的AI检测效果
- 保持与传感器升级的同步适配
预计工作量:
- 模型更新:0.5天
- 算法优化:1-2天
- 完整更新:2-3天
- 测试验证:1-2天
文档版本:v1.0
创建时间:2026年2月26日
适用版本:ESP32固件v2.1.0+
作者:fw (离职前准备文档)