﻿// 全局配置文件（根级 map 结构）
// 注：注释须整行且以 // 开头；键值保持全局可读（不同雷达里同名 key 不要重复语义）
// 结构：
//   "server" / "log"  → 进程级全局配置
//   其它一级键        → 一个"雷达标识"（通信时用 "radar":"xxx" 指定操作哪台雷达），
//                       每个标识下是一份完整参数：radar / scan / detect / count / filter
{
  // ==================== server: 运行模式（全局） ====================
  "server": {
    //运行模式 exe=直接检测 / tcp=服务端模式 / http=HTTP服务端
    "mode": "tcp",
    //TCP/HTTP服务端监听端口
    "port": 9601
  },

  // ==================== log: 日志（全局） ====================
  "log": {
    //日志打印使能 true/false
    "enable": true,
    //日志(任务目录)保留天数, 超出自动删除更早的目录
    "retain_days": 1,
    //每日日志定时清理时刻, 格式 "HH:MM:SS"
    "clean_time": "06:01:30"
  },

  // ==================== radar1: 第1台雷达（完整参数） ====================
  "radar1": {
    // ---- radar: 雷达连接与雷达内置滤波 ----
    "radar": {
      //雷达IP
      "ip": "192.168.1.170",
      //雷达数据端口
      "port": 2368,
      //雷达帧率 Hz (矩形长 = 速度/帧率)
      "hz": 50,
      //拖尾滤波 0=关, 1=弱, 2=中, 3=强
      "tail_filter": 3,
      //前冲滤波 0=关, 1=弱, 2=中, 3=强
      "front_filter": 3,
      //远端高反滤波 0=关, 1=弱, 2=强
      "far_hr_filter": 2,
      //近端高反识别 true开，false关
      "near_hr_filter": true
    },
    // ---- scan: 扫描采集与走行 ----
    "scan": {
      //z轴速度模式: uniformSpeed=匀速(用下方z_speed), configuration=变速(用config/speed.txt)
      "z_speed_type": "uniformSpeed",
      //z轴速度 厘米/秒 (0=z轴为时间ms, >0=z轴为移动距离mm)
      "z_speed": 50,
      //exe模式/默认扫描时长 秒 (tcp/http 模式可被请求中的 scanTime 覆盖)
      "collect_duration_s": 6
    },

    // ---- detect: 截面分析 ----
    "detect": {
      //Z截面区间长度 毫米
      "z_range_mm": 50,
      //Y截面区间长度 毫米
      "y_range_mm": 80,
      //截面矩形宽度 像素
      "rect_width_px": 12,
      //截面矩形长度倍率 (矩形长=速度/帧率×倍率)
      "rect_length_ratio": 1.5
    },

    // ---- count: 分层计数 ----
    "count": {
      //地板高度 毫米 (物品高度 = floor_height - Y轴, count计数用)
      "floor_height": 1600,
      //count分层冗余 初始冗余 毫米 (第1层容差)上下各base_tolerance
      "base_tolerance": 30,
      //count分层冗余 每层增加 毫米
      "per_level_tolerance": 1,
      //count画layer图: 每个点膨胀像素 (point_dilate×point_dilate)
      "point_dilate": 8,
      //count z轴空隙插值模式: none / CopyTranslation / AngleBucketInterpolation/AngleBucketInterpolationByDilate
      "z_interpolate_mode": "AngleBucketInterpolationByDilate",
      //count层数算法:
      //  LevelTolerance = level=round(高度/层高), 判定 |高度-level×层高| <= 容差
      //  HalfMax        = 两步判定: ①本层中间~下一层中间[(level-0.5)层高,(level+0.5)层高]粗筛 ②取①内最高点top, 有效区间=[top-容差, top]
      //  KdePeak        = 两步判定: ①同上粗筛 ②对①内高度做KDE密度曲线取峰值peak, 有效区间=[peak-容差, peak+容差]
      //  容差 = base_tolerance + 层号×per_level_tolerance
      "layer_algorithm": "KdePeak",
      //KDE(KdePeak算法): 高斯核带宽 毫米 (0=按Silverman经验法则自动取)
      "kde_bandwidth": 0,
      //KDE(KdePeak算法): 密度曲线扫描步长 毫米 (越小越精细但越慢)
      "kde_step": 1
    },

    // ---- filter: 软件滤波(多边形 + 拖影) ----
    "filter": {
      //过滤多边形(mm), 至少3个顶点
      "polygon": [[-550,0],[-550,1600],[500,1600],[500,0]],

      //连续段尾部减除(图片级旧方案, 已由点云级 sparse_cut 取代, 建议保持 false)
      "tail_cut": {
        "enable": false,
        "max_tail_length": 30,
        "y_delta": 30,
        "min_run_length": 5,
        "core_min_len": 5,
        "support_rows": 0
      },

      //点云级稀疏拖影过滤(推荐, 默认开)
      "sparse_cut": {
        "enable": true,
        //同圈X邻域半径mm: 调大→删得狠; 调小→保守
        "x_radius": 30,
        //同圈连续: 同一圈内稀疏点数≥此值即删
        "circle_min": 2,
        //跨圈连续: 同一X位置在z方向连续出现≥此圈即删
        "run_min": 2
      }
    }
  }

  // ==================== 追加更多雷达：复制下面一段并改标识/IP/参数即可 ====================
  // 通信时用 "radar":"radar2" 指定；不带 radar 字段的请求默认操作第一个雷达(radar1)
  //,
  //"radar2": {
  //  "radar": { "ip": "192.168.1.171", "port": 2368, "hz": 50,
  //             "tail_filter": 3, "front_filter": 3, "far_hr_filter": 2, "near_hr_filter": true },
  //  "scan":  { "z_speed_type": "uniformSpeed", "z_speed": 20, "collect_duration_s": 6 },
  //  "detect":{ "z_range_mm": 50, "y_range_mm": 80, "rect_width_px": 12, "rect_length_ratio": 1.5 },
  //  "count": { "floor_height": 1600, "base_tolerance": 30, "per_level_tolerance": 1,
  //             "point_dilate": 8, "z_interpolate_mode": "CopyTranslation",
  //             "layer_algorithm": "HalfMax", "kde_bandwidth": 0, "kde_step": 1 },
  //  "filter":{ "polygon": [[-550,0],[-550,1600],[500,1600],[500,0]],
  //             "tail_cut": { "enable": false, "max_tail_length": 30, "y_delta": 30,
  //                           "min_run_length": 5, "core_min_len": 5, "support_rows": 0 },
  //             "sparse_cut": { "enable": true, "x_radius": 30, "circle_min": 2, "run_min": 2 } }
  //}
}
