Skip to main content

mdrive4-json

当前版本:0.0.8

读取和编辑 mdrive4 JSON 标定目录的小工具。包名为 mdrive4-json,导入名为 mdrive4_json

重要约定:所有 JSON 外参均按原文件解释为 sensor->ego,其中 ego 等同于 vrf_ground,即后轴中心接地点。本工具不自动求逆、不转换单位、不改写坐标系语义。 如需与官方 ParamsTreeHelper 对齐,调用 load_numpy_calibration(..., ego_frame="vrf_ground")

官方映射参考

D11 只负责 mdrive4 JSON 的读取、编辑和 workspace 管理,不负责从官方 PB 生成 mdrive4 JSON。官方 vehicle_config.pb.txt 到 JSON 的映射、坐标规则和初始化模板, 以 mdrive 仓库中的 params_convert_l2 为准:

  • 官方 Git 地址:https://git.minieye.tech/ad/mdrive/mdrive/-/tree/xzt_new_factory_calib
  • 当前参考分支:xzt_new_factory_calib
  • 官方转换目录:modules/calibration/params_convert_l2/
  • 重点查询文件:conf/params.jsonREADME_params_convert_l2.mdsrc/params_convert_l2_main.ccinit_template/

当前机器可参考本地路径 /home/mini/code/mdrive_git/mdrive/modules/calibration/params_convert_l2/,但本地仓库路径和分支可能变化。 查询官方规则时优先以 Git URL 对应分支为稳定入口。

职责边界:

  • D11 不隐式复刻 params_convert_l2 的 PB/C01 转换逻辑。
  • params_convert_l2 负责按官方映射和坐标规则从 vehicle_config.pb.txt 生成 JSON。
  • D11 只统一 JSON calib 目录内的车辆公共字段,不接管 PB 到 JSON 的官方转换逻辑。

V0.0.8 标定 payload 合同

  • 所有 calibration sensor payload 缺少 calib_method 时,V0.0.8 默认补齐为整数 16
  • payload 已显式提供 calib_method 时保留原值,不用默认值覆盖。
  • 默认补齐属于有效 payload 内容变化;写盘时沿用现有 calib_timestamp 规则:只有有效内容确实变化的传感器文件刷新时间戳,未变化的文件不因重复处理而刷新。
  • output_dir 写入会复制完整源 calib 目录到新目录后再修改,源目录保持不变;output_dir 必须指向不存在的目录。
  • parse(input_dir, workspace_dir) 只从 input_dir 读取并写入独立 workspace;build(workspace_dir, output_dir) 只从 workspace 读取并写入独立 output 目录。两条路径都不回写各自的源目录。

安装

pip install .

开发验证建议使用仓库约定环境:

conda run -n py310 python -m pytest tests

Python API

from mdrive4_json import (
    build,
    load_dataset,
    load_numpy_calibration,
    parse,
    update_record,
    update_sensor,
    validate_workspace,
)

dataset = load_dataset("/home/mini/Downloads/output_21_0529")
record = dataset.get("at128p_front")
print(record.extrinsic)  # {"pos": [...], "roll": ..., "pitch": ..., "yaw": ...}

numpy_dataset = load_numpy_calibration("/home/mini/Downloads/output_21_0529")
edge = numpy_dataset.get_extrinsic("camera1")
print(edge.source_frame, edge.target_frame)  # camera1 ego
print(edge.translation)  # numpy.ndarray shape=(3,)
print(edge.rotation)     # [qx, qy, qz, qw], degree ZYX RPY

camera = numpy_dataset.get_intrinsic("camera1")
print(camera.K)   # 3x3 numpy.ndarray
print(camera.pb)  # D02.PB文件 camera_params 风格 dict

update_record(
    "/home/mini/Downloads/output_21_0529",
    "camera1",
    {"yaw": 0.2, "focal_u": 7350.0},
    output_dir="/tmp/output_21_0529_edited",
)

parse("/home/mini/Downloads/output_21_0529", "/tmp/output_21_0529_workspace")
update_sensor("/tmp/output_21_0529_workspace", "camera1", {"yaw": 0.2})
assert validate_workspace("/tmp/output_21_0529_workspace")["valid"]
build("/tmp/output_21_0529_workspace", "/tmp/output_21_0529_rebuilt")

