1. 驾驶舱
插件化手册
  • FH2 插件开发手册
    • 产品简介
    • 典型场景
    • 发版说明
    • 快速开始
      • 快速开始总览
      • 第一个插件
      • 后端插件
      • 全栈闭环
    • AI辅助开发
      • AI 开发 Skill
      • 安装与复验
      • 第一个工程
      • 真实需求示例:现场问题上报
      • 改造已有工程
      • 调试与交付
    • 开发指南
      • 开发指南
      • 基础概念
        • 基础概念总览
        • 什么是插件开发
        • 平台架构
        • 前端宿主、扩展点与能力
        • 后端运行时、入口与权限
        • 开发流程
        • 安全与隔离
        • 支持范围与问题反馈
      • 开发指南
        • 开发指南总览
        • 前端插件
          • 前端插件深度指南
          • 前端工程结构
          • 插件清单(fh2-plugin.json)
          • 入口与生命周期
          • 界面与状态
          • 多宿主插件
          • 跨宿主通信服务
          • HTTP、WebSocket 与事件
          • 存储、Blob 与定时器
          • 工具链与本地调试页面
        • 后端插件
          • 后端开发深度指南
          • 后端插件的结构
          • 后端源清单 fh2-plugin.json
          • HTTP 接口处理函数
          • 消息订阅与事件处理函数
          • ctx 与能力注入
          • 数据存储与缓存
          • 流程编排
          • 触发方式
          • 连接外部系统
          • 流程编排练习(DAG)
        • 前后端协作
          • 前后端协作总览
          • 前后端共享契约
          • 端到端幂等
          • 事件、通知与状态
          • 统一错误模型
          • 链路标识与诊断日志
        • 完整练习
          • 环境准备
          • 第一个前端插件
          • 第一个后端插件
          • 第一个全栈插件
      • 能力总览
        • 能力地图
        • 能力可用性矩阵
        • 前端能力
          • 平台通用能力
            • 平台通用能力总览
            • 基础运行时:HTTP、事件、WebSocket 与存储
            • 导航、位置与通知
            • 弹窗、音频与剪贴板
            • 地图能力
            • 项目设备能力
            • WPMZ 与航线预览
            • 受控对象上传
          • 项目宿主
            • 项目宿主总览
            • 项目上下文
            • 项目侧边栏入口
            • 项目插件路由
            • 项目工作区
          • 消息宿主
            • 消息宿主总览
            • 消息告警弹层
            • 消息导航与通知
          • 计划库宿主
            • 计划库宿主总览
            • 计划库表单上下文
            • 计划库表单扩展
            • 校验、提交与 `biz_ext`
          • 驾驶舱
            • 驾驶舱插件能力总览
            • 驾驶舱扩展点
            • 上下文与遥测
            • 相机、检测与 AI
            • 场景几何与直播指针
            • 飞控、云台与任务
            • 驾驶舱平台事件
        • 后端能力
          • 后端能力地图
          • 后端能力总览
          • 配置、受管出网与集成连接
          • 事件与流程
          • 飞行任务与违停巡逻
          • 数据存储
          • 媒体与前端通知
          • 资源租约
          • 作业、目标轨迹与视频处理
      • 调试与测试
        • 调试与测试总览
        • 快速入门排错
        • 本地开发
        • Web IDE:打开工程与保存改动
        • 工作流编辑器:节点、接线与交付
        • 知识与 MCP:先判断需要哪一层事实
        • 前端本地调试
        • 后端运行时与流程调试
        • 模拟数据与测试数据
        • 集成测试与 E2E
        • 日志与链路追踪
        • 常见问题排查
      • 完整示例
        • 示例与案例总览
        • 项目侧边栏与工作区
        • 消息告警卡片
        • 计划表单任务清单
        • 驾驶舱动作与左侧面板
        • 最小后端插件
        • 最小全栈插件
        • 多宿主插件实战
        • 事故快处
        • 交通抓拍
        • 违停巡逻完整案例
      • 构建发布与安全
        • 构建、发布与安全
        • 质量门禁
        • 行业包构建与打包
        • 能力版本发布
        • 安装、升级与回滚
        • 安全基线
      • API参考
        • API 参考总览
        • 前端
          • 前端 API 参考
          • 前端插件清单结构
          • 前端 SDK API
          • 前端扩展点目录
          • 前端能力目录
          • 前端平台事件目录
          • 跨宿主通信服务 API
          • 工具链命令行参考(`fh2-plugin`)
        • 后端
          • 后端 API 参考
          • 后端插件源清单
          • 后端 HTTP 接口参考
          • 后端事件消费参考
          • 后端脚本上下文(`ctx`)
          • 后端数据存储
          • 流程编排语言
          • 流程触发器参考
          • 后端能力目录
          • 后端 HTTP API
        • 共享契约
          • 共享契约参考
          • 类型与契约目录
          • 错误模型
          • 版本兼容性
      • 附录
        • 错误码
        • 术语表
        • 常见问题
  1. 驾驶舱

场景几何与直播指针

这一页讲两个通常配合使用的坐标类能力:cockpit:scene-geometry(画面坐标 ↔ 地理坐标双向投影)和 cockpit:live-pointer(直播画面指针租约)。典型组合是"在直播画面上画框标注,并把框转成地理坐标"。
两个能力都要在清单里声明同名权限,获取后判空使用。

