08 帧率切换
任务目标
事件相机的帧率档位决定事件流的密度。切换帧率使用 Camera::SetFrameRate(),设备端会重启采集流水线使新档位生效。
切档会触发设备重启
SetFrameRate() 发送 USB 命令后,设备端整条流水线(采集→共享内存→USB 发送)会重启,USB gadget 重新枚举。主机必须关闭旧句柄、等待设备恢复、重新打开相机。这是本示例最重要的教学内容。
1. 初始化并识别传感器
Shimeta::hv::DeviceConfig cfg;
cfg.backend = Shimeta::hv::Backend::Usb;
cfg.vendor_id = 0x1d6b;
cfg.product_id = 0x0105;
Shimeta::hv::Camera cam;
cam.Init(cfg); // 内部自动探测 APX003 / APX014
cam.StartStream();SDK 在 Init 时按 APS 首帧长度自动识别传感器型号(700,424B→003 / 983,048B→014),无需手动配置。
2. 获取首帧并判断型号
Shimeta::Frame f0;
// 等待首帧携带几何信息(APS 帧就绪前 width 为 0)
while (f0.width == 0) {
if (!cam.GetFrame(f0, 500)) break;
}
const bool is014 = (f0.width == 640); // 014 APS = 640×1024,003 = 768×6083. 查询当前帧率
unsigned cur = 0;
cam.GetFrameRate(cur); // 返回当前档位,如 6004. 切换帧率(关键流程)
// ① 发切档命令
cam.SetFrameRate(300); // 设备开始重启流水线
// ② 立即释放旧句柄(USB gadget 将重新枚举)
cam.StopStream();
cam.Destroy();
// ③ 等待设备恢复后重新打开(重启含 3A 预热,最长约 30 秒)
for (int i = 0; i < 30; i++) {
cam.StopStream(); // 幂等安全
cam.Destroy();
if (cam.Init(cfg) && cam.StartStream()) break;
std::this_thread::sleep_for(std::chrono::seconds(2));
}
// ④ 回读验证
unsigned got = 0;
cam.GetFrameRate(got); // 应返回 3005. 同档跳过优化
若当前档位已是目标值,跳过切档可避免无谓的设备重启:
unsigned cur = 0;
cam.GetFrameRate(cur);
if (cur == target) {
// 已是目标档,无需切换
return true;
}
// 否则执行切档流程...合法档位
| 传感器 | 档位 | 说明 |
|---|---|---|
| APX003 | 120 / 240 / 500 / 750 / 100 | 仅五档,非法值设备端忽略 |
| APX014 | 240 / 300 / 480 / 600 | 仅四档,非法值设备端忽略 |
注意事项
- 切档后必须重开相机——不重开则后续所有操作都会失败(USB 句柄已失效)
- 恢复窗口——设备重启含 3A 预热,最长约 30 秒,建议至少给 60 秒重试窗口
- 帧率影响事件密度——切到低档后事件吞吐率相应降低(如 600fps→300fps 事件率约降半)