公开 API:

  • load_dataset(input_dir) -> MDrive4JsonDataset
  • load_numpy_calibration(input_dir, ego_frame="ego") -> NumpyCalibrationDataset
  • save_dataset(dataset, output_dir=None, inplace=False)
  • list_records(input_dir) -> list[CalibrationRecord]
  • create_record(input_dir, sensor_id, extrinsic=None, intrinsic=None, output_dir=None, inplace=False, ...)
  • create_name_record/create_extrinsic_record/create_intrinsic_record(...)
  • update_record(input_dir, sensor_id, patch, output_dir=None, inplace=False, allow_unknown=False)
  • normalize_vehicle_context(input_dir, output_dir=None, inplace=False, common_vehicle_fields=None)
  • parse(input_dir, workspace_dir) -> tuple[dict, dict]
  • build(workspace_dir, output_dir) -> list[str]
  • validate_workspace(workspace_dir) -> dict
  • list_sensors/get_sensor/create_sensor/update_sensor/delete_sensor/replace_sensors
  • MDrive4JsonWorkspaceManager(default_workspace_dir)

版本更新:

  • 0.0.8:统一 calibration sensor payload 缺失 calib_method 时的默认值 16,保留显式值,并明确默认补齐与 calib_timestampoutput_dirparsebuild 的源隔离合同。
  • 0.0.7:新增目录级车辆公共字段归一化,统一 vehicle_id/vin/vehicle_length/vehicle_width/vehicle_height/wheel_base;新增记录、record 写入和 workspace 写入会继承非空多数公共字段,冲突时阻断。
  • 0.0.6:新增 native JSON record 创建 API,支持仅名称、仅外参、仅内参、外参+内参创建;信息不足时写入 is_valid=false,不补伪造内参。

sensor_id 规则:

  • 主 ID 优先使用 JSON frame_id;缺失时回退文件名 stem。
  • camera JSON 的 camera{camera_id} 与文件名 stem 会作为查询 alias 保留,例如 dataset.get("camera1") 可兼容旧调用。
  • alias 仅用于查询兼容;NumpyExtrinsic.source_frameNumpyIntrinsic.frame_id 始终使用主 ID。

外参字段固定读取:

  • pos[x,y,z]
  • roll
  • pitch
  • yaw

camera 额外暴露常见内参字段:

  • focal_ufocal_vcucv
  • distort_coeffs
  • image_widthimage_height
  • prj_modelfov
  • affine_paramspoly_coeffsinv_poly_coeffs

未知原始字段会保留。编辑未知字段默认拒绝,确需写入时传 allow_unknown=True 或 CLI --allow-unknown

numpy / PB 风格读取

load_numpy_calibration() 是推荐的统一读取入口:

  • 外参返回 NumpyExtrinsicsource_frame=sensor_idtarget_frame=ego_frametranslation(3,)rotation[qx, qy, qz, qw]
  • 变换语义固定为 p_root = T * p_source,即 source_frame->ego_frame;不求逆、不做轴系转换、不改单位。
  • 默认 ego_frame="ego",文档语义为 vrf_ground 后轴中心接地点。
  • camera 内参返回 NumpyIntrinsicK(3,3)D 为畸变数组,projection_model 保留 camera.proto ProjectionModel 完整枚举名,并保留 D02 风格 pb dict。

PB dict 示例:

{
    "frame_id": "camera1",
    "model_type": "PINHOLE",
    "pinhole": {
        "width": 3840,
        "height": 2160,
        "intrinsic": [focal_u, s, cu, 0.0, focal_v, cv, 0.0, 0.0, 1.0],
        "distortion": distort_coeffs,
    },
}

Mdrive4 JSON prj_model 按完整枚举解释:0=PRJ_MODEL_UNKNOWN1=FISHEYE2=MEI3=PIN_HOLE4=ATAN5=DAVIDE_SCARAMUZZA。D02 兼容 model_type 仅对 1/3 输出 FISHEYE/PINHOLE2/4/5 保留精确枚举名,避免把 DAVIDE_SCARAMUZZA 误写成鱼眼。s 缺省为 0.0

YAML 工作区

0.0.4 提供 D02 风格中间工作区,便于多个 API 共享编辑状态并统一校验/build:

  • order_manifest.yaml:按顺序记录 sensor_idfile、原始 json_fileis_camera、alias。
  • sensors/{sensor_id}.yaml:每个传感器一个可编辑 YAML,字段保持原 JSON key,不做语义转换。
  • .mdrive4_json_meta.json:记录源目录、原始文件名、alias、hash 等追踪信息。

典型流程:

from mdrive4_json import MDrive4JsonWorkspaceManager

