soc bag 目录发现、路径解析与 L2/L3 标准格式归口
Project description
socbag-manager
soc bag 目录的发现、路径解析与 L2/L3 数据格式归口库。
当 data_source.json 声明 topic_channel_inspection_artifact 时,L2 标准化会把它与 topic_channel_inspection.json 作为不可分割的 metadata pair,校验 SOC 内相对路径和 SHA-256,并在标准 L2 保留完全一致的 sidecar 字节。静态 L3 根目录保留这两个文件,同时继续在 env/ 归档;动态流程不创建 L3。
V0.0.8 起,L2 标准化与 L2→L3 静态单帧提取由 socbag-manager 统一管理;V0.0.9 起,INS 坐标、姿态和高度计算全部归口 transform-base>=0.0.5。原始 .record / .mcap 解码仍由现有 Docker / mkit 工具负责。
版本与输入模式(V0.0.9)
| 模式 | 输入含义 | 目录结构 |
|---|---|---|
| multi | 多 base_paths + bag_path |
camera/{name}/data/{frame}.png、lidar/{name}/pcd/{frame}.pcd |
| single | 单一路径(如 .../static_data)或 bag 根 |
camera/{sensor}_{frame}.png、lidar/{sensor}_{frame}.pcd(平铺) |
通过配置 input_mode: "multi" | "single" 决定使用哪套发现与解析逻辑,两种格式分别对应、互不混用。
- multi:与 V0.0.3/V0.0.4 一致,在多数据根下按 priority 查找同一 bag;子目录
data/pcd。 - single:将给定路径视为父目录时用
discover_bags_under扫描其下符合约定的 soc 子目录;每个 bag 根内为平铺文件(如camera/front_120_000005.png)。可选依赖 bag 根下extract_manifest.yaml(query_frame、extracted[].sensor/type)做发现。
single 目录示例:.../static_data/20260208-160115_soc2/ 下存在 camera/front_120_000005.png、lidar/at128p_front_000005.pcd 等;可含 extract_manifest.yaml。
V0.0.6 起,single 平铺帧号按数字等价匹配但保留真实文件帧号:用户传入 5、000005 或 0000000005,都可解析到磁盘上的 front_120_0000000005.jpg、at128p_front_0000000005.pcd;discover_sequences_from_bag_root(..., layout="single") 仍返回真实文件帧号。
V0.0.7 起,single 布局下即使 extract_manifest.yaml 只有 query_frame / matched_frame_stems / copied_files 而没有 extracted 列表,camera/lidar 发现与路径解析也会回退扫描 camera/*.jpg|png、lidar/*.pcd。
V0.0.8 新增 L2/L3 格式归口:
pb_baselineL2:lidar/{sensor}/pcd/{frame}.pcd、camera/{sensor}/data/{frame}.png|jpg或camera/{mapped}_{cameraN}_{frame}.jpg|png、ins/by/by_ins_data*.csv。mdrive4_mcapL2:normalize_l2_soc_to_pb_baseline(..., output_dir=None)默认在原 SOC 目录归档org_data/,同级生成 PB-baseline 布局与normalize_manifest.json。mdrive4-jsonraw/org L2 标准化只读取ins/当前目录的*.pb.txt,合并为ins/by/by_ins_data_utm.csv、ins/by/by_ins_data.tum.csv;时间只使用header.tick / 1e6,不回退header.timestamp;每条记录通过 D01/PyProj 使用 GRS80 计算自身 UTM zone/hemisphere,z/up 使用position.height + geoid_undulation,姿态固定为Rz_Ry_Rx(qz * qy * qx);只写入INS_POS_TYPE_RTK_FIXED且字段完整的记录。全部记录 zone/hemisphere 一致时才生成by_ins_data_enu.csv,否则 manifest 写入skipped_mixed_utm_zones。raw INS pbtxt 仍只保留在org_data/ins/。- IMU 只读取
imu/当前目录的*.pb.txt,使用header.timestamp / 1e6排序并输出无表头七列 CSV;时间保留 6 位小数,其余数据保留 9 位小数。 mdrive4-jsonorg →pb_base:convert_to_pb_base/socbag-org2pb-base作为 legacy/debug 入口保留;支持front30/1/{frame}.jpg、lidar/{sensor}/pcd/{frame}.pcd等 mkit org 结构,输出org2pb_base_manifest.json,target_format=pb_base。- L3 单帧输出:
lidar/{sensor}_{real_frame}.pcd、camera/{sensor}_{real_frame}.png|jpg、env/、extract_manifest.yaml。 - 默认策略:完整 MCAP workflow 只消费
02_parsed_frames/{vehicle_model_id}/{type}/{soc_name}这一处 L2 完成态;该目录内org_data/保存 raw mkit 输出,同级满足 PB-baseline。 - 下游 L3、分类、报告第一批标准只消费
pb_baseline/normalize_manifest.json。pb_base/org2pb_base_manifest.json是 legacy/debug 产物,不能直接作为extract_l2_to_l3或报告输入;需要显式转换到 PB-baseline 合同后再消费。
mdrive4-json INS 时间戳合并维护锁
socbag_manager.mdrive4_ins_trajectory.write_mdrive4_ins_csvs_from_pbtxt(...) 是 mdrive4-json raw/org INS pbtxt 合并到 PB-baseline ins/by 的当前固化入口。该入口的时间戳合同如下:
- 输入目录应是 raw/org INS pbtxt 目录,例如标准化后的
org_data/ins/。 - 只读取当前目录
*.pb.txt,不消费子目录,再按解析出的时间排序输出。 - 输出时间戳只来自
header.tick / 1_000_000.0,并格式化为六位小数。 - 不允许回退使用
header.timestamp;缺header.tick的记录应计入missing_header_tick并跳过。 - 只合并
INS_POS_TYPE_RTK_FIXED且经纬高、欧拉角字段完整的记录。
2026-07-08 已用 ECAR_HW4_XZT500021/dynamic_data/20260703-213808_mcap 的 org_data/ins 做 timestamp 一致性验证:8425 个 INS pbtxt 与指定 C++ 输出在六位小数 timestamp key 上完全重叠,cpp_only=0、socbag_only=0,时间范围均为 1783085888.437000 ~ 1783085972.677000。V0.0.9 保留该时间合同,但 z 使用修正后的 height + geoid_undulation,不复刻参考 C++ 的漏解析。
目录约定与 soc 规则
- soc 规则(multi/single 共用):目录被视为 soc bag 当且仅当:同时存在
camera/与lidar/子目录,且该目录总大小 ≥ 阈值(默认 1MB)。不依赖文件夹名;名称模式bag_name_pattern为可选过滤。 - multi:
{bag_root}/camera/{camera_name}/data/{sequence}.png(或 .jpg),{bag_root}/lidar/{lidar_name}/pcd/{sequence}.pcd。 - single:
{bag_root}/camera/{sensor}_{frame}.png,{bag_root}/lidar/{sensor}_{frame}.pcd。
安装
pip install socbag-manager
统一设置
所有 API 基于 SocbagManagerSettings,可从代码构造或 YAML 加载(兼容 C03 base_paths/priority_base_path 与 C04 data_dirs/default_main_dir):
from socbag_manager import SocbagManagerSettings
settings = SocbagManagerSettings(
base_paths={"pandar": "/data/pandar", "at128": "/data/at128"},
priority_source="pandar",
bag_name_pattern="*_soc*",
input_mode="multi", # 或 "single"
)
# 或
settings = SocbagManagerSettings.from_yaml("/path/to/config.yaml")
主要 API
- 发现(multi):
get_ordered_base_paths,discover_bags,discover_bags_from_scan_root,discover_cameras,discover_lidars,discover_sequences - 发现(single):
discover_bags_under(parent_dir, bag_name_pattern="*_soc*", max_depth=1, min_size_mb=None);discover_sequences_from_bag_root(bag_root, layout=...),discover_cameras_from_bag_root,discover_lidars_from_bag_root(传layout="single"或由 settings.input_mode 决定) - 规则:
is_soc_bag_dir(dir_path, min_size_mb)— 判定目录是否符合 soc 解构 - 路径解析:
resolve_camera_paths,resolve_lidar_paths,resolve_frame_paths(按 input_mode 选 multi/single 路径);resolve_frame_paths_from_bag_root(bag_root, sequence, ..., layout=...) - 候选枚举:
list_frame_candidates,choose_one_candidate(CandidatePath) - 目录树:
TreeNode,build_folder_tree(settings, scope="roots"|"bags"|"sequences", ...) - L2/L3 格式归口:
SocbagFormatinspect_l2_soc(soc_dir, source_format="auto")normalize_l2_soc_to_pb_baseline(input_dir, source_format=..., vehicle_model_id=..., input_data_type=...)read_l2_frame(soc_dir, frame, source_format="pb_baseline")write_l3_single_frame(frame_bundle, output_dir, env_policy=...)extract_l2_to_l3(data_dir, single_frame_root, vehicle_model_id=..., input_data_type=..., query_frame=...)
使用示例
multi 模式
from socbag_manager import (
SocbagManagerSettings,
discover_bags,
discover_sequences,
resolve_frame_paths,
build_folder_tree,
)
settings = SocbagManagerSettings.from_yaml("config.yaml")
bag_names = discover_bags(settings)
sequences = discover_sequences(settings, bag_names[0])
paths = resolve_frame_paths(settings, bag_names[0], sequences[0])
# paths["images"], paths["pcds"]
tree_roots = build_folder_tree(settings, scope="bags")
single 模式
from socbag_manager import (
SocbagManagerSettings,
discover_bags_under,
discover_sequences_from_bag_root,
resolve_frame_paths_from_bag_root,
)
settings = SocbagManagerSettings(
base_paths={"main": "/path/to/static_data_parent"},
input_mode="single",
)
static_data_dir = "/media/mini/T9/03_single_frame/AB6_HW3_XZB600019/static_data"
bag_roots = discover_bags_under(static_data_dir, max_depth=1, min_size_mb=0)
for bag_root in bag_roots:
sequences = discover_sequences_from_bag_root(bag_root, layout="single")
if sequences:
paths = resolve_frame_paths_from_bag_root(bag_root, sequences[0], layout="single")
# paths["images"], paths["pcds"] 与 multi 格式一致
YAML 可选:input_mode: single、static_data_dir: /path/to/static_data(加载后可用 discover_bags_under(settings.static_data_dir))。
L2 标准化与 L3 单帧提取
from socbag_manager import (
SocbagFormat,
extract_l2_to_l3,
normalize_l2_soc_to_pb_baseline,
)
normalize_l2_soc_to_pb_baseline(
"/path/to/mdrive4_l2/soc1",
source_format="mdrive4-json",
vehicle_model_id="CAR_MODEL",
input_data_type="mdrive4-json",
output_dir=None,
)
extract_l2_to_l3(
"/path/to/mdrive4_l2/soc1",
"/path/to/static_data",
vehicle_model_id="CAR_MODEL",
input_data_type="mdrive4-json",
query_frame="000005",
source_format="pb_baseline",
)
CLI:
socbag-normalize-l2 /path/to/l2/soc1 \
--source-format mdrive4_mcap \
--vehicle-model-id CAR_MODEL \
--input-data-type mdrive4-json
socbag-extract-single-frame /path/to/l2/soc1 /path/to/static_data \
--vehicle-model-id CAR_MODEL \
--input-data-type mdrive4-json \
--query-frame 000005 \
--source-format pb_baseline
NAS workflow 建议:
- PB
.record解码后调用socbag-normalize-l2 --source-format pb_baseline做校验和normalize_manifest.json补齐,再调用socbag-extract-single-frame。 - Mdrive4
.mcap经 mkit parse 后,调用socbag-normalize-l2 --source-format mdrive4-json在原 SOC 目录转换:原始内容移动到org_data/,同级生成 PB-baselinecamera/、lidar/、ins/、imu/、gnss/与normalize_manifest.json;其中ins/by/by_ins_data_enu.csv由标准化阶段从 raw INS pbtxt 生成,供后续 INS 分类直接消费。 socbag-org2pb-base/convert_to_pb_base仅作为 legacy/debug 入口保留,不作为分类、L3 或报告输入;发现org2pb_base_manifest.json时应停止并提示转换,而不是自动当作 PB-baseline。- 动态链路只要求 L2 标准化时可复用 inspect/normalize;是否进入 L3 由上层 guard 决定。
约束
- 发现/解析接口仅返回路径,不读取/解析图像或点云文件。
- L2/L3 归口接口会移动/硬链接文件和写 manifest,但不解析图像或点云内容;mdrive4 默认就地标准化不创建 sibling
*_pb_baseline或 L3 下_normalized_l2。 - 依赖:Python >=3.10,PyYAML,transform-base>=0.0.5。
开发与测试
pip install -e ".[dev]"
python -m pytest tests/ -v
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file socbag_manager-0.0.9.tar.gz.
File metadata
- Download URL: socbag_manager-0.0.9.tar.gz
- Upload date:
- Size: 58.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ebd2069dc16507cf8765029e6f2c59dad6ee2458cfacc1449dd354f2b6acd1c
|
|
| MD5 |
31e27aa3d72129f16a09999c4123cde7
|
|
| BLAKE2b-256 |
12f632b845ebf45d424ac73db718914c905f3e4c8c22570ee94dbb7c3e7fe06f
|
File details
Details for the file socbag_manager-0.0.9-py3-none-any.whl.
File metadata
- Download URL: socbag_manager-0.0.9-py3-none-any.whl
- Upload date:
- Size: 44.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bea35d1037fd7b73e7f3d0f889e5bf98619940d5c8a8afd04b078c170323a69
|
|
| MD5 |
11dc428ddf7af1849b71f78daf524e99
|
|
| BLAKE2b-256 |
291c809fef29e3df8a7697100247d31ca63d49d768b1c3a7b0300ac916d87863
|