cockpit:scene-geometry:坐标互投#

方法#

// 实时投影:用调用时刻的几何
projectVideoToGround(points, { groundHeight }): Promise<{ capturedAt; points: (GeoPoint | null)[] } | null>
projectGeoToVideo(points): Promise<{ capturedAt; points: ({ x, y } | null)[] } | null>

// 快照投影:用截图时刻冻结的几何
projectSnapshotVideoToGround(snapshotId, points, { groundHeight }): Promise<Result | null>
projectSnapshotGeoToVideo(snapshotId, points): Promise<Result | null>

releaseSnapshot(snapshotId: string): Promise<void>
画面坐标是有效视频画幅内的归一化 {x, y}(0~1,不含黑边);地理坐标是 { lng, lat, height }。groundHeight 由你的业务提供(平台不算地形高程)。

两种快照语义#

用哪组方法用的几何适用场景
projectVideoToGround / projectGeoToVideo调用那一刻的实时几何实时指示、短暂交互
projectSnapshotVideoToGround / projectSnapshotGeoToVideocamera.captureFrame() 返回的截图时刻几何截图标注、同帧证据、延后投影
快照 ID 是不透明字符串,只在你自己的插件范围内有效。ID 不存在、已释放、属于其他插件、或被容量淘汰时返回 null;一批点里个别点投不出去时该位置为 null,不影响其他点。

快照管理#

快照全局最多 64 个,超出淘汰最旧;没有自动过期,用完要主动 releaseSnapshot()(对未知 ID 重复释放是安全的空操作)。
插件运行时结束和宿主卸载会自动清理你名下的快照。

示例:截图中心的地理坐标#

const camera = await ctx.capabilities.get('cockpit:camera')
const geometry = await ctx.capabilities.get('cockpit:scene-geometry')
if (!camera || !geometry) return

const frame = await camera.captureFrame({ scale: 1, mime: 'image/jpeg' })
const snapshotId = frame.geometrySnapshotId
if (!snapshotId) return
try {
  const result = await geometry.projectSnapshotVideoToGround(
    snapshotId,
    [{ x: 0.5, y: 0.5 }],
    { groundHeight: 0 },
  )
  if (result?.points[0]) ctx.logger.info('截图中心地理点', result.points[0])
} finally {
  await geometry.releaseSnapshot(snapshotId)
}

注意#

能力存在不代表当前有几何:直播未出首帧、姿态数据不足、画面点没有交点,都会返回 null。把 null 当正常降级处理,不要反复重试。
不要调用 cockpit:scene-raycast;当前只有这一组双向投影方法。

cockpit:live-pointer:指针租约#

直播画面上同一时刻只能有一个插件响应鼠标操作。要处理画面的 pointer 事件,先向宿主租用指针:
interface CockpitLivePointerLease {
  stream: string
  release(): Promise<void>
  dispose(): Promise<void>
  onRevoked(handler: (reason: 'host-mode' | 'disposed') => void): Promise<Disposable>
}

acquire(stream?: string): Promise<CockpitLivePointerLease>
stream 缺省 DronePayload。租约只表示"你可以处理这条流的指针",不会自动把你的 live-overlay 变成可交互——覆盖层的 interactive: true 要自己另外设置,两个都配好才有效。

租约会被撤销#

撤销原因含义你该做什么
host-mode宿主进入了不允许插件占用指针的模式立即停止绘制、清掉临时图形
disposed句柄或插件运行时被释放同上,且不要再发起新的 pointer 处理
收到撤销后不要尝试重新抢占形成循环;等合适的时机再 acquire。

示例#

const pointer = await ctx.capabilities.get('cockpit:live-pointer')
if (!pointer) return
const lease = await pointer.acquire('DronePayload')
const revoked = await lease.onRevoked((reason) => {
  annotation.cancel(reason)
})
try {
  await annotation.drawOnce()
} finally {
  await revoked.dispose()
  await lease.release()
}
注意:同流冲突、未知流、SDK 状态错误会直接 reject(没有排队或"acquired: false"这种返回);release()/dispose() 按幂等方式使用即可。

推荐组合:在直播画面上做截图标注#

1.
等 cockpit:context 的 liveReady=true(见 上下文与遥测)。
2.
显示一个 cockpit.ui.live-overlay 的 fill + interactive: true 界面(见 驾驶舱扩展点)。
3.
acquire 指针租约。
4.
在界面里用归一化坐标绘制;需要地理锚定时调 scene-geometry 投影。
5.
要出证据图时用 camera.captureFrame(),再按返回的快照 ID 做同帧投影。
6.
无论完成、取消、被抢占还是卸载,都释放快照、租约和订阅。

常见问题#

现象原因与处理
覆盖层设了 interactive: true 还是收不到鼠标事件没有租约;先 live-pointer.acquire()
投影一直返回 null直播未出首帧或姿态不足;等 liveReady,别硬重试
projectSnapshot... 返回 null快照 ID 无效、已释放、被 64 个容量淘汰,或属于其他插件
绘制到一半失灵租约被撤销(host-mode/disposed);监听 onRevoked 做清理
修改于 2026-10-22 07:06:55
上一页
相机、检测与 AI
下一页
飞控、云台与任务
Built with