mgr = MDrive4JsonWorkspaceManager("/tmp/output_21_0529_workspace")
mgr.parse("/home/mini/Downloads/output_21_0529")
mgr.update_sensor("camera1", {"yaw": 0.2, "focal_u": 7350.0})
mgr.build("/tmp/output_21_0529_rebuilt")

build() 会先调用 validate_workspace(),发现 manifest 引用缺失文件、孤儿 sensors/*.yaml、重复 sensor_id/json_file、pose 非法等问题时拒绝输出。

真实样例 smoke:

cd D_pypi/D11.mdrive4-json处理/V0.0.4
conda run -n py310 python -m pytest tests

/home/mini/Downloads/output_21_0529 存在,测试会验证 15 条外参和 6 条 camera 内参。

CLI

mdrive4-json summary /home/mini/Downloads/output_21_0529
mdrive4-json show /home/mini/Downloads/output_21_0529 --sensor camera1
mdrive4-json edit /home/mini/Downloads/output_21_0529 --sensor camera1 --set yaw=0.2 --output-dir /tmp/edited
mdrive4-json edit /home/mini/Downloads/output_21_0529 --sensor camera1 --set yaw=0.2 --inplace
mdrive4-json parse /home/mini/Downloads/output_21_0529 -o /tmp/output_21_0529_workspace
mdrive4-json validate -i /tmp/output_21_0529_workspace
mdrive4-json build -i /tmp/output_21_0529_workspace -o /tmp/output_21_0529_rebuilt

--set 的值优先按 JSON 解析,因此列表和布尔值可这样写:

mdrive4-json edit input --sensor camera1 --set 'pos=[1,2,3]' --set is_valid=true --output-dir output

写盘规则

  • 默认不写盘;必须显式选择 output_dirinplace=True
  • output_dir 模式要求目标目录不存在,并复制输入目录全部 JSON,再修改目标文件。
  • inplace=True 会覆盖输入目录中的 JSON。
  • 写入型 API 自动维护顶层 calib_timestamp:当某个传感器 JSON/YAML 除 calib_timestamp 外的有效内容发生变化时,写出的对应文件会刷新为运行机器本地时区当前时间,格式为 YYYY-MM-DD-HH-MM-SS
  • 如果 patch 后有效内容与原文件一致,不会仅为了刷新 calib_timestamp 而写盘。
  • calib_timestamp 是工具维护字段,不能通过 Python API patch 或 CLI --set 手动修改;即使启用 allow_unknown=True / --allow-unknown 也会拒绝。
  • build() 从 workspace 生成 JSON 时保留 sensor YAML 中已有的 calib_timestamp,不会因为只读构建流程额外刷新时间。
  • JSON 使用 UTF-8、ensure_ascii=False、4 空格缩进保存。

校验

读取时会校验:

  • 输入目录存在且包含 JSON。
  • JSON 根节点必须是对象。
  • 每个文件使用 frame_id 或文件名 stem 识别主 sensor_id
  • sensor_id 不能重复。
  • pos 必须是 3 个数字,roll/pitch/yaw 必须是数字。

编辑 camera 内参时会做基础类型校验。未知 key 默认拒绝。

设计原则

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mdrive4_json-0.0.8.tar.gz (36.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mdrive4_json-0.0.8-py3-none-any.whl (22.6 kB view details)

Uploaded Python 3

File details

Details for the file mdrive4_json-0.0.8.tar.gz.

File metadata

  • Download URL: mdrive4_json-0.0.8.tar.gz
  • Upload date:
  • Size: 36.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for mdrive4_json-0.0.8.tar.gz
Algorithm Hash digest
SHA256 0c80eefe59ec534c8682be70c24087a1e0bbca53f039f53112d0f39e55b7583b
MD5 be8492902e187c195b27a5823619dd0e
BLAKE2b-256 44db84650ce886c66d0d041202f6eec8fd625df2da8cea2b0b934f58a5a7b5e2

See more details on using hashes here.

File details

Details for the file mdrive4_json-0.0.8-py3-none-any.whl.

File metadata

  • Download URL: mdrive4_json-0.0.8-py3-none-any.whl
  • Upload date:
  • Size: 22.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for mdrive4_json-0.0.8-py3-none-any.whl
Algorithm Hash digest
SHA256 bfabb3b42d82aa1d65e4338107c81f55a00879a942e92149217809c8bba138df
MD5 341c11d3047ee20bf8feb0c029344ae8
BLAKE2b-256 9dd5b64b878c8b17e7289ddf5eedb99f028f48493b166128bf5901fb00e39dbe

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.0.8 This release

2 files

0.0.5

2 files

0.0.4

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page