diff --git a/main.py b/main.py index fb8b2ac..4797e69 100644 --- a/main.py +++ b/main.py @@ -245,8 +245,8 @@ def cmd_str(): # 4. 初始化设备ID(network_manager 内部会自动设置 device_id 和 password) network_manager.read_device_id() - # 5. 创建照片存储目录(如果启用图像保存) - if config.SAVE_IMAGE_ENABLED: + # 5. 创建照片存储目录(如果启用图像保存或检测失败时强制保存) + if config.SAVE_IMAGE_ENABLED or getattr(config, "SAVE_IMAGE_ON_FAILURE", False): photo_dir = config.PHOTO_DIR if photo_dir not in os.listdir("/root"): try: @@ -278,6 +278,12 @@ def cmd_str(): logger.info("系统准备完成...") last_adc_trigger = 0 + # 读取一次ADC初始值,防止开机时传感器已有压力导致误触发 + try: + last_adc_val = hardware_manager.adc_obj.read() + except Exception: + last_adc_val = 0 + peak_adc_val = 0 # 当前周期内的压力峰值 # 气压采样:减少日志频率(每 N 个点输出一条),避免 logger.debug 拖慢采样 PRESSURE_BATCH_SIZE = 100 @@ -367,15 +373,21 @@ def cmd_str(): pressure_max = adc_val if len(pressure_buf) >= PRESSURE_BATCH_SIZE: _flush_pressure_buf("batch") - # if adc_val >= 2000: - # print(f"adc :{adc_val}") - if adc_val >= config.ADC_TRIGGER_THRESHOLD: + # 峰值检测:压力从峰值下降时触发,确保捕获到最大冲击时刻 + if adc_val > peak_adc_val: + peak_adc_val = adc_val # 更新峰值 + if (peak_adc_val >= config.ADC_TRIGGER_THRESHOLD + and adc_val < peak_adc_val + and last_adc_val >= peak_adc_val): + # 封顶后下降沿触发:peak是最大值,当前值开始下降,且上次值还在peak位置 hardware_manager.start_idle_timer() # 重新计时 diff_ms = current_time - last_adc_trigger if diff_ms < 3000: - logger.info(f"[MAIN] 扳机触发过于频繁, {diff_ms}ms") + peak_adc_val = 0 # 去抖期间重置峰值 + time.sleep_ms(5) continue last_adc_trigger = current_time + peak_adc_val = 0 # 触发后重置峰值 # 触发前先把缓存刷出来,避免波形被长耗时处理截断 _flush_pressure_buf("before_trigger") @@ -396,6 +408,7 @@ def cmd_str(): except Exception as e: pass time.sleep_ms(5) + last_adc_val = adc_val except Exception as e: # 主循环的顶层异常捕获,防止程序静默退出 diff --git a/shoot_manager.py b/shoot_manager.py index d94a214..d788fa0 100644 --- a/shoot_manager.py +++ b/shoot_manager.py @@ -520,6 +520,7 @@ def process_shot(adc_val): laser_manager.flash_laser(config.FLASH_LASER_DURATION_MS) # 保存图像(异步队列,与 main.py 一致) + _force_save = (dx is None and dy is None) and getattr(config, "SAVE_IMAGE_ON_FAILURE", False) enqueue_save_shot( result_img, center, @@ -529,8 +530,9 @@ def process_shot(adc_val): (x, y), distance_m, shot_id=shot_id, - photo_dir=config.PHOTO_DIR if config.SAVE_IMAGE_ENABLED else None, + photo_dir=config.PHOTO_DIR if (config.SAVE_IMAGE_ENABLED or _force_save) else None, yolo_roi_xyxy=yolo_roi_xyxy if draw_yolo_roi else None, + force_save=_force_save, ) if logger: diff --git a/test/test_decect_circle_v4.py b/test/test_decect_circle_v4.py index 9f92c84..d4a1d5a 100644 --- a/test/test_decect_circle_v4.py +++ b/test/test_decect_circle_v4.py @@ -154,11 +154,11 @@ def detect_circle_v3(frame, laser_point=None): max_r = max(red_radius, yellow_radius) size_ratio = min_r / max_r if max_r > 0 else 0 print(f"Debug -> 圆心距={distance:.1f}(阈值={max_distance:.1f}), " - f"大小比={size_ratio:.2f}(阈值=0.5), " - f"距离OK={distance < max_distance}, 大小OK={size_ratio > 0.5}") + f"大小比={size_ratio:.2f}(阈值=0.4), " + f"距离OK={distance < max_distance}, 大小OK={size_ratio >= 0.4}") # 允许红圈在黄圈外侧或内侧,只要大小相近(较小/较大 >= 0.5) - if distance < max_distance and size_ratio > 0.5: + if distance < max_distance and size_ratio >= 0.4: found_valid_red = True print( f"[target] -> 找到匹配的红圈: 黄心({yellow_center}), 红心({red_center}), 距离:{distance:.1f}, 黄半径:{yellow_radius}, 红半径:{red_radius}") @@ -598,7 +598,7 @@ if __name__ == "__main__": # 1. 设置要测试的图片路径 # 建议将图片放在与脚本同级目录,或者使用绝对路径 - TARGET_IMAGE = "/root/phot/None_314_258_0_0041.bmp" + TARGET_IMAGE = "/root/phot/shot_1830921_0_no_target.jpg" TARGET_DIR = "/root/phot" # 修改为你想要读取的目录路径