单目3D初始代码

This commit is contained in:
zhao.zhu
2026-06-24 09:35:46 +08:00
commit 04a5895b6b
1153 changed files with 340700 additions and 0 deletions

5
tools/model_inference/.gitignore vendored Executable file
View File

@@ -0,0 +1,5 @@
.cache/
__pycache__/
core/__pycache__/
adapters/__pycache__/
data_tools/__pycache__/

189
tools/model_inference/README.md Executable file
View File

@@ -0,0 +1,189 @@
# Two-ROI Exported Model Inference
`tools/model_inference` contains a self-contained inference pipeline for the exported two-ROI ONNX or TorchScript model.
## Layout
- `run_two_roi_exported_onnx_infer.py`
Compatibility entry point kept at the original path.
- `core/`
Core inference pipeline, decode logic, geometry helpers, and shared types.
- `adapters/`
Input-source adapters for video directories, PDCL clip exports, and event-id resolution.
- `scripts/`
Shell launchers grouped by usage mode.
- `data_tools/`
Small preprocessing helpers for CSV/XLSX conversion.
- `docs/`
Design notes and usage background documents.
- `examples/`
Sample JSON/CSV/XLSX/txt inputs used by the helper scripts.
## Files
- `core/run_two_roi_exported_onnx_infer.py`
Main implementation. Reads one clip-export directory, runs two-ROI ONNX or TorchScript inference, decodes 2D/3D results, and saves visualizations plus `predictions.json`.
- `core/two_roi_infer_utils.py`
Minimal local utilities for ROI crop, calibration handling, 2D decode, top-k selection, and common serialization helpers.
- `core/two_roi_3d_utils.py`
Minimal local 3D geometry, projection, yaw decoding, and 3D drawing helpers.
- `scripts/run_two_roi_exported_onnx_infer.sh`
Example shell wrapper.
## External Dependencies
This package does not depend on `ultralytics` at runtime.
Required Python packages:
- `numpy`
- `opencv-python`
- `pyyaml`
- `onnxruntime` for `.onnx` models
- `torch` for `.torchscript` models
## Expected Input Layout
The script can take a clip-export directory directly.
Expected structure:
```text
clip_export_xxx/
├── images/
│ ├── *.png
│ └── ...
├── calib/
│ └── L2_calib/
│ └── camera4.json
├── manifest.json
└── calib_summary.json
```
The script automatically reads:
- images from `images/`
- calibration from `calib/L2_calib/camera4.json` or `calib/camera4.json`
## Expected Exported Model Outputs
The exported model should be the raw-head merged artifact produced by `tools/model_merging/merge_models_of_2roi_yolo26.py`. The same output contract is used for both ONNX and TorchScript.
Required output tensor names:
- `roi0_boxes_head_raw`
- `roi0_scores_head_raw`
- `roi0_preds_3d_head_raw`
- `roi1_boxes_head_raw`
- `roi1_scores_head_raw`
- `roi1_preds_3d_head_raw`
Optional output tensor names:
- `roi0_preds_edge_head_raw`
- `roi1_preds_edge_head_raw`
If the merged model is exported with `--edge-head-mode drop`, the runtime keeps the
same 2D/3D decode path and automatically disables edge-yaw reconstruction.
## Basic Usage
```bash
python tools/model_inference/run_two_roi_exported_onnx_infer.py \
--case-dir tools/pdcl_inference/clip_exports/clip_export_G1M3_G1Q3_6284_019cb7f4-a944-7c22-5427-5b75b25545c7 \
--exported-model runs/export/train_mono3d_two_roi_202603251430/merged_model.onnx \
--output-dir /tmp/two_roi_exported_model_run
```
For CNCAP JSON batch video inference:
```bash
python tools/model_inference/run_two_roi_exported_onnx_infer.py \
--cncap-json-file tools/model_inference/examples/cncap/G1M3_AFS1616_CNCAP-202411.json \
--cncap-path-prefix-src /mnt/hfs/project-G1M3 \
--cncap-path-prefix-dst /mnt/G1M3 \
--exported-model runs/export/train_mono3d_two_roi_20260403-raw-fuse/merged_model.onnx \
--output-dir /tmp/two_roi_exported_model_cncap_run
```
## Shell Wrapper
```bash
bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer.sh
```
Update the paths in the shell script before handing it to downstream users if needed.
## Important Arguments
- `--case-dir`
Clip-export directory containing `images/` and either `calib/L2_calib/camera4.json` or `calib/camera4.json`.
- `--cncap-json-file`
CNCAP JSON file containing `values` entries that point to `sigmastar.1` directories. The script rewrites each mounted path prefix, resolves `camera4.bin` plus `test_data/calibs/camera4.json`, and then reuses the video-case inference flow.
- `--exported-model`
Merged raw-head exported model path. Supports `.onnx` and `.torchscript`.
- `--output-dir`
Directory used to save visualization images and `predictions.json`.
- `--roi0-model`, `--roi1-model`
Training checkpoints used only for metadata-free ROI preset alignment are no longer required by any external framework, but are still used as plain path fields in the current CLI contract. Keep them aligned with your deployment pair.
- `--roi0-roi`, `--roi1-roi`
ROI crop sizes before resize.
- `--roi0-imgsz`, `--roi1-imgsz`
ROI input tensor sizes used by the exported model. If omitted, the script first tries the export manifest.
- `--classes`
Optional class-id filter.
- `--max-images`
Limit the number of images for quick smoke tests.
- `--providers`
Optional ONNX Runtime providers, for example `CUDAExecutionProvider CPUExecutionProvider`. Only used for `.onnx` models.
## Outputs
The script writes:
- one visualization image per input frame
- `predictions.json`
`predictions.json` contains per-frame, per-ROI prediction records including:
- 2D box
- confidence
- class id and class name
- yaw
- edge-yaw diagnostics
- decoded 3D center
- ROI crop bounds
## Notes
- This pipeline intentionally runs decode and postprocess outside the exported graph.
- It is useful for downstream deployment and migration because the runtime path only depends on common Python packages.
- If the exported model export mode changes, make sure the output tensor names still match the names listed above.
## Known Residuals
Validation against the batch PyTorch reference path
`tools/pdcl_inference/two_roi_inference.py` on the first 20 frames of
`clip_export_G1M3_G1Q3_6284_019cb7f4-a944-7c22-5427-5b75b25545c7`
shows that the self-contained ONNX path matches the 3D branch decisions
after bbox-based matching:
- `visible_face_type` mismatch: `0`
- `visible_face_types` mismatch: `0`
- `edge_yaw_confident` mismatch: `0`
Two near-threshold count mismatches are still treated as known residuals.
In both cases the PyTorch batch path keeps one extra `cls_id=6` detection
with confidence just above the `0.25` threshold, while the ONNX path drops it:
- `019cb7f4-a944-7c22-5427-5b75b25545c7_80364.png`, `roi0`
Batch-only detection: `conf=0.252197`
- `019cb7f4-a944-7c22-5427-5b75b25545c7_80370.png`, `roi0`
Batch-only detection: `conf=0.251094`
Current interpretation:
- These residuals are consistent with small ONNX vs PyTorch numerical drift
around the confidence threshold.
- The implementation is intentionally kept unchanged; no extra confidence
epsilon is applied just to eliminate these edge cases.

View File

@@ -0,0 +1 @@
"""Two-ROI model inference package."""

View File

@@ -0,0 +1 @@
"""Input adapters for model_inference batch sources."""

View File

@@ -0,0 +1,822 @@
from __future__ import annotations
import argparse
from concurrent.futures import ThreadPoolExecutor, as_completed
import json
from dataclasses import dataclass
from pathlib import Path
import re
from typing import Any, Callable, Optional
try:
from .get_clip_by_eventid import get_associated_clip_ids
from .pdcl_clip_export_utils import (
build_clip_tasks_from_clip_ids,
run_clip_tasks_inference_exported,
)
except ImportError:
from get_clip_by_eventid import get_associated_clip_ids
from pdcl_clip_export_utils import (
build_clip_tasks_from_clip_ids,
run_clip_tasks_inference_exported,
)
DEFAULT_EVENT_CACHE_FILE = Path(__file__).resolve().parents[1] / ".cache" / "event_clip_cache.json"
@dataclass(frozen=True)
class ResolvedEventRecord:
scene: str
record_index: int
event_id: str
event_id_field_used: str
source_record: dict[str, Any]
clip_ids: list[str]
clip_source: str
@dataclass(frozen=True)
class EventResolutionStats:
total_events: int
cache_hits: int
cache_misses: int
request_workers: int
cache_file: str
direct_clip_records: int = 0
event_lookup_records: int = 0
def _dedupe_preserve_order(values: list[str]) -> list[str]:
ordered: list[str] = []
seen: set[str] = set()
for value in values:
token = str(value).strip()
if not token or token in seen:
continue
seen.add(token)
ordered.append(token)
return ordered
def _sanitize_identifier_for_path(identifier: str, prefix: str = "event_id") -> str:
token = re.sub(r'[\\/:*?"<>|\s]+', "_", str(identifier or "").strip())
token = token.strip("._")
token = token or "unknown_id"
normalized_prefix = re.sub(r"[^0-9A-Za-z]+", "_", str(prefix or "").strip())
normalized_prefix = normalized_prefix.strip("._") or "id"
return f"{normalized_prefix}_{token}"
def _build_resolution_stats_payload(resolution_stats: "EventResolutionStats") -> dict[str, Any]:
return {
"total_events": resolution_stats.total_events,
"cache_hits": resolution_stats.cache_hits,
"cache_misses": resolution_stats.cache_misses,
"request_workers": resolution_stats.request_workers,
"cache_file": resolution_stats.cache_file,
"direct_clip_records": resolution_stats.direct_clip_records,
"event_lookup_records": resolution_stats.event_lookup_records,
}
def _record_key(record: "ResolvedEventRecord") -> tuple[str, int, str]:
return (record.scene, int(record.record_index), str(record.event_id))
def _normalize_direct_clip_ids(raw_value: Any) -> list[str]:
if isinstance(raw_value, list):
return _dedupe_preserve_order([str(item).strip() for item in raw_value if str(item).strip()])
if isinstance(raw_value, str):
text = raw_value.strip()
if not text:
return []
if text.startswith("["):
try:
parsed = json.loads(text)
except Exception:
parsed = None
if isinstance(parsed, list):
return _dedupe_preserve_order([str(item).strip() for item in parsed if str(item).strip()])
return _dedupe_preserve_order([token for token in re.split(r"[\s,]+", text) if token])
if raw_value is None:
return []
token = str(raw_value).strip()
if not token:
return []
return [token]
def _extract_direct_clip_ids(record: dict[str, Any], clip_ids_field: str) -> tuple[bool, list[str]]:
field_name = str(clip_ids_field or "").strip()
if not field_name or field_name not in record:
return False, []
return True, _normalize_direct_clip_ids(record.get(field_name))
def _resolve_record_identifier(
record: dict[str, Any],
preferred_field: str,
*,
allow_direct_clip_fallback: bool = False,
) -> tuple[str, str]:
candidate_fields: list[str] = []
preferred_token = str(preferred_field or "").strip()
if preferred_token:
candidate_fields.append(preferred_token)
if allow_direct_clip_fallback:
for field_name in ("rawid", "event_id", "data_path"):
if field_name not in candidate_fields:
candidate_fields.append(field_name)
for field_name in candidate_fields:
identifier = str(record.get(field_name, "")).strip()
if identifier:
return identifier, field_name
return "", preferred_token
def _extract_condition_values(source_record: dict[str, Any], condition_fields: list[str]) -> dict[str, str]:
return {
str(field): str(source_record.get(field, "")).strip()
for field in condition_fields
}
def _select_event_records_by_condition(
records: list["ResolvedEventRecord"],
*,
condition_fields: list[str],
max_records_per_condition: int,
selection_strategy: str,
) -> tuple[list["ResolvedEventRecord"], dict[str, Any]]:
normalized_fields = [str(field).strip() for field in condition_fields if str(field).strip()]
limit = max(0, int(max_records_per_condition))
selection_enabled = bool(normalized_fields and limit > 0)
summary: dict[str, Any] = {
"enabled": selection_enabled,
"condition_fields": normalized_fields,
"max_records_per_condition": limit,
"selection_strategy": selection_strategy,
"records_before_selection": len(records),
"records_after_selection": len(records),
"group_count": 0,
"groups": [],
}
if not selection_enabled:
return list(records), summary
if selection_strategy != "first":
raise ValueError(f"Unsupported condition selection strategy: {selection_strategy!r}")
selected_records: list[ResolvedEventRecord] = []
selected_counts: dict[tuple[str, tuple[str, ...]], int] = {}
group_summaries: dict[tuple[str, tuple[str, ...]], dict[str, Any]] = {}
for record in records:
condition_values = _extract_condition_values(record.source_record, normalized_fields)
condition_tuple = tuple(condition_values[field] for field in normalized_fields)
group_key = (record.scene, condition_tuple)
group_summary = group_summaries.setdefault(
group_key,
{
"scene": record.scene,
"condition_values": condition_values,
"record_count": 0,
"selected_count": 0,
"skipped_count": 0,
"selected_record_ids": [],
"selected_record_indices": [],
"skipped_record_ids": [],
"skipped_record_indices": [],
},
)
group_summary["record_count"] += 1
current_selected_count = selected_counts.get(group_key, 0)
if current_selected_count < limit:
selected_records.append(record)
selected_counts[group_key] = current_selected_count + 1
group_summary["selected_count"] += 1
group_summary["selected_record_ids"].append(record.event_id)
group_summary["selected_record_indices"].append(record.record_index)
continue
group_summary["skipped_count"] += 1
group_summary["skipped_record_ids"].append(record.event_id)
group_summary["skipped_record_indices"].append(record.record_index)
summary["records_after_selection"] = len(selected_records)
summary["group_count"] = len(group_summaries)
summary["groups"] = list(group_summaries.values())
return selected_records, summary
def _filter_selection_summary_for_scene(selection_summary: dict[str, Any], scene: str) -> dict[str, Any]:
if not selection_summary:
return {}
scene_groups = [
dict(group)
for group in selection_summary.get("groups", [])
if str(group.get("scene", "")) == str(scene)
]
filtered = dict(selection_summary)
filtered["groups"] = scene_groups
filtered["group_count"] = len(scene_groups)
if scene_groups:
filtered["records_before_selection"] = sum(int(group.get("record_count", 0)) for group in scene_groups)
filtered["records_after_selection"] = sum(int(group.get("selected_count", 0)) for group in scene_groups)
else:
filtered["records_before_selection"] = 0
filtered["records_after_selection"] = 0
return filtered
def _format_condition_summary(source_record: dict[str, Any], condition_fields: list[str]) -> str:
normalized_fields = [str(field).strip() for field in condition_fields if str(field).strip()]
if not normalized_fields:
return ""
values = _extract_condition_values(source_record, normalized_fields)
return ", ".join(f"{field}={values.get(field, '')}" for field in normalized_fields)
def _print_event_json_summary(
*,
args: argparse.Namespace,
manifest_path: Path,
resolved_records: list["ResolvedEventRecord"],
selected_records: list["ResolvedEventRecord"],
selection_summary: dict[str, Any],
scene_results: dict[str, dict[str, Any]],
) -> None:
print(f"Event JSON file: {args.event_json_file}")
if args.scene:
print(f"Scene filter: {args.scene}")
print(
"Resolved records: "
f"{len(resolved_records)}, selected records: {len(selected_records)}"
)
print(f"Manifest: {manifest_path}")
if not selected_records:
print("No records selected.")
return
condition_fields = [str(field).strip() for field in getattr(args, "condition_fields", []) if str(field).strip()]
if args.selection_only:
print("Selection-only mode: no clip export or inference was run.")
elif selection_summary.get("enabled"):
print(
"Condition selection: "
f"{selection_summary.get('group_count', 0)} groups, "
f"strategy={selection_summary.get('selection_strategy', '')}, "
f"max_records_per_condition={selection_summary.get('max_records_per_condition', 0)}"
)
for scene in sorted(scene_results):
scene_result = scene_results[scene]
print(
f"Scene {scene}: selected_record_count="
f"{scene_result.get('selected_record_count', len([record for record in selected_records if record.scene == scene]))}"
)
scene_manifest_path = scene_result.get("scene_manifest_path")
if scene_manifest_path:
print(f" Scene manifest: {scene_manifest_path}")
if scene_result.get("scene_output_dir"):
print(f" Output dir: {scene_result['scene_output_dir']}")
scene_records = [record for record in selected_records if record.scene == scene]
for record in scene_records:
condition_summary = _format_condition_summary(record.source_record, condition_fields)
summary_parts = []
if condition_summary:
summary_parts.append(condition_summary)
summary_parts.append(f"record_id={record.event_id}")
summary_parts.append(f"clips={len(record.clip_ids)}")
print(f" - {'; '.join(summary_parts)}")
def _build_scene_manifest_payload(
*,
args: argparse.Namespace,
scene: str,
scene_records: list["ResolvedEventRecord"],
resolution_stats: "EventResolutionStats",
selection_summary: Optional[dict[str, Any]] = None,
) -> dict[str, Any]:
payload = {
"event_json_file": args.event_json_file,
"scene": scene,
"event_id_field": args.event_id_field,
"event_clip_ids_field": args.event_clip_ids_field,
"resolution_stats": _build_resolution_stats_payload(resolution_stats),
"event_record_count": len(scene_records),
"records": [
{
"record_index": record.record_index,
"event_id": record.event_id,
"event_id_field_used": record.event_id_field_used,
"clip_ids": record.clip_ids,
"clip_source": record.clip_source,
"source_record": record.source_record,
}
for record in scene_records
],
}
if selection_summary is not None:
payload["selection"] = selection_summary
return payload
def _build_event_manifest_payload(
*,
args: argparse.Namespace,
scene: str,
event_id: str,
event_records: list["ResolvedEventRecord"],
clip_ids: list[str],
resolution_stats: "EventResolutionStats",
) -> dict[str, Any]:
condition_fields = [str(field).strip() for field in getattr(args, "condition_fields", []) if str(field).strip()]
payload = {
"event_json_file": args.event_json_file,
"scene": scene,
"event_id_field": args.event_id_field,
"event_clip_ids_field": args.event_clip_ids_field,
"event_id": event_id,
"resolution_stats": _build_resolution_stats_payload(resolution_stats),
"event_record_count": len(event_records),
"clip_ids": clip_ids,
"clip_count": len(clip_ids),
"records": [
{
"record_index": record.record_index,
"event_id": record.event_id,
"event_id_field_used": record.event_id_field_used,
"clip_ids": record.clip_ids,
"clip_source": record.clip_source,
"source_record": record.source_record,
}
for record in event_records
],
}
if event_records:
payload["event_id_field_used"] = event_records[0].event_id_field_used
payload["clip_source"] = sorted({record.clip_source for record in event_records})
if condition_fields and event_records:
payload["condition_values"] = _extract_condition_values(event_records[0].source_record, condition_fields)
return payload
def load_event_scene_json(json_file: str) -> dict[str, list[dict[str, Any]]]:
path = Path(json_file)
with path.open("r", encoding="utf-8") as file:
payload = json.load(file)
if not isinstance(payload, dict):
raise ValueError(f"Expected top-level dict in {path}, got {type(payload).__name__}")
normalized: dict[str, list[dict[str, Any]]] = {}
for scene, records in payload.items():
if not isinstance(records, list):
raise ValueError(f"Scene {scene!r} should map to a list, got {type(records).__name__}")
normalized[str(scene)] = [dict(item) if isinstance(item, dict) else {"value": item} for item in records]
return normalized
def load_event_clip_cache(cache_file: str | Path) -> dict[str, list[str]]:
cache_path = Path(cache_file)
if not cache_path.exists():
return {}
try:
payload = json.loads(cache_path.read_text(encoding="utf-8"))
except Exception:
return {}
if not isinstance(payload, dict):
return {}
cache: dict[str, list[str]] = {}
for event_id, clip_ids in payload.items():
if isinstance(clip_ids, list):
cache[str(event_id)] = [str(item).strip() for item in clip_ids if str(item).strip()]
return cache
def save_event_clip_cache(cache_file: str | Path, cache_payload: dict[str, list[str]]) -> Path:
cache_path = Path(cache_file)
cache_path.parent.mkdir(parents=True, exist_ok=True)
normalized = {
str(event_id): [str(item).strip() for item in clip_ids if str(item).strip()]
for event_id, clip_ids in cache_payload.items()
}
with cache_path.open("w", encoding="utf-8") as file:
json.dump(normalized, file, indent=2, ensure_ascii=False)
return cache_path
def resolve_event_clip_ids(
event_ids: list[str],
*,
timeout: float = 60.0,
cache_file: str | Path = DEFAULT_EVENT_CACHE_FILE,
workers: int = 4,
max_retries: int = 3,
retry_backoff_sec: float = 2.0,
) -> tuple[dict[str, list[str]], EventResolutionStats]:
ordered_event_ids: list[str] = []
seen: set[str] = set()
for event_id in event_ids:
normalized = str(event_id).strip()
if not normalized or normalized in seen:
continue
seen.add(normalized)
ordered_event_ids.append(normalized)
cache_payload = load_event_clip_cache(cache_file)
resolved: dict[str, list[str]] = {}
unresolved_event_ids: list[str] = []
cache_hits = 0
cache_misses = 0
for event_id in ordered_event_ids:
if event_id in cache_payload:
resolved[event_id] = list(cache_payload[event_id])
cache_hits += 1
else:
unresolved_event_ids.append(event_id)
cache_misses += 1
if unresolved_event_ids:
max_workers = max(1, min(int(workers), len(unresolved_event_ids)))
if max_workers == 1:
for event_id in unresolved_event_ids:
clip_ids = get_associated_clip_ids(
event_id,
timeout=timeout,
max_retries=max_retries,
retry_backoff_sec=retry_backoff_sec,
)
resolved[event_id] = clip_ids
cache_payload[event_id] = clip_ids
else:
with ThreadPoolExecutor(max_workers=max_workers) as executor:
future_to_event_id = {
executor.submit(
get_associated_clip_ids,
event_id,
timeout,
max_retries,
retry_backoff_sec,
): event_id
for event_id in unresolved_event_ids
}
for future in as_completed(future_to_event_id):
event_id = future_to_event_id[future]
clip_ids = future.result()
resolved[event_id] = clip_ids
cache_payload[event_id] = clip_ids
save_event_clip_cache(cache_file, cache_payload)
worker_count = max(1, min(int(workers), len(unresolved_event_ids)))
else:
worker_count = 0
stats = EventResolutionStats(
total_events=len(ordered_event_ids),
cache_hits=cache_hits,
cache_misses=cache_misses,
request_workers=worker_count,
cache_file=str(Path(cache_file).resolve()),
)
return resolved, stats
def resolve_event_records(
json_file: str,
scene_filter: Optional[str] = None,
event_id_field: str = "data_path",
clip_ids_field: str = "clips",
max_events: int = 0,
timeout: float = 60.0,
cache_file: str | Path = DEFAULT_EVENT_CACHE_FILE,
workers: int = 4,
max_retries: int = 3,
retry_backoff_sec: float = 2.0,
) -> tuple[list[ResolvedEventRecord], EventResolutionStats]:
scene_payload = load_event_scene_json(json_file)
scene_names = [scene_filter] if scene_filter else list(scene_payload)
pending_records: list[tuple[str, int, dict[str, Any], str, str, list[str], str]] = []
lookup_event_ids: list[str] = []
processed = 0
direct_clip_records = 0
event_lookup_records = 0
for scene in scene_names:
records = scene_payload.get(scene)
if records is None:
raise ValueError(f"Scene {scene!r} not found in {json_file}")
for index, record in enumerate(records):
has_direct_clip_ids, direct_clip_ids = _extract_direct_clip_ids(record, clip_ids_field)
event_id, resolved_id_field = _resolve_record_identifier(
record,
event_id_field,
allow_direct_clip_fallback=has_direct_clip_ids,
)
if not event_id:
continue
clip_source = "direct_clip_ids_field" if has_direct_clip_ids else "event_lookup"
if has_direct_clip_ids:
direct_clip_records += 1
else:
event_lookup_records += 1
lookup_event_ids.append(event_id)
pending_records.append(
(scene, index, record, event_id, resolved_id_field, direct_clip_ids, clip_source)
)
processed += 1
if max_events > 0 and processed >= max_events:
break
if max_events > 0 and processed >= max_events:
break
resolved_clip_map: dict[str, list[str]] = {}
lookup_stats = EventResolutionStats(
total_events=0,
cache_hits=0,
cache_misses=0,
request_workers=0,
cache_file=str(Path(cache_file).resolve()),
)
if lookup_event_ids:
resolved_clip_map, lookup_stats = resolve_event_clip_ids(
lookup_event_ids,
timeout=timeout,
cache_file=cache_file,
workers=workers,
max_retries=max_retries,
retry_backoff_sec=retry_backoff_sec,
)
resolved = [
ResolvedEventRecord(
scene=scene,
record_index=index,
event_id=event_id,
event_id_field_used=resolved_id_field,
source_record=record,
clip_ids=direct_clip_ids if clip_source == "direct_clip_ids_field" else resolved_clip_map.get(event_id, []),
clip_source=clip_source,
)
for scene, index, record, event_id, resolved_id_field, direct_clip_ids, clip_source in pending_records
]
stats = EventResolutionStats(
total_events=len(pending_records),
cache_hits=lookup_stats.cache_hits,
cache_misses=lookup_stats.cache_misses,
request_workers=lookup_stats.request_workers,
cache_file=str(Path(cache_file).resolve()),
direct_clip_records=direct_clip_records,
event_lookup_records=event_lookup_records,
)
return resolved, stats
def build_event_resolution_payload(
json_file: str,
resolved_records: list[ResolvedEventRecord],
event_id_field: str,
clip_ids_field: str,
stats: EventResolutionStats,
selection_summary: Optional[dict[str, Any]] = None,
selected_record_keys: Optional[set[tuple[str, int, str]]] = None,
) -> dict[str, Any]:
selection_enabled = bool(selection_summary and selection_summary.get("enabled"))
selected_keys = selected_record_keys or set()
scenes: dict[str, list[dict[str, Any]]] = {}
for record in resolved_records:
scenes.setdefault(record.scene, []).append(
{
"record_index": record.record_index,
"event_id_field": event_id_field,
"event_id_field_used": record.event_id_field_used,
"event_id": record.event_id,
"event_clip_ids_field": clip_ids_field,
"clip_ids": record.clip_ids,
"clip_count": len(record.clip_ids),
"clip_source": record.clip_source,
"selected_for_inference": True if not selection_enabled else _record_key(record) in selected_keys,
"source_record": record.source_record,
}
)
payload = {
"event_json_file": json_file,
"event_id_field": event_id_field,
"event_clip_ids_field": clip_ids_field,
"scene_count": len(scenes),
"record_count": len(resolved_records),
"selected_record_count": len(selected_keys) if selection_enabled else len(resolved_records),
"resolution_stats": _build_resolution_stats_payload(stats),
"scenes": scenes,
}
if selection_summary is not None:
payload["selection"] = selection_summary
return payload
def save_event_resolution_manifest(
output_root: Path,
json_file: str,
resolved_records: list[ResolvedEventRecord],
event_id_field: str,
clip_ids_field: str,
stats: EventResolutionStats,
selection_summary: Optional[dict[str, Any]] = None,
selected_record_keys: Optional[set[tuple[str, int, str]]] = None,
) -> Path:
manifest_path = output_root / "_status" / "event_scene_manifest.json"
manifest_path.parent.mkdir(parents=True, exist_ok=True)
payload = build_event_resolution_payload(
json_file,
resolved_records,
event_id_field,
clip_ids_field,
stats,
selection_summary=selection_summary,
selected_record_keys=selected_record_keys,
)
with manifest_path.open("w", encoding="utf-8") as file:
json.dump(payload, file, indent=2, ensure_ascii=False)
return manifest_path
def run_event_json_inference_exported(
*,
context: Any,
args: argparse.Namespace,
load_env: Callable[[], Any],
run_case_inference: Callable[..., dict[str, Any]],
) -> dict[str, Any]:
resolved_records, resolution_stats = resolve_event_records(
json_file=args.event_json_file,
scene_filter=args.scene,
event_id_field=args.event_id_field,
clip_ids_field=args.event_clip_ids_field,
max_events=args.max_events,
timeout=args.event_request_timeout,
cache_file=args.event_cache_file,
workers=args.event_resolve_workers,
max_retries=args.event_request_retries,
retry_backoff_sec=args.event_request_retry_backoff_sec,
)
selected_records, selection_summary = _select_event_records_by_condition(
resolved_records,
condition_fields=[str(field).strip() for field in getattr(args, "condition_fields", []) if str(field).strip()],
max_records_per_condition=int(getattr(args, "max_records_per_condition", 0)),
selection_strategy=str(getattr(args, "condition_select_strategy", "first")),
)
selected_record_keys = {_record_key(record) for record in selected_records}
output_root = Path(args.output_dir).resolve()
output_root.mkdir(parents=True, exist_ok=True)
manifest_path = save_event_resolution_manifest(
output_root=output_root,
json_file=args.event_json_file,
resolved_records=resolved_records,
event_id_field=args.event_id_field,
clip_ids_field=args.event_clip_ids_field,
stats=resolution_stats,
selection_summary=selection_summary,
selected_record_keys=selected_record_keys,
)
summary_by_scene: dict[str, dict[str, Any]] = {}
for scene in sorted({record.scene for record in selected_records}):
scene_records = [record for record in selected_records if record.scene == scene]
scene_selection_summary = _filter_selection_summary_for_scene(selection_summary, scene)
scene_export_root = Path(args.export_root).resolve() / scene
scene_output_root = output_root / scene
scene_output_root.mkdir(parents=True, exist_ok=True)
scene_manifest_path = scene_output_root / "_status" / "scene_event_manifest.json"
scene_manifest_path.parent.mkdir(parents=True, exist_ok=True)
with scene_manifest_path.open("w", encoding="utf-8") as file:
json.dump(
_build_scene_manifest_payload(
args=args,
scene=scene,
scene_records=scene_records,
resolution_stats=resolution_stats,
selection_summary=scene_selection_summary,
),
file,
indent=2,
ensure_ascii=False,
)
if args.selection_only:
summary_by_scene[scene] = {
"scene_output_dir": str(scene_output_root),
"scene_manifest_path": str(scene_manifest_path),
"selected_record_count": len(scene_records),
"selection_only": True,
}
continue
event_records_by_id: dict[str, list[ResolvedEventRecord]] = {}
event_order: list[str] = []
for record in scene_records:
if record.event_id not in event_records_by_id:
event_order.append(record.event_id)
event_records_by_id.setdefault(record.event_id, []).append(record)
selected_scene_clip_ids: set[str] = set()
event_results: dict[str, dict[str, Any]] = {}
event_dirs: dict[str, str] = {}
event_export_dirs: dict[str, str] = {}
for event_id in event_order:
event_records = event_records_by_id[event_id]
event_clip_ids = _dedupe_preserve_order(
[clip_id for record in event_records for clip_id in record.clip_ids]
)
if args.limit_clips > 0:
limited_clip_ids: list[str] = []
for clip_id in event_clip_ids:
if clip_id in selected_scene_clip_ids:
limited_clip_ids.append(clip_id)
continue
if len(selected_scene_clip_ids) >= args.limit_clips:
continue
selected_scene_clip_ids.add(clip_id)
limited_clip_ids.append(clip_id)
event_clip_ids = limited_clip_ids
clip_tasks = build_clip_tasks_from_clip_ids(event_clip_ids)
dir_prefix = "event_id"
if any(record.clip_source == "direct_clip_ids_field" for record in event_records):
dir_prefix = event_records[0].event_id_field_used or args.event_id_field or "record_id"
event_dir_name = _sanitize_identifier_for_path(event_id, prefix=dir_prefix)
event_export_root = scene_export_root / event_dir_name
event_output_root = scene_output_root / event_dir_name
event_export_dirs[event_id] = str(event_export_root)
event_dirs[event_id] = str(event_output_root)
def on_before_run(export_root: Path, inference_root: Path, tasks: list[Any], *, _event_id: str = event_id, _event_records: list[ResolvedEventRecord] = event_records, _event_clip_ids: list[str] = event_clip_ids) -> None:
payload = _build_event_manifest_payload(
args=args,
scene=scene,
event_id=_event_id,
event_records=_event_records,
clip_ids=_event_clip_ids,
resolution_stats=resolution_stats,
)
manifest_path = inference_root / "_status" / "event_manifest.json"
manifest_path.parent.mkdir(parents=True, exist_ok=True)
with manifest_path.open("w", encoding="utf-8") as file:
json.dump(payload, file, indent=2, ensure_ascii=False)
event_results[event_id] = run_clip_tasks_inference_exported(
context=context,
args=args,
clip_tasks=clip_tasks,
load_env=load_env,
run_case_inference=run_case_inference,
export_root=event_export_root,
output_root=event_output_root,
on_before_run=on_before_run,
)
summary_by_scene[scene] = {
"scene_output_dir": str(scene_output_root),
"scene_manifest_path": str(scene_manifest_path),
"event_export_dirs": event_export_dirs,
"event_dirs": event_dirs,
"event_results": event_results,
}
result = {
"event_json_file": args.event_json_file,
"scene": args.scene or "",
"event_id_field": args.event_id_field,
"event_clip_ids_field": args.event_clip_ids_field,
"manifest_path": str(manifest_path),
"selection": selection_summary,
"selected_record_count": len(selected_records),
"resolution_stats": _build_resolution_stats_payload(resolution_stats),
"scene_results": summary_by_scene,
}
_print_event_json_summary(
args=args,
manifest_path=manifest_path,
resolved_records=resolved_records,
selected_records=selected_records,
selection_summary=selection_summary,
scene_results=summary_by_scene,
)
return result

View File

@@ -0,0 +1,141 @@
from __future__ import annotations
import argparse
import json
import time
from typing import Any
import requests
EVENT_META_INFO_URL = "https://d.minieye.tech/ess-api/dashoard/event/meta_info"
CLIP_ID_KEYS = ("clip_id", "clip_uuid", "clip_ukey", "ukey", "id")
def fetch_event_meta(
event_id: str,
timeout: float = 60.0,
max_retries: int = 3,
retry_backoff_sec: float = 2.0,
) -> dict[str, Any]:
event_id = str(event_id).strip()
if not event_id:
raise ValueError("event_id is required")
last_error: Exception | None = None
total_attempts = max(1, int(max_retries))
for attempt in range(1, total_attempts + 1):
try:
response = requests.post(
url=EVENT_META_INFO_URL,
json={"event_id": event_id},
timeout=timeout,
)
response.raise_for_status()
payload = response.json()
if not isinstance(payload, dict):
raise ValueError(f"Unexpected event meta response type: {type(payload).__name__}")
return payload
except (requests.exceptions.Timeout, requests.exceptions.RequestException, ValueError) as exc:
last_error = exc
if attempt >= total_attempts:
break
sleep_sec = max(0.0, float(retry_backoff_sec)) * (2 ** (attempt - 1))
print(
f"[warn] event_id={event_id} request attempt {attempt}/{total_attempts} failed: "
f"{type(exc).__name__}: {exc}. retry in {sleep_sec:.1f}s"
)
if sleep_sec > 0:
time.sleep(sleep_sec)
assert last_error is not None
raise last_error
def _append_clip_id(clip_ids: list[str], seen: set[str], value: Any) -> None:
clip_id = str(value).strip()
if clip_id and clip_id not in seen:
seen.add(clip_id)
clip_ids.append(clip_id)
def _extract_clip_ids_from_item(item: Any, clip_ids: list[str], seen: set[str]) -> None:
if item is None:
return
if isinstance(item, str):
_append_clip_id(clip_ids, seen, item)
return
if isinstance(item, (list, tuple, set)):
for sub_item in item:
_extract_clip_ids_from_item(sub_item, clip_ids, seen)
return
if isinstance(item, dict):
matched_key = False
for key in CLIP_ID_KEYS:
value = item.get(key)
if value is not None:
matched_key = True
_extract_clip_ids_from_item(value, clip_ids, seen)
if matched_key:
return
for value in item.values():
_extract_clip_ids_from_item(value, clip_ids, seen)
return
_append_clip_id(clip_ids, seen, item)
def extract_associated_clip_ids(payload: dict[str, Any]) -> list[str]:
clip_items = payload.get("associated_clip_list", [])
if clip_items is None:
return []
clip_ids: list[str] = []
seen: set[str] = set()
_extract_clip_ids_from_item(clip_items, clip_ids, seen)
return clip_ids
def get_associated_clip_ids(
event_id: str,
timeout: float = 60.0,
max_retries: int = 3,
retry_backoff_sec: float = 2.0,
) -> list[str]:
payload = fetch_event_meta(
event_id,
timeout=timeout,
max_retries=max_retries,
retry_backoff_sec=retry_backoff_sec,
)
return extract_associated_clip_ids(payload)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Resolve PDCL clip ids from one or more event ids.")
parser.add_argument("event_ids", nargs="+", help="One or more event ids to resolve.")
parser.add_argument("--timeout", type=float, default=60.0, help="HTTP request timeout in seconds.")
parser.add_argument("--retries", type=int, default=3, help="Max request attempts per event id.")
parser.add_argument("--retry-backoff-sec", type=float, default=2.0, help="Base retry backoff in seconds.")
parser.add_argument("--pretty", action="store_true", help="Pretty-print the JSON result.")
return parser.parse_args()
def main() -> None:
args = parse_args()
result = {
event_id: get_associated_clip_ids(
event_id,
timeout=args.timeout,
max_retries=args.retries,
retry_backoff_sec=args.retry_backoff_sec,
)
for event_id in args.event_ids
}
if args.pretty:
print(json.dumps(result, indent=2, ensure_ascii=False))
else:
print(json.dumps(result, ensure_ascii=False))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,826 @@
from __future__ import annotations
import argparse
import io
import json
import os
import traceback
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from pathlib import Path
from threading import Lock
from typing import Any, Callable, Optional
import cv2
import numpy as np
CALIB_ATTACHMENT_NAMES = (
"sigmastar.1/calibs/camera4.json",
"test_data/calibs/camera4.json",
"calibs/camera4.json",
)
BEIJING_TZ = timezone(timedelta(hours=8))
DEFAULT_DATE_NAME = "unknown_date"
DEFAULT_VEHICLE_NAME = "unknown_vehicle"
LOCAL_MCAP_VEHICLE_NAME = "local_mcap"
@dataclass(frozen=True)
class ClipTask:
clip_uuid: str
date_name: str
vehicle_name: str
clip_path: str
@property
def task_id(self) -> str:
return self.clip_uuid
@dataclass
class TaskResult:
task_id: str
success: bool
message: str
output_dir: Optional[str] = None
class StatusStore:
"""Persistent status tracker for resumable batch inference."""
def __init__(self, status_file: Path):
self.status_file = status_file
self.lock = Lock()
self._status: dict[str, dict[str, str]] = {}
self.status_file.parent.mkdir(parents=True, exist_ok=True)
if self.status_file.exists():
try:
self._status = json.loads(self.status_file.read_text())
except Exception:
self._status = {}
def is_done(self, task_id: str) -> bool:
return self._status.get(task_id, {}).get("state") == "done"
def get(self, task_id: str) -> Optional[dict[str, str]]:
return self._status.get(task_id)
def mark_running(self, task_id: str, detail: str) -> None:
with self.lock:
self._status[task_id] = {"state": "running", "detail": detail}
self._flush()
def mark_done(self, task_id: str, detail: str) -> None:
with self.lock:
self._status[task_id] = {"state": "done", "detail": detail}
self._flush()
def mark_failed(self, task_id: str, detail: str) -> None:
with self.lock:
self._status[task_id] = {"state": "failed", "detail": detail}
self._flush()
def summary(self) -> dict[str, int]:
done = 0
running = 0
failed = 0
for item in self._status.values():
state = item.get("state")
if state == "done":
done += 1
elif state == "running":
running += 1
elif state == "failed":
failed += 1
return {"done": done, "running": running, "failed": failed, "total": len(self._status)}
def _flush(self) -> None:
self.status_file.write_text(json.dumps(self._status, indent=2, ensure_ascii=False))
def _ensure_pdcl_auth_defaults() -> None:
os.environ.setdefault("STS_UID", "dis-uploader")
os.environ.setdefault("STS_SECRET_KEY", "277310cc09724d315514a79701fecb0f")
def validate_pdcl_auth_env() -> None:
_ensure_pdcl_auth_defaults()
required_vars = ["STS_UID", "STS_SECRET_KEY"]
missing = [name for name in required_vars if not os.getenv(name)]
if missing:
raise ValueError(
"Missing required PDCL auth env vars: "
+ ", ".join(missing)
+ ". Please export them in shell or set them in .env before running."
)
def _normalize_metadata_value(value: Any) -> str:
text = str(value or "").strip()
return text if text and text.lower() != "none" else ""
def _normalize_frame_name_token(value: Any) -> str:
text = str(value or "").strip()
if not text or text.lower() == "none":
return ""
return text.replace("/", "_").replace("\\", "_").replace(" ", "")
def _format_ms_to_date_name(timestamp_ms: Any) -> str:
if not isinstance(timestamp_ms, (int, float)) or timestamp_ms <= 0:
return ""
dt = datetime.fromtimestamp(timestamp_ms / 1000, tz=timezone.utc).astimezone(BEIJING_TZ)
return dt.strftime("%Y%m%d%H%M%S")
def _build_clip_task(clip_uuid: str) -> Optional[ClipTask]:
_ensure_pdcl_auth_defaults()
from pdcl_dss import Clip
date_name = DEFAULT_DATE_NAME
vehicle_name = DEFAULT_VEHICLE_NAME
try:
clip = Clip(clip_uuid)
clip_meta = dict(clip.meta)
files, _ = clip.list_files()
if not files:
print(f"Skip clip_id={clip_uuid}: no files found")
return None
clip_path = clip.get_cache_path(files[0])
except Exception as exc:
print(f"Skip clip_id={clip_uuid}: failed to load clip metadata. {type(exc).__name__}: {exc}")
return None
clip_date_name = _format_ms_to_date_name(clip_meta.get("start_time_ms"))
if clip_date_name:
date_name = clip_date_name
try:
group_id = clip.get_group_id()
if group_id:
group_meta = dict(clip.get_group().meta)
for key in ("plate_number", "vehicle_name", "car_name", "plateNumber", "vehicleName", "carName"):
value = _normalize_metadata_value(group_meta.get(key))
if value:
vehicle_name = value
break
project_name = _normalize_metadata_value(group_meta.get("project_name"))
if vehicle_name == DEFAULT_VEHICLE_NAME and project_name:
vehicle_name = project_name
group_date_name = _format_ms_to_date_name(group_meta.get("collection_time"))
if group_date_name:
date_name = group_date_name
except Exception as exc:
print(
f"[warn] clip_id={clip_uuid}: failed to load group metadata, "
f"fallback vehicle={vehicle_name} date={date_name}. {type(exc).__name__}: {exc}"
)
return ClipTask(
clip_uuid=clip_uuid,
date_name=date_name,
vehicle_name=vehicle_name,
clip_path=clip_path,
)
def parse_clip_list(clip_list_file: str) -> list[ClipTask]:
tasks: list[ClipTask] = []
with open(clip_list_file, "r", encoding="utf-8") as file:
for line in file:
line = line.strip()
if not line or line.startswith("#"):
continue
clip_uuid = line.split()[0]
task = _build_clip_task(clip_uuid)
if task is not None:
tasks.append(task)
return tasks
def build_clip_tasks_from_clip_ids(clip_ids: list[str]) -> list[ClipTask]:
tasks: list[ClipTask] = []
seen: set[str] = set()
for clip_id in clip_ids:
clip_uuid = str(clip_id).strip()
if not clip_uuid or clip_uuid in seen:
continue
seen.add(clip_uuid)
task = _build_clip_task(clip_uuid)
if task is not None:
tasks.append(task)
return tasks
def build_clip_task_from_mcap_file(
mcap_file: str | Path,
*,
clip_id: str = "",
date_name: str = "",
vehicle_name: str = "",
) -> ClipTask:
mcap_path = Path(mcap_file).expanduser().resolve()
if not mcap_path.is_file():
raise FileNotFoundError(f"MCAP file not found: {mcap_path}")
stem = mcap_path.stem
resolved_clip_id = _normalize_metadata_value(clip_id) or stem
resolved_date_name = _normalize_metadata_value(date_name)
if not resolved_date_name and len(stem) == 14 and stem.isdigit():
resolved_date_name = stem
resolved_vehicle_name = _normalize_metadata_value(vehicle_name) or LOCAL_MCAP_VEHICLE_NAME
return ClipTask(
clip_uuid=resolved_clip_id,
date_name=resolved_date_name or DEFAULT_DATE_NAME,
vehicle_name=resolved_vehicle_name,
clip_path=str(mcap_path),
)
def build_case_dir_name(prefix: str, clip_task: ClipTask) -> str:
safe_clip_uuid = clip_task.clip_uuid.replace("/", "_")
return f"{prefix}_{clip_task.vehicle_name}_{clip_task.date_name}_{safe_clip_uuid}"
def _plane_to_ndarray(plane: Any) -> np.ndarray:
stride = plane.line_size
height = plane.height
width = plane.width
array = np.frombuffer(plane, dtype=np.uint8)
if stride == width:
return array.reshape(height, width)
return array.reshape(height, stride)[:, :width]
def _yuvj420p_to_nv12(
y_plane: np.ndarray,
u_plane: np.ndarray,
v_plane: np.ndarray,
) -> tuple[np.ndarray, np.ndarray]:
uv_height = u_plane.shape[0]
uv_width = u_plane.shape[1]
uv_plane = np.zeros((uv_height, uv_width * 2), dtype=np.uint8)
uv_plane[:, 0::2] = u_plane
uv_plane[:, 1::2] = v_plane
return y_plane.copy(), uv_plane
def _h265_payload_to_bgr(payload: bytes) -> np.ndarray:
try:
import av
except ImportError as exc:
raise ImportError("PyAV is required for mcap decoding. Please install: pip install av") from exc
container = av.open(io.BytesIO(payload))
for frame in container.decode(video=0):
y_plane = _plane_to_ndarray(frame.planes[0])
u_plane = _plane_to_ndarray(frame.planes[1])
v_plane = _plane_to_ndarray(frame.planes[2])
y_nv12, uv_nv12 = _yuvj420p_to_nv12(y_plane, u_plane, v_plane)
yuv_image = np.concatenate((y_nv12, uv_nv12), axis=0)
return cv2.cvtColor(yuv_image, cv2.COLOR_YUV2BGR_NV12)
raise ValueError("decode failed: no video frame in payload")
def _resolve_calib_file_for_clip(clip_path: str) -> Optional[Path]:
base = Path(clip_path).resolve()
search_dir = base.parent
candidates: list[Path] = []
for _ in range(4):
candidates.extend(
[
search_dir / "calibs" / "camera4.json",
search_dir / "test_data" / "calibs" / "camera4.json",
search_dir / "L2_calib" / "camera4.json",
search_dir / "calib" / "L2_calib" / "camera4.json",
]
)
parent = search_dir.parent
if parent == search_dir:
break
search_dir = parent
for calib_path in candidates:
if calib_path.exists():
return calib_path
return None
def _candidate_camera_topics(camera_topic: str) -> list[str]:
topic = str(camera_topic or "").strip()
if not topic:
return []
topics = [topic]
if "." in topic:
topics.append(topic.rsplit(".", 1)[-1])
else:
topics.append(f"sigmastar.1.{topic}")
return list(dict.fromkeys(topics))
def _resolve_reader_camera_topics(reader: Any, camera_topic: str) -> list[str]:
candidates = _candidate_camera_topics(camera_topic)
topic_map = getattr(reader, "_topic_map", None)
if isinstance(topic_map, dict):
for candidate in candidates:
if candidate in topic_map:
return [candidate]
for key, values in topic_map.items():
if any(candidate in values for candidate in candidates):
return [key]
return candidates
def _decode_mcap_to_images(
clip_uuid: str,
clip_path: str,
output_dir: Path,
camera_topic: str,
max_frames: int,
) -> tuple[int, Optional[dict[str, Any]], list[dict[str, Any]]]:
from pdcl_pyclip.decoder_struct import StructDecoder
from pdcl_pyclip.msg_camera import VideoMessage
from pdcl_pyclip.reader import ClipReader
output_dir.mkdir(parents=True, exist_ok=True)
reader = ClipReader(clip_path)
struct_decoder = StructDecoder()
saved = 0
camera4_json = None
decode_errors: list[dict[str, Any]] = []
camera_topics = _resolve_reader_camera_topics(reader, camera_topic)
for schema, channel, msg in reader.iter_messages(topics=camera_topics):
if schema.encoding != "struct":
continue
data = struct_decoder.decode(schema, channel, msg)
if not isinstance(data, VideoMessage):
continue
try:
image = _h265_payload_to_bgr(data.payload)
except Exception as exc:
frame_id = getattr(data, "frame_id", None)
error_record = {
"frame_id": None if frame_id is None else str(frame_id),
"error_type": type(exc).__name__,
"error": str(exc),
}
decode_errors.append(error_record)
print(
f"[warn] clip_id={clip_uuid} frame_id={error_record['frame_id']} "
f"-> skip bad frame: {error_record['error_type']}: {error_record['error']}"
)
continue
frame_id_token = _normalize_frame_name_token(getattr(data, "frame_id", None))
timestamp_token = _normalize_frame_name_token(getattr(msg, "log_time", None))
if frame_id_token and timestamp_token:
frame_name = f"{clip_uuid}_{frame_id_token}_{timestamp_token}.png"
elif frame_id_token:
frame_name = f"{clip_uuid}_{frame_id_token}.png"
elif timestamp_token:
frame_name = f"{clip_uuid}_{saved:06d}_{timestamp_token}.png"
else:
frame_name = f"{clip_uuid}_{saved:06d}.png"
if not cv2.imwrite(str(output_dir / frame_name), image):
raise IOError(f"Failed to write image: {output_dir / frame_name}")
saved += 1
if max_frames > 0 and saved >= max_frames:
break
for attachment in reader.iter_attachments():
if attachment.name in CALIB_ATTACHMENT_NAMES:
camera4_json = json.loads(attachment.data.decode("utf-8"))
break
return saved, camera4_json, decode_errors
def _save_decode_errors(output_dir: Path, clip_uuid: str, decode_errors: list[dict[str, Any]]) -> Optional[Path]:
if not decode_errors:
return None
output_dir.mkdir(parents=True, exist_ok=True)
decode_errors_path = output_dir / "decode_errors.json"
payload = {
"clip_uuid": clip_uuid,
"skipped_bad_frame_count": len(decode_errors),
"errors": decode_errors,
}
with open(decode_errors_path, "w", encoding="utf-8") as file:
json.dump(payload, file, indent=2, ensure_ascii=False)
return decode_errors_path
def _save_calib_for_clip(
clip_path: str,
calib_output_path: Path,
calib_file_override: str,
embedded_calib: Optional[dict[str, Any]],
) -> str:
calib_output_path.parent.mkdir(parents=True, exist_ok=True)
if calib_file_override:
calib_src = Path(calib_file_override).resolve()
if not calib_src.exists():
raise FileNotFoundError(f"Calibration file {calib_src} does not exist.")
calib_output_path.write_bytes(calib_src.read_bytes())
return f"override:{calib_src}"
calib_src = _resolve_calib_file_for_clip(clip_path)
if calib_src is not None:
calib_output_path.write_bytes(calib_src.read_bytes())
return f"file:{calib_src}"
if embedded_calib is None:
raise FileNotFoundError(
"Calibration file camera4.json not found near clip and not found in mcap attachments. "
"Please provide --calib-file explicitly."
)
with open(calib_output_path, "w", encoding="utf-8") as file:
json.dump(embedded_calib, file, indent=2, ensure_ascii=False)
return "mcap_attachment"
def _build_calib_summary(calib_payload: Optional[dict[str, Any]]) -> dict[str, Any]:
if not isinstance(calib_payload, dict):
return {
"format": "unknown",
"has_distortion": False,
}
intrinsics = calib_payload
extrinsics = None
calib_format = "flat_camera4"
if "intrinsics" in calib_payload:
intrinsics = calib_payload.get("intrinsics", {}).get("camera4.json", {}) or {}
extrinsics = calib_payload.get("extrinsics", {}).get("camera4.json", {}) or {}
calib_format = "combined_calibration"
distort_coeffs = intrinsics.get("distort_coeffs", calib_payload.get("distort_coeffs", [])) or []
return {
"format": calib_format,
"focal_u": intrinsics.get("focal_u"),
"focal_v": intrinsics.get("focal_v"),
"cu": intrinsics.get("cu"),
"cv": intrinsics.get("cv"),
"pitch": calib_payload.get("pitch", extrinsics.get("rpy", [None, None, None])[1] if extrinsics else None),
"yaw": calib_payload.get("yaw", extrinsics.get("rpy", [None, None, None])[2] if extrinsics else None),
"image_width": calib_payload.get("image_width", calib_payload.get("img_width")),
"image_height": calib_payload.get("image_height", calib_payload.get("img_height")),
"distort_coeff_count": len(distort_coeffs),
"has_distortion": bool(distort_coeffs),
}
def _save_export_manifest(
output_dir: Path,
clip_task: ClipTask,
frame_count: int,
calib_source: str,
camera_topic: str,
calib_summary: Optional[dict[str, Any]] = None,
skipped_bad_frame_count: int = 0,
decode_errors_path: Optional[str] = None,
) -> None:
manifest = {
"clip_uuid": clip_task.clip_uuid,
"date_name": clip_task.date_name,
"vehicle_name": clip_task.vehicle_name,
"clip_path": clip_task.clip_path,
"camera_topic": camera_topic,
"frame_count": frame_count,
"skipped_bad_frame_count": skipped_bad_frame_count,
"calib_source": calib_source,
"calib_summary": calib_summary,
}
if decode_errors_path:
manifest["decode_errors_path"] = decode_errors_path
with open(output_dir / "manifest.json", "w", encoding="utf-8") as file:
json.dump(manifest, file, indent=2, ensure_ascii=False)
def _input_source_label(args: argparse.Namespace) -> str:
return str(getattr(args, "mcap_file", "") or getattr(args, "clip_list_file", ""))
def _input_source_mode(args: argparse.Namespace) -> str:
if getattr(args, "mcap_file", ""):
return "mcap_file"
return "clip_list"
def _save_calib_summary(output_dir: Path, calib_source: str, calib_summary: dict[str, Any]) -> None:
payload = {
"calib_source": calib_source,
"calib_summary": calib_summary,
}
with open(output_dir / "calib_summary.json", "w", encoding="utf-8") as file:
json.dump(payload, file, indent=2, ensure_ascii=False)
def export_one_clip(
clip_task: ClipTask,
args: argparse.Namespace,
status: StatusStore,
) -> TaskResult:
task_id = clip_task.task_id
if args.skip_done and status.is_done(task_id):
info = status.get(task_id) or {}
return TaskResult(task_id=task_id, success=True, message=f"skip done: {info.get('detail', '')}")
case_dir = Path(args.output_root) / build_case_dir_name(args.output_prefix, clip_task)
images_dir = case_dir / "images"
calib_path = case_dir / "calib" / "L2_calib" / "camera4.json"
status.mark_running(task_id, f"running source={clip_task.clip_path}")
try:
frame_count, embedded_calib, decode_errors = _decode_mcap_to_images(
clip_uuid=clip_task.clip_uuid,
clip_path=clip_task.clip_path,
output_dir=images_dir,
camera_topic=args.camera_topic,
max_frames=args.max_frames_per_clip,
)
decode_errors_path = _save_decode_errors(case_dir, clip_task.clip_uuid, decode_errors)
if frame_count <= 0:
if decode_errors:
first_error = decode_errors[0]
raise RuntimeError(
f"Failed to decode any frames; skipped {len(decode_errors)} bad frames. "
f"First error: {first_error['error_type']}: {first_error['error']}. "
f"See {decode_errors_path}"
)
raise RuntimeError(
f"No frames were decoded from clip {clip_task.clip_uuid} on topic "
f"{args.camera_topic!r} (tried: {', '.join(_candidate_camera_topics(args.camera_topic))})."
)
calib_source = _save_calib_for_clip(
clip_path=clip_task.clip_path,
calib_output_path=calib_path,
calib_file_override=args.calib_file,
embedded_calib=embedded_calib,
)
with open(calib_path, "r", encoding="utf-8") as file:
calib_payload = json.load(file)
calib_summary = _build_calib_summary(calib_payload)
_save_export_manifest(
output_dir=case_dir,
clip_task=clip_task,
frame_count=frame_count,
calib_source=calib_source,
camera_topic=args.camera_topic,
calib_summary=calib_summary,
skipped_bad_frame_count=len(decode_errors),
decode_errors_path=str(decode_errors_path) if decode_errors_path else None,
)
_save_calib_summary(case_dir, calib_source=calib_source, calib_summary=calib_summary)
status.mark_done(task_id, str(case_dir))
return TaskResult(
task_id=task_id,
success=True,
message=f"ok frames={frame_count} skipped_bad_frames={len(decode_errors)}",
output_dir=str(case_dir),
)
except Exception as exc:
message = f"{type(exc).__name__}: {exc}"
status.mark_failed(task_id, message)
err_log = Path(args.output_root) / "_status" / "errors.log"
err_log.parent.mkdir(parents=True, exist_ok=True)
with open(err_log, "a", encoding="utf-8") as file:
file.write(f"[{task_id}] {message}\n{traceback.format_exc()}\n")
return TaskResult(task_id=task_id, success=False, message=message)
def save_run_manifest(args: argparse.Namespace, clip_tasks: list[ClipTask]) -> None:
manifest_path = Path(args.output_root) / "_status" / "run_manifest.json"
manifest_path.parent.mkdir(parents=True, exist_ok=True)
payload = {
"source_mode": _input_source_mode(args),
"source": _input_source_label(args),
"clip_list_file": getattr(args, "clip_list_file", ""),
"mcap_file": getattr(args, "mcap_file", ""),
"output_root": args.output_root,
"camera_topic": args.camera_topic,
"max_frames_per_clip": args.max_frames_per_clip,
"num_tasks": len(clip_tasks),
"tasks": [
{
"task_id": task.task_id,
"clip_uuid": task.clip_uuid,
"date_name": task.date_name,
"vehicle_name": task.vehicle_name,
"clip_path": task.clip_path,
}
for task in clip_tasks
],
}
with open(manifest_path, "w", encoding="utf-8") as file:
json.dump(payload, file, indent=2, ensure_ascii=False)
def has_reusable_exported_case(case_dir: Path) -> bool:
images_dir = case_dir / "images"
calib_path = case_dir / "calib" / "L2_calib" / "camera4.json"
if not images_dir.is_dir() or not calib_path.is_file():
return False
return any(path.is_file() for path in images_dir.iterdir())
def save_exported_batch_manifest(args: argparse.Namespace, clip_tasks: list[ClipTask], output_root: Path) -> None:
manifest_path = output_root / "_status" / "run_manifest.json"
manifest_path.parent.mkdir(parents=True, exist_ok=True)
payload = {
"source_mode": _input_source_mode(args),
"source": _input_source_label(args),
"clip_list_file": getattr(args, "clip_list_file", ""),
"mcap_file": getattr(args, "mcap_file", ""),
"export_root": args.export_root,
"output_dir": str(output_root),
"camera_topic": args.camera_topic,
"max_frames_per_clip": args.max_frames_per_clip,
"exported_model": args.exported_model,
"edge_yaw_max_lateral_dist_m": args.edge_yaw_max_lateral_dist,
"roi_models": {
"roi0": args.roi0_model,
"roi1": args.roi1_model,
},
"num_tasks": len(clip_tasks),
"tasks": [
{
"task_id": task.task_id,
"clip_uuid": task.clip_uuid,
"date_name": task.date_name,
"vehicle_name": task.vehicle_name,
"clip_path": task.clip_path,
}
for task in clip_tasks
],
}
with manifest_path.open("w", encoding="utf-8") as file:
json.dump(payload, file, indent=2, ensure_ascii=False)
def run_clip_tasks_inference_exported(
*,
context: Any,
args: argparse.Namespace,
clip_tasks: list[ClipTask],
load_env: Callable[[], Any],
run_case_inference: Callable[..., dict[str, Any]],
export_root: str | Path | None = None,
output_root: str | Path | None = None,
on_before_run: Optional[Callable[[Path, Path, list[ClipTask]], None]] = None,
require_pdcl_auth: bool = True,
) -> dict[str, Any]:
load_env()
if require_pdcl_auth:
validate_pdcl_auth_env()
export_root = Path(args.export_root if export_root is None else export_root).resolve()
output_root = Path(args.output_dir if output_root is None else output_root).resolve()
export_root.mkdir(parents=True, exist_ok=True)
output_root.mkdir(parents=True, exist_ok=True)
args.output_root = str(export_root)
if not clip_tasks:
print("No clip tasks discovered. Exit.")
return {
"source_mode": _input_source_mode(args),
"source": _input_source_label(args),
"clip_list_file": getattr(args, "clip_list_file", ""),
"mcap_file": getattr(args, "mcap_file", ""),
"output_dir": str(output_root),
"total": 0,
"success": 0,
"failed": 0,
}
export_status = StatusStore(export_root / "_status" / "task_status.json")
infer_status = StatusStore(output_root / "_status" / "task_status.json")
if on_before_run is not None:
on_before_run(export_root, output_root, clip_tasks)
save_run_manifest(args, clip_tasks)
save_exported_batch_manifest(args, clip_tasks, output_root)
print(f"Discovered {len(clip_tasks)} clips.")
print(f"Export root: {export_root}")
print(f"Visualization root: {output_root}")
success = 0
fail = 0
for index, clip_task in enumerate(clip_tasks, start=1):
task_id = clip_task.task_id
if args.skip_done and infer_status.is_done(task_id):
info = infer_status.get(task_id) or {}
print(f"[{index}/{len(clip_tasks)}] clip_id={task_id} -> skip done: {info.get('detail', '')}")
continue
print(f"[{index}/{len(clip_tasks)}] clip_id={task_id} source={clip_task.clip_path}")
infer_status.mark_running(task_id, "exporting clip and running exported two-roi inference")
try:
case_dir = export_root / build_case_dir_name(args.output_prefix, clip_task)
if has_reusable_exported_case(case_dir):
export_status.mark_done(task_id, f"reuse existing export: {case_dir}")
print(f" -> reuse exported clip data from {case_dir}")
else:
export_result = export_one_clip(clip_task, args, export_status)
if not export_result.success or not export_result.output_dir:
raise RuntimeError(export_result.message)
case_dir = Path(export_result.output_dir)
infer_result = run_case_inference(
context=context,
case_dir=str(case_dir),
output_dir=output_root / case_dir.name,
glob_pattern=args.glob,
max_images=args.max_images,
save_aggregate_predictions=bool(getattr(args, "save_aggregate_predictions", False)),
save_visualizations=not bool(getattr(args, "skip_visualizations", False)),
)
infer_status.mark_done(task_id, infer_result["output_dir"])
success += 1
print(f" -> saved {infer_result['num_frames']} frames to {infer_result['output_dir']}")
except Exception as exc:
fail += 1
message = f"{type(exc).__name__}: {exc}"
infer_status.mark_failed(task_id, message)
err_log = output_root / "_status" / "errors.log"
err_log.parent.mkdir(parents=True, exist_ok=True)
with err_log.open("a", encoding="utf-8") as file:
file.write(f"[{task_id}] {message}\n{traceback.format_exc()}\n")
print(f" -> failed: {message}")
print("\nBatch inference done.")
print(f"success={success}, fail={fail}")
print(f"infer_status_summary={infer_status.summary()}")
return {
"source_mode": _input_source_mode(args),
"source": _input_source_label(args),
"clip_list_file": getattr(args, "clip_list_file", ""),
"mcap_file": getattr(args, "mcap_file", ""),
"export_root": str(export_root),
"output_dir": str(output_root),
"total": len(clip_tasks),
"success": success,
"failed": fail,
}
def run_clip_list_inference_exported(
*,
context: Any,
args: argparse.Namespace,
load_env: Callable[[], Any],
run_case_inference: Callable[..., dict[str, Any]],
) -> dict[str, Any]:
clip_tasks = parse_clip_list(args.clip_list_file)
if args.limit_clips > 0:
clip_tasks = clip_tasks[: args.limit_clips]
return run_clip_tasks_inference_exported(
context=context,
args=args,
clip_tasks=clip_tasks,
load_env=load_env,
run_case_inference=run_case_inference,
)
def run_mcap_file_inference_exported(
*,
context: Any,
args: argparse.Namespace,
load_env: Callable[[], Any],
run_case_inference: Callable[..., dict[str, Any]],
) -> dict[str, Any]:
clip_task = build_clip_task_from_mcap_file(
args.mcap_file,
clip_id=args.mcap_clip_id,
date_name=args.mcap_date_name,
vehicle_name=args.mcap_vehicle_name,
)
result = run_clip_tasks_inference_exported(
context=context,
args=args,
clip_tasks=[clip_task],
load_env=load_env,
run_case_inference=run_case_inference,
require_pdcl_auth=False,
)
if result.get("failed", 0) > 0 or result.get("success", 0) < result.get("total", 0):
raise RuntimeError(f"MCAP inference failed for {args.mcap_file}")
return result

View File

@@ -0,0 +1,247 @@
from __future__ import annotations
import json
from pathlib import Path
from typing import Any, Iterable, Optional
import cv2
import numpy as np
DEFAULT_CNCAP_PATH_PREFIX_SRC = "/mnt/hfs/project-G1M3"
DEFAULT_CNCAP_PATH_PREFIX_DST = "/mnt/G1M3"
DEFAULT_OUTPUT_RELATIVE_ANCHORS = ("CNCAP2024数采", "gt_org_data")
def rewrite_path_prefix(path_str: str, prefix_src: str, prefix_dst: str) -> str:
normalized_path = str(path_str).strip()
normalized_src = str(prefix_src).rstrip("/")
normalized_dst = str(prefix_dst).rstrip("/")
if normalized_src and normalized_path.startswith(normalized_src):
return f"{normalized_dst}{normalized_path[len(normalized_src):]}"
return normalized_path
def load_path_list_from_json(json_file: str | Path, values_key: str = "values") -> list[str]:
json_path = Path(json_file).resolve()
with json_path.open("r", encoding="utf-8") as file:
payload = json.load(file)
if not isinstance(payload, dict):
raise ValueError(f"Expected top-level dict in {json_path}, got {type(payload).__name__}")
values = payload.get(values_key)
if not isinstance(values, list):
raise ValueError(f"Expected {values_key!r} list in {json_path}, got {type(values).__name__}")
return [str(item).strip() for item in values if str(item).strip()]
def _normalize_video_case_input(video_case_dir: str | Path) -> Path:
input_path = Path(video_case_dir).resolve()
if input_path.is_file() and input_path.name == "camera4.bin":
return input_path.parent.parent
if input_path.is_dir() and input_path.name == "sigmastar.1":
return input_path.parent
return input_path
def build_case_output_rel_dir(
case_dir: str | Path,
preferred_anchor_names: Iterable[str] = DEFAULT_OUTPUT_RELATIVE_ANCHORS,
) -> Path:
resolved_case_dir = Path(case_dir).resolve()
parts = resolved_case_dir.parts
for anchor_name in preferred_anchor_names:
if anchor_name in parts:
anchor_index = parts.index(anchor_name)
suffix_parts = parts[anchor_index + 1 :]
if suffix_parts:
return Path(*suffix_parts)
if len(parts) >= 3:
return Path(*parts[-3:])
if len(parts) >= 2:
return Path(*parts[-2:])
if parts:
return Path(parts[-1])
return Path("case")
def resolve_video_case_paths(video_case_dir: str | Path) -> tuple[Path, Path, Path]:
case_dir = _normalize_video_case_input(video_case_dir)
if not case_dir.is_dir():
raise FileNotFoundError(f"Video case directory not found: {case_dir}")
video_path = case_dir / "sigmastar.1" / "camera4.bin"
if not video_path.is_file():
raise FileNotFoundError(f"camera4.bin not found under {case_dir}")
calib_candidates = [
case_dir / "test_data" / "calibs" / "camera4.json",
case_dir.parent / "test_data" / "calibs" / "camera4.json",
case_dir / "sigmastar.1" / "calibs" / "camera4.json",
case_dir / "calibs" / "camera4.json",
]
calib_path = next((path for path in calib_candidates if path.is_file()), None)
if calib_path is None:
checked = ", ".join(str(path) for path in calib_candidates)
raise FileNotFoundError(f"camera4.json not found for {case_dir}. Checked: {checked}")
return case_dir, video_path, calib_path
def collect_video_case_dirs(video_root_dir: str | Path) -> list[Path]:
root_dir = Path(video_root_dir).resolve()
if not root_dir.is_dir():
raise FileNotFoundError(f"Video root directory not found: {root_dir}")
case_dirs: list[Path] = []
for path in sorted(root_dir.iterdir()):
if not path.is_dir():
continue
try:
resolve_video_case_paths(path)
except FileNotFoundError:
continue
case_dirs.append(path)
if not case_dirs:
raise FileNotFoundError(f"No valid video case directories found under {root_dir}")
return case_dirs
def read_video_frame_index(video_path: str | Path) -> Optional[dict[str, Any]]:
try:
video_path_obj = Path(video_path).resolve()
case_dir = video_path_obj.parent.parent
video_folder = video_path_obj.parent.name
video_file = video_path_obj.stem
index_path = case_dir / "L2" / f"{video_folder}.{video_file}.index.json"
if not index_path.is_file():
return None
with index_path.open("r", encoding="utf-8") as file:
payload = json.load(file)
return payload if isinstance(payload, dict) else None
except Exception:
return None
def get_video_frame_info(frame_index_payload: Optional[dict[str, Any]], frame_idx: int) -> Optional[dict[str, Any]]:
if not frame_index_payload:
return None
try:
fields = frame_index_payload.get("fields", {})
index_list = frame_index_payload.get("index", [])
if not isinstance(fields, dict) or not isinstance(index_list, list) or frame_idx >= len(index_list):
return None
frame_data = index_list[frame_idx]
if not isinstance(frame_data, (list, tuple)):
return None
frame_info = {}
for field_name, field_idx in fields.items():
if isinstance(field_idx, int) and 0 <= field_idx < len(frame_data):
frame_info[str(field_name)] = frame_data[field_idx]
return frame_info
except Exception:
return None
def _normalize_frame_info_token(value: Any) -> str:
token = str(value or "").strip()
if not token or token.lower() == "none":
return ""
return token.replace("/", "_").replace("\\", "_").replace(" ", "")
def _safe_int(value: Any) -> Optional[int]:
try:
if value is None:
return None
return int(str(value).strip())
except (TypeError, ValueError):
return None
def get_video_frame_id(frame_info: Optional[dict[str, Any]]) -> Optional[int]:
if not frame_info:
return None
for key in ("frame_id", "cve_frame_id", "frameId"):
frame_id = _safe_int(frame_info.get(key))
if frame_id is not None:
return frame_id
return None
def iter_video_case_frames(
video_path: str | Path,
*,
frame_index_payload: Optional[dict[str, Any]] = None,
frame_stride: int = 1,
max_frames: int = 0,
frame_index_start: Optional[int] = None,
frame_index_end: Optional[int] = None,
frame_id_start: Optional[int] = None,
frame_id_end: Optional[int] = None,
) -> Iterable[tuple[int, np.ndarray, str, Optional[dict[str, Any]]]]:
resolved_video_path = Path(video_path).resolve()
cap = cv2.VideoCapture(str(resolved_video_path))
if not cap.isOpened():
raise RuntimeError(f"Failed to open video file: {resolved_video_path}")
stride = max(1, int(frame_stride))
resolved_frame_index_start = None if frame_index_start is None else max(0, int(frame_index_start))
resolved_frame_index_end = None if frame_index_end is None else int(frame_index_end)
resolved_frame_id_start = None if frame_id_start is None else int(frame_id_start)
resolved_frame_id_end = None if frame_id_end is None else int(frame_id_end)
read_frame_index = 0
emitted_count = 0
try:
while True:
ret, frame = cap.read()
if not ret:
break
if resolved_frame_index_end is not None and read_frame_index > resolved_frame_index_end:
break
frame_info = get_video_frame_info(frame_index_payload, read_frame_index)
frame_id_value = get_video_frame_id(frame_info)
if resolved_frame_index_start is not None and read_frame_index < resolved_frame_index_start:
read_frame_index += 1
continue
if resolved_frame_id_start is not None:
if frame_id_value is None or frame_id_value < resolved_frame_id_start:
read_frame_index += 1
continue
if resolved_frame_id_end is not None and frame_id_value is not None and frame_id_value > resolved_frame_id_end:
break
if read_frame_index % stride != 0:
read_frame_index += 1
continue
frame_id_token = _normalize_frame_info_token(frame_id_value)
timestamp_token = _normalize_frame_info_token(None if frame_info is None else frame_info.get("timestamp"))
if frame_id_token and timestamp_token:
frame_name = f"{resolved_video_path.stem}_{frame_id_token}_{timestamp_token}.png"
elif frame_id_token:
frame_name = f"{resolved_video_path.stem}_{frame_id_token}.png"
elif timestamp_token:
frame_name = f"{resolved_video_path.stem}_{read_frame_index:06d}_{timestamp_token}.png"
else:
frame_name = f"{resolved_video_path.stem}_{read_frame_index:06d}.png"
yield read_frame_index, frame, frame_name, frame_info
emitted_count += 1
read_frame_index += 1
if max_frames > 0 and emitted_count >= max_frames:
break
finally:
cap.release()

View File

@@ -0,0 +1 @@
"""Core inference modules for the self-contained two-ROI runtime."""

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,346 @@
#!/usr/bin/env python3
"""Download L2 raw packages referenced by scene-grouped event JSON records."""
from __future__ import annotations
import argparse
import json
import os
import re
import shutil
import subprocess
import sys
from dataclasses import dataclass
from datetime import datetime
from pathlib import Path
from typing import Any
try:
from dotenv import load_dotenv
except ImportError:
def load_dotenv(*args: Any, **kwargs: Any) -> bool:
return False
FILE = Path(__file__).resolve()
ROOT = FILE.parents[3]
if str(ROOT) not in sys.path:
sys.path.append(str(ROOT))
from tools.model_inference.adapters.eventid_clip_resolver import ( # noqa: E402
DEFAULT_EVENT_CACHE_FILE,
ResolvedEventRecord,
_extract_condition_values,
_sanitize_identifier_for_path,
_select_event_records_by_condition,
resolve_event_records,
)
TIMESTAMP_RE = re.compile(r"^\d{14}$")
@dataclass
class DownloadResult:
scene: str
record_index: int
rawid: str
rawid_field_used: str
condition_values: dict[str, str]
l2_timestamp: str | None
mdi_key: str | None
source_data_path: str | None
output_dir: str
expected_download_dir: str | None
status: str
detail: str
command: list[str] | None = None
def to_dict(self) -> dict[str, Any]:
return {
"scene": self.scene,
"record_index": self.record_index,
"rawid": self.rawid,
"rawid_field_used": self.rawid_field_used,
"condition_values": self.condition_values,
"l2_timestamp": self.l2_timestamp,
"mdi_key": self.mdi_key,
"source_data_path": self.source_data_path,
"output_dir": self.output_dir,
"expected_download_dir": self.expected_download_dir,
"status": self.status,
"detail": self.detail,
"command": self.command,
}
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Download L2 data packages by resolving rawid metadata from an event JSON file."
)
parser.add_argument("--event-json-file", required=True)
parser.add_argument("--scene", default="")
parser.add_argument("--event-id-field", default="rawid")
parser.add_argument("--event-clip-ids-field", default="clips")
parser.add_argument("--condition-fields", nargs="*", default=[])
parser.add_argument("--max-records-per-condition", type=int, default=0)
parser.add_argument("--condition-select-strategy", default="first")
parser.add_argument("--max-events", type=int, default=0)
parser.add_argument("--event-cache-file", default=str(DEFAULT_EVENT_CACHE_FILE))
parser.add_argument("--event-resolve-workers", type=int, default=4)
parser.add_argument("--event-request-timeout", type=float, default=60.0)
parser.add_argument("--event-request-retries", type=int, default=3)
parser.add_argument("--event-request-retry-backoff-sec", type=float, default=2.0)
parser.add_argument("--output-root", required=True)
parser.add_argument("--manifest-path", default="")
parser.add_argument("--dry-run", action="store_true")
parser.add_argument("--skip-done", action="store_true")
parser.add_argument("--strict", action="store_true")
return parser.parse_args()
def ensure_pdcl_auth_defaults() -> None:
load_dotenv()
os.environ.setdefault("STS_UID", "dis-uploader")
os.environ.setdefault("STS_SECRET_KEY", "277310cc09724d315514a79701fecb0f")
def log_progress(message: str) -> None:
timestamp = datetime.now().astimezone().strftime("%Y-%m-%d %H:%M:%S")
print(f"[download_rawid_l2 {timestamp}] {message}", flush=True)
def extract_l2_timestamp_from_meta(meta: dict[str, Any]) -> tuple[str, str]:
data_info = meta.get("data_info")
if isinstance(data_info, dict):
items = data_info.get("items")
if isinstance(items, list):
for item in items:
if not isinstance(item, dict):
continue
if str(item.get("data_type", "")).strip() != "onboard":
continue
if item.get("available") is False:
continue
data_path = str(item.get("data_path", "")).strip()
timestamp = Path(data_path).stem
if TIMESTAMP_RE.fullmatch(timestamp):
return timestamp, data_path
store_path = str(meta.get("store_path", "")).strip()
timestamp = Path(store_path).stem
if TIMESTAMP_RE.fullmatch(timestamp):
return timestamp, store_path
return "", ""
def load_raw_meta(rawid: str) -> dict[str, Any]:
ensure_pdcl_auth_defaults()
from pdcl_dss import Raw
with Raw(rawid) as raw:
return dict(raw.meta)
def build_output_dir(output_root: Path, record: ResolvedEventRecord) -> Path:
rawid_dir = _sanitize_identifier_for_path(record.event_id, prefix=record.event_id_field_used or "rawid")
return output_root / record.scene / rawid_dir
def write_manifest(
manifest_path: Path,
*,
args: argparse.Namespace,
selected_records: list[ResolvedEventRecord],
selection_summary: dict[str, Any],
results: list[DownloadResult],
) -> None:
manifest_path.parent.mkdir(parents=True, exist_ok=True)
payload = {
"event_json_file": str(Path(args.event_json_file).resolve()),
"scene": args.scene,
"event_id_field": args.event_id_field,
"event_clip_ids_field": args.event_clip_ids_field,
"output_root": str(Path(args.output_root).resolve()),
"dry_run": bool(args.dry_run),
"skip_done": bool(args.skip_done),
"strict": bool(args.strict),
"selected_record_count": len(selected_records),
"selection": selection_summary,
"summary": summarize_results(results),
"results": [result.to_dict() for result in results],
}
manifest_path.write_text(json.dumps(payload, indent=2, ensure_ascii=False), encoding="utf-8")
def summarize_results(results: list[DownloadResult]) -> dict[str, int]:
summary: dict[str, int] = {}
for result in results:
summary[result.status] = summary.get(result.status, 0) + 1
return dict(sorted(summary.items()))
def run_mdi_download(mdi_key: str, output_dir: Path, expected_download_dir: Path, *, dry_run: bool, skip_done: bool) -> tuple[str, str, list[str]]:
command = ["mdi", "raw", "-r", mdi_key, "-s", str(output_dir)]
if skip_done and expected_download_dir.exists():
return "exists", f"target already exists: {expected_download_dir}", command
if dry_run:
return "planned", f"would run {' '.join(command)}", command
output_dir.mkdir(parents=True, exist_ok=True)
if shutil.which("mdi") is None:
return "failed", "mdi command not found in PATH", command
completed = subprocess.run(
command,
check=False,
capture_output=True,
text=True,
encoding="utf-8",
)
if completed.returncode == 0:
return "downloaded", completed.stdout.strip() or "mdi raw completed", command
detail = completed.stderr.strip() or completed.stdout.strip() or "mdi raw failed"
return "failed", detail, command
def download_one_record(
record: ResolvedEventRecord,
*,
output_root: Path,
condition_fields: list[str],
dry_run: bool,
skip_done: bool,
) -> DownloadResult:
rawid = record.event_id
output_dir = build_output_dir(output_root, record)
condition_values = _extract_condition_values(record.source_record, condition_fields)
try:
meta = load_raw_meta(rawid)
l2_timestamp, source_data_path = extract_l2_timestamp_from_meta(meta)
except Exception as exc:
return DownloadResult(
scene=record.scene,
record_index=record.record_index,
rawid=rawid,
rawid_field_used=record.event_id_field_used,
condition_values=condition_values,
l2_timestamp=None,
mdi_key=None,
source_data_path=None,
output_dir=str(output_dir),
expected_download_dir=None,
status="failed_meta",
detail=f"{type(exc).__name__}: {exc}",
)
if not l2_timestamp:
return DownloadResult(
scene=record.scene,
record_index=record.record_index,
rawid=rawid,
rawid_field_used=record.event_id_field_used,
condition_values=condition_values,
l2_timestamp=None,
mdi_key=None,
source_data_path=source_data_path or None,
output_dir=str(output_dir),
expected_download_dir=None,
status="failed_no_l2_timestamp",
detail="no onboard L2 timestamp was found in Raw.meta",
)
mdi_key = f"{rawid}::{l2_timestamp}"
expected_download_dir = output_dir / l2_timestamp
status, detail, command = run_mdi_download(
mdi_key,
output_dir,
expected_download_dir,
dry_run=dry_run,
skip_done=skip_done,
)
return DownloadResult(
scene=record.scene,
record_index=record.record_index,
rawid=rawid,
rawid_field_used=record.event_id_field_used,
condition_values=condition_values,
l2_timestamp=l2_timestamp,
mdi_key=mdi_key,
source_data_path=source_data_path,
output_dir=str(output_dir),
expected_download_dir=str(expected_download_dir),
status=status,
detail=detail,
command=command,
)
def main() -> None:
args = parse_args()
condition_fields = [str(field).strip() for field in args.condition_fields if str(field).strip()]
output_root = Path(args.output_root).resolve()
manifest_path = (
Path(args.manifest_path).resolve()
if args.manifest_path
else output_root / "download_manifest.json"
)
resolved_records, _ = resolve_event_records(
json_file=args.event_json_file,
scene_filter=args.scene or None,
event_id_field=args.event_id_field,
clip_ids_field=args.event_clip_ids_field,
max_events=args.max_events,
timeout=args.event_request_timeout,
cache_file=args.event_cache_file,
workers=args.event_resolve_workers,
max_retries=args.event_request_retries,
retry_backoff_sec=args.event_request_retry_backoff_sec,
)
selected_records, selection_summary = _select_event_records_by_condition(
resolved_records,
condition_fields=condition_fields,
max_records_per_condition=args.max_records_per_condition,
selection_strategy=args.condition_select_strategy,
)
log_progress(
f"selected {len(selected_records)} rawid record(s) from {len(resolved_records)} resolved record(s)"
)
results: list[DownloadResult] = []
for index, record in enumerate(selected_records, start=1):
log_progress(f"[{index}/{len(selected_records)}] {record.scene} {record.event_id}")
result = download_one_record(
record,
output_root=output_root,
condition_fields=condition_fields,
dry_run=args.dry_run,
skip_done=args.skip_done,
)
results.append(result)
log_progress(f" -> {result.status}: {result.mdi_key or result.detail}")
write_manifest(
manifest_path,
args=args,
selected_records=selected_records,
selection_summary=selection_summary,
results=results,
)
summary = summarize_results(results)
log_progress(f"manifest: {manifest_path}")
log_progress("summary: " + ", ".join(f"{key}={value}" for key, value in summary.items()))
if args.strict and any(result.status.startswith("failed") for result in results):
raise SystemExit(1)
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,921 @@
from __future__ import annotations
import math
from typing import Any, Optional
import cv2
import numpy as np
try:
from .two_roi_types import (
Decoded3DPrediction,
DecodedVisibleEdge,
Prediction3DAttrs,
ResizedCalib,
)
except ImportError:
from two_roi_types import (
Decoded3DPrediction,
DecodedVisibleEdge,
Prediction3DAttrs,
ResizedCalib,
)
PROJECTION_Z_MIN = 0.1
YAW_BIN_OFFSETS = (0.0, np.pi / 2, -np.pi / 2, np.pi)
FACE_OFFSETS_41 = (0, 6, 12, 18)
FACE_EDGE_OFFSETS_60 = (0, 15, 30, 45)
FACE_CORNERS = {0: (4, 5, 6, 7), 1: (0, 1, 2, 3), 2: (1, 2, 5, 6), 3: (0, 3, 4, 7)}
FACE_BOTTOM_EDGE_CORNERS = {0: (6, 7), 1: (2, 3), 2: (2, 6), 3: (3, 7)}
FACE_CENTER_OFFSETS = {0: [1, 0.5, 0.5], 1: [0, 0.5, 0.5], 2: [0.5, 0.5, 1], 3: [0.5, 0.5, 0]}
FACE_VISIBILITY_SCORE_THRESH = 0.05
CUT_STATE_NORMAL = 0
CUT_STATE_IN = 1
CUT_STATE_OUT = 2
FACE_COLORS = ((0, 0, 255), (255, 0, 0), (0, 255, 0), (0, 255, 255))
def rotation_3d_in_axis(points, angles, axis=1):
rot_sin = np.sin(angles)
rot_cos = np.cos(angles)
ones = np.ones_like(rot_cos)
zeros = np.zeros_like(rot_cos)
if axis == 1:
rot_mat = np.stack(
[
np.stack([rot_cos, zeros, -rot_sin]),
np.stack([zeros, ones, zeros]),
np.stack([rot_sin, zeros, rot_cos]),
]
)
elif axis == 2:
rot_mat = np.stack(
[
np.stack([rot_cos, rot_sin, zeros]),
np.stack([-rot_sin, rot_cos, zeros]),
np.stack([zeros, zeros, ones]),
]
)
elif axis == 0:
rot_mat = np.stack(
[
np.stack([ones, zeros, zeros]),
np.stack([zeros, rot_cos, rot_sin]),
np.stack([zeros, -rot_sin, rot_cos]),
]
)
else:
raise ValueError(f"axis should be in [0, 1, 2], got {axis}")
return np.dot(points, rot_mat)
def compute_3d_box_corners(center_3d, dimensions, rotation, face_type=-1):
l, h, w = dimensions
corners_norm = np.stack(np.unravel_index(np.arange(8), [2] * 3), axis=1).astype(np.float64)
corners_norm = corners_norm[[0, 1, 3, 2, 4, 5, 7, 6]]
corners_norm -= FACE_CENTER_OFFSETS.get(face_type, [0.5, 0.5, 0.5])
corners = np.array([l, h, w]).reshape(1, 3) * corners_norm.reshape(8, 3)
corners = rotation_3d_in_axis(corners, rotation, axis=1)
corners += np.array(center_3d).reshape(1, 3)
return corners
def apply_fisheye_distortion(x, y, distort_coeffs):
if distort_coeffs is None or len(distort_coeffs) < 4:
return x, y
k1, k2, k3, k4 = distort_coeffs[:4]
r = np.sqrt(x * x + y * y)
if r < 1e-8:
return x, y
theta = np.arctan(r)
theta2 = theta * theta
theta4 = theta2 * theta2
theta6 = theta4 * theta2
theta8 = theta4 * theta4
theta_d = theta * (1 + k1 * theta2 + k2 * theta4 + k3 * theta6 + k4 * theta8)
scale = theta_d / r
return x * scale, y * scale
def remove_fisheye_distortion(xd, yd, distort_coeffs, max_iter=20):
if distort_coeffs is None or len(distort_coeffs) < 4:
return xd, yd
k1, k2, k3, k4 = distort_coeffs[:4]
r_d = np.sqrt(xd * xd + yd * yd)
if r_d < 1e-8:
return xd, yd
theta_d = r_d
theta_d2 = theta_d * theta_d
theta = theta_d / (1 + k1 * theta_d2)
for _ in range(max_iter):
theta2 = theta * theta
theta4 = theta2 * theta2
theta6 = theta4 * theta2
theta8 = theta4 * theta4
f = theta * (1 + k1 * theta2 + k2 * theta4 + k3 * theta6 + k4 * theta8) - theta_d
f_prime = 1 + 3 * k1 * theta2 + 5 * k2 * theta4 + 7 * k3 * theta6 + 9 * k4 * theta8
theta_new = theta - f / f_prime
if abs(theta_new - theta) < 1e-8:
theta = theta_new
break
theta = theta_new
r = np.tan(theta)
scale = r / r_d
return xd * scale, yd * scale
def project_3d_to_2d_with_distortion(points_3d, calib: ResizedCalib):
fx, fy = calib["fx"], calib["fy"]
cx, cy = calib["cx"], calib["cy"]
distort_coeffs = calib.get("distort_coeffs", [])
points_2d = np.full((len(points_3d), 2), np.nan)
for index, (x, y, z) in enumerate(points_3d):
if z > PROJECTION_Z_MIN:
xn, yn = x / z, y / z
xd, yd = apply_fisheye_distortion(xn, yn, distort_coeffs)
points_2d[index] = [fx * xd + cx, fy * yd + cy]
return points_2d
def project_3d_to_2d_with_calib(points_3d, calib: ResizedCalib):
fx, fy = calib["fx"], calib["fy"]
cx, cy = calib["cx"], calib["cy"]
points_2d = np.full((len(points_3d), 2), np.nan)
for index, (x, y, z) in enumerate(points_3d):
if z > PROJECTION_Z_MIN:
points_2d[index] = [fx * x / z + cx, fy * y / z + cy]
return points_2d
def project_3d_to_2d(points_3d, calib: ResizedCalib):
if calib is None:
return np.full((len(points_3d), 2), np.nan)
distort_coeffs = calib.get("distort_coeffs", [])
if distort_coeffs is not None and len(distort_coeffs) >= 4:
return project_3d_to_2d_with_distortion(points_3d, calib)
return project_3d_to_2d_with_calib(points_3d, calib)
def sample_3d_edge(p1, p2, num_samples=10):
t = np.linspace(0.0, 1.0, num_samples, dtype=np.float64).reshape(-1, 1)
return p1 + t * (p2 - p1)
def _point_inside_image(point_2d, img_w, img_h):
x, y = float(point_2d[0]), float(point_2d[1])
return np.isfinite(x) and np.isfinite(y) and 0.0 <= x <= img_w - 1 and 0.0 <= y <= img_h - 1
def _solve_edge_image_boundary_t(p0_2d, p1_2d, img_w, img_h):
p0 = np.asarray(p0_2d, dtype=np.float64)
p1 = np.asarray(p1_2d, dtype=np.float64)
if not np.isfinite(p0).all() or not np.isfinite(p1).all():
return None
dx, dy = p1 - p0
t_min, t_max = 0.0, 1.0
for p, q in ((-dx, p0[0]), (dx, (img_w - 1) - p0[0]), (-dy, p0[1]), (dy, (img_h - 1) - p0[1])):
if abs(p) < 1e-12:
if q < 0:
return None
continue
t = q / p
if p < 0:
t_min = max(t_min, t)
else:
t_max = min(t_max, t)
if t_min > t_max:
return None
return t_min, t_max
def _project_edge_point_at_t(p1, p2, t, calib: ResizedCalib):
point_3d = np.asarray(p1, dtype=np.float64) + float(t) * (np.asarray(p2, dtype=np.float64) - np.asarray(p1, dtype=np.float64))
point_2d = project_3d_to_2d(point_3d[None, :], calib)[0]
return point_3d, point_2d
def _refine_visible_edge_boundary(p1, p2, calib: ResizedCalib, img_w, img_h, t_out, t_in, steps=12):
lo, hi = (float(t_out), float(t_in)) if t_out < t_in else (float(t_in), float(t_out))
for _ in range(steps):
mid = 0.5 * (lo + hi)
_, point_2d = _project_edge_point_at_t(p1, p2, mid, calib)
if _point_inside_image(point_2d, img_w, img_h):
hi = mid
else:
lo = mid
return hi if t_out < t_in else lo
def sample_partial_3d_edge(p1, p2, calib: ResizedCalib, img_w, img_h, num_samples=5, dense_samples=129):
endpoints_3d = np.asarray([p1, p2], dtype=np.float64)
dense_t = np.linspace(0.0, 1.0, dense_samples, dtype=np.float64)
dense_points_3d = endpoints_3d[0:1] + dense_t[:, None] * (endpoints_3d[1:2] - endpoints_3d[0:1])
dense_points_2d = project_3d_to_2d(dense_points_3d, calib)
visible = np.array([_point_inside_image(point_2d, img_w, img_h) for point_2d in dense_points_2d], dtype=bool)
if not visible.any():
return None, None
visible_idx = np.flatnonzero(visible)
split_idx = np.where(np.diff(visible_idx) > 1)[0] + 1
visible_runs = np.split(visible_idx, split_idx)
visible_run = max(visible_runs, key=len)
first_idx, last_idx = int(visible_run[0]), int(visible_run[-1])
t_start = dense_t[first_idx]
if first_idx > 0:
t_start = _refine_visible_edge_boundary(
endpoints_3d[0],
endpoints_3d[1],
calib,
img_w,
img_h,
dense_t[first_idx - 1],
dense_t[first_idx],
)
t_end = dense_t[last_idx]
if last_idx < len(dense_t) - 1:
t_end = _refine_visible_edge_boundary(
endpoints_3d[0],
endpoints_3d[1],
calib,
img_w,
img_h,
dense_t[last_idx + 1],
dense_t[last_idx],
)
if t_end - t_start < 1e-6:
return None, None
sample_t = np.linspace(t_start, t_end, num_samples, dtype=np.float64)
sample_points_3d = endpoints_3d[0:1] + sample_t[:, None] * (endpoints_3d[1:2] - endpoints_3d[0:1])
sample_points_2d = project_3d_to_2d(sample_points_3d, calib)
if np.any(np.isnan(sample_points_2d)):
return None, None
if not np.all([_point_inside_image(point_2d, img_w, img_h) for point_2d in sample_points_2d]):
return None, None
order = np.argsort(sample_points_2d[:, 0], kind="stable")
return sample_points_3d[order], sample_points_2d[order]
def project_3d_box_edges_with_distortion(corners_3d, calib: ResizedCalib, samples_per_edge=10):
edges = {
"back_0": (4, 5),
"back_1": (5, 6),
"back_2": (6, 7),
"back_3": (7, 4),
"connect_0": (0, 4),
"connect_1": (1, 5),
"connect_2": (2, 6),
"connect_3": (3, 7),
"front_0": (0, 1),
"front_1": (1, 2),
"front_2": (2, 3),
"front_3": (3, 0),
"front_x1": (0, 2),
"front_x2": (1, 3),
}
edge_points_2d = {}
for edge_name, (i, j) in edges.items():
sampled_3d = sample_3d_edge(corners_3d[i], corners_3d[j], samples_per_edge)
edge_points_2d[edge_name] = project_3d_to_2d_with_distortion(sampled_3d, calib)
return edge_points_2d
def plot_box3d_on_img_with_distortion(
img,
edge_points_2d,
color_front=(0, 0, 255),
color_back=(255, 0, 0),
color_side=(255, 255, 0),
thickness=1,
):
front_edges = {"front_0", "front_1", "front_2", "front_3", "front_x1", "front_x2"}
back_edges = {"back_0", "back_1", "back_2", "back_3", "back_x1", "back_x2"}
for edge_name, points in edge_points_2d.items():
if np.any(np.isnan(points)):
continue
pts = points.astype(np.int32)
color = color_front if edge_name in front_edges else color_back if edge_name in back_edges else color_side
cv2.polylines(img, [pts], isClosed=False, color=color, thickness=thickness, lineType=cv2.LINE_AA)
return img
def plot_box3d_on_img(img, corners_2d, color_front=(0, 0, 255), color_back=(255, 0, 0), color_side=(255, 255, 0), thickness=1):
line_indices = (
(4, 5),
(5, 6),
(6, 7),
(7, 4),
(0, 4),
(1, 5),
(2, 6),
(3, 7),
(0, 1),
(1, 2),
(2, 3),
(3, 0),
(0, 2),
(1, 3),
)
front_edges = {(0, 1), (1, 2), (2, 3), (3, 0), (0, 2), (1, 3)}
back_edges = {(4, 5), (5, 6), (6, 7), (7, 4)}
pts = corners_2d.astype(np.int32)
for i, j in line_indices:
color = color_front if (i, j) in front_edges else color_back if (i, j) in back_edges else color_side
cv2.line(img, tuple(pts[i]), tuple(pts[j]), color, thickness, cv2.LINE_AA)
return img
def back_project_2d_to_3d(uv, depth, calib: ResizedCalib):
if calib is None or depth <= 0:
return None
fx, fy = calib["fx"], calib["fy"]
cx, cy = calib["cx"], calib["cy"]
u, v = uv
xd = (u - cx) / fx
yd = (v - cy) / fy
distort_coeffs = calib.get("distort_coeffs", [])
if distort_coeffs is not None and len(distort_coeffs) >= 4:
xn, yn = remove_fisheye_distortion(xd, yd, distort_coeffs)
else:
xn, yn = xd, yd
return np.array([xn * depth, yn * depth, depth], dtype=np.float64)
def reconstruct_3d_box_from_face(face_uv, face_z, dims, rot_y, face_type, calib: ResizedCalib):
if calib is None or face_z <= 0:
return None
center_3d = back_project_2d_to_3d(face_uv, face_z, calib)
if center_3d is None:
return None
if np.any(np.isnan(np.asarray(dims, dtype=np.float64))) or not np.isfinite(float(rot_y)):
return None
return compute_3d_box_corners(center_3d, dims, rot_y, face_type)
def reconstruct_3d_box_from_whole(uv, z3d, dims, rot_y, calib: ResizedCalib):
if calib is None or z3d <= 0:
return None
center_3d = back_project_2d_to_3d(uv, z3d, calib)
if center_3d is None:
return None
if np.any(np.isnan(np.asarray(dims, dtype=np.float64))) or not np.isfinite(float(rot_y)):
return None
return compute_3d_box_corners(center_3d, dims, rot_y, face_type=-1)
def get_face_bottom_edge_points(corners_3d, face_type, num_samples=5):
if corners_3d is None or face_type not in FACE_BOTTOM_EDGE_CORNERS:
return None
start_idx, end_idx = FACE_BOTTOM_EDGE_CORNERS[face_type]
return sample_3d_edge(corners_3d[start_idx], corners_3d[end_idx], num_samples=num_samples)
def project_face_bottom_edge(corners_3d, face_type, calib: ResizedCalib, num_samples=5):
points_3d = get_face_bottom_edge_points(corners_3d, face_type, num_samples=num_samples)
if points_3d is None:
return None, None
points_2d = project_3d_to_2d(points_3d, calib)
if np.any(np.isnan(points_2d)):
return points_3d, None
order = np.argsort(points_2d[:, 0], kind="stable")
return points_3d[order], points_2d[order]
def project_partial_face_bottom_edge(corners_3d, face_type, calib: ResizedCalib, img_w, img_h, num_samples=5):
if corners_3d is None or face_type not in FACE_BOTTOM_EDGE_CORNERS:
return None, None
start_idx, end_idx = FACE_BOTTOM_EDGE_CORNERS[face_type]
return sample_partial_3d_edge(corners_3d[start_idx], corners_3d[end_idx], calib, img_w, img_h, num_samples=num_samples)
def collect_face_bottom_edges(corners_3d, face_types, calib: ResizedCalib, num_samples=5):
if corners_3d is None:
return None, None
edge_points_3d, edge_points_2d = [], []
for face_type in face_types:
points_3d, points_2d = project_face_bottom_edge(corners_3d, face_type, calib, num_samples=num_samples)
if points_3d is None or points_2d is None:
continue
edge_points_3d.append(points_3d.astype(np.float32, copy=False))
edge_points_2d.append(points_2d.astype(np.float32, copy=False))
if not edge_points_2d:
return None, None
if len(edge_points_2d) == 1:
return edge_points_3d[0], edge_points_2d[0]
return np.stack(edge_points_3d, axis=0), np.stack(edge_points_2d, axis=0)
def _edge_batches_to_list(edge_points):
if edge_points is None:
return []
arr = np.asarray(edge_points, dtype=np.float32)
if arr.ndim == 2:
return [arr]
return [arr[i] for i in range(arr.shape[0])]
def _stack_edge_batches(edge_batches):
if not edge_batches:
return None
if len(edge_batches) == 1:
return edge_batches[0]
return np.stack(edge_batches, axis=0)
def _append_edge_batch(edge_points_3d, edge_points_2d, decoded_edge: DecodedVisibleEdge):
if decoded_edge.points_3d is None:
return edge_points_3d, edge_points_2d
edge3d_list = _edge_batches_to_list(edge_points_3d)
edge2d_list = _edge_batches_to_list(edge_points_2d)
edge3d_list.append(np.asarray(decoded_edge.points_3d, dtype=np.float32))
edge2d_list.append(np.asarray(decoded_edge.points_2d, dtype=np.float32))
return _stack_edge_batches(edge3d_list), _stack_edge_batches(edge2d_list)
def decode_visible_face_edge_from_prediction(pred_edge_60, face_type, anchor_xy, stride) -> Optional[DecodedVisibleEdge]:
if pred_edge_60 is None or face_type not in range(4):
return None
off = FACE_EDGE_OFFSETS_60[face_type]
face = np.asarray(pred_edge_60[off : off + 15], dtype=np.float32).reshape(5, 3)
points_2d = np.empty((5, 2), dtype=np.float32)
points_2d[:, 0] = (anchor_xy[0] + face[:, 0]) * stride
points_2d[:, 1] = (anchor_xy[1] + face[:, 1]) * stride
order = np.argsort(points_2d[:, 0], kind="stable")
return DecodedVisibleEdge(
face_type=int(face_type),
points_2d=points_2d[order],
depths=face[order, 2].astype(np.float32),
)
def get_cut_side_from_bbox_xyxy(bbox_xyxy, img_w, tol=1.0):
if bbox_xyxy is None:
return None
x1, _, x2, _ = np.asarray(bbox_xyxy, dtype=np.float64)
touch_left = x1 <= tol and x2 > tol
touch_right = x2 >= img_w - 1 - tol and x1 < img_w - 1 - tol
if touch_left == touch_right:
return None
return "left" if touch_left else "right"
def get_cut_object_side_face(face_type_or_state, cut_side=None):
if cut_side not in {"left", "right"}:
return None
if face_type_or_state not in {CUT_STATE_IN, CUT_STATE_OUT}:
return None
return 3 if cut_side == "left" else 2
def get_pred_cut_state(pred_41):
cut_logits = np.asarray(pred_41[38:41], dtype=np.float32)
return int(np.argmax(cut_logits))
def get_pred_cut_primary_face(cut_state):
if cut_state == CUT_STATE_IN:
return 0
if cut_state == CUT_STATE_OUT:
return 1
return None
def _resolve_pred_cut_state_for_decode(pred_41, bbox_xyxy=None, img_w=None):
cut_state = get_pred_cut_state(pred_41)
if cut_state == CUT_STATE_NORMAL:
return cut_state, None
cut_side = None
if bbox_xyxy is not None and img_w is not None:
cut_side = get_cut_side_from_bbox_xyxy(bbox_xyxy, img_w)
if cut_side not in {"left", "right"}:
return CUT_STATE_NORMAL, None
return cut_state, cut_side
def select_pred_visible_faces(pred_41, score_thr=FACE_VISIBILITY_SCORE_THRESH):
selected = []
for face_type, off in enumerate(FACE_OFFSETS_41):
score = float(pred_41[off + 5])
if np.isnan(score) or score < score_thr:
continue
selected.append((face_type, score))
return selected
def _select_best_pred_face_score(pred_41):
best_face_type, best_score = None, float("-inf")
for face_type, off in enumerate(FACE_OFFSETS_41):
score = float(pred_41[off + 5])
if not np.isfinite(score):
continue
if score > best_score:
best_face_type = int(face_type)
best_score = float(score)
if best_face_type is None:
return None
return best_face_type, best_score
def select_pred_visible_faces_for_decode(pred_41, score_thr=FACE_VISIBILITY_SCORE_THRESH, bbox_xyxy=None, img_w=None):
cut_state, _ = _resolve_pred_cut_state_for_decode(pred_41, bbox_xyxy=bbox_xyxy, img_w=img_w)
primary_face = get_pred_cut_primary_face(cut_state)
if primary_face is not None:
off = FACE_OFFSETS_41[primary_face]
return [(primary_face, float(pred_41[off + 5]))]
visible_faces = list(select_pred_visible_faces(pred_41, score_thr=score_thr))
best_face = _select_best_pred_face_score(pred_41)
if best_face is None:
return visible_faces
best_face_type, best_score = best_face
if all(int(face_type) != int(best_face_type) for face_type, _ in visible_faces):
visible_faces.append((int(best_face_type), float(best_score)))
return visible_faces
def decode_cut_partial_side_edge_from_prediction(pred_41, pred_edge_60, anchor_xy, stride, img_w, cut_side=None) -> Optional[DecodedVisibleEdge]:
if pred_edge_60 is None:
return None
cut_state = get_pred_cut_state(pred_41)
if cut_state == CUT_STATE_NORMAL:
return None
side_face_type = get_cut_object_side_face(cut_state, cut_side)
if side_face_type is None:
return None
return decode_visible_face_edge_from_prediction(pred_edge_60, side_face_type, anchor_xy, stride)
def _decoded_edge_to_points_3d(decoded_edge: Optional[DecodedVisibleEdge], calib: ResizedCalib) -> Optional[np.ndarray]:
if decoded_edge is None:
return None
points = [back_project_2d_to_3d(tuple(pt), depth, calib) for pt, depth in zip(decoded_edge.points_2d, decoded_edge.depths)]
if any(point is None for point in points):
return None
return np.asarray(points, dtype=np.float32)
def edge_points_to_yaw(points_3d, face_type):
points = np.asarray(points_3d, dtype=np.float32)
if points.shape[0] < 2:
return float("nan")
direction = points[-1] - points[0]
yaw = math.atan2(float(direction[0]), float(direction[2]))
if face_type == 0:
return yaw
if face_type == 1:
return yaw + np.pi
if face_type == 2:
return yaw + np.pi / 2
if face_type == 3:
return yaw - np.pi / 2
return float("nan")
def visible_face_edges_to_yaw(face_edges_3d, face_scores=None):
if not face_edges_3d:
return float("nan")
if face_scores:
face_type = max(face_edges_3d.keys(), key=lambda ft: face_scores.get(ft, 0.0))
return edge_points_to_yaw(face_edges_3d[face_type], face_type)
face_type = next(iter(face_edges_3d))
return edge_points_to_yaw(face_edges_3d[face_type], face_type)
def _draw_edge_points(img, edge_points_2d=None, edge_color=(0, 255, 0), thickness=1):
if edge_points_2d is None:
return
points = np.asarray(edge_points_2d, dtype=np.float32)
if points.ndim == 2:
points = points[None, ...]
for batch in points:
for point in batch:
cv2.circle(img, tuple(np.round(point).astype(np.int32)), max(thickness + 1, 2), edge_color, -1, cv2.LINE_AA)
def _decode_yaw_from_prediction(pred_41):
yaw_cls_logits = pred_41[30:34]
yaw_residual_sin = np.clip(pred_41[34:38], -1.0, 1.0)
best_bin = int(np.argmax(yaw_cls_logits))
return np.arcsin(yaw_residual_sin[best_bin]) + YAW_BIN_OFFSETS[best_bin]
def decode_3d_prediction(
pred_41,
anchor_xy,
stride,
calib,
img_w,
img_h,
face_3d_classes,
complete_3d_classes,
cls_id,
pred_edge_60=None,
score_thr=FACE_VISIBILITY_SCORE_THRESH,
bbox_xyxy=None,
) -> Optional[Decoded3DPrediction]:
pred = pred_41
rot_y = _decode_yaw_from_prediction(pred)
z_whole = pred[24]
uv_whole_offset = pred[25:27]
dims_whole = pred[27:30]
u_whole = (anchor_xy[0] + uv_whole_offset[0]) * stride
v_whole = (anchor_xy[1] + uv_whole_offset[1]) * stride
if cls_id in face_3d_classes:
_, cut_side = _resolve_pred_cut_state_for_decode(pred, bbox_xyxy=bbox_xyxy, img_w=img_w)
visible_faces = select_pred_visible_faces_for_decode(pred, score_thr=score_thr, bbox_xyxy=bbox_xyxy, img_w=img_w)
best_type, _ = (-1, -1.0) if not visible_faces else max(visible_faces, key=lambda item: item[1])
if best_type < 0:
return None
off = best_type * 6
z_face = pred[off]
uv_face_offset = pred[off + 1 : off + 3]
u_face = (anchor_xy[0] + uv_face_offset[0]) * stride
v_face = (anchor_xy[1] + uv_face_offset[1]) * stride
corners = reconstruct_3d_box_from_face((u_face, v_face), z_face, dims_whole, rot_y, best_type, calib)
if corners is None:
return None
edge_points_3d, edge_points_2d = collect_face_bottom_edges(
corners,
[face_type for face_type, _ in visible_faces],
calib,
num_samples=5,
)
if pred_edge_60 is not None:
pred_edge_points_2d, pred_edge_points_3d = [], []
for face_type, _ in visible_faces:
pred_edge = decode_visible_face_edge_from_prediction(pred_edge_60, face_type, anchor_xy, stride)
if pred_edge is None:
continue
points_3d = [back_project_2d_to_3d(tuple(pt), depth, calib) for pt, depth in zip(pred_edge.points_2d, pred_edge.depths)]
if any(point is None for point in points_3d):
continue
pred_edge_points_2d.append(pred_edge.points_2d.astype(np.float32, copy=False))
pred_edge_points_3d.append(np.asarray(points_3d, dtype=np.float32))
if pred_edge_points_2d:
edge_points_2d = _stack_edge_batches(pred_edge_points_2d)
edge_points_3d = _stack_edge_batches(pred_edge_points_3d)
partial_edge = decode_cut_partial_side_edge_from_prediction(
pred,
pred_edge_60,
anchor_xy,
stride,
img_w,
cut_side=cut_side,
)
if partial_edge is not None:
partial_points_3d = [back_project_2d_to_3d(tuple(pt), depth, calib) for pt, depth in zip(partial_edge.points_2d, partial_edge.depths)]
if all(point is not None for point in partial_points_3d):
partial_edge.points_3d = np.asarray(partial_points_3d, dtype=np.float32)
visible_face_types = {face_type for face_type, _ in visible_faces}
if partial_edge.face_type not in visible_face_types:
edge_points_3d, edge_points_2d = _append_edge_batch(edge_points_3d, edge_points_2d, partial_edge)
visible_faces = [*visible_faces, (partial_edge.face_type, 1.0)]
return Decoded3DPrediction(
corners_3d=np.asarray(corners, dtype=np.float32),
face_center_2d=(u_face, v_face),
face_color=FACE_COLORS[best_type],
visible_face_type=best_type,
visible_face_types=tuple(face_type for face_type, _ in visible_faces),
edge_points_2d=None if edge_points_2d is None else np.asarray(edge_points_2d, dtype=np.float32),
edge_points_3d=None if edge_points_3d is None else np.asarray(edge_points_3d, dtype=np.float32),
cls_id=cls_id,
)
if cls_id in complete_3d_classes:
corners = reconstruct_3d_box_from_whole((u_whole, v_whole), z_whole, dims_whole, rot_y, calib)
if corners is None:
return None
return Decoded3DPrediction(
corners_3d=np.asarray(corners, dtype=np.float32),
face_center_2d=None,
face_color=None,
visible_face_type=None,
visible_face_types=(),
edge_points_2d=None,
edge_points_3d=None,
cls_id=cls_id,
)
return None
def draw_3d_box(img, corners_3d, calib: ResizedCalib, face_center_2d=None, face_color=None, edge_points_2d=None, edge_color=(0, 255, 0), thickness=1):
corners_3d = corners_3d[[4, 5, 6, 7, 0, 1, 2, 3]]
color_front = (0, 0, 255)
color_back = (255, 0, 0)
color_side = (255, 255, 0)
distort_coeffs = calib.get("distort_coeffs", []) if calib is not None else []
if distort_coeffs is not None and len(distort_coeffs) >= 4:
edge_points_2d_box = project_3d_box_edges_with_distortion(corners_3d, calib, samples_per_edge=15)
plot_box3d_on_img_with_distortion(
img,
edge_points_2d_box,
color_front=color_front,
color_back=color_back,
color_side=color_side,
thickness=thickness,
)
else:
corners_2d = project_3d_to_2d(corners_3d, calib)
if np.any(np.isnan(corners_2d)):
return img
plot_box3d_on_img(
img,
corners_2d,
color_front=color_front,
color_back=color_back,
color_side=color_side,
thickness=thickness,
)
if face_center_2d is not None and face_color is not None:
cv2.circle(img, (int(face_center_2d[0]), int(face_center_2d[1])), 2, face_color, -1, cv2.LINE_AA)
_draw_edge_points(img, edge_points_2d=edge_points_2d, edge_color=edge_color, thickness=thickness)
return img
def decode_visible_face_yaw_from_prediction(pred_41, pred_edge_60, anchor_xy, stride, face_type, calib: ResizedCalib):
if pred_edge_60 is None or face_type not in range(4):
return float("nan")
decoded = decode_visible_face_edge_from_prediction(pred_edge_60, face_type, anchor_xy, stride)
points_3d = _decoded_edge_to_points_3d(decoded, calib)
if points_3d is None:
return float("nan")
return edge_points_to_yaw(points_3d, face_type)
def decode_multi_visible_face_yaw_from_prediction(
pred_41,
pred_edge_60,
anchor_xy,
stride,
calib,
fallback_face_type=None,
score_thr=FACE_VISIBILITY_SCORE_THRESH,
bbox_xyxy=None,
img_w=None,
):
if pred_edge_60 is None:
if fallback_face_type in range(4):
return decode_visible_face_yaw_from_prediction(pred_41, pred_edge_60, anchor_xy, stride, fallback_face_type, calib)
return float("nan")
inferred_img_w = float(img_w) if img_w is not None else None
if inferred_img_w is None:
if bbox_xyxy is not None:
inferred_img_w = max(float(np.asarray(bbox_xyxy, dtype=np.float64)[2]), 1.0)
else:
inferred_img_w = max(float((anchor_xy[0] + pred_41[25]) * stride) * 2.0, 1.0)
cut_state, cut_side = _resolve_pred_cut_state_for_decode(pred_41, bbox_xyxy=bbox_xyxy, img_w=inferred_img_w)
face_edges_3d, face_scores = {}, {}
for face_type, score in select_pred_visible_faces_for_decode(pred_41, score_thr=score_thr, bbox_xyxy=bbox_xyxy, img_w=inferred_img_w):
decoded = decode_visible_face_edge_from_prediction(pred_edge_60, face_type, anchor_xy, stride)
points_3d = _decoded_edge_to_points_3d(decoded, calib)
if points_3d is None:
continue
face_edges_3d[face_type] = points_3d
face_scores[face_type] = float(score)
partial_edge = decode_cut_partial_side_edge_from_prediction(
pred_41,
pred_edge_60,
anchor_xy,
stride,
img_w=inferred_img_w,
cut_side=cut_side,
)
partial_points_3d = _decoded_edge_to_points_3d(partial_edge, calib)
if cut_state != CUT_STATE_NORMAL:
if partial_edge is not None and partial_points_3d is not None:
return edge_points_to_yaw(partial_points_3d, int(partial_edge.face_type))
return float("nan")
if any(face_type in (2, 3) for face_type in face_edges_3d):
side_face_type = max(
(face_type for face_type in face_edges_3d if face_type in (2, 3)),
key=lambda face_type: face_scores.get(face_type, 0.0),
)
return edge_points_to_yaw(face_edges_3d[side_face_type], side_face_type)
if partial_points_3d is not None:
face_edges_3d[partial_edge.face_type] = partial_points_3d
face_scores[partial_edge.face_type] = max(face_scores.get(partial_edge.face_type, 0.0), 1.0)
if len(face_edges_3d) >= 2:
yaw = visible_face_edges_to_yaw(face_edges_3d, face_scores=face_scores)
if np.isfinite(yaw):
return yaw
if fallback_face_type in range(4):
return decode_visible_face_yaw_from_prediction(pred_41, pred_edge_60, anchor_xy, stride, fallback_face_type, calib)
return visible_face_edges_to_yaw(face_edges_3d, face_scores=face_scores)
def _back_project_metric_point(u, v, z, calib: ResizedCalib) -> np.ndarray:
if calib is not None and z > 0:
center_3d = back_project_2d_to_3d((u, v), z, calib)
if center_3d is None:
x3d, y3d = float("nan"), float("nan")
else:
x3d, y3d = center_3d[0], center_3d[1]
else:
x3d, y3d = float("nan"), float("nan")
return np.array([x3d, y3d, z], dtype=np.float32)
def extract_3d_attrs_from_prediction(
pred_41,
anchor_xy,
stride,
calib: ResizedCalib,
face_type=None,
pred_edge_60=None,
) -> Optional[Prediction3DAttrs]:
pred = pred_41
rot_y = _decode_yaw_from_prediction(pred)
dims = pred[27:30].astype(np.float32)
if face_type is None:
z = float(pred[24])
uv_offset = pred[25:27]
edge_yaw = float("nan")
else:
off = FACE_OFFSETS_41[face_type]
z = float(pred[off])
uv_offset = pred[off + 1 : off + 3]
edge_yaw = decode_multi_visible_face_yaw_from_prediction(
pred,
pred_edge_60,
anchor_xy,
stride,
calib,
fallback_face_type=face_type,
)
u = float((anchor_xy[0] + uv_offset[0]) * stride)
v = float((anchor_xy[1] + uv_offset[1]) * stride)
center = _back_project_metric_point(u, v, z, calib)
return Prediction3DAttrs(
center=center,
depth=z,
dims=dims,
yaw=float(rot_y),
edge_yaw=float(edge_yaw),
uv=np.array([u, v], dtype=np.float32),
visible_face_type=None if face_type is None else int(face_type),
face_center=None if face_type is None else center,
)
def face_center_from_corners(corners_3d, face_type):
if corners_3d is None or face_type not in FACE_CORNERS:
return None
corners = np.asarray(corners_3d, dtype=np.float32)
if corners.shape != (8, 3) or not np.isfinite(corners).all():
return None
return corners[list(FACE_CORNERS[face_type])].mean(axis=0)
def rebuild_box_corners_for_visualization(
corners_3d,
dims,
yaw,
visible_face_type=None,
face_center_3d=None,
box_center_3d=None,
):
dims_arr = np.asarray(dims, dtype=np.float32)
if dims_arr.shape != (3,) or not np.isfinite(dims_arr).all() or not np.isfinite(float(yaw)):
return None
if visible_face_type is not None:
if face_center_3d is None:
face_center_3d = face_center_from_corners(corners_3d, int(visible_face_type))
else:
face_center_3d = np.asarray(face_center_3d, dtype=np.float32)
if face_center_3d is None or face_center_3d.shape != (3,) or not np.isfinite(face_center_3d).all():
return None
return compute_3d_box_corners(face_center_3d, dims_arr, float(yaw), face_type=int(visible_face_type))
if box_center_3d is not None:
box_center_3d = np.asarray(box_center_3d, dtype=np.float32)
if box_center_3d.shape != (3,) or not np.isfinite(box_center_3d).all():
return None
return compute_3d_box_corners(box_center_3d, dims_arr, float(yaw), face_type=-1)
corners = np.asarray(corners_3d, dtype=np.float32)
if corners.shape != (8, 3) or not np.isfinite(corners).all():
return None
return compute_3d_box_corners(corners.mean(axis=0), dims_arr, float(yaw), face_type=-1)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Optional, TypedDict
import numpy as np
ColorBGR = tuple[int, int, int]
ImagePoint2D = tuple[float, float]
class RawCameraCalib(TypedDict, total=False):
focal_u: float
focal_v: float
cu: float
cv: float
roll: float
pitch: float
yaw: float
pos: list[float]
distort_coeffs: list[float]
image_width: Any
image_height: Any
source_format: str
angle_unit: str
class ROICropCalib(TypedDict):
focal_u: float
focal_v: float
cu: float
cv: float
src_w: int
src_h: int
distort_coeffs: list[float]
class ResizedCalib(TypedDict):
fx: float
fy: float
cx: float
cy: float
distort_coeffs: list[float]
depth_scale: float
@dataclass
class DecodedVisibleEdge:
face_type: int
points_2d: np.ndarray
depths: np.ndarray
points_3d: Optional[np.ndarray] = None
@dataclass
class Decoded3DPrediction:
corners_3d: np.ndarray
face_center_2d: Optional[ImagePoint2D]
face_color: Optional[ColorBGR]
visible_face_type: Optional[int]
visible_face_types: tuple[int, ...]
edge_points_2d: Optional[np.ndarray]
edge_points_3d: Optional[np.ndarray]
cls_id: int
@dataclass
class Prediction3DAttrs:
center: np.ndarray
depth: float
dims: np.ndarray
yaw: float
edge_yaw: float
uv: np.ndarray
visible_face_type: Optional[int]
face_center: Optional[np.ndarray]
class SerializedPredictionRecord(TypedDict, total=False):
bbox_xyxy: Any
confidence: float
cls_id: int
cls_name: str
difficulty_logit: Optional[float]
difficulty_prob: Optional[float]
difficulty_label: Optional[int]
difficulty_name: Optional[str]
edge_head_available: bool
xyzlhwyaw: Any
xyzlhwyaw_ego: Any
box_center_xyz: Any
box_center_xyz_ego: Any
depth_m: Optional[float]
box_depth_m: Optional[float]
lateral_distance_m: Optional[float]
euclidean_distance_m: Optional[float]
xz_distance_m: Optional[float]
attribute: Any
yaw_rad: Optional[float]
edge_yaw_rad: Optional[float]
edge_yaw_confident: bool
edge_yaw_lateral_distance_m: Optional[float]
edge_yaw_lateral_ok: bool
edge_yaw_two_face_eligible: bool
edge_yaw_selected_face_types: Any
edge_yaw_selected_face_is_partial: Any
edge_vs_reg_yaw_rad: Optional[float]
selected_edge_direct_box_fit_available: bool
selected_edge_direct_box_fit_mean_px: Optional[float]
selected_edge_direct_box_fit_max_px: Optional[float]
selected_edge_direct_box_fit_per_face_mean_px: Any
selected_edge_edgeyaw_box_fit_available: bool
selected_edge_edgeyaw_box_fit_mean_px: Optional[float]
selected_edge_edgeyaw_box_fit_max_px: Optional[float]
selected_edge_edgeyaw_box_fit_per_face_mean_px: Any
selected_edge_fit_gain_px: Optional[float]
edge_box_center_3d: Any
edge_box_dims: Any
edge_box_length_m: Optional[float]
edge_box_width_m: Optional[float]
edge_box_mode: Optional[str]
edge_box_length_source: Optional[str]
edge_box_width_source: Optional[str]
all_edge_predictions: Any
edge_selection: Any
center_uv: Any
center_3d: Any
dims: Any
cut_cls: Optional[int]
roi_id: Optional[int]
visible_face_type: Any
visible_face_count: int
visible_face_types: Any
crop_bounds: list[int]
original_bbox_xyxy: Any
class SerializedROIPayload(TypedDict):
crop_bounds: list[int]
vp_x: float
vp_y: float
crop_center_x: float
crop_center_y: float
edge_head_available: bool
edge_yaw_max_lateral_dist_m: float
calib: dict[str, Any]
predictions: list[SerializedPredictionRecord]
class SerializedMergedPayload(TypedDict, total=False):
method: str
edge_head_available: bool
roi_bounds: dict[str, list[int]]
predictions: list[SerializedPredictionRecord]
visualization: str
class SerializedFramePayload(TypedDict, total=False):
frame_index: int
frame_name: str
rois: dict[str, SerializedROIPayload]
merged: SerializedMergedPayload
merged_vru: SerializedMergedPayload
visualization: str
class SerializedPredictionsPayload(TypedDict):
case_name: str
images_dir: str
calib_file: str
exported_model_path: str
edge_head_available: bool
edge_yaw_max_lateral_dist_m: float
frames: list[SerializedFramePayload]

View File

@@ -0,0 +1 @@
"""Small data-preparation helpers for model_inference."""

View File

@@ -0,0 +1,234 @@
from __future__ import annotations
import argparse
import csv
import json
import re
import sys
from pathlib import Path
try:
from openpyxl import load_workbook
except ImportError:
load_workbook = None
FILE = Path(__file__).resolve()
DEFAULT_INPUT_FILE = FILE.parents[1] / "examples" / "cncap" / "G1M3_AFS1616_CNCAP-2024_11月_0306.xlsx"
DEFAULT_COLUMN_NAME = "原始数据地址"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Extract one column from a CSV/XLSX table and print or save the values."
)
parser.add_argument(
"--input-file",
type=str,
default=str(DEFAULT_INPUT_FILE),
help="Path to the input .xlsx or .csv file.",
)
parser.add_argument(
"--column-name",
type=str,
default=DEFAULT_COLUMN_NAME,
help="Header name of the target column.",
)
parser.add_argument(
"--sheet-name",
type=str,
default="",
help="Worksheet name for .xlsx files. Defaults to the first sheet.",
)
parser.add_argument(
"--output-file",
type=str,
default="",
help="Optional output text file. If omitted, values are written to stdout.",
)
parser.add_argument(
"--json-file",
type=str,
default="",
help="Optional output json file. Defaults to a sibling json file next to the input table.",
)
parser.add_argument(
"--dedupe",
action="store_true",
help="Remove duplicate values while preserving the original order.",
)
parser.add_argument(
"--list-columns",
action="store_true",
help="List the discovered header names and exit.",
)
return parser.parse_args()
def normalize_header(value: str) -> str:
return re.sub(r"\s+", "", str(value or "")).strip()
def sanitize_filename(value: str) -> str:
sanitized = re.sub(r'[\\/:*?"<>|]+', "_", str(value or "").strip())
sanitized = re.sub(r"\s+", "_", sanitized)
return sanitized.strip("._") or "column"
def build_default_json_path(input_path: Path, column_name: str) -> Path:
return input_path.with_name(f"{input_path.stem}_{sanitize_filename(column_name)}.json")
def load_xlsx_table(path: Path, sheet_name: str) -> tuple[list[str], list[dict[str, str]], str]:
if load_workbook is None:
raise ImportError("openpyxl is required for .xlsx files. Please install it first.")
workbook = load_workbook(path, read_only=True, data_only=True)
try:
if sheet_name:
if sheet_name not in workbook.sheetnames:
available = ", ".join(workbook.sheetnames)
raise ValueError(f"Worksheet {sheet_name!r} not found. Available sheets: {available}")
worksheet = workbook[sheet_name]
else:
worksheet = workbook[workbook.sheetnames[0]]
header_row_values: list[str] | None = None
header_indices: list[int] = []
records: list[dict[str, str]] = []
for row in worksheet.iter_rows(values_only=True):
normalized_row = [str(value).strip() if value is not None else "" for value in row]
if not any(normalized_row):
continue
if header_row_values is None:
header_indices = [index for index, value in enumerate(normalized_row) if value]
header_row_values = [normalized_row[index] for index in header_indices]
continue
record = {
header_row_values[index]: normalized_row[col_idx] if col_idx < len(normalized_row) else ""
for index, col_idx in enumerate(header_indices)
}
if any(record.values()):
records.append(record)
if header_row_values is None:
raise ValueError("The worksheet is empty.")
return header_row_values, records, worksheet.title
finally:
workbook.close()
def load_csv_table(path: Path) -> tuple[list[str], list[dict[str, str]], str]:
with path.open("r", encoding="utf-8-sig", newline="") as file:
sample = file.read(4096)
file.seek(0)
dialect = csv.Sniffer().sniff(sample) if sample.strip() else csv.excel
reader = csv.DictReader(file, dialect=dialect)
headers = reader.fieldnames or []
records = []
for row in reader:
normalized_row = {str(key).strip(): str(value or "").strip() for key, value in row.items() if key is not None}
if any(normalized_row.values()):
records.append(normalized_row)
return [str(header).strip() for header in headers], records, ""
def load_table(path: Path, sheet_name: str) -> tuple[list[str], list[dict[str, str]], str]:
suffix = path.suffix.lower()
if suffix == ".xlsx":
return load_xlsx_table(path, sheet_name)
if suffix == ".csv":
return load_csv_table(path)
raise ValueError(f"Unsupported input format: {suffix}. Only .xlsx and .csv are supported.")
def extract_column(records: list[dict[str, str]], column_name: str, dedupe: bool) -> list[str]:
if not records:
return []
normalized_to_actual = {normalize_header(name): name for name in records[0].keys()}
target_key = normalized_to_actual.get(normalize_header(column_name))
if target_key is None:
available = ", ".join(records[0].keys())
raise ValueError(f"Column {column_name!r} not found. Available columns: {available}")
values = [record.get(target_key, "").strip() for record in records]
values = [value for value in values if value]
if not dedupe:
return values
deduped_values: list[str] = []
seen: set[str] = set()
for value in values:
if value in seen:
continue
seen.add(value)
deduped_values.append(value)
return deduped_values
def write_output(values: list[str], output_file: str) -> None:
content = "\n".join(values)
if output_file:
output_path = Path(output_file)
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(content + ("\n" if values else ""), encoding="utf-8")
print(f"Saved {len(values)} rows to {output_path}", file=sys.stderr)
return
if content:
sys.stdout.write(content)
sys.stdout.write("\n")
def write_json_output(
input_path: Path,
resolved_sheet_name: str,
column_name: str,
values: list[str],
json_file: str,
) -> Path:
json_path = Path(json_file) if json_file else build_default_json_path(input_path, column_name)
json_path.parent.mkdir(parents=True, exist_ok=True)
payload = {
"input_file": str(input_path),
"sheet_name": resolved_sheet_name,
"column_name": column_name,
"num_rows": len(values),
"values": values,
}
json_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
print(f"Saved json to {json_path}", file=sys.stderr)
return json_path
def main() -> int:
args = parse_args()
input_path = Path(args.input_file)
if not input_path.is_file():
raise FileNotFoundError(f"Input file not found: {input_path}")
headers, records, resolved_sheet_name = load_table(input_path, args.sheet_name)
if args.list_columns:
for header in headers:
print(header)
return 0
values = extract_column(records, args.column_name, args.dedupe)
write_output(values, args.output_file)
json_path = write_json_output(input_path, resolved_sheet_name, args.column_name, values, args.json_file)
sheet_info = f", sheet={resolved_sheet_name}" if resolved_sheet_name else ""
print(
f"Extracted {len(values)} rows from column {args.column_name!r} in {input_path}{sheet_info}, json={json_path}",
file=sys.stderr,
)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,131 @@
from __future__ import annotations
import argparse
import csv
import json
import sys
from collections import OrderedDict
from pathlib import Path
FILE = Path(__file__).resolve()
DEFAULT_INPUT_FILE = FILE.parents[1] / "examples" / "events" / "G1Q3_场地评测数据集.csv"
DEFAULT_SCENE_COLUMN = "scene"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Parse a CSV table and save a scene-keyed JSON file."
)
parser.add_argument(
"--input-file",
type=str,
default=str(DEFAULT_INPUT_FILE),
help="Path to the input CSV file.",
)
parser.add_argument(
"--scene-column",
type=str,
default=DEFAULT_SCENE_COLUMN,
help="Column name used as the top-level JSON key.",
)
parser.add_argument(
"--output-file",
type=str,
default="",
help="Optional output JSON path. Defaults to a sibling .json file next to the CSV.",
)
parser.add_argument(
"--keep-scene-field",
action="store_true",
help="Keep the scene column inside each grouped record.",
)
return parser.parse_args()
def normalize_row(row: dict[str, str | None]) -> dict[str, str]:
return {str(key).strip(): str(value or "").strip() for key, value in row.items() if key is not None}
def resolve_output_path(input_path: Path, output_file: str) -> Path:
if output_file:
return Path(output_file)
return input_path.with_suffix(".json")
def load_csv_rows(path: Path) -> tuple[list[str], list[dict[str, str]]]:
with path.open("r", encoding="utf-8-sig", newline="") as file:
sample = file.read(4096)
file.seek(0)
dialect = csv.Sniffer().sniff(sample) if sample.strip() else csv.excel
reader = csv.DictReader(file, dialect=dialect)
headers = [str(header).strip() for header in (reader.fieldnames or [])]
rows: list[dict[str, str]] = []
for row in reader:
normalized = normalize_row(row)
if any(normalized.values()):
rows.append(normalized)
return headers, rows
def group_rows_by_scene(
rows: list[dict[str, str]],
scene_column: str,
keep_scene_field: bool,
) -> OrderedDict[str, list[dict[str, str]]]:
grouped: OrderedDict[str, list[dict[str, str]]] = OrderedDict()
missing_scene_rows = 0
for row in rows:
scene_value = row.get(scene_column, "").strip()
if not scene_value:
missing_scene_rows += 1
continue
payload = dict(row)
if not keep_scene_field:
payload.pop(scene_column, None)
grouped.setdefault(scene_value, []).append(payload)
if missing_scene_rows > 0:
print(
f"Skipped {missing_scene_rows} rows because column {scene_column!r} was empty.",
file=sys.stderr,
)
return grouped
def save_grouped_json(grouped: OrderedDict[str, list[dict[str, str]]], output_path: Path) -> None:
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(
json.dumps(grouped, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
def main() -> int:
args = parse_args()
input_path = Path(args.input_file)
if not input_path.is_file():
raise FileNotFoundError(f"Input file not found: {input_path}")
headers, rows = load_csv_rows(input_path)
if args.scene_column not in headers:
available = ", ".join(headers)
raise ValueError(f"Column {args.scene_column!r} not found. Available columns: {available}")
grouped = group_rows_by_scene(rows, args.scene_column, args.keep_scene_field)
output_path = resolve_output_path(input_path, args.output_file)
save_grouped_json(grouped, output_path)
print(
f"Saved {len(rows)} rows across {len(grouped)} scenes to {output_path}",
file=sys.stderr,
)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,48 @@
{
"0": {
"type": "0",
"type_name": "truck",
"score": "0.9664586186408997",
"roi_id": "0",
"box2d": [
"1357.25390625",
"542.76123046875",
"1743.7847290039062",
"803.9830627441406"
],
"xyzlhwyaw": [
"3.5862553000515422",
"0.6910880269131991",
"5.21181583404541",
"4.622976303100586",
"1.9204307794570923",
"1.481898546218872",
"-1.5685003995895386"
],
"face_cls": "tail",
"cut_cls": "0"
},
"1": {
"type": "0",
"type_name": "truck",
"score": "0.9642692804336548",
"roi_id": "0",
"box2d": [
"791.8895263671875",
"498.2795104980469",
"1162.1598205566406",
"816.8395385742188"
],
"xyzlhwyaw": [
"-0.04261477524786694",
"0.5091491993856199",
"6.116147041320801",
"4.321102619171143",
"2.0373644828796387",
"1.6876970529556274",
"-1.5730922222137451"
],
"face_cls": "tail",
"cut_cls": "0"
}
}

View File

@@ -0,0 +1,9 @@
tools/model_inference/examples/cncap/G1M3_AFS1616_CNCAP-202411.json文件中记录了一批场地评测数据的路径。
一组数据路径的示例为:"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_AEB_20_5_1_20251115140740/sigmastar.1",查找本地挂载路径时,需替换'hfs/project-G1M3'为'G1M3'同时查找路径下的camera4.bin。
具体的视频路径为"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_AEB_20_5_1_20251115140740/sigmastar.1/camera4.bin"
另外,其对应的标定参数路径为:"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/test_data/calibs/camera4.json"
现在期望tools/model_inference/run_two_roi_exported_onnx_infer.py脚本能够接收tools/model_inference/examples/cncap/G1M3_AFS1616_CNCAP-202411.json的输入从而对相关的视频数据进行模型推理。

View File

@@ -0,0 +1,5 @@
tools/model_inference/examples/events/G1Q3_场地评测数据集.json文件中记录了不同工况的数据每个工况下有多组数据每组数据中的data_path为eventid信息。
tools/model_inference/adapters/get_clip_by_eventid.py脚本可以用过event_id信息获取clip数据
现在期望tools/model_inference/run_two_roi_exported_onnx_infer.py脚本能够接收tools/model_inference/examples/events/G1Q3_场地评测数据集.json的输入从而对相关的clip数据进行模型推理。

View File

@@ -0,0 +1,8 @@
/data1/dongying/Mono3d/G1M3/test_data/cncap_20260408
上述路径中存放了多组测试数据,每组测试数据中有视频数据和标定参数,具体示例路径如下:
/data1/dongying/Mono3d/G1M3/test_data/cncap_20260408/20260407203248/sigmastar.1/camera4.bin
/data1/dongying/Mono3d/G1M3/test_data/cncap_20260408/20260407203248/test_data/calibs/camera4.json
请对脚本tools/model_inference/run_two_roi_exported_onnx_infer.py的输入接口进行扩展支持这种视频数据路径的模型推理。

View File

@@ -0,0 +1,654 @@
# 双ROI导出模型设计说明新版
> 若当前使用的是带 `difficulty` 分支或 `fake 3D` 分支的新版本双 ROI 合并模型,请优先参考:
> `tools/model_inference/docs/two_roi_model_design_with_diff_and_fake3d.md`
## 1. 文档目标
本文档以 `tools/model_inference/run_two_roi_exported_onnx_infer.py``tools/model_inference/core/run_two_roi_exported_onnx_infer.py` 的当前实现为准,说明新版双 ROI 导出模型在部署侧的输入约定、前处理、输出张量、后处理、结果序列化方式,以及与旧版说明文档之间的差异。
本文档关注的是“部署可执行设计”而不是训练侧的完整网络细节。凡与脚本实现冲突之处,以当前推理脚本和其依赖的本地工具模块为准。
如需查看旧版文档,可参考 `tools/model_inference/docs/two_roi_model_design_bak.md`
---
## 2. 方案概览
新版方案仍然采用双 ROI 单目 3D 检测思路,但部署形态已经收敛为一个“自包含的合并导出模型 + Python 侧解码”的运行时:
1. 同一帧原图按两套 ROI 规则分别裁剪,得到 `ROI0``ROI1`
2. 两个 ROI 图像分别送入一个合并后的导出模型,模型输出每个 ROI 的原始检测头张量。
3. 2D 框解码、Top-K 选择、3D 反归一化、深度恢复、3D 框重建、edge yaw 精化、可视化和 JSON 序列化全部在 Python 侧完成。
当前实现支持:
- `ONNX` 推理:通过 `onnxruntime`
- `TorchScript` 推理:通过 `torch.jit.load`
- 单 case 推理:`--case-dir`
- mined eval 数据集批量推理:`--eval-dir`
当前运行时不依赖 `ultralytics`
---
## 3. 模型与运行时契约
### 3.1 导出模型形态
当前脚本只接受双 ROI 合并后的导出模型:
- 后缀为 `.onnx` 时走 ONNX Runtime
- 后缀为 `.torchscript` / `.ts` / `.jit` 时走 TorchScript
脚本会读取导出清单:
- ONNX 优先读取同名 sidecar`merged_model.export.json`
- TorchScript 优先读 sidecarsidecar 不存在时再读模型内嵌的 `config.txt`
当前实现会显式校验:
```text
export_mode == "raw_head_outputs"
```
也就是说,当前部署脚本只支持“原始检测头输出”模式,不接受 `hybrid_outputs``postprocessed_outputs` 等其他导出模式。
### 3.2 输入输出名称
若导出清单可用,则直接使用清单中的:
- `input_names`
- `output_names`
- `input_sizes_wh`
若清单缺失,则回退到默认约定:
- 输入名:`roi0_input``roi1_input`
- 输出名:
- `roi0_boxes_head_raw`
- `roi0_scores_head_raw`
- `roi0_preds_3d_head_raw`
- `roi0_preds_edge_head_raw`
- `roi1_boxes_head_raw`
- `roi1_scores_head_raw`
- `roi1_preds_3d_head_raw`
- `roi1_preds_edge_head_raw`
### 3.3 默认 ROI 配置
默认 ROI 配置来自 `tools/model_inference/core/two_roi_infer_utils.py` 中的 `DEFAULT_DATASET_CONFIG`
| ROI | 裁剪尺寸 `(w, h)` | 裁剪中心模式 | `virtual_fx` | 默认输入尺寸 `(w, h)` |
|---|---:|---|---:|---:|
| `ROI0` | `1920 x 880` | `cxvy` | `537.0` | `768 x 352` |
| `ROI1` | `768 x 352` | `vxvy` | `537.0` | `768 x 352` |
其中:
- `cxvy`:裁剪中心 `x` 取原图水平中心,`y` 取灭点 `vp_y`
- `vxvy`:裁剪中心 `x` 取灭点 `vp_x``y` 取灭点 `vp_y`
这些默认值可以被 `--data-config``--roi0-data``--roi1-data` 中的 `roi_configs` 覆盖;若命令行显式传参,也可以进一步覆盖。
### 3.4 运行时元数据
推理脚本会从数据配置中加载以下元数据:
- `class_map`
- `face_3d_classes`
- `complete_3d_classes`
- `norm_scales_3d`
若没有额外 YAML使用内置默认值。
---
## 4. 前处理设计
### 4.1 相机标定读取
当前脚本兼容两种 `camera4.json` 结构:
1. 扁平格式:
```json
{
"focal_u": ...,
"focal_v": ...,
"cu": ...,
"cv": ...,
"pitch": ...,
"yaw": ...,
"distort_coeffs": [...]
}
```
2. 合并格式:
```json
{
"intrinsics": { "camera4.json": { ... } },
"extrinsics": { "camera4.json": { "rpy": [...] } }
}
```
脚本会规范化出:
- `focal_u`, `focal_v`
- `cu`, `cv`
- `pitch`, `yaw`
- `distort_coeffs`
- `angle_unit`
### 4.2 灭点计算
灭点计算逻辑保持不变:
```text
vp_x = cu + focal_u * tan(yaw)
vp_y = cv - focal_v * tan(pitch)
```
其中角度会先根据 `angle_unit` 统一到弧度制。
### 4.3 ROI 裁剪
对每一帧原图:
1. 读取原始宽高 `ori_w`, `ori_h`
2. 根据 ROI 配置确定目标裁剪尺寸 `roi_w`, `roi_h`
3. 根据 `crop_center_mode` 计算裁剪中心
4. 通过 `compute_centered_roi_bounds()` 做边界裁剪
裁剪边界为:
```text
crop_x1 = clamp(center_x - roi_w / 2, 0, ori_w - roi_w)
crop_y1 = clamp(center_y - roi_h / 2, 0, ori_h - roi_h)
crop_x2 = crop_x1 + roi_w
crop_y2 = crop_y1 + roi_h
```
### 4.4 缩放与标定更新
这是新版实现中一个关键变化点。
旧版文档默认把 ROI 裁剪结果直接一次性 resize 到模型输入尺寸;而当前实现使用 `_resize_ground3d_image_in_steps()`,先重复做若干次 `0.5x` 下采样,再做最后一次 resize以匹配 Ground3D 训练侧的图像缩放行为。
缩放完成后,相机标定会更新到 ROI-resized 坐标系:
```text
scale_x = target_w / crop_w
scale_y = target_h / crop_h
fx = focal_u * scale_x
fy = focal_v * scale_y
cx = (cu - crop_x1) * scale_x
cy = (cv - crop_y1) * scale_y
depth_scale = fx / virtual_fx
```
其中:
- `fx, fy, cx, cy` 是 resized ROI 空间下的标定
- `depth_scale` 用于后处理阶段把网络预测深度恢复到真实焦距尺度
### 4.5 图像张量化
当前脚本的输入张量构造为:
```python
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
array = image_rgb.transpose(2, 0, 1).astype(np.float32) / 256.0
input = array[None, ...]
```
注意这里是:
```text
/ 256.0
```
而不是旧文档中的 `/ 255.0`
TorchScript 路径与 ONNX 路径共用同一份前处理逻辑。
---
## 5. 输出张量设计
### 5.1 每个 ROI 的输出分支
当前部署脚本假设每个 ROI 仍然输出四个分支:
1. `boxes_head_raw`
2. `scores_head_raw`
3. `preds_3d_head_raw`
4. `preds_edge_head_raw`
即合并模型总共有 8 个输出张量。
### 5.2 3D 分支定义41 维)
3D 分支通道布局沿用旧版设计:
| 通道范围 | 含义 |
|---|---|
| `0-5` | front face`z3d, u_offset, v_offset, h, w, visible_score` |
| `6-11` | rear face`z3d, u_offset, v_offset, h, w, visible_score` |
| `12-17` | left face`z3d, u_offset, v_offset, l, h, visible_score` |
| `18-23` | right face`z3d, u_offset, v_offset, l, h, visible_score` |
| `24` | whole-box `z3d` |
| `25-26` | whole-box `u_offset, v_offset` |
| `27-29` | whole-box `l, h, w` |
| `30-33` | yaw 4-bin 分类 logits |
| `34-37` | yaw 残差 `sin(delta)` |
| `38-40` | cut state logits |
### 5.3 Edge 分支定义60 维)
Edge 分支依然是四个面的底边缘采样点,每个采样点 3 维:
```text
[du, dv, z]
```
每个面 5 个点,共 `5 x 3 = 15` 维,四个面共 60 维:
| 面 | 通道范围 |
|---|---|
| front | `0-14` |
| rear | `15-29` |
| left | `30-44` |
| right | `45-59` |
### 5.4 默认输出形状
对默认输入尺寸 `768 x 352`
```text
A = (352/8 * 768/8) + (352/16 * 768/16) + (352/32 * 768/32)
= 4224 + 1056 + 264
= 5544
```
因此典型输出为:
| 输出名 | 形状 | 含义 |
|---|---|---|
| `roi*_boxes_head_raw` | `[1, 4 * reg_max, 5544]` | 2D 框原始回归输出 |
| `roi*_scores_head_raw` | `[1, nc, 5544]` | 分类原始 logits |
| `roi*_preds_3d_head_raw` | `[1, 41, 5544]` | 3D 原始预测 |
| `roi*_preds_edge_head_raw` | `[1, 60, 5544]` | edge 原始预测 |
脚本支持 `reg_max > 1` 的通用 DFL 解码;当前导出模型若 `reg_max == 1`,会退化为直接距离回归。
---
## 6. 后处理设计
### 6.1 2D 框解码
2D 框解码由 `decode_boxes_xyxy()` 完成:
1.`boxes_head_raw` 还原为 `l, t, r, b`
2. 与预先缓存的 anchor 网格中心做几何组合
3. 再乘以 stride 还原到 ROI-resized 图像像素坐标
anchor 由 `build_anchor_cache()` 预生成,默认 stride 为:
```text
(8, 16, 32)
```
### 6.2 Top-K 选择
当前脚本没有做 NMS而是严格遵循导出 raw head 的 one-to-one Top-K 路径:
1. 对分类 logits 做 sigmoid
2. 每个 anchor 取最大类别分数
3. 先按 anchor 最大分类分数做一轮 Top-K
4. 再对 gather 后的 `(anchor, class)` 展平分数做第二轮 Top-K
5. 生成 `detections = [x1, y1, x2, y2, conf, cls_id]`
### 6.3 3D / Edge 反归一化
`preds_3d_head_raw``preds_edge_head_raw` 会用 `norm_scales_3d` 做反归一化:
| 项目 | 反归一化方式 |
|---|---|
| `z3d` | `raw * z3d_scale + z3d_offset` |
| `u/v offset` | `sigmoid(raw) * 16 - 8` |
| `size` | `raw * size_scale + size_offset` |
| yaw residual | `tanh(raw)` |
| edge `z` | `raw * z3d_scale + z3d_offset` |
| edge `du/dv` | `sigmoid(raw) * 16 - 8` |
默认值来自内置配置:
```text
z3d_scale = 24.415
z3d_offset = 39.937
size_scale = 1.945
size_offset = 3.780
```
### 6.4 深度恢复
由于训练时使用 `virtual_fx`,部署时必须恢复真实焦距尺度:
```text
preds_3d[:, (0, 6, 12, 18, 24)] *= depth_scale
preds_edge[:, 2::3] *= depth_scale
```
这里的 `depth_scale = fx / virtual_fx` 是按每个 ROI、每一帧动态计算的。
### 6.5 置信度与类别过滤
当前脚本在完成 Top-K 后,再通过 `filter_prediction_rows()` 做最终过滤:
- `conf >= roi.spec.conf`
- 若给了 `--classes`,则再做类别白名单过滤
- 最终数量再截断到 `max_det`
### 6.6 3D 框解码与重建
#### 6.6.1 面型 3D 类别
`face_3d_classes` 中的类别,当前实现使用“可见面驱动”的 3D 解码:
1. 根据 `pred_41` 中的 face visibility 选择可见面
2. 根据最佳可见面读取 `z_face + uv_face_offset`
3. 利用整体尺寸 `dims_whole` 和回归的 `yaw` 重建 3D 框
4.`pred_edge_60` 可用,则同时解码可见底边缘点
5. 若目标处于 cut 状态,还会尝试解码 partial side edge并把它补充进可见面集合
这部分比旧版文档中的描述更具体,已经显式纳入了:
- cut state 感知
- partial edge 补边
- 多可见面 edge 采样
#### 6.6.2 完整体 3D 类别
`complete_3d_classes` 中的类别,直接使用 whole-box 分支:
- `z_whole`
- `uv_whole`
- `dims_whole`
- `yaw`
重建完整 3D 包围盒。
#### 6.6.3 其他类别
对不属于上述两类集合的类别,脚本通常不会生成可视化 3D 框,但仍会保留 whole-box 分支解码出的:
- `center_3d`
- `dims`
- `yaw_rad`
用于结果序列化。
### 6.7 Yaw 解码
Yaw 解码仍是 4-bin 分类 + 残差方式:
```text
best_bin = argmax(pred[30:34])
yaw = arcsin(clamp(pred[34 + best_bin], -1, 1)) + yaw_bin_offset[best_bin]
```
### 6.8 Edge Yaw 与 Edge Box 重建
新版实现中edge 分支不只是“可选 yaw 精化”,而是形成了一条完整的 edge-based 几何诊断链:
1.`pred_edge_60` 解码选中的可见底边缘点
2. 反投影得到 3D edge points
3.`decode_edge_yaw_selection_from_prediction()` 选择最可信的单面或双面组合
4. 计算 `edge_yaw_rad`
5. 判断横向距离是否满足 `max_lateral_dist_m`
6. 基于选中的 edge 几何重建 `edge_box`
7. 若重建可信,则生成 `decoded_edge_heading`
默认横向距离阈值为:
```text
edge_yaw_max_lateral_dist_m = 5.0
```
当前实现额外产出以下诊断信息:
- `edge_yaw_confident`
- `edge_yaw_lateral_distance_m`
- `edge_yaw_lateral_ok`
- `edge_yaw_two_face_eligible`
- `edge_yaw_selected_face_types`
- `edge_yaw_selected_face_is_partial`
- `edge_vs_reg_yaw_rad`
- `edge_box_center_3d`
- `edge_box_dims`
- `edge_box_mode`
- `edge_box_length_source`
- `edge_box_width_source`
- `selected_edge_direct_box_fit_*`
- `selected_edge_edgeyaw_box_fit_*`
- `selected_edge_fit_gain_px`
### 6.9 可视化
每个 ROI 会输出三张 panel
1. `2D`:绘制 ROI-resized 坐标系中的检测框
2. `3D`:绘制常规回归 yaw 的 3D 框
3. `3D EdgeRecon (1+ face)`:只绘制 `edge_yaw_confident=True` 的 edge 重建结果
最终按 ROI 拼成一个总览网格图。
---
## 7. 输出数据设计
### 7.1 输出目录结构
单 case 推理时,输出目录下会生成:
```text
output_dir/
├── visualizations/
│ ├── *.jpg
├── predictions/
│ ├── *.json
└── predictions.json
```
其中:
- `visualizations/*.jpg`:每帧一个可视化网格图
- `predictions/*.json`:下游消费的简化逐帧结果
- `predictions.json`:完整聚合结果
批量 eval 推理时,会在 `output_dir` 下保留与 `eval_dir` 相同的相对目录层级。
### 7.2 完整聚合结果 `predictions.json`
聚合结果顶层结构为:
```json
{
"case_name": "...",
"images_dir": "...",
"calib_file": "...",
"exported_model_path": "...",
"edge_yaw_max_lateral_dist_m": 5.0,
"frames": [
{
"frame_index": 0,
"frame_name": "000000.png",
"visualization": ".../visualizations/000000.jpg",
"rois": {
"roi0": {
"crop_bounds": [x1, y1, x2, y2],
"vp_x": ...,
"vp_y": ...,
"crop_center_x": ...,
"crop_center_y": ...,
"edge_yaw_max_lateral_dist_m": 5.0,
"calib": {
"fx": ...,
"fy": ...,
"cx": ...,
"cy": ...,
"depth_scale": ...
},
"predictions": [
{
"bbox_xyxy": [...],
"original_bbox_xyxy": [...],
"confidence": 0.93,
"cls_id": 6,
"cls_name": "truck",
"center_uv": [...],
"center_3d": [...],
"dims": [...],
"yaw_rad": ...,
"edge_yaw_rad": ...,
"edge_yaw_confident": true,
"cut_cls": 0,
"roi_id": 0,
"visible_face_type": 1,
"visible_face_types": [1, 2]
}
]
}
}
}
]
}
```
### 7.3 简化逐帧结果 `predictions/*.json`
脚本还会额外导出更接近下游消费格式的逐帧 JSON例如
```json
{
"0": {
"type": "0",
"type_name": "truck",
"score": "0.9664",
"roi_id": "0",
"box2d": ["1357.25", "542.76", "1743.78", "803.98"],
"xyzlhwyaw": ["3.58", "0.69", "5.21", "4.62", "1.92", "1.48", "-1.57"],
"face_cls": "tail",
"cut_cls": "0",
"edge_yaw_rad": "-1.56",
"edge_yaw_confident": true,
"edge_vs_reg_yaw_rad": "0.01"
}
}
```
这里有一个新版语义变化:
- `box2d` 优先使用 `original_bbox_xyxy`
- 若原图坐标不可用,才回退到 `bbox_xyxy`
也就是说,简化逐帧 JSON 里的 2D 框优先是“原图坐标系”。
### 7.4 坐标系约定
当前实现涉及四种常见坐标系:
1. `bbox_xyxy`
ROI 裁剪并缩放后的图像坐标系
2. `original_bbox_xyxy`
原始整图坐标系
3. `center_uv`
ROI-resized 图像坐标系下的中心点
4. `center_3d`
相机坐标系,单位米
旧版文档中“所有二维坐标均在 ROI 坐标系”这一表述对当前实现已不完全成立,因为现在明确同时输出了 `original_bbox_xyxy`
---
## 8. 默认类别配置
当前运行时默认的 `class_map` 为:
| `cls_id` | 类别 |
|---|---|
| `0` | `car` |
| `1` | `suv` |
| `2` | `pickup` |
| `3` | `medium_car` |
| `4` | `van` |
| `5` | `bus` |
| `6` | `truck` / `tanker` / `large_truck` / `construction_vehicle` |
| `7` | `special_vehicle` |
| `8` | `unknown` |
| `9` | `pedestrian` |
| `10` | `bicyclist` / `motorcyclist` |
| `11` | `bicycle` / `motorcycle` |
| `12` | `tricycle` / `tricyclist` |
| `13` | `traffic_sign` |
| `14` | `wheel` |
| `15` | `plate` |
| `16` | `face` |
默认 3D 类别分组为:
- `face_3d_classes = {0,1,2,3,4,5,6,7,8}`
- `complete_3d_classes = {9,10,11,12}`
因此:
- `0-8` 使用“可见面驱动”的 3D 解码
- `9-12` 使用 whole-box 3D 解码
- `13-16` 默认不绘制 3D 框,但仍保留部分序列化属性
---
## 9. 新旧版本差异总结
下表总结了新版实现相对旧版说明文档的主要差异。
| 项目 | 旧版说明 | 新版实现 |
|---|---|---|
| 导出模式 | 文档列出了 `raw_head_outputs``hybrid_outputs``postprocessed_outputs``denorm_branch_outputs` | 当前脚本只接受 `raw_head_outputs`,并在启动时校验 |
| 后端支持 | 主要按 ONNX 方案描述 | 当前同时支持 `ONNX``TorchScript`,并自动解析 manifest |
| 运行时依赖 | 更偏训练/导出视角 | 当前是完全自包含的部署侧实现,不依赖 `ultralytics` |
| ROI 缩放 | 单次 resize 描述 | 当前实现先多次 `0.5x` 下采样,再最终 resize以贴合训练前处理 |
| 图像归一化 | `/255.0` | 当前脚本实际使用 `/256.0` |
| 输入尺寸来源 | 假定固定输入尺寸 | 当前优先读 manifest 中的 `input_sizes_wh`,也支持命令行覆盖 |
| 标定输入格式 | 主要描述平铺内参格式 | 当前同时兼容 flat `camera4.json` 和 combined calibration |
| 类别定义 | 类别表较粗,`face_3d_classes``complete_3d_classes` 范围较小 | 默认类表扩展到 17 个 id`face_3d_classes=0-8``complete_3d_classes=9-12` |
| 3D 解码 | 描述了基础 face / whole 两条路径 | 当前新增 cut-aware partial edge、edge 几何筛选、edge box 重建等更完整逻辑 |
| edge yaw | 作为可选精化模块描述 | 当前 edge yaw 已融入主结果结构,带 lateral gating、双面可见判断和拟合残差诊断 |
| 输出 JSON | 主要描述聚合 JSON字段较少 | 当前同时输出完整聚合 JSON 和简化逐帧 JSON并新增大量 edge 诊断字段 |
| 2D 坐标语义 | 默认都在 ROI-resized 坐标系 | 当前同时输出 `bbox_xyxy``original_bbox_xyxy`,两种坐标系并存 |
| 可视化 | 只描述 2D/3D 结果 | 当前每个 ROI 输出 `2D``3D``3D EdgeRecon` 三个 panel |
| 运行模式 | 以单 case 为主 | 当前新增 `--eval-dir`,支持整个 mined eval 数据集复用同一个模型批量跑 |
### 9.1 对齐建议
如果后续继续维护部署文档,建议把以下三项视为“新版真值来源”:
1. `tools/model_inference/run_two_roi_exported_onnx_infer.py`
2. `tools/model_inference/core/two_roi_infer_utils.py`
3. `tools/model_inference/core/two_roi_3d_utils.py`
特别是以下内容最容易因实现更新而与文档产生偏差:
- 输入归一化常数
- ROI resize 策略
- 类别映射与 3D 类别分组
- edge yaw 的筛选和诊断字段
- 简化 JSON 中 `box2d` 的坐标系定义

View File

@@ -0,0 +1,385 @@
# 双ROI合并模型方案文档
## 1. 概述
本文档描述基于 YOLO26-3D 的双 ROIRegion of Interest单目3D目标检测方案。该方案将同一张原始图像按两种不同的裁剪策略分别送入两个独立训练的 Detect3D 模型,并将两模型合并导出为单一 ONNX/TorchScript 文件实现2D检测框与3D属性深度、尺寸、朝向角的联合预测。
---
## 2. 模型架构
### 2.1 骨干网络与检测头
模型基于 `yolo26-3d.yaml` 配置,结构如下:
```
输入 (3 × H × W)
├── Backbone: Conv → C3k2 × 2 → Conv → C3k2 × 2 → Conv → C3k2 → Conv → C3k2 → SPPF → C2PSA
└── Neck (FPN): Upsample + Concat × 2 → C3k2
→ Detect3D(P3/8, P4/16, P5/32)
```
模型使用 `end2end=True`,即训练时启用 one-to-one 分支,推理时直接输出 Top-K 检测结果,无需 NMS。
### 2.2 Detect3D 检测头
`Detect3D` 继承自标准 `Detect`在2D分支cv2 box、cv3 cls基础上新增
- **cv43D预测分支**:每个 anchor 输出 41 维张量;
- **cv5可见面边缘分支**:每个 anchor 输出 60 维张量。
#### 3D预测张量41维格式
| 通道范围 | 含义 |
|----------|------|
| 05 | 前面Front face: z3d, u_offset, v_offset, h, w, visible_score |
| 611 | 后面Rear face: z3d, u_offset, v_offset, h, w, visible_score |
| 1217 | 左面Left face: z3d, u_offset, v_offset, l, h, visible_score |
| 1823 | 右面Right face: z3d, u_offset, v_offset, l, h, visible_score |
| 24 | 整体 z3d |
| 2526 | 整体 u_offset, v_offset网格坐标偏移 |
| 2729 | 整体 l, h, w |
| 3033 | 4个朝向 bin 的分类 logits |
| 3437 | 4个朝向 bin 的残差 sin 值 |
| 3840 | cut 状态分类 logitsnormal/cut-in/cut-out |
#### 可见面边缘张量60维格式
每张可见面对应 5 个采样点 × 3 维du, dv, z共 4 个面 × 15 维 = 60 维:
| 面索引 | 通道范围 |
|--------|----------|
| 前面 | 014 |
| 后面 | 1529 |
| 左面 | 3044 |
| 右面 | 4559 |
每个采样点格式:`[du (网格偏移), dv (网格偏移), z (米)]`
### 2.3 双 ROI 设计
两个独立模型分别对同一帧图像的不同感兴趣区域进行预测:
| 参数 | ROI0 | ROI1 |
|------|------|------|
| 裁剪尺寸(宽×高) | 1920 × 880 | 768 × 352 |
| 裁剪中心模式 | `cxvy`(图像水平中心 + 灭点y | `vxvy`灭点x + 灭点y |
| 虚拟焦距 virtual_fx | 537.0 | 537.0 |
| 模型输入尺寸 | 768 × 352 | 768 × 352 |
- **ROI0**以图像水平中心为裁剪中心x涵盖宽视野适合远距离大视野检测
- **ROI1**:以灭点为裁剪中心,聚焦正前方,适合近中距离精细检测。
### 2.4 合并导出
两模型通过 `merge_models_of_2roi_yolo26.py` 合并为单一模型文件(`merged_model.onnx``.torchscript`),导出时同时写出 `merged_model.export.json` 元数据 sidecar 文件,记录 input_names、output_names、input_sizes_wh 等信息。
支持多种导出模式(`--export-mode`
| 模式 | 描述 |
|------|------|
| `raw_head_outputs`(默认) | 输出各分支的原始未后处理张量,所有解码在推理侧完成 |
| `hybrid_outputs` | 输出后处理2D检测 + 原始 3D/edge 张量 |
| `postprocessed_outputs` | 输出完整后处理结果(含 Top-K 选取) |
| `denorm_branch_outputs` | 输出反归一化后、Top-K 选取前的分支张量 |
---
## 3. 推理前处理
### 3.1 加载相机标定
`camera4.json` 读取原始相机内参和外参:
```
RawCameraCalib:
focal_u, focal_v — 原始像素焦距
cu, cv — 主点 (principal point)
pitch, yaw — 相机安装角度(弧度)
distort_coeffs — 鱼眼畸变系数 [k1, k2, k3, k4](可选)
```
### 3.2 计算灭点Vanishing Point
根据相机安装姿态计算图像灭点坐标:
```
vp_x = cu + focal_u × tan(yaw)
vp_y = cv - focal_v × tan(pitch)
```
### 3.3 ROI 裁剪
根据 ROI 规格(`roi_size``crop_center_mode`)在原图上确定裁剪区域:
```
crop_center_x:
cxvy 模式: ori_w / 2
vxvy 模式: vp_x
crop_center_y = vp_y两种模式均以灭点y为中心
crop_bounds [x1, y1, x2, y2]:
x1 = clamp(crop_center_x - roi_w/2, 0, ori_w - roi_w)
y1 = clamp(crop_center_y - roi_h/2, 0, ori_h - roi_h)
```
裁剪结果为固定尺寸图像块roi_w × roi_h
### 3.4 缩放与标定更新
将裁剪图像缩放到模型输入尺寸768 × 352同时更新相机内参
```
scale_x = target_w / crop_w
scale_y = target_h / crop_h
fx = focal_u × scale_x
fy = focal_v × scale_y
cx = (cu - crop_x1) × scale_x
cy = (cv - crop_y1) × scale_y
depth_scale = fx / virtual_fx # 深度恢复系数
```
`depth_scale` 记录了当前帧缩放后真实焦距与虚拟训练焦距之间的比值,用于后处理阶段的深度恢复。
### 3.5 图像归一化
```
image_rgb = BGR → RGB 转换
tensor = image_rgb.transpose(2,0,1) # HWC → CHW
tensor = tensor / 255.0 # 归一化到 [0, 1]
input = tensor[None, ...] # 增加 batch 维
```
---
## 4. 模型输出格式
以默认 `raw_head_outputs` 模式为例,合并模型共输出 **8 个张量**(每 ROI 4 个):
| 输出名 | 形状 | 含义 |
|--------|------|------|
| `roi0_boxes_head_raw` | `[1, 4×reg_max, A]` | ROI0 DFL box 回归原始 logits |
| `roi0_scores_head_raw` | `[1, nc, A]` | ROI0 类别分数原始 logits |
| `roi0_preds_3d_head_raw` | `[1, 41, A]` | ROI0 3D 预测原始值 |
| `roi0_preds_edge_head_raw` | `[1, 60, A]` | ROI0 可见面边缘原始值 |
| `roi1_boxes_head_raw` | `[1, 4×reg_max, A]` | ROI1 DFL box 回归原始 logits |
| `roi1_scores_head_raw` | `[1, nc, A]` | ROI1 类别分数原始 logits |
| `roi1_preds_3d_head_raw` | `[1, 41, A]` | ROI1 3D 预测原始值 |
| `roi1_preds_edge_head_raw` | `[1, 60, A]` | ROI1 可见面边缘原始值 |
其中 `nc` 为类别数,`A` 为总 anchor 数(三个尺度之和):
```
A = (H/8 × W/8) + (H/16 × W/16) + (H/32 × W/32)
对于 352×768: = (44×96) + (22×48) + (11×24) = 4224 + 1056 + 264 = 5544
```
`reg_max=1`(当前配置),因此 box 分支通道数为 4。
---
## 5. 后处理步骤
### 5.1 2D 检测框解码
**DFL 解码**(分布式焦点损失解码):
```python
# reg_max == 1 时简化为:
dist = raw_boxes.reshape(batch, 4, A) # [l, t, r, b] 形式的距离预测
# 还原为 anchor-relative xyxy:
boxes_xyxy[:, 0:2] = anchors - dist[:, 0:2] # x1, y1
boxes_xyxy[:, 2:4] = anchors + dist[:, 2:4] # x2, y2
# 乘以 stride 还原到像素坐标:
boxes_xyxy = boxes_xyxy * strides
```
Anchor 坐标为各尺度特征图的网格中心点0.5 偏移),由 `build_anchor_cache()` 预计算。
### 5.2 Top-K 选取(无 NMS
模型使用 end-to-end one-to-one 训练,推理时直接按类别最高分取 Top-K默认 K=300无需 NMS
```python
# 1. sigmoid 激活类别分数
scores = sigmoid(raw_scores) # [1, A, nc]
# 2. 每个 anchor 取最大分数,选 Top-K anchor
anchor_max_scores = scores.max(axis=-1) # [1, A]
topk_anchor_indices = argsort(anchor_max_scores)[-K:]
# 3. 再对 gathered scores 扁平化取 Top-K双重 Top-K
# 最终输出形状: detections [1, K, 6] (x1,y1,x2,y2, conf, cls_id)
```
### 5.3 3D 预测反归一化
原始 3D 张量在网络内经过归一化压缩,推理侧需还原为物理量:
| 通道 | 操作 | 含义 |
|------|------|------|
| z3dch 0,6,12,18,24 | `raw × z3d_scale + z3d_offset` | 深度(米),默认 scale=24.415, offset=39.937 |
| UV 偏移ch 1-2, 7-8, 13-14, 19-20, 25-26 | `sigmoid(raw) × 16 8` | 网格坐标偏移(格子数,范围约 [8, 8] |
| 尺寸 l/h/wch 3-4, 9-10, 15-16, 21-22, 27-29 | `raw × size_scale + size_offset` | 尺寸(米),默认 scale=1.945, offset=3.780 |
| 朝向 bin logitsch 30-33 | 保持原始 logits | 4-bin softmax 分类 |
| 朝向残差ch 34-37 | `tanh(raw)` | sin(Δ) in [1, 1] |
| face visibilitych 5,11,17,23 | 保持原始分数 | 各面可见置信度 |
| cut 状态ch 38-40 | 保持原始 logits | normal/cut-in/cut-out |
同理edge 张量60维的 UV 偏移和深度 z 也做相同的 sigmoid/线性反归一化。
### 5.4 深度恢复Depth Scale 还原)
由于训练时使用固定 `virtual_fx` 虚拟焦距,而实际推理焦距因裁剪+缩放而变化,需乘以 `depth_scale` 还原真实深度:
```python
preds_3d[:, [0, 6, 12, 18, 24]] *= depth_scale # z3d 通道
preds_edge[:, 2::3] *= depth_scale # edge 深度通道
```
其中 `depth_scale = fx_actual / virtual_fx`,每帧根据实际裁剪/缩放参数计算。
### 5.5 置信度过滤
按置信度阈值(默认 0.25)和类别白名单过滤低质量检测:
```python
keep = detections[:, 4] >= conf_thres
if classes is not None:
keep &= cls_id in classes
detections = detections[keep][:max_det]
```
### 5.6 朝向角解码
模型采用 **4-bin 分类 + 残差 sin** 联合解码朝向角:
```
4 个 bin 偏置角: [0°, 90°, 90°, 180°]
yaw_bin = argmax(logits[30:34])
bin_offset = {0: 0, 1: π/2, 2: −π/2, 3: π}[yaw_bin]
sin_delta = tanh(raw[34 + yaw_bin])
delta = arcsin(clamp(sin_delta, 1, 1))
yaw_reg = bin_offset + delta
```
### 5.7 3D 包围盒重建
#### 面型类face_3d_classes车辆等大目标
1. 按 face visibility score 选取最高置信可见面front/rear/left/right
2. 用该面的 UV 偏移 + z 在像素坐标系中反投影,得到 3D 中心点;
3. 结合整体尺寸 l/h/w 和朝向角 yaw计算 8 个角点坐标;
4. 若有 edge 预测,用 cv5 中对应面的5个采样点重投影辅助可视化。
```python
# 面中心 UV → 像素坐标
u_face = (anchor_x + u_offset) * stride
v_face = (anchor_y + v_offset) * stride
# 像素坐标 → 相机坐标系 3D 中心
X = (u_face - cx) / fx * z_face
Y = (v_face - cy) / fy * z_face
Z = z_face
# 基于 3D 中心 + 尺寸 + 朝向重建 8 角点
corners = compute_3d_box_corners(center_3d, [l, h, w], yaw, face_type)
```
#### 完整型类complete_3d_classes行人、骑手等
直接使用整体预测(通道 2429重建包围盒无需面选择。
### 5.8 Edge Yaw 精化(可选)
对于横向距离 ≤ `edge_yaw_max_lateral_dist_m`(默认 5.0m)的目标,尝试利用可见面底边缘点拟合更精确的朝向角:
1. 从 cv5 解码可选的1-2个可见面底边缘采样点2D
2. 结合深度,将采样点反投影到 3D
3. 拟合底边缘方向,得到 `edge_yaw_rad`
4. 若两面同时可见two-face eligible优先使用双面拟合结果`edge_yaw_confident=True`
---
## 6. 输出数据格式
每帧的结构化输出以 JSON 格式保存:
```json
{
"frame_index": 0,
"frame_name": "000000.png",
"rois": {
"roi0": {
"crop_bounds": [x1, y1, x2, y2],
"vp_x": 960.0,
"vp_y": 175.0,
"calib": { "fx": ..., "fy": ..., "cx": ..., "cy": ..., "depth_scale": ... },
"predictions": [
{
"bbox_xyxy": [x1, y1, x2, y2],
"confidence": 0.87,
"cls_id": 0,
"cls_name": "car",
"yaw_rad": -0.32,
"edge_yaw_rad": -0.31,
"edge_yaw_confident": true,
"edge_yaw_lateral_distance_m": 3.2,
"edge_yaw_lateral_ok": true,
"edge_yaw_two_face_eligible": true,
"edge_yaw_selected_face_types": [2, 0],
"edge_vs_reg_yaw_rad": 0.01,
"center_uv": [u, v],
"center_3d": [X, Y, Z],
"visible_face_type": 2,
"visible_face_types": [2, 0],
"crop_bounds": [x1, y1, x2, y2]
}
]
},
"roi1": { ... }
},
"visualization": "/path/to/000000.jpg"
}
```
所有二维坐标(`bbox_xyxy``center_uv`)均在对应 ROI 裁剪并缩放后的图像坐标系下;`center_3d` 在相机坐标系下,单位为米。
---
## 7. 类别定义
| cls_id | 类别名称(示例) |
|--------|-----------------|
| 0 | car含 suv, van 等) |
| 1 | bus |
| 2 | truck含 large_truck |
| 3 | tanker / construction_vehicle |
| 4 | unknown |
| 5 | pedestrian |
| 6 | bicycle / motorcycle |
| 7 | motorcyclist / bicyclist |
| 8 | tricycle / tricyclist |
| 9 | traffic_sign |
| 10 | wheel |
| 11 | plate |
| 12 | face |
类别 04 属于 `face_3d_classes`面型3D重建类别 58 属于 `complete_3d_classes`整体3D重建
---
## 8. 鱼眼镜头支持
若相机标定文件中包含有效的 `distort_coeffs`4个系数 [k1, k2, k3, k4]),则:
- 2D 坐标系下 3D 点投影时使用鱼眼畸变正向模型(`apply_fisheye_distortion`
- 2D → 3D 反投影时使用 Newton 迭代法求解畸变逆映射(`remove_fisheye_distortion`
- 3D 包围盒可视化时对各条棱进行密集采样后逐点投影,确保曲线正确。

View File

@@ -0,0 +1,690 @@
# 双ROI导出模型设计说明Diff 与 Fake3D 版本)
## 1. 文档目标
本文档说明当前新版双 ROI 合并导出模型在部署侧的输入约定、输出张量、后处理流程,以及 `difficulty` 分支与 `fake 3D` 分支的运行时语义。
本文档覆盖的对象是:
- `tools/model_merging/merge_models_of_2roi_yolo26.py`
- `tools/model_inference/core/run_two_roi_exported_onnx_infer.py`
- `tools/model_inference/core/two_roi_infer_utils.py`
- `ultralytics/nn/modules/head.py`
凡与旧文档冲突之处,以当前代码实现为准。
如只查看旧版双 ROI 合并模型,请参考:
- `tools/model_inference/docs/two_roi_model_design.md`
---
## 2. 版本背景
当前仓库中的双 ROI 合并导出模型已经从旧版的:
- `2D boxes + class scores + 3D branch (+ 可选 edge branch)`
演进为新版可选扩展的形态:
- `2D boxes + class scores + 3D branch + difficulty branch`
- `2D boxes + class scores + 3D branch + difficulty branch + fake 3D branch`
- `(+ 可选 edge branch)`
其中:
- `difficulty branch` 用于输出目标 difficulty 二分类 logit
- `fake 3D branch` 用于输出 fake class 专用的 3D 预测
当前合并导出脚本支持以下控制项:
- `--edge-head-mode keep|drop`
- `--fake-3d-branch-mode keep|drop`
因此新版模型存在两条主要导出变体:
1. `drop fake_3d`:导出 `3D + diff`
2. `keep fake_3d`:导出 `3D + diff + fake_3d`
---
## 3. 方案概览
当前运行时仍然沿用双 ROI 单目 3D 检测的总体思路,但部署形态已经收敛为:
1. 原图按 `ROI0``ROI1` 两套规则分别裁剪
2. 两个 ROI 图像送入同一个合并导出模型
3. 模型输出每个 ROI 的原始检测头张量
4. 2D 框解码、Top-K、3D 反归一化、深度恢复、3D 框重建、fake-class 路由、可视化与 JSON 序列化全部在 Python 侧完成
当前支持:
- ONNX`onnxruntime`
- TorchScript`torch.jit.load`
- 单 case 推理
- mined / eval 数据集批量推理
当前部署脚本不依赖训练时的 `ultralytics` dataloader只依赖导出张量契约和运行时元数据。
---
## 4. 模型与运行时契约
### 4.1 导出模型形态
当前推理脚本只接受双 ROI 合并后的导出模型:
- `.onnx`
- `.torchscript` / `.ts` / `.jit`
脚本会读取导出清单:
- ONNX 优先读取 sidecar`merged_model.export.json`
- TorchScript 优先读 sidecar若 sidecar 缺失再读取模型内嵌 `config.txt`
当前部署脚本会显式要求:
```text
export_mode == "raw_head_outputs"
```
也就是说,当前文档只讨论原始检测头输出模式,不讨论 `hybrid_outputs``postprocessed_outputs` 等其他导出形态。
### 4.2 输入名称
默认输入名为:
- `roi0_input`
- `roi1_input`
默认输入尺寸为:
- `768 x 352`
若导出清单里提供了 `input_names``input_sizes_wh`,运行时以清单为准。
### 4.3 导出控制开关
当前导出脚本暴露两个关键开关:
```bash
--edge-head-mode keep|drop
--fake-3d-branch-mode keep|drop
```
它们会直接影响导出后的输出张量数量与名称。
### 4.4 运行时元数据
运行时会从数据配置 YAML 中读取以下元数据:
- `class_map`
- `face_3d_classes`
- `complete_3d_classes`
- `fake_3d_classes`
- `norm_scales_3d`
若未提供额外 YAML则使用 `tools/model_inference/core/two_roi_infer_utils.py` 中的 `DEFAULT_DATASET_CONFIG`
当前内置默认值包括:
- `face_3d_classes = [0,1,2,3,4,5,6,7,8,17]`
- `complete_3d_classes = [9,10,11,12,18,19]`
- `fake_3d_classes = [17,18,19]`
对应 fake 类别名称:
- `car_fake`
- `bicyclist_fake`
- `pedestrian_fake`
### 4.5 新旧版本输出类别对比
当前部署侧的 `cls_id` / `cls_name``class_map` 决定。
旧版与新版的主要差异不只是输出分支数量,还包括默认类别集合本身已经扩展。
旧版默认类别定义为:
| `cls_id` | 旧版默认类别 |
|---|---|
| `0` | `car` |
| `1` | `suv` |
| `2` | `pickup` |
| `3` | `medium_car` |
| `4` | `van` |
| `5` | `bus` |
| `6` | `truck` / `tanker` / `large_truck` / `construction_vehicle` |
| `7` | `special_vehicle` |
| `8` | `unknown` |
| `9` | `pedestrian` |
| `10` | `bicyclist` / `motorcyclist` |
| `11` | `bicycle` / `motorcycle` |
| `12` | `tricycle` / `tricyclist` |
| `13` | `traffic_sign` |
| `14` | `wheel` |
| `15` | `plate` |
| `16` | `face` |
新版默认类别定义为:
| `cls_id` | 新版默认类别 |
|---|---|
| `0-16` | 与旧版相同 |
| `17` | `car_fake` |
| `18` | `bicyclist_fake` |
| `19` | `pedestrian_fake` |
因此默认 `scores_head_raw` 的类别数从旧版的:
- `nc = 17`
扩展为新版的:
- `nc = 20`
对应的 3D 类别分组也从旧版:
- `face_3d_classes = [0,1,2,3,4,5,6,7,8]`
- `complete_3d_classes = [9,10,11,12]`
扩展为新版:
- `face_3d_classes = [0,1,2,3,4,5,6,7,8,17]`
- `complete_3d_classes = [9,10,11,12,18,19]`
- `fake_3d_classes = [17,18,19]`
语义上可以理解为:
- `0-16`:延续旧版类别语义
- `17-19`:新增 fake 类别2D 分类仍走统一 `scores_head_raw`
- `17` 会按 face 类路径参与 3D 解码,但在保留 fake 分支时优先读取 `preds_3d_fake_head_raw`
- `18-19` 会按 complete 类路径参与 3D 解码,但在保留 fake 分支时同样优先读取 `preds_3d_fake_head_raw`
---
## 5. ROI 与前处理设计
### 5.1 默认 ROI 配置
默认 ROI 配置来自 `DEFAULT_DATASET_CONFIG["roi_configs"]`
| ROI | 裁剪尺寸 `(w, h)` | 裁剪中心模式 | `virtual_fx` | 默认输入尺寸 `(w, h)` |
|---|---:|---|---:|---:|
| `ROI0` | `1920 x 880` | `cxvy` | `537.0` | `768 x 352` |
| `ROI1` | `768 x 352` | `vxvy` | `537.0` | `768 x 352` |
其中:
- `cxvy`:裁剪中心 `x` 取图像水平中心,`y` 取灭点 `vp_y`
- `vxvy`:裁剪中心 `x` 取灭点 `vp_x``y` 取灭点 `vp_y`
### 5.2 标定与灭点
当前运行时兼容扁平 `camera4.json` 与合并格式 `camera4.json`
灭点计算逻辑:
```text
vp_x = cu + focal_u * tan(yaw)
vp_y = cv - focal_v * tan(pitch)
```
### 5.3 ROI 裁剪
裁剪边界通过 `compute_centered_roi_bounds()` 计算:
```text
crop_x1 = clamp(center_x - roi_w / 2, 0, ori_w - roi_w)
crop_y1 = clamp(center_y - roi_h / 2, 0, ori_h - roi_h)
crop_x2 = crop_x1 + roi_w
crop_y2 = crop_y1 + roi_h
```
### 5.4 resize 与标定更新
当前脚本会把 ROI 图像 resize 到模型输入尺寸,并同步更新 resized ROI 坐标系下的标定:
```text
fx = focal_u * scale_x
fy = focal_v * scale_y
cx = (cu - crop_x1) * scale_x
cy = (cv - crop_y1) * scale_y
depth_scale = fx / virtual_fx
```
其中 `depth_scale` 会在 3D 后处理阶段恢复真实焦距下的深度尺度。
### 5.5 输入张量化
输入张量构造方式:
```python
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
array = image_rgb.transpose(2, 0, 1).astype(np.float32) / 256.0
input = array[None, ...]
```
注意是:
```text
/ 256.0
```
不是 `/ 255.0`
---
## 6. 输出张量设计
### 6.1 总体原则
当前部署脚本只支持每个 ROI 输出原始检测头张量。
输出张量是否包含 `preds_edge``preds_3d_fake` 由导出开关控制。
每个 ROI 至少包含:
1. `boxes_head_raw`
2. `scores_head_raw`
3. `preds_3d_head_raw`
4. `preds_diff_head_raw`
### 6.2 `drop fake_3d` 且 `drop edge`
当:
```bash
--fake-3d-branch-mode drop
--edge-head-mode drop
```
合并模型总输出为 8 个:
1. `roi0_boxes_head_raw`
2. `roi0_scores_head_raw`
3. `roi0_preds_3d_head_raw`
4. `roi0_preds_diff_head_raw`
5. `roi1_boxes_head_raw`
6. `roi1_scores_head_raw`
7. `roi1_preds_3d_head_raw`
8. `roi1_preds_diff_head_raw`
### 6.3 `keep fake_3d` 且 `drop edge`
当:
```bash
--fake-3d-branch-mode keep
--edge-head-mode drop
```
合并模型总输出为 10 个:
1. `roi0_boxes_head_raw`
2. `roi0_scores_head_raw`
3. `roi0_preds_3d_head_raw`
4. `roi0_preds_diff_head_raw`
5. `roi0_preds_3d_fake_head_raw`
6. `roi1_boxes_head_raw`
7. `roi1_scores_head_raw`
8. `roi1_preds_3d_head_raw`
9. `roi1_preds_diff_head_raw`
10. `roi1_preds_3d_fake_head_raw`
### 6.4 `keep edge` 的扩展
若再加:
```bash
--edge-head-mode keep
```
则每个 ROI 还会额外多一个:
- `roi*_preds_edge_head_raw`
### 6.5 典型 shape
对默认输入尺寸 `768 x 352`
```text
A = (352/8 * 768/8) + (352/16 * 768/16) + (352/32 * 768/32)
= 4224 + 1056 + 264
= 5544
```
所以典型输出 shape 为:
| 输出名 | 形状 | 含义 |
|---|---|---|
| `roi*_boxes_head_raw` | `[1, 4, 5544]``[1, 4*reg_max, 5544]` | 2D 框回归头原始输出 |
| `roi*_scores_head_raw` | `[1, nc, 5544]` | 分类原始 logits旧版默认 `nc=17`,新版默认 `nc=20` |
| `roi*_preds_3d_head_raw` | `[1, 41, 5544]` | 常规 3D 分支 |
| `roi*_preds_diff_head_raw` | `[1, 1, 5544]` | difficulty 二分类分支 |
| `roi*_preds_3d_fake_head_raw` | `[1, 41, 5544]` | fake class 专用 3D 分支 |
| `roi*_preds_edge_head_raw` | `[1, 60, 5544]` | edge 分支 |
注意:
- 实际 `boxes_head_raw` 通道数取决于 `reg_max`
- 旧版本文档里常见的 `[1, 4*reg_max, 5544]` 写法仍然成立
- 你当前部分导出模型如果已在导出前把 `reg_max` 相关结构折叠,也可能看到 `[1, 4, 5544]`
### 6.6 各分支语义
#### 6.6.1 `boxes_head_raw`
2D 框回归头的原始输出,逐 anchor 表示边界框回归量。
运行时需要结合 anchor 网格与 stride 做 decode不能直接作为最终 bbox。
#### 6.6.2 `scores_head_raw`
分类头的原始 logits逐 anchor、逐类输出。
运行时会先做 sigmoid再走 one-to-one Top-K 选择。
#### 6.6.3 `preds_3d_head_raw`
常规 3D 分支,适用于常规 3D 类别。
该分支输出 41 维 3D 表达,后续会按 `norm_scales_3d` 做反归一化。
#### 6.6.4 `preds_diff_head_raw`
difficulty 分支输出,每个 anchor 只有 1 维 logit。
当前训练逻辑中difficulty 被视为二分类:
- `0/1 -> easy-like`
- `2/3 -> hard-like`
部署侧目前保留该分支输出,但默认主推理可视化链路还不会直接把它画到结果图上。
#### 6.6.5 `preds_3d_fake_head_raw`
fake class 专用 3D 分支。
该分支与常规 3D 分支一样,也是 41 维,但只用于 fake 类别:
- `car_fake`
- `bicyclist_fake`
- `pedestrian_fake`
当导出模型包含这个张量且当前 detection 的 `cls_id` 落在 `fake_3d_classes` 中时,运行时会优先用它,而不是 `preds_3d_head_raw`
#### 6.6.6 `preds_edge_head_raw`
edge 分支输出 60 维。
每个面的底边缘由 5 个采样点组成,每个采样点 3 维:
```text
[du, dv, z]
```
4 个面一共 60 维。
---
## 7. 3D 分支定义
### 7.1 常规 3D 分支41 维)
通道布局:
| 通道范围 | 含义 |
|---|---|
| `0-5` | front face`z3d, u_offset, v_offset, h, w, visible_score` |
| `6-11` | rear face`z3d, u_offset, v_offset, h, w, visible_score` |
| `12-17` | left face`z3d, u_offset, v_offset, l, h, visible_score` |
| `18-23` | right face`z3d, u_offset, v_offset, l, h, visible_score` |
| `24` | whole-box `z3d` |
| `25-26` | whole-box `u_offset, v_offset` |
| `27-29` | whole-box `l, h, w` |
| `30-33` | yaw 4-bin 分类 logits |
| `34-37` | yaw 残差 `sin(delta)` |
| `38-40` | cut state logits |
### 7.2 fake 3D 分支41 维)
`preds_3d_fake_head_raw``preds_3d_head_raw` 在张量结构上完全一致,也是 41 维。
区别只在于用途:
- `preds_3d_head_raw`:常规类别使用
- `preds_3d_fake_head_raw`fake class 使用
### 7.3 edge 分支60 维)
| 面 | 通道范围 |
|---|---|
| front | `0-14` |
| rear | `15-29` |
| left | `30-44` |
| right | `45-59` |
---
## 8. 后处理设计
### 8.1 2D 框解码
运行时用 `decode_boxes_xyxy()``boxes_head_raw` 解码:
1. 还原 `l, t, r, b`
2. 与 anchor 网格中心组合
3. 乘以 stride 还原到 ROI-resized 图像坐标
anchor 由 `build_anchor_cache()` 预生成,默认 stride
```text
(8, 16, 32)
```
### 8.2 Top-K 选择
当前推理脚本沿用 one-to-one Top-K 路径:
1. 对分类 logits 做 sigmoid
2. 每个 anchor 取最大类别分数
3. 做 Top-K
4. 生成 `detections = [x1, y1, x2, y2, conf, cls_id]`
### 8.3 3D / Edge 反归一化
`preds_3d_head_raw``preds_3d_fake_head_raw``preds_edge_head_raw` 会用 `norm_scales_3d` 做反归一化:
| 项目 | 反归一化方式 |
|---|---|
| `z3d` | `raw * z3d_scale + z3d_offset` |
| `u/v offset` | `sigmoid(raw) * 16 - 8` |
| `size` | `raw * size_scale + size_offset` |
| yaw residual | `tanh(raw)` |
| edge `z` | `raw * z3d_scale + z3d_offset` |
| edge `du/dv` | `sigmoid(raw) * 16 - 8` |
默认值:
```text
z3d_scale = 24.415
z3d_offset = 39.937
size_scale = 1.945
size_offset = 3.780
yaw_scale = 1.5707963
```
### 8.4 深度恢复
部署时需要按真实焦距恢复深度尺度:
```text
preds_3d[:, (0, 6, 12, 18, 24)] *= depth_scale
preds_3d_fake[:, (0, 6, 12, 18, 24)] *= depth_scale
preds_edge[:, 2::3] *= depth_scale
```
其中:
```text
depth_scale = fx / virtual_fx
```
### 8.5 fake class 的 3D 路由
这是新版运行时与旧版的关键差异之一。
当前 exported inference 在逐检测框解码时,会做如下判断:
1. 读取 detection 的 `cls_id`
2.`cls_id in fake_3d_classes`
3. 且当前导出模型包含 `preds_3d_fake`
4. 则用 `preds_3d_fake` 作为该框的 3D 解码输入
5. 否则继续使用 `preds_3d`
也就是说:
- `keep fake_3d`fake 类别走专用 3D 分支
- `drop fake_3d` 时:所有类别都走主 `preds_3d`
### 8.6 difficulty 分支的使用
当前部署侧已经能把 `preds_diff` 读入运行时结果结构:
- `ROISelectedPredictions.preds_diff`
但默认主推理链路暂未把它用于:
- 过滤
- 合并
- 可视化绘制
- JSON 输出主字段
因此当前它的状态是:
- 已导出
- 已可解析
- 已可供后续扩展
- 默认主链路尚未深度消费
### 8.7 edge yaw 与 edge box
若导出模型包含 edge 分支,则运行时可继续执行 edge-based 诊断链:
1. 反投影可见底边缘点
2. 选择单面或双面组合
3. 计算 `edge_yaw`
4. 约束横向距离阈值
5. 重建 `edge_box`
6. 生成额外诊断信息
若使用:
```bash
--edge-head-mode drop
```
则该能力在部署侧被关闭。
---
## 9. 下游解析逻辑
### 9.1 新旧输出协议兼容
当前 `run_two_roi_exported_onnx_infer.py` 对以下情况都兼容:
1. 旧版仅 `boxes + scores + preds_3d`
2. 新版 `boxes + scores + preds_3d + preds_diff`
3. 新版 `boxes + scores + preds_3d + preds_diff + preds_3d_fake`
4. 上述版本再叠加 `preds_edge`
兼容方式为:
- 必需输出只要求旧版最小集合
- 若发现 `preds_3d_fake` / `preds_diff` / `preds_edge` 则自动启用
- 若缺失则退化为旧行为
### 9.2 建议的外部调用方式
外部调用方不要按固定 output index 写死解析逻辑。
推荐使用:
1. 先读取 `merged_model.export.json`
2.`output_names` 解析输出
原因是:
- `keep/drop fake_3d_branch` 会改变输出总数
- `keep/drop edge_head` 也会改变输出总数
---
## 10. 与旧版文档的主要差异
相对旧版双 ROI 文档,当前新版多出以下变化:
1. 新增 `preds_diff_head_raw`
2. 新增可选 `preds_3d_fake_head_raw`
3. 默认输出类别从 `17` 类扩展到 `20` 类,新增:
- `car_fake`
- `bicyclist_fake`
- `pedestrian_fake`
4. 运行时引入 `fake_3d_classes`
5. fake 类别不再强制走主 `preds_3d`
6. 导出 manifest 中新增:
- `fake_3d_branch_mode`
- `keep_fake_3d_branch`
7. 输出总数不再固定为 8
典型情况:
- 旧版 no-edge8 输出
- 新版 drop fake + drop edge8 输出
- 新版 keep fake + drop edge10 输出
- 新版 keep fake + keep edge12 输出
---
## 11. 导出示例
### 11.1 保留 fake 3D 分支
```bash
python tools/model_merging/merge_models_of_2roi_yolo26.py \
--roi0-model-path runs/detect/mono3d_roi0_20260506_epoch99.pt \
--roi1-model-path runs/detect/mono3d_roi1_20260506_epoch99.pt \
--save-dir runs/export/train_mono3d_two_roi_20260506-keep_fake_3d_branch \
--imgsz 768 352 \
--edge-head-mode drop \
--fake-3d-branch-mode keep
```
输出:
- `boxes`
- `scores`
- `preds_3d`
- `preds_diff`
- `preds_3d_fake`
### 11.2 去掉 fake 3D 分支
```bash
python tools/model_merging/merge_models_of_2roi_yolo26.py \
--roi0-model-path runs/detect/mono3d_roi0_20260506_epoch99.pt \
--roi1-model-path runs/detect/mono3d_roi1_20260506_epoch99.pt \
--save-dir runs/export/train_mono3d_two_roi_20260506-drop_fake_3d_branch \
--imgsz 768 352 \
--edge-head-mode drop \
--fake-3d-branch-mode drop
```
输出:
- `boxes`
- `scores`
- `preds_3d`
- `preds_diff`
---
## 12. 建议与注意事项
1. 如果下游要使用 fake class 的专用 3D 几何,请使用 `--fake-3d-branch-mode keep`
2. 如果只想保持旧版解析复杂度,可使用 `--fake-3d-branch-mode drop`
3. 如果外部部署程序不是本仓库当前的 `run_two_roi_exported_onnx_infer.py`,请务必按 manifest 的 `output_names` 解析。
4. `preds_diff` 当前默认未用于主要可视化与合并策略,但导出时建议保留,便于后续直接扩展。
5. `keep fake_3d``drop fake_3d` 的输出总数不同,不能混用固定 index 的后处理脚本。

View File

@@ -0,0 +1,272 @@
# 单目3D测距周期性波动问题分析与解决方案
## 1. 文档目标
本文档聚焦当前双 ROI 单目 3D 检测部署方案中出现的“目标测距周期性波动”问题,结合现有实现分析可能成因,并给出可落地的改进方案与推荐推进顺序。
本文档不替代 `tools/model_inference/docs/two_roi_model_design.md`。凡涉及当前部署链路的事实性描述,仍以现有推理脚本及其依赖模块为准。
---
## 2. 问题描述
当前模型在部分场景下会出现如下现象:
- 同一目标在连续帧中的测距结果呈现周期性起伏
- 目标实际距离变化不大,但 `z3d``center_3d.z` 存在明显波动
- 波动往往与车辆颠簸、路面不平、减速带、桥头跳车等场景同步出现
初步分析表明,该问题很可能与自车俯仰姿态变化有关。当自车颠簸时,目标在图像中的垂直位置会发生上下起伏,而当前单帧单目 3D 模型会将这类图像变化部分解释为距离变化。
---
## 3. 与当前实现的关系
### 3.1 当前实现中的关键链路
结合现有设计与代码实现,测距波动问题存在以下可能传播链路:
1. 当前灭点计算依赖静态标定中的 `pitch`
```text
vp_y = cv - focal_v * tan(pitch)
```
2. 当前 `camera4.json` 在 case 开始时加载一次,后续帧默认复用同一份标定,不会按帧更新 `pitch / roll`
3. 当前 ROI 裁剪在 `y` 方向上直接依赖 `vp_y`,也就是依赖静态俯仰角计算出的灭点位置。
4. ROI 裁剪和 resize 后,会重新计算 `fx / fy / cx / cy`,后续 3D 回投和深度恢复仍继续使用这套 ROI 坐标系下的标定。
5. 当真实车身姿态随时间变化、但运行时仍使用静态姿态来解释图像时,目标的上下漂移会被系统误解释为深度变化,最终表现为 `z3d` 周期性波动。
### 3.2 问题本质
问题本质可以概括为:
- 当前实现默认相机姿态在时序上稳定
- 实际车辆在颠簸场景下存在动态 `pitch / roll`
- 单帧视觉观测中,目标垂直位移与真实深度变化发生耦合
因此,该问题既是“相机姿态建模不足”的问题,也是“单帧深度估计对图像上下扰动敏感”的问题。
---
## 4. 解决方案分层
从工程与算法角度可以将方案分为五层逐帧姿态补偿、时序平滑、ROI 抗扰动、训练增强、几何一致性融合。
### 4.1 逐帧姿态补偿
这是最接近根因修复的方案。
核心思路:
- 获取逐帧 `pitch / roll`
- 按帧更新灭点位置、ROI 裁剪中心和相机姿态
- 必要时在进入模型前先完成图像稳定,再执行 ROI 裁剪与推理
可选实现路径:
- 接入 `IMU / CAN` 的实时姿态信号
- 无额外传感器时,基于地平线、车道线、路面结构、稳定背景点估计视觉姿态
建议改造点:
- 将静态 `camera4.json` 扩展为逐帧动态姿态输入
- 按帧更新 `vp_y`
- 按帧更新 ROI 的 `crop_center_y`
- 若结果需要映射到 ego 坐标系,则同步更新相机到 ego 的姿态变换
优点:
- 直接处理误差源头
- 同时改善 ROI 对位与 3D 回投
缺点:
- 依赖新增姿态源或新增视觉姿态估计模块
- 集成复杂度最高
### 4.2 Track 级时序平滑
这是最适合快速落地的工程方案。
核心思路:
- 不直接使用单帧 `z3d` 作为最终结果
- 先对目标建立 track
- 再对同一目标的连续帧 3D 结果做时序滤波
推荐方式:
- 基于 2D/3D 关联建立 tracking
-`center_3d.z``center_3d.x``yaw` 等量做 `EMA``Kalman Filter` 或固定窗平滑
- 根据类别、置信度、框尺寸、edge 几何一致性等动态调整测量噪声
优点:
- 不需要修改训练
- 工程改造范围小
- 对周期性抖动通常能快速见效
缺点:
- 只能抑制表现,不能消除根因
- 会引入一定延迟
### 4.3 降低 ROI 对上下抖动的敏感性
当前 ROI 在 `y` 方向上缺少独立的稳定策略,因此可以先做轻量改造。
可选方案:
- 引入独立的 `crop_center_y_mode`
- 支持 `fixed_cy`
- 支持 `smoothed_vpy`
- 支持 `blend(cv, vp_y)` 形式的加权中心
-`crop_center_y` 做低通滤波或逐帧最大步长限制
- 适当增大 ROI 高度,降低轻微颠簸引入的相对位置扰动
优点:
- 代码改动较小
- 便于快速验证问题是否主要由 ROI 跟随静态灭点触发
缺点:
- 只能缓解,不能完整表达真实动态姿态
### 4.4 训练侧抗颠簸增强
若该问题在量产场景中普遍存在,建议在训练侧显式纳入姿态扰动域。
建议方向:
- 增加 `pitch / roll` 扰动增强
- 增加垂直平移、轻微透视变化、动态模糊等增强
- 对连续帧加入时序一致性约束
- 条件允许时,将姿态信息、地平线位置或多帧特征作为额外输入
进一步方案:
- 训练轻量多帧模型
- 引入显式姿态辅助分支
- 增加地平线或路面几何中间量预测
优点:
- 可以从模型层面提升鲁棒性
缺点:
- 需要重新训练和完整回归验证
### 4.5 几何一致性融合
对于车辆类目标,可将网络输出与几何约束融合,以降低单一回归分支对上下抖动的敏感性。
可利用信息包括:
- ground plane 或接地点约束
- 目标底边缘与 edge 分支几何
- 类别尺寸先验
- 连续帧运动学先验
可选策略:
-`z3d` 与 edge / ground 几何明显冲突时,对该帧深度降权
- 将网络回归深度与几何估计深度做加权融合
- 将异常跳变作为诊断信号输出
优点:
- 提高异常帧下的可解释性
- 有助于构建更稳健的诊断链路
缺点:
- 依赖额外几何假设,适用范围需要单独验证
---
## 5. 推荐推进顺序
若目标是“先快速抑制线上波动,再逐步修复根因”,建议按以下顺序推进:
1. 先增加 `track` 级时序平滑,快速压制测距抖动
2. 同时引入 ROI `y` 向稳定策略,验证 ROI 机制的敏感性
3. 若验证表明问题与车身俯仰强相关,再接入逐帧 `pitch / roll` 补偿
4. 在训练侧加入抗颠簸增强,降低模型对垂直扰动的敏感性
5. 视业务需要补充 edge / ground / 运动学等几何一致性融合
该顺序兼顾了:
- 短期可落地性
- 中期定位能力
- 长期根因修复效果
---
## 6. 推荐实施策略
从工程收益比看,建议优先采用“两阶段策略”。
### 6.1 第一阶段:快速止血
目标:
- 尽快降低线上测距周期波动
- 快速判断问题是否主要与姿态扰动相关
建议动作:
- 增加 track 级滤波
- 为 ROI 增加 `y` 向平滑或固定策略
- 输出更多诊断字段例如平滑前后深度、ROI 中心变化量、疑似姿态扰动标记
### 6.2 第二阶段:根因修复
目标:
- 将静态姿态假设升级为动态姿态建模
建议动作:
- 接入逐帧姿态输入
- 按帧更新灭点、裁剪、回投与 ego 变换
- 联合训练增强与几何融合进一步提升鲁棒性
---
## 7. 验证建议
为了判断方案是否有效,建议重点关注以下指标:
- 同一目标连续帧 `center_3d.z` 的标准差
- 目标静稳跟车场景下的深度峰峰值
- 颠簸场景中深度频谱的主频能量
- 引入平滑后的延迟和响应速度
- ego 坐标系下 `xyzlhwyaw` 的稳定性
建议单独构建以下评测子集:
- 路面平稳场景
- 明显颠簸场景
- 远距离车辆场景
- 近距离跟车场景
- 高速桥头或减速带场景
---
## 8. 结论
当前测距周期性波动问题,很大概率与“真实动态俯仰变化”和“运行时静态姿态假设”之间的不一致有关。
从方案优先级上看:
- 短期最有效的是 `track` 级时序平滑与 ROI `y` 向稳定
- 中长期最关键的是逐帧姿态补偿
- 若要进一步提升模型鲁棒性,应结合训练增强与几何一致性融合
其中,逐帧姿态补偿是最接近根因修复的方案;其余方案更适合作为快速缓解、问题定位和整体稳健性增强手段。

View File

@@ -0,0 +1,3 @@
019cb7f4-a944-7c22-5427-5b75b25545c7
019cb801-e7af-79f1-5756-78ada964e108
019cb831-743a-7e7d-478e-b587b7b11f53

View File

@@ -0,0 +1,14 @@
019d2d81-94d4-7ab9-4d65-e90fd652c2c1
019d2d86-4a7b-72da-6e09-1e7ab3494d0b
019d3285-23db-70e6-514a-74bd4625dccd
019d3dd9-a63f-78ce-5b22-266a7341f02c
019d2d80-5ea0-7421-4993-4609caa731c7
019d2d81-3aff-7084-7647-f535e3cf831c
019d2d84-5d15-7481-530d-181d75f140ca
019d7126-ada5-7ac0-7bb4-9c43c96dbd18
019d7127-b405-7b1a-632a-d71011c12232
019d7129-30a7-742e-6bab-6ed6fbc860f0
019d7121-321f-7c62-4c7f-0115796fdd98
019d3289-e2fb-789e-7f54-e65b10a77f87 CPLA
019d3289-8e19-71f0-6d2e-56570badbaa6 CPLA
019d328b-bdf7-74fa-6e5c-0da5ff8dab71 CPLA

View File

@@ -0,0 +1,45 @@
019b178d-54a2-78b7-a2d2-0ec63d651a4d
019b18ef-ca2b-7e97-8ca5-d4b1d7eefdbb
019b29ac-d00b-7e97-96c6-de9573eb6472
019b2a13-9af3-7e97-a109-9fb7ba7a8f22
019b2a23-9885-7e97-adf6-81bfb1f7f707
019b4415-d171-7ae9-88ed-0065c4c6e1e0
019b446e-7133-7ae9-a686-034223f9376d
019b446e-71c2-71c3-afe1-7f0a988a4261
019b4687-0a6c-7c8d-b54e-51b3c5bdc6c2
019b471c-84fa-7ae9-9172-add82a30ba76
019b4731-38fb-71c3-b0a6-0e90759fc79b
019b475a-21db-7ae9-806c-15e4cdf59567
019b475e-c8f5-7ae9-b60d-96b5a9e36f3f
019b4bbf-a702-7c8d-abee-ec1ec17e66e9
019b4c4f-83c5-7aea-b364-cdaf93be8759
019b4e2c-f464-7aea-af9f-e61135bb3eed
019b661c-eb04-7029-af8c-515fd4d10a05
019b662e-49a4-781f-85f5-c2cc76921b63
019b6659-e97b-7029-a77a-6df3c01005bf
019b6659-ea8d-7029-9614-f067b92a50cf
019b674f-ebde-781f-92e8-2fd9efaf4115
019b6aa1-a8ed-7029-8b8c-68311394dade
019b6aa1-b243-7767-b03e-30423635fae3
019b6aa1-b3a5-7820-8fb8-703b5324aa37
019b6ba0-6fca-7029-9f49-010991c25574
019b6bf2-0124-7820-91b7-c5eb42150cd2
019b6bf2-01a6-7029-9232-fce2bbcd2d73
019b6c1a-07f7-7029-8dad-b327a960c8ab
019b6d98-2e01-7f56-a142-7d10b54b901e
019b6f9d-bd6e-7765-b32c-ec6c75945898
019b6fa2-e7d8-7765-a96d-d8b341fa1d92
019b70f6-7bcc-7765-a5fb-f6338d5d9494
019b70f6-7c68-7765-9fbf-fa174798c144
019b71ae-35d8-7a2c-816f-fc6cca709e79
019b731a-0b43-7a2c-a6de-629a7f8cb7bb
019b7850-bfaf-70f1-bdf0-3fa1ba836dee
019b7857-33d4-74bc-b492-de067f8e1899
019b8ddb-ae8a-70f3-b86f-055894c79724
019ba16f-fba6-762c-a961-007f0ce78e19
019ba16f-fece-718b-a51d-1bcd2414b52e
019ba185-7b16-7866-98a5-c3d5c1b136c0
019ba1d6-5faa-762c-9de7-597f2d19d55e
019ba1d8-b791-7866-866f-f556fa7405fd
019ba1d8-b998-762c-a2b9-92580ee6b16d
019ba1d8-c230-762c-9dae-f1b5d391dc04

View File

@@ -0,0 +1,186 @@
{
"input_file": "/deeplearning_team/ydong/dongying/projects/yolo26-3d/tools/model_inference/examples/cncap/G1M3_AFS1616_CNCAP-2024_11月_0306.xlsx",
"sheet_name": "G1M3_AFS1616_CNCAP-2024_11月",
"column_name": "原始数据地址",
"num_rows": 178,
"values": [
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_AEB_20_5_1_20251115140740/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_AEB_20_5_2_20251115140941/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_AEB_20_5_4_20251115141340/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_AEB_40_5_1_20251115154533/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_AEB_40_5_2_20251115154730/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_AEB_40_5_3_20251115154936/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_AEB_NIGHT_20_2_20251120190340/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_AEB_NIGHT_20_3_20251120190536/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_AEB_NIGHT_20_4_20251120200100/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_AEB_NIGHT_40_1_20251120200307/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_AEB_NIGHT_40_2_20251120200500/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_AEB_NIGHT_40_3_20251120200634/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_FCW_60_5_2_20251115160419/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_FCW_60_5_3_20251115160612/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_FCW_80_5_1_20251115161433/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_FCW_80_5_2_20251115161702/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CPLA_RL_FCW_80_5_3_20251115162115/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_FCW_NIGHT_60_1_20251120201141/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_FCW_NIGHT_60_2_20251120201314/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_FCW_NIGHT_60_3_20251120201458/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_FCW_NIGHT_80_1_20251120202048/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_FCW_NIGHT_80_2_20251120202303/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_FCW_NIGHT_80_3_20251120202606/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_20_1_20251116145122/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_20_2_20251116145250/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_20_3_20251116145409/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_40_1_20251116145541/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_40_2_20251116145658/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_40_3_20251116150142/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_60_1_20251116150405/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_60_2_20251116150531/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPFAO_AEB_60_3_20251116150722/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_20_1_20251120211354/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_20_2_20251120211541/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_20_3_20251120211658/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_40_2_20251120212613/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_40_3_20251120212936/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_40_4_20251120213053/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_60_1_20251120213326/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_60_2_20251120213531/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPFAO_AEB_NIGHT_60_4_20251120214003/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_AEB_20_15_1_20251115164146/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_AEB_20_15_2_20251115164517/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_AEB_20_15_3_20251115164652/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_AEB_40_15_1_20251115165709/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_AEB_40_15_2_20251115165908/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_AEB_40_15_3_20251115170039/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_FCW_60_15_1_20251115171927/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_FCW_60_15_2_20251115172124/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_FCW_60_15_3_20251115172426/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_FCW_80_15_1_20251115172854/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_FCW_80_15_2_20251115173342/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251115/CVE/CBLA_FCW_80_15_5_20251115174113/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_AEB_20_1_20251117112812/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_AEB_20_2_20251117112949/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_AEB_20_3_20251117113128/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_AEB_40_1_20251117113354/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_AEB_40_4_20251117114030/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_AEB_40_5_20251117114211/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_FCW_60_1_20251117114410/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_FCW_60_2_20251117114541/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251117/CVE/CCRS_FCW_60_3_20251117114726/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_FCW_80_1_20251118165115/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_FCW_80_2_20251118165417/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_FCW_80_3_20251118165714/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_AEB_30_1_20251118171813/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_AEB_30_2_20251118171927/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_AEB_30_3_20251118172047/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_FCW_50_1_20251118172359/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_FCW_50_2_20251118172529/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_FCW_50_3_20251118172648/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_FCW_70_1_20251118173427/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_FCW_70_2_20251118173727/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CCRS_RR_FCW_70_5_20251118174256/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CBNAO_AEB_20_1_20251116115843/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CBNAO_AEB_20_3_20251116120432/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CBNAO_AEB_40_2_20251116162411/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CBNAO_AEB_40_3_20251116162528/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CBNAO_AEB_40_4_20251116162828/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CBNAO_AEB_60_1_20251116163110/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CBNAO_AEB_60_2_20251116163314/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CBNAO_AEB_60_3_20251116163456/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_20_1_20251116094544/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_20_2_20251116094807/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_20_3_20251116095003/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_40_1_20251116111946/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_40_2_20251116112240/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_40_3_20251116112403/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_60_5_20251116113407/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_60_6_20251116113532/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPNCO_AEB_60_7_20251116113702/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_AEB_30_1_20251120125750/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_AEB_30_2_20251120131043/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_AEB_30_3_20251120131354/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_AEB_40_1_20251120133202/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_AEB_40_2_20251120135059/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_AEB_40_3_20251120135316/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_50_1_20251120140205/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_50_2_20251120141420/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_50_3_20251120141611/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_50_4_20251120141754/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_50_5_20251120143758/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_50_6_20251120143949/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_60_1_20251121132303/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_60_2_20251121132531/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/C2CSCP_FCW_60_3_20251120145205/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCRH_FCW_120_1_20251121142329/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCRH_FCW_120_2_20251121142615/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCRH_FCW_120_3_20251121142858/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCRH_FCW_80_1_20251121134351/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCRH_FCW_80_2_20251121134820/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCRH_FCW_80_3_20251121135124/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LF_AEB_10_1_20251116165509/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LF_AEB_10_2_20251116165624/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LF_AEB_10_3_20251116165726/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LF_AEB_20_1_20251116170243/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LF_AEB_20_2_20251116170440/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LF_AEB_20_3_20251116170553/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LF_AEB_20_4_20251116170703/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LN_AEB_10_1_20251116153118/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LN_AEB_10_2_20251116153233/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LN_AEB_10_3_20251116153353/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LN_AEB_20_1_20251116154321/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LN_AEB_20_2_20251116154424/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251116/CVE/CPTA_LN_AEB_20_3_20251116154522/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTA-RF_AEB_10_2_20251118152341/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTA-RF_AEB_10_3_20251118152502/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTA-RF_AEB_10_4_20251118152627/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTA-RF_AEB_20_1_20251118153924/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTA-RF_AEB_20_2_20251118154118/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTA-RF_AEB_20_3_20251118154310/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LF_AEB_30_1_20251118162051/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LF_AEB_30_2_20251118162258/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LF_AEB_30_3_20251118162502/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LF_AEB_30_4_20251118162753/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LN_AEB_30_1_20251118155909/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LN_AEB_30_2_20251118160410/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LN_AEB_30_3_20251118160701/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LN_AEB_30_4_20251118160910/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_20_1_20251118100252/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_20_2_20251118100507/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_20_3_20251118100811/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_20_4_20251118100943/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_40_1_20251118101132/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_40_2_20251118101308/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_40_3_20251118101449/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_40_4_20251118102012/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_60_1_20251118102439/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_60_2_20251118102648/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSFAO_AEB_60_3_20251118102842/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA-RN_AEB_10_1_20251118135544/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA-RN_AEB_10_2_20251118140105/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA-RN_AEB_10_3_20251118141436/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA-RN_AEB_10_4_20251118141606/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA-RN_AEB_10_5_20251118141805/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA-RN_AEB_20_1_20251118142701/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA-RN_AEB_20_2_20251118142901/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA-RN_AEB_20_3_20251118143114/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_10_1_20251118125212/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_10_2_20251118125425/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_10_3_20251118125731/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_20_1_20251118130844/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_20_2_20251118131325/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_20_3_20251118131506/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_20_4_20251118131706/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_30_1_20251118132854/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_30_2_20251118133333/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CSTA_LN_AEB_30_3_20251118133500/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_10_1_20251120111329/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_10_2_20251120111531/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_10_3_20251120111715/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_20_1_20251120112848/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_20_2_20251120113358/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_20_3_20251120113552/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_20_4_20251120114255/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_30_1_20251120115726/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_30_2_20251120115936/sigmastar.1",
"/mnt/hfs/project-G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CCFT_AEB_30_3_20251120120135/sigmastar.1"
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,401 @@
datetime,rawid,scene,offset,gvt_speed,vut_speed,event_uuid
20260322175850,ADAS_S751NX0Y800506T_20260402120500514190_df44c7e0f558,CPNA,75,5.0,30,019dba8a-6dba-7ea7-6158-864c5ca840b5
20260322175649,ADAS_S751NX0Y800506T_20260402120500514190_41bdeb4dc9c9,CPNA,75,5.0,30,019dba8a-71d2-7c37-57c9-fee30c51daac
20260322175205,ADAS_S751NX0Y800506T_20260402120500514190_7a0cbe1afafb,CPNA,75,5.0,30,019dba8a-7550-7db2-7ed3-f5ff17d3dbb3
20260322174325,ADAS_S751NX0Y800506T_20260402120500514190_5827b3b5ec93,CPNA,75,5.0,20,019dba8a-78d3-7e4e-43e2-b7d0566ecb42
20260322174119,ADAS_S751NX0Y800506T_20260402120500514190_17aba2ec3a91,CPNA,75,5.0,20,019dba8a-7cae-78df-6969-b210ce359472
20260322173859,ADAS_S751NX0Y800506T_20260402120500514190_d05ce02d8128,CPNA,75,5.0,20,019dba8a-80ea-73d0-72cf-d3e25d54aa43
20260322173530,ADAS_S751NX0Y800506T_20260402120500514190_4d885636e544,CPNA,25,5.0,40,019dba8a-84b3-7685-4ee6-1a776977717b
20260322173110,ADAS_S751NX0Y800506T_20260402120500514190_3121fd72c10e,CPNA,25,5.0,40,019dba8a-8899-75c9-41d2-637c2d1013d4
20260322172726,ADAS_S751NX0Y800506T_20260402120500514190_160bff7a0258,CPNA,25,5.0,40,019dba8a-8c0e-7024-6dce-aab8c15b5a8c
20260322163631,ADAS_S751NX0Y800506T_20260402120500514190_f38d79224c9b,CPNA,25,5.0,30,019dba8a-8fc2-7d9e-66f9-9066d8c47e71
20260322163412,ADAS_S751NX0Y800506T_20260402120500514190_188bbc4fd7cd,CPNA,25,5.0,30,019dba8a-94be-7449-4666-31c9070bae44
20260322162901,ADAS_S751NX0Y800506T_20260402120500514190_9ec9c9547f85,CPNA,25,5.0,30,019dba8a-983d-7c1a-6e21-ae950e359c19
20260322162319,ADAS_S751NX0Y800506T_20260402120500514190_1ae2913db09c,CPNA,25,5.0,20,019dba8a-9b90-7e99-7cce-bfabafff8ab9
20260322161344,ADAS_S751NX0Y800506T_20260402120500514190_e9e3c9e67eac,CPNA,25,5.0,20,019dba8a-9f8f-78ba-56f9-9aaccfc0a68b
20260322160034,ADAS_S751NX0Y800506T_20260402120500514190_e774fbfe04b5,CPNA,25,5.0,20,019dba8a-a2fd-7cd8-507b-748aecd99ee6
20260322154206,ADAS_S751NX0Y800506T_20260402120500514190_2cae2b77af35,CPFA,50,6.5,30,019dba8a-a68f-72a6-62e6-1f870ef06880
20260322154017,ADAS_S751NX0Y800506T_20260402120500514190_18742842430a,CPFA,50,6.5,30,019dba8a-aa11-7937-7299-50e612807225
20260322153820,ADAS_S751NX0Y800506T_20260402120500514190_88239721e460,CPFA,50,6.5,30,019dba8a-adb4-7008-5783-6777b442c00d
20260322153301,ADAS_S751NX0Y800506T_20260402120500514190_e843fb7f3356,CPFA,50,6.5,20,019dba8a-b4fd-7bcc-5eea-3ebd69418d2f
20260322152819,ADAS_S751NX0Y800506T_20260402120500514190_56ffe9a635e2,CPFA,50,6.5,20,019dba8a-b873-76a5-53f9-b587a63998f5
20260322152509,ADAS_S751NX0Y800506T_20260402120500514190_55e385cadd8f,CPFA,50,6.5,20,019dba8a-bcaa-7a83-65a1-b4e2be991e90
20260323151226,ADAS_S751NX0Y800506T_20260402120500514190_9bfcc283ca9f,CPFA,25,6.5,60,019dba8b-9d64-76b1-7952-46899675e6b7
20260323150956,ADAS_S751NX0Y800506T_20260402120500514190_3f67a521af37,CPFA,25,6.5,60,019dba8b-a4d0-7f78-4e07-171b4b6fd04f
20260323150051,ADAS_S751NX0Y800506T_20260402120500514190_832aca065af3,CPFA,25,6.5,60,019dba8b-a980-7e97-6891-d9404946ad3a
20260323142614,ADAS_S751NX0Y800506T_20260402120500514190_b840a33bb533,CPFA,25,6.5,50,019dba8b-ae8d-7ddb-5b73-ea9d44b373b4
20260323142435,ADAS_S751NX0Y800506T_20260402120500514190_0cd79bd65838,CPFA,25,6.5,50,019dba8b-b507-7f98-7702-b7db890c40fe
20260323142206,ADAS_S751NX0Y800506T_20260402120500514190_8509ac645d11,CPFA,25,6.5,50,019dba8b-ba4e-7c3e-655e-0ce237eebf1c
20260323141946,ADAS_S751NX0Y800506T_20260402120500514190_257c4d40a320,CPFA,25,6.5,40,019dba8b-bd96-7937-6b97-d81bf764b42f
20260323140816,ADAS_S751NX0Y800506T_20260402120500514190_5852cf241628,CPFA,25,6.5,40,019dba8b-c31a-7327-6f84-61b66598e4de
20260323140108,ADAS_S751NX0Y800506T_20260402120500514190_084f8d8a14ff,CPFA,25,6.5,40,019dba8b-c81f-7e39-6bf6-b163da68789b
20260323114938,ADAS_S751NX0Y800506T_20260402120500514190_a004524019b0,CPFA,25,6.5,30,019dba8b-cef9-7fc3-5d3a-e566162fb14d
20260323114629,ADAS_S751NX0Y800506T_20260402120500514190_ab11efa628ee,CPFA,25,6.5,30,019dba8b-d39b-7461-6911-f8fa3c698828
20260323113832,ADAS_S751NX0Y800506T_20260402120500514190_36dade09baea,CPFA,25,6.5,20,019dba8b-d733-7158-7322-b3a79ad240b5
20260323113612,ADAS_S751NX0Y800506T_20260402120500514190_68e77ef5aa44,CPFA,25,6.5,20,019dba8b-dc52-725a-6164-f54217be3322
20260323113249,ADAS_S751NX0Y800506T_20260402120500514190_91fe5e43236d,CPFA,50,6.5,60,019dba8b-e0ec-7898-41fe-2e7c99bfa4c5
20260323113007,ADAS_S751NX0Y800506T_20260402120500514190_4c9b9263a276,CPFA,50,6.5,60,019dba8b-e560-71f5-47d1-9a47f71d2486
20260323112758,ADAS_S751NX0Y800506T_20260402120500514190_119e9e58e546,CPFA,50,6.5,60,019dba8b-e928-7b8b-45d9-bd5a3aa357d0
20260323112515,ADAS_S751NX0Y800506T_20260402120500514190_f6dcf99a5ca1,CPFA,50,6.5,50,019dba8b-ece3-737b-4212-613b8128cd83
20260323112255,ADAS_S751NX0Y800506T_20260402120500514190_7d7a31a63e86,CPFA,50,6.5,50,019dba8b-f27e-7117-5f7c-1486db8bf775
20260323112055,ADAS_S751NX0Y800506T_20260402120500514190_532d066d050d,CPFA,50,6.5,50,019dba8b-f6eb-7b46-450e-a2c071792e36
20260323111755,ADAS_S751NX0Y800506T_20260402120500514190_79b8ac183c24,CPFA,50,6.5,40,019dba8b-fa4f-7ce8-4bff-9e568881e959
20260323111522,ADAS_S751NX0Y800506T_20260402120500514190_b93edaab8c70,CPFA,50,6.5,40,019dba8b-fe00-75ac-746e-1462d5eba7c5
20260323111334,ADAS_S751NX0Y800506T_20260402120500514190_af02999872b1,CPFA,50,6.5,40,019dba8c-0165-7dda-56fe-5447b413082e
20260324174238,ADAS_S751NX0Y800506T_20260402120500514190_e113d246ac8a,CPNA,75,5.0,60,019dba8c-3c06-7577-515d-1b415add0b64
20260324173924,ADAS_S751NX0Y800506T_20260402120500514190_747514674cb5,CPNA,75,5.0,60,019dba8c-4003-71d1-4be4-60e61f8ee1d6
20260324173139,ADAS_S751NX0Y800506T_20260402120500514190_ba8b47506266,CPNA,75,5.0,60,019dba8c-441c-7a49-4b3e-c7b3cc2f455a
20260324172833,ADAS_S751NX0Y800506T_20260402120500514190_20ff1981dcd9,CPNA,75,5.0,50,019dba8c-4a81-79ea-530a-6d8e24f8fa55
20260324172558,ADAS_S751NX0Y800506T_20260402120500514190_fc2ec8859218,CPNA,75,5.0,50,019dba8c-8a61-70ac-48b6-aad76a1df1bc
20260324172350,ADAS_S751NX0Y800506T_20260402120500514190_6d1f2fdaffe1,CPNA,75,5.0,50,019dba8c-9193-7803-50c3-051a99f1a74f
20260324172117,ADAS_S751NX0Y800506T_20260402120500514190_14bcdf9bf591,CPNA,75,5.0,40,019dba8c-9744-7a3f-72a5-7a3769d61b3a
20260324171844,ADAS_S751NX0Y800506T_20260402120500514190_fc3b19e58c4b,CPNA,75,5.0,40,019dba8c-9ccc-7acb-4242-cb82cba15ffc
20260324165218,ADAS_S751NX0Y800506T_20260402120500514190_2c6193e79a1b,CPNA,25,5.0,60,019dba8c-a624-7342-681f-72a187ecd3e1
20260324164151,ADAS_S751NX0Y800506T_20260402120500514190_765b60cf1fe3,CPNA,25,5.0,60,019dba8c-a971-747a-6253-d7b5cbdeca3f
20260324161933,ADAS_S751NX0Y800506T_20260402120500514190_25c2f29a8f42,CPNA,25,5.0,50,019dba8c-adc3-7e77-6900-8ee40e9167de
20260325181249,ADAS_S751NX0Y800506T_20260402120500514190_a6bb10ce6479,CPLA,25,5.0,30,019dba8c-df89-7a07-4c90-6c1384a83f89
20260325180857,ADAS_S751NX0Y800506T_20260402120500514190_6033ca518600,CPLA,25,5.0,30,019dba8c-e80f-7a40-7545-8778073cd4a9
20260325180602,ADAS_S751NX0Y800506T_20260402120500514190_04ab6361c6f8,CPLA,25,5.0,30,019dba8c-efc0-729a-4ed1-bfc4765a8b8a
20260325180337,ADAS_S751NX0Y800506T_20260402120500514190_e463db00873c,CPLA,25,5.0,20,019dba8c-fac6-78fe-66f5-8c188d47193d
20260325180145,ADAS_S751NX0Y800506T_20260402120500514190_c2c07583877e,CPLA,25,5.0,20,019dba8c-ff1a-78b1-45c0-c3cb9b7fe17b
20260325175106,ADAS_S751NX0Y800506T_20260402120500514190_30ce60e0d63d,CPLA,25,5.0,20,019dba8d-03ff-7dbb-7726-6072569fdbdb
20260325172254,ADAS_S751NX0Y800506T_20260402120500514190_072cb4411b63,CSFA,50,20.0,60,019dba8d-0c92-72be-5401-d3b6c808e155
20260325171905,ADAS_S751NX0Y800506T_20260402120500514190_dfbc1dbd393c,CSFA,50,20.0,60,019dba8d-1377-7a61-6259-ee58519c1f2c
20260325170448,ADAS_S751NX0Y800506T_20260402120500514190_f83a9601f577,CSFA,50,20.0,60,019dba8d-1900-7e31-7e13-939985c88c24
20260325170106,ADAS_S751NX0Y800506T_20260402120500514190_2c54e25cb32f,CSFA,50,20.0,50,019dba8d-1cc8-72b5-4762-d7ce61ca9a8f
20260325165620,ADAS_S751NX0Y800506T_20260402120500514190_7389767ab909,CSFA,50,20.0,50,019dba8d-2045-72c5-603a-af19182d9279
20260325165344,ADAS_S751NX0Y800506T_20260402120500514190_e95155ae8f08,CSFA,50,20.0,50,019dba8d-27ad-72af-7a44-61659faf5fd2
20260325165101,ADAS_S751NX0Y800506T_20260402120500514190_1fe6d0c95742,CSFA,50,20.0,40,019dba8d-3aa4-7535-74b5-40c2664d916c
20260325164557,ADAS_S751NX0Y800506T_20260402120500514190_5779b22a5c73,CSFA,50,20.0,40,019dba8d-4432-72b9-65bf-a7469b53e92a
20260325164019,ADAS_S751NX0Y800506T_20260402120500514190_b224bea0ddbb,CSFA,50,20.0,40,019dba8d-49da-791e-6a8d-888d048776f6
20260325163640,ADAS_S751NX0Y800506T_20260402120500514190_d6f39345461f,CSFA,50,20.0,30,019dba8d-4e2d-766f-41ef-a9d706dd6b14
20260325163344,ADAS_S751NX0Y800506T_20260402120500514190_12f793d51613,CSFA,50,20.0,30,019dba8d-5244-7c4b-5154-8f67232a9fcf
20260325160450,ADAS_S751NX0Y800506T_20260402120500514190_e2efe25a6880,CSFA,50,20.0,30,019dba8d-57ff-7056-6808-a60b07d1a70d
20260325153627,ADAS_S751NX0Y800506T_20260402120500514190_a2ca26a51193,CBNA,50,15.0,60,019dba8d-5f80-702b-57d2-52dcd6e8f914
20260325153201,ADAS_S751NX0Y800506T_20260402120500514190_bf145238287f,CBNA,50,15.0,60,019dba8d-6933-7d3e-7039-92af7f4913aa
20260325151329,ADAS_S751NX0Y800506T_20260402120500514190_0b861057a7d9,CBNA,50,15.0,50,019dba8d-6e1b-735a-70ad-b297ffc7c1c8
20260325150516,ADAS_S751NX0Y800506T_20260402120500514190_26d04cf53d23,CBNA,50,15.0,50,019dba8d-7231-77a8-5c8f-c9953ee04d96
20260325150059,ADAS_S751NX0Y800506T_20260402120500514190_1aa11c5aeba7,CBNA,50,15.0,50,019dba8d-7a28-7d05-7761-8f8c6f7d40a2
20260325145759,ADAS_S751NX0Y800506T_20260402120500514190_38491776ee5a,CBNA,50,15.0,40,019dba8d-7ec0-71b4-4e23-8212e624c34e
20260325145539,ADAS_S751NX0Y800506T_20260402120500514190_a05517753a60,CBNA,50,15.0,40,019dba8d-82b2-7fc4-7b6d-63cbb1ce20e6
20260325145316,ADAS_S751NX0Y800506T_20260402120500514190_a5d59f3e0de2,CBNA,50,15.0,40,019dba8d-8775-7f47-5f49-4b816ccfa55f
20260325144443,ADAS_S751NX0Y800506T_20260402120500514190_8991319529c4,CBNA,50,15.0,30,019dba8d-8d91-76bd-5bac-05a1c88be6e1
20260325144228,ADAS_S751NX0Y800506T_20260402120500514190_154ac0410795,CBNA,50,15.0,30,019dba8d-9280-78e1-4f43-21e7f891ef13
20260325142826,ADAS_S751NX0Y800506T_20260402120500514190_25b1c474d0bb,CBNA,50,15.0,30,019dba8d-9876-75ca-6228-3852a33be169
20260325142109,ADAS_S751NX0Y800506T_20260402120500514190_83ab0ea00dc7,CBNA,50,15.0,20,019dba8d-9f36-7a3c-5528-a3e87a3ff57a
20260325141355,ADAS_S751NX0Y800506T_20260402120500514190_369491fcade7,CBNA,50,15.0,20,019dba8d-a510-7f61-6e11-41b6a1365217
20260325140126,ADAS_S751NX0Y800506T_20260402120500514190_57283841b369,CBNA,50,15.0,20,019dba8d-ab06-74df-7b01-7fe7576c7888
20260326181430,ADAS_S751NX0Y601865J_20260328113450259688_1e9541a7d2c7,CPLA,50,5.0,50,019dba8d-bf15-777f-4952-c6680aca4c1e
20260326180301,ADAS_S751NX0Y601865J_20260328113450259688_713766bcf1f2,CPLA,50,5.0,50,019dba8d-c3ff-7f5b-7ced-a19828dbdd94
20260326175733,ADAS_S751NX0Y601865J_20260328113450259688_43fbd00148aa,CPLA,50,5.0,50,019dba8d-c87a-70bc-480f-e37a9c2c6a0c
20260326174803,ADAS_S751NX0Y601865J_20260328113450259688_1ced9e7a5ff4,CBLA-CN21,50,15.0,60,019dba8d-cd58-783e-5ef9-fd9c655a8ada
20260326174513,ADAS_S751NX0Y601865J_20260328113450259688_183e46d60337,CBLA-CN21,50,15.0,60,019dba8d-d21e-7ef7-5e82-6e0df2672823
20260326173610,ADAS_S751NX0Y601865J_20260328113450259688_559e79696f59,CBLA-CN21,50,15.0,60,019dba8d-d707-7b92-796c-e9efb20c179d
20260326171109,ADAS_S751NX0Y601865J_20260328113450259688_490ba9b95ba9,CBLA-CN21,50,15.0,50,019dba8d-dc89-7f13-493e-ca1d492ad142
20260326170202,ADAS_S751NX0Y601865J_20260328113450259688_347a11543c73,CBLA-CN21,50,15.0,50,019dba8d-e0ff-731d-6ee9-b6d77b1a89f4
20260326164438,ADAS_S751NX0Y601865J_20260328113450259688_5241e2ff36e4,CBLA-CN21,50,15.0,50,019dba8d-e717-74bc-7616-4cd4feb90dea
20260326164202,ADAS_S751NX0Y601865J_20260328113450259688_10e68e264ee3,CBLA-CN21,50,15.0,40,019dba8d-ec33-75e6-784b-6b652685bd1a
20260326162358,ADAS_S751NX0Y601865J_20260328113450259688_2b77ce9a349e,CBLA-CN21,50,15.0,40,019dba8d-f191-7302-7488-9f1fda4f8bba
20260326162136,ADAS_S751NX0Y601865J_20260328113450259688_900166524e3b,CBLA-CN21,50,15.0,40,019dba8d-f5ec-756f-7f21-3367acc845a3
20260326161852,ADAS_S751NX0Y601865J_20260328113450259688_67fd2a079d1d,CBLA-CN21,50,15.0,30,019dba8d-fc3c-73dd-582b-1399182fd5bc
20260326161642,ADAS_S751NX0Y601865J_20260328113450259688_fd8ae38ed3ef,CBLA-CN21,50,15.0,30,019dba8e-02d0-7c88-49fb-085e3437eada
20260326161154,ADAS_S751NX0Y601865J_20260328113450259688_8d0bdc3af3ad,CBLA-CN21,50,15.0,30,019dba8e-08e7-7519-7dc7-f4a077a7a73d
20260326160814,ADAS_S751NX0Y601865J_20260328113450259688_46197d491ed8,CBLA-CN21,50,15.0,20,019dba8e-1062-7f53-702d-ff7c593e020e
20260326155847,ADAS_S751NX0Y601865J_20260328113450259688_f55db8debcca,CBLA-CN21,50,15.0,20,019dba8e-189b-72b8-612a-9504d52fab99
20260326153031,ADAS_S751NX0Y601865J_20260328113450259688_336615afba11,CPLA,50,5.0,60,019dba8e-1ea1-709e-52ed-95d228e800d1
20260326152808,ADAS_S751NX0Y601865J_20260328113450259688_740131f6e72c,CPLA,50,5.0,60,019dba8e-274b-75e0-7f9e-adfd1a86b923
20260326152355,ADAS_S751NX0Y601865J_20260328113450259688_1f80da22f45a,CPLA,50,5.0,60,019dba8e-3255-7ba6-689e-0df1a6329004
20260326144728,ADAS_S751NX0Y601865J_20260328113450259688_010690530eb1,CPLA,50,5.0,40,019dba8e-4d61-717b-5331-405c302917da
20260326144521,ADAS_S751NX0Y601865J_20260328113450259688_88f480b20482,CPLA,50,5.0,40,019dba8e-53ad-7fc8-4112-5fec894af7d9
20260326144301,ADAS_S751NX0Y601865J_20260328113450259688_11edf0db8552,CPLA,50,5.0,40,019dba8e-5864-761c-7e3c-6778151f6515
20260326143953,ADAS_S751NX0Y601865J_20260328113450259688_31374e23ea52,CPLA,50,5.0,30,019dba8e-5e3e-7f71-4bf4-42d174dda454
20260326143553,ADAS_S751NX0Y601865J_20260328113450259688_208c31032ab7,CPLA,50,5.0,30,019dba8e-653e-7350-7f96-54bf58ecd18d
20260326143325,ADAS_S751NX0Y601865J_20260328113450259688_890e13a19330,CPLA,50,5.0,30,019dba8e-6bcb-7b38-42f0-821b34cf3881
20260326143002,ADAS_S751NX0Y601865J_20260328113450259688_253cc2246a46,CPLA,50,5.0,20,019dba8e-7358-7062-6dc4-6d75f763f51c
20260326141816,ADAS_S751NX0Y601865J_20260328113450259688_968bbf10d481,CPLA,50,5.0,20,019dba8e-7ecd-7010-765a-37ff228578bb
20260326141456,ADAS_S751NX0Y601865J_20260328113450259688_7089abe3283f,CPLA,50,5.0,20,019dba8e-8260-7436-7560-c44860a34ddb
20260326121348,ADAS_S751NX0Y601865J_20260328113450259688_434da435af46,CPLA,25,5.0,40,019dba8e-892e-7527-59df-97eb0cd6ba13
20260326120929,ADAS_S751NX0Y601865J_20260328113450259688_19aa5768291c,CPLA,25,5.0,40,019dba8e-8e70-7609-6e15-004dd8b4e3c5
20260326113327,ADAS_S751NX0Y601865J_20260328113450259688_cf29bc58f910,CPLA,25,5.0,40,019dba8e-9518-7a09-599b-5064d89540f2
20260327164844,ADAS_S751NX0Y601739V_20260330104120600319_b8ffb91ad5b3,CCRS,-50,0.0,20,019dba8e-a1eb-759c-5e99-d91414dbcb65
20260327164715,ADAS_S751NX0Y601739V_20260330104120600319_25960516b170,CCRS,-50,0.0,20,019dba8e-a70f-72ac-7996-79cec1bab193
20260327163408,ADAS_S751NX0Y601739V_20260330104120600319_2bcd36764fdc,CCRS,-50,0.0,20,019dba8e-adc1-7a3f-4e2a-bdfa804aa9a1
20260327160636,ADAS_S751NX0Y601739V_20260330104120600319_5e14779592f2,CCRS,100,0.0,40,019dba8e-b4be-739a-5297-d7b60f37f030
20260327155725,ADAS_S751NX0Y601739V_20260330104120600319_44d7b1f69620,CCRS,100,0.0,40,019dba8e-b913-7be7-4071-4e349a8bb241
20260327155538,ADAS_S751NX0Y601739V_20260330104120600319_eb4efa485513,CCRS,100,0.0,40,019dba8e-be43-7519-589e-a06a5e71a75d
20260327153617,ADAS_S751NX0Y601739V_20260330104120600319_4f029dbe74a6,CCRS,100,0.0,30,019dba8e-c22f-7a21-4b8c-a4828bc3bd5a
20260327152708,ADAS_S751NX0Y601739V_20260330104120600319_c84cd8106f77,CCRS,100,0.0,30,019dba8e-c6ac-7d85-7c7d-64e4dfb6b36a
20260327151710,ADAS_S751NX0Y601739V_20260330104120600319_eb5e6353a9b5,CCRS,100,0.0,30,019dba8e-cccf-7893-48ea-3325a5c5ab52
20260327150850,ADAS_S751NX0Y601739V_20260330104120600319_96c7a7f2338c,CCRS,100,0.0,20,019dba8e-d206-713a-69d8-0c350ff48f24
20260327150639,ADAS_S751NX0Y601739V_20260330104120600319_c06f5150f502,CCRS,100,0.0,20,019dba8e-d61d-7256-536b-e6b1dbf769c4
20260327150038,ADAS_S751NX0Y601739V_20260330104120600319_4b079fa4769c,CCRS,100,0.0,20,019dba8e-dae4-7c57-40c8-da652cb563eb
20260327115408,ADAS_S751NX0Y601739V_20260330104120600319_89971a38a795,CCRM,100,20.0,40,019dba8e-dfa7-79b3-76d7-ea9ef016e0fe
20260327115052,ADAS_S751NX0Y601739V_20260330104120600319_9fde171dd0c5,CCRM,100,20.0,40,019dba8e-e685-75e5-5a4e-a0555eecf3aa
20260327113709,ADAS_S751NX0Y601739V_20260330104120600319_310c2fb9e063,CCRM,100,20.0,40,019dba8e-eb36-79a9-56dc-5a777e892f92
20260327112148,ADAS_S751NX0Y601739V_20260330104120600319_71c00fa5c46c,CCRM,100,20.0,30,019dba8e-effd-731c-481d-0e8c2bd318e3
20260327111430,ADAS_S751NX0Y601739V_20260330104120600319_49f67f0f4c84,CCRM,100,20.0,30,019dba8e-f43e-7095-4bd1-83e7a1623df2
20260327110922,ADAS_S751NX0Y601739V_20260330104120600319_d9c5e242cd43,CCRM,100,20.0,30,019dba8e-f9e8-7230-7426-8beae71bc750
20260329154913,ADAS_S5STNF0T504465N_20260330162214124146_0491e7efbd55,CCRS,100,0.0,60,019dba8e-fe8c-74b0-5020-04219d015632
20260329154719,ADAS_S5STNF0T504465N_20260330162214124146_6bc547d69cf8,CCRS,100,0.0,60,019dba8f-036c-7eaf-6636-653468b7bb3b
20260329154536,ADAS_S5STNF0T504465N_20260330162214124146_a82545a4fac4,CCRS,100,0.0,50,019dba8f-0896-7317-6a4e-ae75c0ebab7c
20260329154203,ADAS_S5STNF0T504465N_20260330162214124146_e0dfc76d03a5,CCRS,100,0.0,50,019dba8f-0ccb-71d4-5be7-b8cfb15bb6f0
20260329142003,ADAS_S5STNF0T504465N_20260330162214124146_c74af4cc5253,CCRS,-50,0.0,40,019dba8f-3e92-70ab-408c-7ffce13cd657
20260329141813,ADAS_S5STNF0T504465N_20260330162214124146_370de986d132,CCRS,-50,0.0,40,019dba8f-4244-7d9f-6c58-6888367f5ffd
20260329120223,ADAS_S5STNF0T504465N_20260330162214124146_28f2102c8b7d,CCRS,-50,0.0,40,019dba8f-4864-7226-6921-6248ac3e0cb7
20260329115326,ADAS_S5STNF0T504465N_20260330162214124146_73d6bf86aabf,CCRS,50,0.0,30,019dba8f-54d6-7cdf-4702-c00b0e1ee340
20260329115057,ADAS_S5STNF0T504465N_20260330162214124146_22ec55135ffb,CCRS,50,0.0,30,019dba8f-5945-75a8-6bf2-ecd05a34755f
20260329114336,ADAS_S5STNF0T504465N_20260330162214124146_c68c2ee15588,CCRS,50,0.0,30,019dba8f-5d2f-7a1d-6bad-78ead7afc89d
20260331175331,ADAS_S5STNF0T406280R_20260402104850269428_d22b22f0957c,CPNA,25,5.0,60,019dba8f-873f-7bba-6f02-448274ca1cfd
20260331163715,ADAS_S5STNF0T406280R_20260402104850269428_53960b821f6f,CPNA,75,5.0,40,019dba8f-a46a-7861-45f4-4366c3a1851c
20260331151454,ADAS_S5STNF0T406280R_20260402104850269428_98e24c39222d,CPNA,25,5.0,50,019dba8f-d397-79d5-7e79-cdb2b84dd620
20260331151250,ADAS_S5STNF0T406280R_20260402104850269428_f0cf082bc503,CPNA,25,5.0,50,019dba8f-d8e8-7886-5c86-b70a49d7cf07
20260401105643,ADAS_S5STNF0T504465N_20260402191154995992_22c18553e90d,CBNA,50,15.0,60,019dba7e-fede-7b33-5088-856cadb9f663
20260402163705,ADAS_S751NX0Y601865J_20260404102607981812_a61254e06e07,CCRM,100,20.0,FCW70,019dba82-192f-7a87-5d00-ab7caf376a6c
20260402161029,ADAS_S751NX0Y601865J_20260404102607981812_8e62c1e285e4,CCRM,50,20.0,50,019dba82-21c1-7551-4315-9753aaf80d19
20260402160740,ADAS_S751NX0Y601865J_20260404102607981812_88676757d6a7,CCRM,50,20.0,50,019dba82-2bc2-7045-7f2d-3471a81da6c5
20260402160313,ADAS_S751NX0Y601865J_20260404102607981812_85683577a86c,CCRM,50,20.0,50,019dba82-3312-7a73-670b-b0a071570a7c
20260402155719,ADAS_S751NX0Y601865J_20260404102607981812_59d8b2bb7b26,CCRM,100,20.0,50,019dba82-3db1-7c70-7f71-00aac10e069f
20260402155441,ADAS_S751NX0Y601865J_20260404102607981812_83a21145e104,CCRM,100,20.0,50,019dba82-474f-7d9b-4930-a6da99da2524
20260402140527,ADAS_S751NX0Y601865J_20260404102607981812_94a82a4fc7ed,CCRM,100,20.0,50,019dba82-4fbc-7403-457b-29842a656fa3
20260402112926,ADAS_S751NX0Y601865J_20260404102607981812_9d1774bc6384,CCRM,-50,20.0,40,019dba82-761b-7d10-4499-5a77b88cc146
20260402112746,ADAS_S751NX0Y601865J_20260404102607981812_66692e40d317,CCRM,-50,20.0,40,019dba82-7c59-76ec-5d20-6327cf819094
20260402112422,ADAS_S751NX0Y601865J_20260404102607981812_169c8d652d38,CCRM,-50,20.0,40,019dba82-81a0-7252-43d2-9f4b1d9a497f
20260402104850,ADAS_S751NX0Y601865J_20260404102607981812_9d2cab2c0acc,CCRM,50,20.0,30,019dba82-9f89-728e-7730-8c6a71cdd37f
20260402104654,ADAS_S751NX0Y601865J_20260404102607981812_6dc1ef0b9205,CCRM,50,20.0,30,019dba82-a6d3-73e1-7ec1-32c4a371507d
20260402104227,ADAS_S751NX0Y601865J_20260404102607981812_440893f8545b,CCRM,50,20.0,30,019dba82-acf6-7c89-6855-f1d4920fcacc
20260403111717,ADAS_S751NX0Y601739V_20260404180449233610_5e1c121e3173,CPLA,25,5.0,FCW80,019dba84-a4fc-793c-5e97-c56d370aa46f
20260403111530,ADAS_S751NX0Y601739V_20260404180449233610_60322c693233,CPLA,25,5.0,FCW80,019dba84-a828-7b0b-6dbb-5426ddd3f782
20260403111209,ADAS_S751NX0Y601739V_20260404180449233610_0090dd8e218e,CPLA,25,5.0,FCW80,019dba84-ac55-7507-793f-6b1b83c171c9
20260403110410,ADAS_S751NX0Y601739V_20260404180449233610_5e216b122d19,CPLA,25,5.0,FCW70,019dba84-afb5-7412-6f5a-0f209e51e0be
20260403110146,ADAS_S751NX0Y601739V_20260404180449233610_0af677bafa70,CPLA,25,5.0,FCW70,019dba84-b302-7a2f-55b1-55d74ca34b97
20260403105607,ADAS_S751NX0Y601739V_20260404180449233610_77171219d205,CPLA,25,5.0,FCW70,019dba84-b659-73f9-6f2d-2bfbf4e2b661
20260403105245,ADAS_S751NX0Y601739V_20260404180449233610_d69464e39b14,CPLA,25,5.0,FCW60,019dba84-ba6b-76da-4ccc-99233bcff685
20260403105025,ADAS_S751NX0Y601739V_20260404180449233610_e29f23ae0340,CPLA,25,5.0,FCW60,019dba84-bd90-70bc-619f-b8dde6b730e8
20260403104553,ADAS_S751NX0Y601739V_20260404180449233610_2bcd8b998839,CPLA,25,5.0,FCW60,019dba84-c0c7-7183-5e8d-870fc4d04964
20260403104107,ADAS_S751NX0Y601739V_20260404180449233610_c1e13502a0e1,CPLA,25,5.0,FCW50,019dba84-c4af-7d97-7e6d-b6239722ec96
20260403103901,ADAS_S751NX0Y601739V_20260404180449233610_9ba0984bad5a,CPLA,25,5.0,FCW50,019dba84-c809-743e-5080-1de74eb35b5a
20260403103238,ADAS_S751NX0Y601739V_20260404180449233610_349b6b6c98d3,CPLA,25,5.0,FCW50,019dba84-cb24-71cb-47cf-0fb636fe7071
20260407235712,ADAS_S5STNF0T406280R_20260409152111002995_efab4f9a5f9e,CPLA-夜晚,50.0,5.0,40,019d9aa9-076e-7b24-5f16-a4774edf4093
20260407235601,ADAS_S5STNF0T406280R_20260409152111002995_cfeadccd6caf,CPLA-夜晚,50.0,5.0,40,019d9aa9-0f61-7497-7d99-c5748212bfc8
20260407235425,ADAS_S5STNF0T406280R_20260409152111002995_49e7f088e808,CPLA-夜晚,50.0,5.0,30,019d9aa9-15e1-7e51-41cc-c6a705f1dd9a
20260407235247,ADAS_S5STNF0T406280R_20260409152111002995_3c85c3558988,CPLA-夜晚,50.0,5.0,30,019d9aa9-1b86-72f8-5625-626e1d10850a
20260407235041,ADAS_S5STNF0T406280R_20260409152111002995_24f188716448,CPLA-夜晚,50.0,5.0,20,019d9aa9-21b4-7853-54b1-bf3e6771ffc2
20260407234858,ADAS_S5STNF0T406280R_20260409152111002995_5b39e9130eb2,CPLA-夜晚,50.0,5.0,20,019d9aa9-26b6-7452-51e8-a185ef8f03f9
20260407234222,ADAS_S5STNF0T406280R_20260409152111002995_425ba64c99f3,CPLA-夜晚,25.0,5.0,FCW80,019d9aa9-2b19-73e6-4765-3c7d280b3ee6
20260407234024,ADAS_S5STNF0T406280R_20260409152111002995_bb954963fead,CPLA-夜晚,25.0,5.0,FCW80,019d9aa9-30c5-7636-549f-81144cc4f62e
20260407233737,ADAS_S5STNF0T406280R_20260409152111002995_409f58cad2b1,CPLA-夜晚,25.0,5.0,FCW70,019d9aa9-3496-7948-5037-2a02204cc43e
20260407233549,ADAS_S5STNF0T406280R_20260409152111002995_dd98b096d792,CPLA-夜晚,25.0,5.0,FCW70,019d9aa9-3977-7d5b-652d-66a266e6c60a
20260407233339,ADAS_S5STNF0T406280R_20260409152111002995_c105bad6812b,CPLA-夜晚,25.0,5.0,FCW60,019d9aa9-4051-7b14-5e87-20cd3532ef90
20260407233159,ADAS_S5STNF0T406280R_20260409152111002995_8065a4b59db6,CPLA-夜晚,25.0,5.0,FCW60,019d9aa9-4536-7af2-6562-40e4b9c89ccc
20260407232758,ADAS_S5STNF0T406280R_20260409152111002995_851306838843,CPLA-夜晚,25.0,5.0,FCW50,019d9aa9-48a9-7e39-6d1d-9ed1732bfbb9
20260407232406,ADAS_S5STNF0T406280R_20260409152111002995_877fb48c53e8,CPLA-夜晚,25.0,5.0,FCW50,019d9aa9-4cd4-77d7-7aa5-0b4314a7fd3e
20260407231753,ADAS_S5STNF0T406280R_20260409152111002995_d89ac36f740c,CPLA-夜晚,25.0,5.0,FCW50,019d9aa9-5140-7c6c-5cc1-ae1058843056
20260407225130,ADAS_S5STNF0T406280R_20260409152111002995_92dd871fc3bd,CPFAO-夜晚,25.0,6.5,60,019d9aa9-556c-7ab5-5d3f-6e63014ce80b
20260407224321,ADAS_S5STNF0T406280R_20260409152111002995_797f2a520f7f,CPFAO-夜晚,25.0,6.5,60,019d9aa9-5aaa-7b33-6455-8489710518a9
20260407224125,ADAS_S5STNF0T406280R_20260409152111002995_955748274b43,CPFAO-夜晚,25.0,6.5,60,019d9aa9-6119-7cc4-7699-7f644dc2a964
20260407223853,ADAS_S5STNF0T406280R_20260409152111002995_f5829f94e220,CPFAO-夜晚,25.0,6.5,40,019d9aa9-65aa-7748-63fd-6b9ada70eef2
20260407223726,ADAS_S5STNF0T406280R_20260409152111002995_9dd57efb9e3f,CPFAO-夜晚,25.0,6.5,40,019d9aa9-6a50-79cf-76fd-a98eb8d5f5a8
20260407223528,ADAS_S5STNF0T406280R_20260409152111002995_53a024ff00b0,CPFAO-夜晚,25.0,6.5,40,019d9aa9-7016-793e-44de-b79af7e1456b
20260407223054,ADAS_S5STNF0T406280R_20260409152111002995_1f4fb829d5c1,CPFAO-夜晚,25.0,6.5,20,019d9aa9-7472-764a-545a-99cbb25f9835
20260407222854,ADAS_S5STNF0T406280R_20260409152111002995_65df5c754a08,CPFAO-夜晚,25.0,6.5,20,019d9aa9-7865-74d7-7e59-093438dc3388
20260407222417,ADAS_S5STNF0T406280R_20260409152111002995_cf1dfc5751fb,CPFAO-夜晚,25.0,6.5,20,019d9aa9-7c27-729c-4d7b-3713e76ef75b
20260407221421,ADAS_S5STNF0T406280R_20260409152111002995_79ead953a267,CPFA-夜晚,25.0,6.5,60,019d9aa9-827d-7a37-78e5-4ea0ec992c77
20260407215247,ADAS_S5STNF0T406280R_20260409152111002995_a345faf933c1,CPFA-夜晚,25.0,6.5,60,019d9aa9-8986-7e12-6f1c-7b4541a5c438
20260407214759,ADAS_S5STNF0T406280R_20260409152111002995_3c626bbc7af6,CPFA-夜晚,25.0,6.5,50,019d9aa9-8e5d-7bae-7fa6-a1243ad252b1
20260407214009,ADAS_S5STNF0T406280R_20260409152111002995_bc6c0c01e193,CPFA-夜晚,25.0,6.5,50,019d9aa9-91e3-7a04-77dd-d1fec1704486
20260407213801,ADAS_S5STNF0T406280R_20260409152111002995_48410cc6c373,CPFA-夜晚,25.0,6.5,50,019d9aa9-9842-7b06-643f-a6d3c27fdb4a
20260407212845,ADAS_S5STNF0T406280R_20260409152111002995_f81455ea3eed,CPFA-夜晚,25.0,6.5,40,019d9aa9-9e5a-761b-71ee-2c0daebc363a
20260407211000,ADAS_S5STNF0T406280R_20260409152111002995_bc6ff7c44071,CPFA-夜晚,25.0,6.5,40,019d9aa9-a2ea-729b-61da-46dc65e0f2c9
20260407210630,ADAS_S5STNF0T406280R_20260409152111002995_aa33868a5965,CPFA-夜晚,25.0,6.5,30,019d9aa9-a8a0-748d-612c-77c42f99428c
20260407205653,ADAS_S5STNF0T406280R_20260409152111002995_2264933415a6,CPFA-夜晚,25.0,6.5,30,019d9aa9-b0a4-7dd1-5fb1-4bd3842b0a0d
20260407203248,ADAS_S5STNF0T406280R_20260409152111002995_51b93fb7cf53,CPFA-夜晚,25.0,6.5,30,019d9aa9-b6b3-7abb-6f43-815eb75834a8
20260407203003,ADAS_S5STNF0T406280R_20260409152111002995_ddada7c982c6,CPFA-夜晚,25.0,6.5,20,019d9aa9-bd6e-746b-556d-0c089251cc57
20260407202812,ADAS_S5STNF0T406280R_20260409152111002995_4779e10c3a5b,CPFA-夜晚,25.0,6.5,20,019d9aa9-c38e-7e79-70b1-615b22a4f86b
20260407202502,ADAS_S5STNF0T406280R_20260409152111002995_bf0967499ed6,CPFA-夜晚,25.0,6.5,20,019d9aa9-c752-7a92-44e6-69411b6e44aa
20260407182536,ADAS_S5STNF0T406280R_20260409152111002995_4f1437a97128,CPFAO,25.0,6.5,60,019d9aa9-cb33-7375-4f41-2a8282140d9a
20260407181809,ADAS_S5STNF0T406280R_20260409152111002995_bfa7f306290b,CPFAO,25.0,6.5,60,019d9aa9-cff8-7e52-4e27-eecdd74e70c4
20260407181450,ADAS_S5STNF0T406280R_20260409152111002995_716c2b09c740,CPFAO,25.0,6.5,40,019d9aa9-d4d7-7a5d-7eac-fadf6fb9d2ea
20260407181122,ADAS_S5STNF0T406280R_20260409152111002995_da621561033c,CPFAO,25.0,6.5,40,019d9aa9-ecfb-73fb-4b6b-743b7bbb2b08
20260407180720,ADAS_S5STNF0T406280R_20260409152111002995_9f26c651c46d,CPFAO,25.0,6.5,40,019d9aa9-f13a-7b1a-5760-09e35fc5d834
20260407150403,ADAS_S5STNF0T406280R_20260409152111002995_9c12dd965fc5,CPFAO,25.0,6.5,20,019d9aaa-0ccb-70bc-45e1-85a75961a5ee
20260407145705,ADAS_S5STNF0T406280R_20260409152111002995_eb1aa8b08248,CPFAO,25.0,6.5,20,019d9aaa-127b-78ef-57df-f568d78eeab5
20260407115528,ADAS_S5STNF0T406280R_20260409152111002995_7254e457ef67,CBLA,25.0,15.0,FCW80,019d9aaa-18f2-75d9-59e2-25649bb25498
20260407115335,ADAS_S5STNF0T406280R_20260409152111002995_6325ec39b751,CBLA,25.0,15.0,FCW80,019d9aaa-1ccc-70e2-4a60-07216d9dd359
20260407115155,ADAS_S5STNF0T406280R_20260409152111002995_b51fdac11ab8,CBLA,25.0,15.0,FCW80,019d9aaa-21bb-7429-6b35-a725a9993bdd
20260407114731,ADAS_S5STNF0T406280R_20260409152111002995_44c27781ddc3,CBLA,25.0,15.0,FCW70,019d9aaa-2891-7960-7681-84be2eac02d1
20260407114555,ADAS_S5STNF0T406280R_20260409152111002995_33b078bf6216,CBLA,25.0,15.0,FCW70,019d9aaa-2d9b-7b10-54bd-88503a0ed61b
20260407114352,ADAS_S5STNF0T406280R_20260409152111002995_ecfd3b259961,CBLA,25.0,15.0,FCW60,019d9aaa-3150-7366-774b-946d68a529f8
20260407114204,ADAS_S5STNF0T406280R_20260409152111002995_562404e71005,CBLA,25.0,15.0,FCW60,019d9aaa-37bb-7b90-788b-66a42a574474
20260407114023,ADAS_S5STNF0T406280R_20260409152111002995_7071743abdf9,CBLA,25.0,15.0,FCW60,019d9aaa-3d58-7acb-73f3-444d666e03e7
20260407113824,ADAS_S5STNF0T406280R_20260409152111002995_f016eafc886a,CBLA,25.0,15.0,FCW50,019d9aaa-4167-7eeb-4715-7892f58a5271
20260407113633,ADAS_S5STNF0T406280R_20260409152111002995_14b6fffb9346,CBLA,25.0,15.0,FCW50,019d9aaa-48af-7840-4f34-59a83f60ae4f
20260407113402,ADAS_S5STNF0T406280R_20260409152111002995_2db981f7c452,CBLA,25.0,15.0,FCW50,019d9aaa-4e92-743e-673b-19ca695f6571
20260407112549,ADAS_S5STNF0T406280R_20260409152111002995_915cffcc1584,CBLA,50.0,15.0,60,019d9aaa-524c-7950-5d38-965c8a7044b5
20260407112334,ADAS_S5STNF0T406280R_20260409152111002995_72cb0932d90e,CBLA,50.0,15.0,60,019d9aaa-590d-77a4-7db2-923118c55be9
20260407112214,ADAS_S5STNF0T406280R_20260409152111002995_2ac2047ca290,CBLA,50.0,15.0,60,019d9aaa-5e44-7fc5-6e5b-8c43a352ccb7
20260407112037,ADAS_S5STNF0T406280R_20260409152111002995_3aaeea19a547,CBLA,50.0,15.0,50,019d9aaa-630d-77f1-5bdd-d09431e1e161
20260407111922,ADAS_S5STNF0T406280R_20260409152111002995_4deb6874a615,CBLA,50.0,15.0,50,019d9aaa-67ec-7410-5d97-7f3371866c7c
20260407111812,ADAS_S5STNF0T406280R_20260409152111002995_d39a5d1c908f,CBLA,50.0,15.0,50,019d9aaa-6b63-73bf-73bb-5a3f96ace7b3
20260407111307,ADAS_S5STNF0T406280R_20260409152111002995_7a5e67352e0e,CBLA,50.0,15.0,40,019d9aaa-70a3-748e-6d05-0c2d1a31dcae
20260407111122,ADAS_S5STNF0T406280R_20260409152111002995_d3ab196e744a,CBLA,50.0,15.0,40,019d9aaa-88a0-7970-4ceb-15bb8ab3b1ff
20260407110751,ADAS_S5STNF0T406280R_20260409152111002995_5c50e575f464,CBLA,50.0,15.0,40,019d9aaa-8fd9-7ab1-6a49-72b63397588c
20260407110422,ADAS_S5STNF0T406280R_20260409152111002995_4045be63fc22,CBLA,50.0,15.0,30,019d9aaa-b385-753d-5faa-1ad2759f5a5f
20260407110300,ADAS_S5STNF0T406280R_20260409152111002995_ea8e031bb31e,CBLA,50.0,15.0,30,019d9aaa-b8bb-7da2-4d44-23f067e0d663
20260407110130,ADAS_S5STNF0T406280R_20260409152111002995_6e0a4c97c8c1,CBLA,50.0,15.0,30,019d9aaa-bee0-7dab-4651-4c3915a8c5cd
20260407105941,ADAS_S5STNF0T406280R_20260409152111002995_621325fdf415,CBLA,50.0,15.0,20,019d9aaa-c31f-7e26-75c6-e02b1700a8a8
20260407105753,ADAS_S5STNF0T406280R_20260409152111002995_069a2c13319e,CBLA,50.0,15.0,20,019d9aaa-c7f4-7027-50c2-58b40e941188
20260407105535,ADAS_S5STNF0T406280R_20260409152111002995_0e1ce93501ef,CBLA,50.0,15.0,20,019d9aaa-cb54-7853-7393-0d3928f895f9
20260407102008,ADAS_S5STNF0T406280R_20260409152111002995_ef2816221a27,CPLA,50.0,5.0,60,019d9aaa-cf01-761f-690c-7f2090d7277d
20260407101706,ADAS_S5STNF0T406280R_20260409152111002995_2249a6c9c868,CPLA,50.0,5.0,60,019d9aaa-d4af-7f14-5347-005312fcbb02
20260407101455,ADAS_S5STNF0T406280R_20260409152111002995_3aec82d2ae5b,CPLA,50.0,5.0,60,019d9aaa-dc19-7189-7ea1-1c6b2bb3a963
20260407100842,ADAS_S5STNF0T406280R_20260409152111002995_a33d9aa63d97,CPLA,50.0,5.0,50,019d9aaa-df67-7cea-7ac6-b5783b3aeab8
20260407100530,ADAS_S5STNF0T406280R_20260409152111002995_a3fd722c219d,CPLA,50.0,5.0,50,019d9aaa-e4a6-7293-71ed-bd5ffeae3cbf
20260407100321,ADAS_S5STNF0T406280R_20260409152111002995_0a59f61cc73e,CPLA,50.0,5.0,50,019d9aaa-e9bc-72a1-511e-051af8249f39
20260407095827,ADAS_S5STNF0T406280R_20260409152111002995_522b6859b7cc,CPLA,50.0,5.0,40,019d9aaa-ed4f-7c64-734b-853b64feafdf
20260407095546,ADAS_S5STNF0T406280R_20260409152111002995_f45e8cd87f19,CPLA,50.0,5.0,40,019d9aaa-f24d-7e7f-513b-50bbd4dde342
20260407095253,ADAS_S5STNF0T406280R_20260409152111002995_d635dca3a188,CPLA,50.0,5.0,40,019d9aaa-f79c-7528-63f5-3d6592aedbfb
20260408161638,ADAS_S5STNF0T504465N_20260409152139658693_8dbfcbfeb5ee,CBNAO,50.0,15.0,60,019d9aa4-e596-73a3-563e-91eff907fc5f
20260408161312,ADAS_S5STNF0T504465N_20260409152139658693_552b57bd437a,CBNAO,50.0,15.0,60,019d9aa4-e97b-7f4c-71fe-27fb3e92820c
20260408161043,ADAS_S5STNF0T504465N_20260409152139658693_159245c0434e,CBNAO,50.0,15.0,60,019d9aa4-eddd-77f5-6ce3-9eb75c9e126c
20260408160836,ADAS_S5STNF0T504465N_20260409152139658693_235d852f9406,CBNAO,50.0,15.0,40,019d9aa4-f55c-7254-6da3-9371446494a2
20260408160613,ADAS_S5STNF0T504465N_20260409152139658693_dbb8344a1203,CBNAO,50.0,15.0,40,019d9aa4-fa8b-7cdf-51c3-118b7c34368e
20260408160358,ADAS_S5STNF0T504465N_20260409152139658693_6c96ac950cc5,CBNAO,50.0,15.0,40,019d9aa4-ff05-79fb-58c4-c719f7dc6e07
20260408160123,ADAS_S5STNF0T504465N_20260409152139658693_259ff1913329,CBNAO,50.0,15.0,20,019d9aa5-049f-7bb1-5e03-978f6b092895
20260408155917,ADAS_S5STNF0T504465N_20260409152139658693_7f68037838f3,CBNAO,50.0,15.0,20,019d9aa5-09c3-78fc-73b5-7aa4c811f39a
20260408155451,ADAS_S5STNF0T504465N_20260409152139658693_0a7f2b349464,CBNAO,50.0,15.0,20,019d9aa5-0dcf-7135-4e96-d516559ebc9e
20260408152655,ADAS_S5STNF0T504465N_20260409152139658693_6d37a9755ccc,CPNCO,25.0,5.0,60,019d9aa5-11b0-7f7b-79ff-9a433fc42aef
20260408151807,ADAS_S5STNF0T504465N_20260409152139658693_0d829e9357a4,CPNCO,25.0,5.0,60,019d9aa5-18c9-724e-7f73-8fe42bd39b5b
20260408150258,ADAS_S5STNF0T504465N_20260409152139658693_7a94940f5d03,CPNCO,25.0,5.0,60,019d9aa5-1d67-79ab-6805-059001b21a42
20260408145812,ADAS_S5STNF0T504465N_20260409152139658693_750011a9dfe4,CPNCO,25.0,5.0,40,019d9aa5-24e4-79fe-549c-19e449a23c53
20260408145424,ADAS_S5STNF0T504465N_20260409152139658693_ea7728a2697d,CPNCO,25.0,5.0,40,019d9aa5-2aa5-7d7c-75b8-2b60ef3eed08
20260408145214,ADAS_S5STNF0T504465N_20260409152139658693_4948b709cf5d,CPNCO,25.0,5.0,40,019d9aa5-31da-7d88-4f99-11dd0d0f8499
20260408141857,ADAS_S5STNF0T504465N_20260409152139658693_4eb92c8fee57,CPNCO,25.0,5.0,20,019d9aa5-4eca-7f08-635b-2fa3bc598c09
20260408141334,ADAS_S5STNF0T504465N_20260409152139658693_b0faffa9dc30,CPNCO,25.0,5.0,20,019d9aa5-538a-772a-494d-35f736399e65
20260408134743,ADAS_S5STNF0T504465N_20260409152139658693_b5876596c9d1,CPNCO,25.0,5.0,20,019d9aa5-5802-7924-6ce0-ffb4967f13bd
20260408002949,ADAS_S5STNF0T406280R_20260409152111002995_45d2787fbc67,CPLA-夜晚,25.0,5.0,FCW80,019d9aa5-5bf7-7fb2-6efc-6d8161e18c1b
20260408002550,ADAS_S5STNF0T406280R_20260409152111002995_5e07f54bbb10,CPLA-夜晚,25.0,5.0,FCW60,019d9aa5-63e8-711a-417e-c616fe4e5eda
20260408002023,ADAS_S5STNF0T406280R_20260409152111002995_0b5d60209c57,CPLA-夜晚,25.0,5.0,40,019d9aa5-6c4f-7ebf-5b32-53e5c680be0a
20260408001902,ADAS_S5STNF0T406280R_20260409152111002995_edda23ef80bd,CPLA-夜晚,25.0,5.0,40,019d9aa5-701a-7bf6-4e38-45d884353a70
20260408001653,ADAS_S5STNF0T406280R_20260409152111002995_b29f5723b2c0,CPLA-夜晚,25.0,5.0,20,019d9aa5-735a-75f3-5ba4-93902a277d59
20260408001434,ADAS_S5STNF0T406280R_20260409152111002995_c14dc9bae519,CPLA-夜晚,25.0,5.0,20,019d9aa5-76fe-7d1f-598b-5e7dd61280e9
20260408000623,ADAS_S5STNF0T406280R_20260409152111002995_46815deac491,CPLA-夜晚,50.0,5.0,60,019d9aa5-7b0e-75c8-4334-61c3ab70abbb
20260408000446,ADAS_S5STNF0T406280R_20260409152111002995_c62ef90d053e,CPLA-夜晚,50.0,5.0,60,019d9aa5-7e74-7664-6f81-427fa818ade0
20260408000248,ADAS_S5STNF0T406280R_20260409152111002995_543e826a5e70,CPLA-夜晚,50.0,5.0,50,019d9aa5-8200-7f80-46a0-02307e146cfa
20260408000108,ADAS_S5STNF0T406280R_20260409152111002995_4086a9a63200,CPLA-夜晚,50.0,5.0,50,019d9aa5-8a5a-7798-53ee-8ebecd6efac0
20260410183944,ADAS_S751NX0Y601865J_20260412195842469563_433f140b95d6,CCRS,-50.0,0.0,FCW80,019d9a96-c1d6-7326-728e-02a54fd8e225
20260410183322,ADAS_S751NX0Y601865J_20260412195842469563_a7973f1e9bb1,CCRS,100.0,0.0,FCW80,019d9a96-cb3d-7c97-7ea5-b3f748d9eb5e
20260410183032,ADAS_S751NX0Y601865J_20260412195842469563_ef2acadfb2bd,CCRS,100.0,0.0,FCW80,019d9a96-d38c-7078-46fe-d780744cb909
20260410182651,ADAS_S751NX0Y601865J_20260412195842469563_62b3ba276352,CCRS,50.0,0.0,FCW70,019d9a96-da33-7c3b-6246-61da039dfa20
20260410182102,ADAS_S751NX0Y601865J_20260412195842469563_cbcfff9884b1,CCRS,50.0,0.0,FCW70,019d9a96-dff9-7b8f-4705-38c5c58c2599
20260410180809,ADAS_S751NX0Y601865J_20260412195842469563_1f2727954bca,CCRS,50.0,0.0,FCW70,019d9a96-e5e5-782c-65d1-48036de2d14a
20260410180043,ADAS_S751NX0Y601865J_20260412195842469563_9e2611ec8323,CCRS,100.0,0.0,FCW70,019d9a97-02a2-7ad2-6658-aa217ab89e55
20260410175829,ADAS_S751NX0Y601865J_20260412195842469563_042f5636d4f4,CCRS,100.0,0.0,FCW70,019d9a97-08a2-71ca-7a1a-4bec6e69a901
20260410175602,ADAS_S751NX0Y601865J_20260412195842469563_7787aecfa77f,CCRS,100.0,0.0,FCW70,019d9a97-0d8d-7a20-489c-f90e4ce10e22
20260410175256,ADAS_S751NX0Y601865J_20260412195842469563_13f6d65d0058,CCRS,-50.0,0.0,FCW60,019d9a97-11c1-742b-5d71-2074250c8b5f
20260410174813,ADAS_S751NX0Y601865J_20260412195842469563_74864ef9dfac,CCRS,100.0,0.0,FCW60,019d9a97-1719-70e0-6008-7ca16945ea6b
20260410174417,ADAS_S751NX0Y601865J_20260412195842469563_fb97c4371e87,CCRS,100.0,0.0,FCW60,019d9a97-1c3b-74fa-4273-514b875c17ad
20260410172805,ADAS_S751NX0Y601865J_20260412195842469563_ca74d9bf7865,CCRS,100.0,0.0,FCW60,019d9a97-1fe2-7480-417b-a86fbb036b09
20260410171831,ADAS_S751NX0Y601865J_20260412195842469563_3299757de161,CCRS,-50.0,0.0,FCW60,019d9a97-2bee-7107-401d-4d872729a179
20260410171425,ADAS_S751NX0Y601865J_20260412195842469563_9cae1d226719,CCRS,-50.0,0.0,FCW60,019d9a97-3091-7993-662c-cd6a5a2ec208
20260410135043,ADAS_S751NX0Y601865J_20260412195842469563_5a853fcb203a,CCRS,50.0,0.0,FCW50,019d9a97-5715-7df7-79f8-bee1114b0445
20260410134822,ADAS_S751NX0Y601865J_20260412195842469563_32bc05a9d954,CCRS,50.0,0.0,FCW50,019d9a97-5b96-76ad-6af6-261e504f4b6a
20260410134541,ADAS_S751NX0Y601865J_20260412195842469563_7110684c2ec6,CCRS,50.0,0.0,FCW50,019d9a97-5f4c-7d07-6fd5-6301296712e0
20260410121059,ADAS_S751NX0Y601865J_20260412195842469563_2f056f43e537,CCRS,100.0,0.0,FCW50,019d9a97-646e-749d-78fc-7c1177a082e4
20260410120748,ADAS_S751NX0Y601865J_20260412195842469563_f719a9f14f03,CCRS,100.0,0.0,FCW50,019d9a97-6c15-71d7-7ca4-8aa861b4f657
20260410120327,ADAS_S751NX0Y601865J_20260412195842469563_b1089228c2a7,CCRS,100.0,0.0,FCW50,019d9a97-707f-7b4c-6f73-bfdca7b99135
20260410111646,ADAS_S751NX0Y601865J_20260412195842469563_c5d7494583d0,CSFAO,50.0,20.0,60,019d9a97-7721-744b-6f9d-3e7f33022481
20260410104110,ADAS_S751NX0Y601865J_20260412195842469563_99948185a04d,CSFAO,50.0,20.0,60,019d9a97-7c0c-7a18-6c44-0245ab8bf1ad
20260410103025,ADAS_S751NX0Y601865J_20260412195842469563_09a490787dad,CSFAO,50.0,20.0,60,019d9a97-8221-7aa2-49ac-411ab9a7b24a
20260410102715,ADAS_S751NX0Y601865J_20260412195842469563_5e4f95ca5ba9,CSFAO,50.0,20.0,40,019d9a97-86f6-711a-68e0-69a9b8e9b359
20260410102527,ADAS_S751NX0Y601865J_20260412195842469563_e88c82463dde,CSFAO,50.0,20.0,40,019d9a97-8bb3-7007-7c41-c7edd0edb95e
20260410102252,ADAS_S751NX0Y601865J_20260412195842469563_e12a5bd21c7b,CSFAO,50.0,20.0,40,019d9a97-9152-7292-7210-da999124e35f
20260410102018,ADAS_S751NX0Y601865J_20260412195842469563_02d5dd72de6e,CSFAO,50.0,20.0,20,019d9a97-96f8-7f2d-7675-481089eac2c7
20260410101810,ADAS_S751NX0Y601865J_20260412195842469563_f4a683d9d4db,CSFAO,50.0,20.0,20,019d9a97-9ba9-75da-6e53-b4e8575ac660
20260410101534,ADAS_S751NX0Y601865J_20260412195842469563_cda9e45c8fd1,CSFAO,50.0,20.0,20,019d9a97-9fb4-76a5-5fa4-3bdfcdf3da32
20260411183829,ADAS_S751NX0Y601739V_20260413155723466116_a04db0919eec,CCRS,-50.0,0.0,FCW80,019d9a7c-a893-7ebe-44fc-88658f70c9a2
20260411182247,ADAS_S751NX0Y601739V_20260413155723466116_d1186bf4a065,CCRS,-50.0,0.0,FCW80,019d9a7c-af31-7626-5765-81fc0f62c50b
20260411180919,ADAS_S751NX0Y601739V_20260413155723466116_9a6876a65dca,CCRS,100.0,0.0,FCW80,019d9a7c-b749-77a4-57a0-8db9b20ff808
20260411175300,ADAS_S751NX0Y601739V_20260413155723466116_d852ebd5465e,CCRM,-50.0,20.0,FCW80,019d9a7c-c5e4-7e00-7abc-0b61af7b34d2
20260411174303,ADAS_S751NX0Y601739V_20260413155723466116_434fdd766056,CCRM,-50.0,20.0,FCW80,019d9a7c-c955-7e81-4d13-eb44371e532a
20260411173124,ADAS_S751NX0Y601739V_20260413155723466116_97ec63da982a,CCRM,-50.0,20.0,FCW80,019d9a7c-cd7f-78f7-5c70-131af26cc440
20260411172605,ADAS_S751NX0Y601739V_20260413155723466116_71bcb435e71c,CCRM,100.0,20.0,FCW80,019d9a7c-d846-741b-7597-41b66b95e10a
20260411172410,ADAS_S751NX0Y601739V_20260413155723466116_6d8d13f750fc,CCRM,100.0,20.0,FCW80,019d9a7c-dc76-7635-5934-90774c92ed6d
20260411172142,ADAS_S751NX0Y601739V_20260413155723466116_723bebf4506d,CCRM,100.0,20.0,FCW80,019d9a7c-e374-7a08-41df-cb22895e85e9
20260411171702,ADAS_S751NX0Y601739V_20260413155723466116_8f574aa74cca,CCRM,50.0,20.0,FCW70,019d9a7c-e985-7d35-73d6-3c32a44ef500
20260411171447,ADAS_S751NX0Y601739V_20260413155723466116_5c3cb97938c5,CCRM,50.0,20.0,FCW70,019d9a7c-ed45-704a-56af-2fee6afc2bb7
20260411171038,ADAS_S751NX0Y601739V_20260413155723466116_d8fc43891af6,CCRM,50.0,20.0,FCW70,019d9a7c-f0ef-7ec9-5285-16661cc3be7c
20260411170537,ADAS_S751NX0Y601739V_20260413155723466116_0c1194076828,CCRM,100.0,20.0,FCW70,019d9a7c-f5c8-76c5-5dcb-0ab62615959e
20260411170231,ADAS_S751NX0Y601739V_20260413155723466116_4f8d3c73fffa,CCRM,100.0,20.0,FCW70,019d9a7c-fb91-766b-4c07-18323de8251c
20260411165955,ADAS_S751NX0Y601739V_20260413155723466116_a3fe89de5059,CCRM,100.0,20.0,FCW70,019d9a7d-0105-7b5e-4b10-da65ba7b2306
20260411165255,ADAS_S751NX0Y601739V_20260413155723466116_2481817963a5,CCRM,-50.0,20.0,FCW60,019d9a7d-04b7-74fb-75ff-d8cc08b2e6b5
20260411164856,ADAS_S751NX0Y601739V_20260413155723466116_a591780712a5,CCRM,-50.0,20.0,FCW60,019d9a7d-0989-7b0c-46a1-e621003a415e
20260411164604,ADAS_S751NX0Y601739V_20260413155723466116_a570cbea0f8c,CCRM,-50.0,20.0,FCW60,019d9a7d-0e02-7c5f-4163-756d1d22c96b
20260411164110,ADAS_S751NX0Y601739V_20260413155723466116_1c8ce6be64a0,CCRM,100.0,20.0,FCW60,019d9a7d-12b7-7c15-46a5-256d59cba379
20260411163351,ADAS_S751NX0Y601739V_20260413155723466116_c5c8b22ad3dc,CCRM,100.0,20.0,FCW60,019d9a7d-16fa-7aaf-44ff-9516a0d5684e
20260411162856,ADAS_S751NX0Y601739V_20260413155723466116_45a1708bd6e7,CCRM,100.0,20.0,FCW60,019d9a7d-1ba0-7648-61c9-bcc36579b627
20260413184006,ADAS_S5STNF0T504465N_20260414163318204977_94d493ef794c,CPTA-LN,50.0,5.0,20,019d9a5d-b50f-75d1-79cd-6450dfebdd5d
20260413182950,ADAS_S5STNF0T504465N_20260414163318204977_65588ce02434,CPTA-LF,50.0,6.5,20,019d9a5d-bc97-7015-4292-587775914bad
20260413182735,ADAS_S5STNF0T504465N_20260414163318204977_e9c68de37ce5,CPTA-LF,50.0,6.5,20,019d9a5d-c404-7ec9-463d-bc3ccd120447
20260413181209,ADAS_S5STNF0T504465N_20260414163318204977_731fe43b77a4,CPTA-LF,50.0,6.5,10,019d9a5d-ca7c-7e1c-5065-445b231ab139
20260413180557,ADAS_S5STNF0T504465N_20260414163318204977_ab161275fcdd,CPTA-LF,50.0,6.5,10,019d9a5d-cf2a-700e-426b-4834795e46e4
20260413155722,ADAS_S5STNF0T504465N_20260414163318204977_de1770ab54a4,CPTA-LF,50.0,6.5,10,019d9a5d-d6a3-7582-7ec1-e15fbd30314f
20260413152044,ADAS_S5STNF0T504465N_20260414163318204977_2c16f786a458,CPTA-LN,50.0,5.0,20,019d9a5d-daa6-7d0b-6040-634b0adc26d5
20260413144918,ADAS_S5STNF0T504465N_20260414163318204977_311e2e4f3469,CPTA-LN,50.0,5.0,20,019d9a5d-e12b-77ed-795b-a177a975d2d8
20260413143117,ADAS_S5STNF0T504465N_20260414163318204977_912131df3c3f,CPTA-LN,50.0,5.0,10,019d9a5d-e9f7-75fb-70c7-d966c6229458
20260413142635,ADAS_S5STNF0T504465N_20260414163318204977_c83b9a3226dd,CPTA-LN,50.0,5.0,10,019d9a5d-f0bf-7b9f-40d2-7e37931ed680
20260413141932,ADAS_S5STNF0T504465N_20260414163318204977_0c640c814bc3,CPTA-LN,50.0,5.0,10,019d9a5d-f609-786e-7cac-da37ebc1ae67
20260414182041,ADAS_S5STNF0T406280R_20260415153614565776_6717025a2999,CPTA-RF,50.0,6.5,20,019d9a51-ae0f-7c50-6dfb-9ebe3bd45849
20260414181827,ADAS_S5STNF0T406280R_20260415153614565776_a6af70bdfa52,CPTA-RF,50.0,6.5,20,019d9a51-b50b-7acf-6c49-f52dc69a2850
20260414181027,ADAS_S5STNF0T406280R_20260415153614565776_ac6a27726e5c,CPTA-RF,50.0,6.5,20,019d9a51-b8cf-7339-595c-1dde3419ee32
20260414175932,ADAS_S5STNF0T406280R_20260415153614565776_641a01713a60,CPTA-RF,50.0,6.5,10,019d9a51-cc24-7989-4be4-e3ad8d2aa724
20260414175703,ADAS_S5STNF0T406280R_20260415153614565776_2ddbe4a780d2,CPTA-RF,50.0,6.5,10,019d9a51-d078-7764-4942-78794b5f6907
20260414175324,ADAS_S5STNF0T406280R_20260415153614565776_423750bdef2c,CPTA-RF,50.0,6.5,10,019d9a51-d672-7605-4f29-b37caa9eae1c
20260414173141,ADAS_S5STNF0T406280R_20260415153614565776_6304fc524d71,CSTA-LN,50.0,20.0,10,019d9a51-de91-792b-5301-78dc8837a22a
20260414172819,ADAS_S5STNF0T406280R_20260415153614565776_7b6bcdb90977,CSTA-LN,50.0,20.0,10,019d9a51-e518-7bef-6d16-c7ba8b8a2aab
20260414171833,ADAS_S5STNF0T406280R_20260415153614565776_0ae4e25121ec,CSTA-LN,50.0,20.0,20,019d9a51-e91f-7b43-7e4d-c687d932dba0
20260414170603,ADAS_S5STNF0T406280R_20260415153614565776_c66607e24083,CSTA-LN,50.0,20.0,20,019d9a51-ef9e-7b48-4a73-df674f472c55
20260414170224,ADAS_S5STNF0T406280R_20260415153614565776_db50a7ab7485,CSTA-LN,50.0,20.0,20,019d9a51-f683-7a5e-5364-1896e1ca6598
20260414165228,ADAS_S5STNF0T406280R_20260415153614565776_94db38de8391,CSTA-LN,50.0,20.0,30,019d9a51-ff2c-7cc2-58c8-05cae8d4ec9e
20260414164728,ADAS_S5STNF0T406280R_20260415153614565776_c0b75572b138,CSTA-LN,50.0,20.0,30,019d9a52-04fd-75e5-57f7-54b7dc96246c
20260414151451,ADAS_S5STNF0T406280R_20260415153614565776_672a18ed480a,CSTA-LN,50.0,20.0,30,019d9a52-0afa-71e8-6e1c-e534a2850eff
20260414141804,ADAS_S5STNF0T406280R_20260415153614565776_593e8310f18f,CSTA-LN,50.0,20.0,10,019d9a52-2237-7843-4407-6cac5ae39635
20260414103823,ADAS_S5STNF0T406280R_20260415153614565776_e3a569188ace,CPTA-LF,50.0,6.5,30,019d9a52-5247-719d-6774-a834bc949e33
20260414103041,ADAS_S5STNF0T406280R_20260415153614565776_d357ca15a359,CPTA-LF,50.0,6.5,30,019d9a52-5694-7c91-7a0e-072b54ee0879
20260414101728,ADAS_S5STNF0T406280R_20260415153614565776_8b3b17c2bee2,CPTA-LN,50.0,5.0,30,019d9a52-5a9a-738a-531b-2e60fa91338a
20260414100312,ADAS_S5STNF0T406280R_20260415153614565776_1cd9b9feba23,CPTA-LN,50.0,5.0,30,019d9a52-5e3c-77fc-7644-8b46ab7c192f
20260415182950,ADAS_S751NX0Y601865J_20260417101159978228_f3c4f45b6d78,SCPO,,40.0,FCW50,019d9ad0-974c-72b2-6576-d90453782b51
20260415181728,ADAS_S751NX0Y601865J_20260417101159978228_2dcca16a3b4a,SCPO,,50.0,FCW60,019d9ad0-9f8a-791b-47b1-572744314e8d
20260415181449,ADAS_S751NX0Y601865J_20260417101159978228_349202d868d0,SCPO,,50.0,FCW60,019d9ad0-a733-7e52-4dc3-5974dde5ad99
20260415181218,ADAS_S751NX0Y601865J_20260417101159978228_8f80b1fd043d,SCPO,,50.0,FCW60,019d9ad0-c235-74dc-4c71-dbd7bf6a42fb
20260415175852,ADAS_S751NX0Y601865J_20260417101159978228_9ec3b55f6845,SCPO,,40.0,FCW50,019d9ad0-c6b4-75f7-49ac-215a534b203e
20260415175352,ADAS_S751NX0Y601865J_20260417101159978228_66569e4b4cb2,SCPO,,40.0,FCW50,019d9ad0-cd9a-7dbf-49b5-3f9fb8a2b943
20260415170215,ADAS_S751NX0Y601865J_20260417101159978228_a058dd06c98c,SCP,,40.0,FCW50,019d9ad0-d40c-7f86-4f01-c92465e0cde5
20260415161100,ADAS_S751NX0Y601865J_20260417101159978228_56ea31bafe02,SCP,,50.0,FCW60,019d9ad0-da51-773d-557f-4684de8f8593
20260415160711,ADAS_S751NX0Y601865J_20260417101159978228_46aa39158604,SCP,,50.0,FCW60,019d9ad0-df57-78ff-4590-ebcaaec53aab
20260415160405,ADAS_S751NX0Y601865J_20260417101159978228_bee8068c98fc,SCP,,50.0,FCW60,019d9ad0-e30f-79ed-7a0d-884a4f6c1cd0
20260415154024,ADAS_S751NX0Y601865J_20260417101159978228_2f1ade039337,SCP,,40.0,FCW50,019d9ad0-e757-741a-5156-6385fc72f938
20260415153332,ADAS_S751NX0Y601865J_20260417101159978228_3af6ab7e3d9d,SCP,,40.0,FCW50,019d9ad0-ff56-74ec-7f7a-ca0ea75f8957
20260415152337,ADAS_S751NX0Y601865J_20260417101159978228_04a9c20fdd89,SCP,,30.0,40,019d9ad1-02de-7ebf-7adf-a12148a9ee51
20260415152009,ADAS_S751NX0Y601865J_20260417101159978228_6d4572f106f9,SCP,,30.0,40,019d9ad1-06e0-7a20-4613-411bd3ac6621
20260415151432,ADAS_S751NX0Y601865J_20260417101159978228_747d58ffa48f,SCP,,20.0,30,019d9ad1-0a91-71ea-5da9-c9d7d7dc91b8
20260415150905,ADAS_S751NX0Y601865J_20260417101159978228_3e31d0688fc8,SCP,,20.0,30,019d9ad1-11d0-7099-76b0-aaf48cfd3794
20260415104410,ADAS_S751NX0Y601865J_20260417101159978228_ba06434aae58,SCP,,30.0,40,019d9ad1-1ba5-730a-4504-896c892f8486
20260415102130,ADAS_S751NX0Y601865J_20260417101159978228_01906cac8a3a,SCP,,20.0,30,019d9ad1-300a-7509-7f94-984b56ab2f8b
20260416151630,ADAS_S751NX0Y601739V_20260418160638633646_496ebb0a2ff1,CBLA-CN24,25,15.0,FCW80,019db3f6-1d15-718a-724d-bed4c91ba628
20260416151431,ADAS_S751NX0Y601739V_20260418160638633646_22612682b9c9,CBLA-CN24,25,15.0,FCW80,019db3f6-2443-7632-47c8-410071836c58
20260416151047,ADAS_S751NX0Y601739V_20260418160638633646_8a773af16606,CBLA-CN24,25,15.0,FCW80,019db3f6-2b30-79d4-708d-4b239be1acf2
20260416150314,ADAS_S751NX0Y601739V_20260418160638633646_ae0b94f3324a,CBLA-CN24,25,15.0,FCW60,019db3f6-4031-7053-6ba9-b9ff190b8f0c
20260416145925,ADAS_S751NX0Y601739V_20260418160638633646_05bb8a06451c,CBLA-CN24,25,15.0,FCW60,019db3f6-47d7-75e8-6251-fd30d96e2abc
20260416145727,ADAS_S751NX0Y601739V_20260418160638633646_3a1fb37781a4,CBLA-CN24,25,15.0,FCW60,019db3f6-5171-7b48-5c29-f20016206acf
20260416143538,ADAS_S751NX0Y601739V_20260418160638633646_74c05ab76327,CBLA-CN21,25,15.0,FCW80,019db3f6-58e5-767b-72c7-ea46de3a19fe
20260416143214,ADAS_S751NX0Y601739V_20260418160638633646_b5a9cd0663a3,CBLA-CN21,25,15.0,FCW80,019db3f6-646a-7e0b-54b1-c6f31a4bc344
20260416142947,ADAS_S751NX0Y601739V_20260418160638633646_b4ba81b4492d,CBLA-CN21,25,15.0,FCW80,019db3f6-6db0-70b6-5602-b61e51fb6b00
20260416142739,ADAS_S751NX0Y601739V_20260418160638633646_d007dbd1fef6,CBLA-CN21,25,15.0,FCW70,019db3f6-768c-7955-4db7-82fcdc8ecf11
20260416142527,ADAS_S751NX0Y601739V_20260418160638633646_cea22e9fc4b2,CBLA-CN21,25,15.0,FCW70,019db3f6-7ceb-7b0d-513e-ddfafe62acc2
20260416142206,ADAS_S751NX0Y601739V_20260418160638633646_cea65402d2f0,CBLA-CN21,25,15.0,FCW70,019db3f6-868f-7ceb-6169-86d01d3e09ae
20260416141321,ADAS_S751NX0Y601739V_20260418160638633646_9b2070e30a94,CBLA-CN21,25,15.0,FCW60,019db3f6-9c95-7da4-5f42-a598dee5935c
20260416141056,ADAS_S751NX0Y601739V_20260418160638633646_05e29a63c4c5,CBLA-CN21,25,15.0,FCW60,019db3f6-a785-77de-6fd3-f841e40d90d9
20260416140906,ADAS_S751NX0Y601739V_20260418160638633646_443fc0fdce22,CBLA-CN21,25,15.0,FCW60,019db3f6-b875-77ad-533c-dc77dc3745a2
20260416140653,ADAS_S751NX0Y601739V_20260418160638633646_915c24c91174,CBLA-CN21,25,15.0,FCW50,019db3f6-c0e8-714a-7ead-cf6fa750249c
20260416140423,ADAS_S751NX0Y601739V_20260418160638633646_3727f5ceb78c,CBLA-CN21,25,15.0,FCW50,019db3f6-c84c-7b3a-4cf3-65ebf97ca2db
20260416140135,ADAS_S751NX0Y601739V_20260418160638633646_aad58490855a,CBLA-CN21,25,15.0,FCW50,019db3f6-ce3f-707c-718b-b7c1cd4c072b
1 datetime rawid scene offset gvt_speed vut_speed event_uuid
2 20260322175850 ADAS_S751NX0Y800506T_20260402120500514190_df44c7e0f558 CPNA 75 5.0 30 019dba8a-6dba-7ea7-6158-864c5ca840b5
3 20260322175649 ADAS_S751NX0Y800506T_20260402120500514190_41bdeb4dc9c9 CPNA 75 5.0 30 019dba8a-71d2-7c37-57c9-fee30c51daac
4 20260322175205 ADAS_S751NX0Y800506T_20260402120500514190_7a0cbe1afafb CPNA 75 5.0 30 019dba8a-7550-7db2-7ed3-f5ff17d3dbb3
5 20260322174325 ADAS_S751NX0Y800506T_20260402120500514190_5827b3b5ec93 CPNA 75 5.0 20 019dba8a-78d3-7e4e-43e2-b7d0566ecb42
6 20260322174119 ADAS_S751NX0Y800506T_20260402120500514190_17aba2ec3a91 CPNA 75 5.0 20 019dba8a-7cae-78df-6969-b210ce359472
7 20260322173859 ADAS_S751NX0Y800506T_20260402120500514190_d05ce02d8128 CPNA 75 5.0 20 019dba8a-80ea-73d0-72cf-d3e25d54aa43
8 20260322173530 ADAS_S751NX0Y800506T_20260402120500514190_4d885636e544 CPNA 25 5.0 40 019dba8a-84b3-7685-4ee6-1a776977717b
9 20260322173110 ADAS_S751NX0Y800506T_20260402120500514190_3121fd72c10e CPNA 25 5.0 40 019dba8a-8899-75c9-41d2-637c2d1013d4
10 20260322172726 ADAS_S751NX0Y800506T_20260402120500514190_160bff7a0258 CPNA 25 5.0 40 019dba8a-8c0e-7024-6dce-aab8c15b5a8c
11 20260322163631 ADAS_S751NX0Y800506T_20260402120500514190_f38d79224c9b CPNA 25 5.0 30 019dba8a-8fc2-7d9e-66f9-9066d8c47e71
12 20260322163412 ADAS_S751NX0Y800506T_20260402120500514190_188bbc4fd7cd CPNA 25 5.0 30 019dba8a-94be-7449-4666-31c9070bae44
13 20260322162901 ADAS_S751NX0Y800506T_20260402120500514190_9ec9c9547f85 CPNA 25 5.0 30 019dba8a-983d-7c1a-6e21-ae950e359c19
14 20260322162319 ADAS_S751NX0Y800506T_20260402120500514190_1ae2913db09c CPNA 25 5.0 20 019dba8a-9b90-7e99-7cce-bfabafff8ab9
15 20260322161344 ADAS_S751NX0Y800506T_20260402120500514190_e9e3c9e67eac CPNA 25 5.0 20 019dba8a-9f8f-78ba-56f9-9aaccfc0a68b
16 20260322160034 ADAS_S751NX0Y800506T_20260402120500514190_e774fbfe04b5 CPNA 25 5.0 20 019dba8a-a2fd-7cd8-507b-748aecd99ee6
17 20260322154206 ADAS_S751NX0Y800506T_20260402120500514190_2cae2b77af35 CPFA 50 6.5 30 019dba8a-a68f-72a6-62e6-1f870ef06880
18 20260322154017 ADAS_S751NX0Y800506T_20260402120500514190_18742842430a CPFA 50 6.5 30 019dba8a-aa11-7937-7299-50e612807225
19 20260322153820 ADAS_S751NX0Y800506T_20260402120500514190_88239721e460 CPFA 50 6.5 30 019dba8a-adb4-7008-5783-6777b442c00d
20 20260322153301 ADAS_S751NX0Y800506T_20260402120500514190_e843fb7f3356 CPFA 50 6.5 20 019dba8a-b4fd-7bcc-5eea-3ebd69418d2f
21 20260322152819 ADAS_S751NX0Y800506T_20260402120500514190_56ffe9a635e2 CPFA 50 6.5 20 019dba8a-b873-76a5-53f9-b587a63998f5
22 20260322152509 ADAS_S751NX0Y800506T_20260402120500514190_55e385cadd8f CPFA 50 6.5 20 019dba8a-bcaa-7a83-65a1-b4e2be991e90
23 20260323151226 ADAS_S751NX0Y800506T_20260402120500514190_9bfcc283ca9f CPFA 25 6.5 60 019dba8b-9d64-76b1-7952-46899675e6b7
24 20260323150956 ADAS_S751NX0Y800506T_20260402120500514190_3f67a521af37 CPFA 25 6.5 60 019dba8b-a4d0-7f78-4e07-171b4b6fd04f
25 20260323150051 ADAS_S751NX0Y800506T_20260402120500514190_832aca065af3 CPFA 25 6.5 60 019dba8b-a980-7e97-6891-d9404946ad3a
26 20260323142614 ADAS_S751NX0Y800506T_20260402120500514190_b840a33bb533 CPFA 25 6.5 50 019dba8b-ae8d-7ddb-5b73-ea9d44b373b4
27 20260323142435 ADAS_S751NX0Y800506T_20260402120500514190_0cd79bd65838 CPFA 25 6.5 50 019dba8b-b507-7f98-7702-b7db890c40fe
28 20260323142206 ADAS_S751NX0Y800506T_20260402120500514190_8509ac645d11 CPFA 25 6.5 50 019dba8b-ba4e-7c3e-655e-0ce237eebf1c
29 20260323141946 ADAS_S751NX0Y800506T_20260402120500514190_257c4d40a320 CPFA 25 6.5 40 019dba8b-bd96-7937-6b97-d81bf764b42f
30 20260323140816 ADAS_S751NX0Y800506T_20260402120500514190_5852cf241628 CPFA 25 6.5 40 019dba8b-c31a-7327-6f84-61b66598e4de
31 20260323140108 ADAS_S751NX0Y800506T_20260402120500514190_084f8d8a14ff CPFA 25 6.5 40 019dba8b-c81f-7e39-6bf6-b163da68789b
32 20260323114938 ADAS_S751NX0Y800506T_20260402120500514190_a004524019b0 CPFA 25 6.5 30 019dba8b-cef9-7fc3-5d3a-e566162fb14d
33 20260323114629 ADAS_S751NX0Y800506T_20260402120500514190_ab11efa628ee CPFA 25 6.5 30 019dba8b-d39b-7461-6911-f8fa3c698828
34 20260323113832 ADAS_S751NX0Y800506T_20260402120500514190_36dade09baea CPFA 25 6.5 20 019dba8b-d733-7158-7322-b3a79ad240b5
35 20260323113612 ADAS_S751NX0Y800506T_20260402120500514190_68e77ef5aa44 CPFA 25 6.5 20 019dba8b-dc52-725a-6164-f54217be3322
36 20260323113249 ADAS_S751NX0Y800506T_20260402120500514190_91fe5e43236d CPFA 50 6.5 60 019dba8b-e0ec-7898-41fe-2e7c99bfa4c5
37 20260323113007 ADAS_S751NX0Y800506T_20260402120500514190_4c9b9263a276 CPFA 50 6.5 60 019dba8b-e560-71f5-47d1-9a47f71d2486
38 20260323112758 ADAS_S751NX0Y800506T_20260402120500514190_119e9e58e546 CPFA 50 6.5 60 019dba8b-e928-7b8b-45d9-bd5a3aa357d0
39 20260323112515 ADAS_S751NX0Y800506T_20260402120500514190_f6dcf99a5ca1 CPFA 50 6.5 50 019dba8b-ece3-737b-4212-613b8128cd83
40 20260323112255 ADAS_S751NX0Y800506T_20260402120500514190_7d7a31a63e86 CPFA 50 6.5 50 019dba8b-f27e-7117-5f7c-1486db8bf775
41 20260323112055 ADAS_S751NX0Y800506T_20260402120500514190_532d066d050d CPFA 50 6.5 50 019dba8b-f6eb-7b46-450e-a2c071792e36
42 20260323111755 ADAS_S751NX0Y800506T_20260402120500514190_79b8ac183c24 CPFA 50 6.5 40 019dba8b-fa4f-7ce8-4bff-9e568881e959
43 20260323111522 ADAS_S751NX0Y800506T_20260402120500514190_b93edaab8c70 CPFA 50 6.5 40 019dba8b-fe00-75ac-746e-1462d5eba7c5
44 20260323111334 ADAS_S751NX0Y800506T_20260402120500514190_af02999872b1 CPFA 50 6.5 40 019dba8c-0165-7dda-56fe-5447b413082e
45 20260324174238 ADAS_S751NX0Y800506T_20260402120500514190_e113d246ac8a CPNA 75 5.0 60 019dba8c-3c06-7577-515d-1b415add0b64
46 20260324173924 ADAS_S751NX0Y800506T_20260402120500514190_747514674cb5 CPNA 75 5.0 60 019dba8c-4003-71d1-4be4-60e61f8ee1d6
47 20260324173139 ADAS_S751NX0Y800506T_20260402120500514190_ba8b47506266 CPNA 75 5.0 60 019dba8c-441c-7a49-4b3e-c7b3cc2f455a
48 20260324172833 ADAS_S751NX0Y800506T_20260402120500514190_20ff1981dcd9 CPNA 75 5.0 50 019dba8c-4a81-79ea-530a-6d8e24f8fa55
49 20260324172558 ADAS_S751NX0Y800506T_20260402120500514190_fc2ec8859218 CPNA 75 5.0 50 019dba8c-8a61-70ac-48b6-aad76a1df1bc
50 20260324172350 ADAS_S751NX0Y800506T_20260402120500514190_6d1f2fdaffe1 CPNA 75 5.0 50 019dba8c-9193-7803-50c3-051a99f1a74f
51 20260324172117 ADAS_S751NX0Y800506T_20260402120500514190_14bcdf9bf591 CPNA 75 5.0 40 019dba8c-9744-7a3f-72a5-7a3769d61b3a
52 20260324171844 ADAS_S751NX0Y800506T_20260402120500514190_fc3b19e58c4b CPNA 75 5.0 40 019dba8c-9ccc-7acb-4242-cb82cba15ffc
53 20260324165218 ADAS_S751NX0Y800506T_20260402120500514190_2c6193e79a1b CPNA 25 5.0 60 019dba8c-a624-7342-681f-72a187ecd3e1
54 20260324164151 ADAS_S751NX0Y800506T_20260402120500514190_765b60cf1fe3 CPNA 25 5.0 60 019dba8c-a971-747a-6253-d7b5cbdeca3f
55 20260324161933 ADAS_S751NX0Y800506T_20260402120500514190_25c2f29a8f42 CPNA 25 5.0 50 019dba8c-adc3-7e77-6900-8ee40e9167de
56 20260325181249 ADAS_S751NX0Y800506T_20260402120500514190_a6bb10ce6479 CPLA 25 5.0 30 019dba8c-df89-7a07-4c90-6c1384a83f89
57 20260325180857 ADAS_S751NX0Y800506T_20260402120500514190_6033ca518600 CPLA 25 5.0 30 019dba8c-e80f-7a40-7545-8778073cd4a9
58 20260325180602 ADAS_S751NX0Y800506T_20260402120500514190_04ab6361c6f8 CPLA 25 5.0 30 019dba8c-efc0-729a-4ed1-bfc4765a8b8a
59 20260325180337 ADAS_S751NX0Y800506T_20260402120500514190_e463db00873c CPLA 25 5.0 20 019dba8c-fac6-78fe-66f5-8c188d47193d
60 20260325180145 ADAS_S751NX0Y800506T_20260402120500514190_c2c07583877e CPLA 25 5.0 20 019dba8c-ff1a-78b1-45c0-c3cb9b7fe17b
61 20260325175106 ADAS_S751NX0Y800506T_20260402120500514190_30ce60e0d63d CPLA 25 5.0 20 019dba8d-03ff-7dbb-7726-6072569fdbdb
62 20260325172254 ADAS_S751NX0Y800506T_20260402120500514190_072cb4411b63 CSFA 50 20.0 60 019dba8d-0c92-72be-5401-d3b6c808e155
63 20260325171905 ADAS_S751NX0Y800506T_20260402120500514190_dfbc1dbd393c CSFA 50 20.0 60 019dba8d-1377-7a61-6259-ee58519c1f2c
64 20260325170448 ADAS_S751NX0Y800506T_20260402120500514190_f83a9601f577 CSFA 50 20.0 60 019dba8d-1900-7e31-7e13-939985c88c24
65 20260325170106 ADAS_S751NX0Y800506T_20260402120500514190_2c54e25cb32f CSFA 50 20.0 50 019dba8d-1cc8-72b5-4762-d7ce61ca9a8f
66 20260325165620 ADAS_S751NX0Y800506T_20260402120500514190_7389767ab909 CSFA 50 20.0 50 019dba8d-2045-72c5-603a-af19182d9279
67 20260325165344 ADAS_S751NX0Y800506T_20260402120500514190_e95155ae8f08 CSFA 50 20.0 50 019dba8d-27ad-72af-7a44-61659faf5fd2
68 20260325165101 ADAS_S751NX0Y800506T_20260402120500514190_1fe6d0c95742 CSFA 50 20.0 40 019dba8d-3aa4-7535-74b5-40c2664d916c
69 20260325164557 ADAS_S751NX0Y800506T_20260402120500514190_5779b22a5c73 CSFA 50 20.0 40 019dba8d-4432-72b9-65bf-a7469b53e92a
70 20260325164019 ADAS_S751NX0Y800506T_20260402120500514190_b224bea0ddbb CSFA 50 20.0 40 019dba8d-49da-791e-6a8d-888d048776f6
71 20260325163640 ADAS_S751NX0Y800506T_20260402120500514190_d6f39345461f CSFA 50 20.0 30 019dba8d-4e2d-766f-41ef-a9d706dd6b14
72 20260325163344 ADAS_S751NX0Y800506T_20260402120500514190_12f793d51613 CSFA 50 20.0 30 019dba8d-5244-7c4b-5154-8f67232a9fcf
73 20260325160450 ADAS_S751NX0Y800506T_20260402120500514190_e2efe25a6880 CSFA 50 20.0 30 019dba8d-57ff-7056-6808-a60b07d1a70d
74 20260325153627 ADAS_S751NX0Y800506T_20260402120500514190_a2ca26a51193 CBNA 50 15.0 60 019dba8d-5f80-702b-57d2-52dcd6e8f914
75 20260325153201 ADAS_S751NX0Y800506T_20260402120500514190_bf145238287f CBNA 50 15.0 60 019dba8d-6933-7d3e-7039-92af7f4913aa
76 20260325151329 ADAS_S751NX0Y800506T_20260402120500514190_0b861057a7d9 CBNA 50 15.0 50 019dba8d-6e1b-735a-70ad-b297ffc7c1c8
77 20260325150516 ADAS_S751NX0Y800506T_20260402120500514190_26d04cf53d23 CBNA 50 15.0 50 019dba8d-7231-77a8-5c8f-c9953ee04d96
78 20260325150059 ADAS_S751NX0Y800506T_20260402120500514190_1aa11c5aeba7 CBNA 50 15.0 50 019dba8d-7a28-7d05-7761-8f8c6f7d40a2
79 20260325145759 ADAS_S751NX0Y800506T_20260402120500514190_38491776ee5a CBNA 50 15.0 40 019dba8d-7ec0-71b4-4e23-8212e624c34e
80 20260325145539 ADAS_S751NX0Y800506T_20260402120500514190_a05517753a60 CBNA 50 15.0 40 019dba8d-82b2-7fc4-7b6d-63cbb1ce20e6
81 20260325145316 ADAS_S751NX0Y800506T_20260402120500514190_a5d59f3e0de2 CBNA 50 15.0 40 019dba8d-8775-7f47-5f49-4b816ccfa55f
82 20260325144443 ADAS_S751NX0Y800506T_20260402120500514190_8991319529c4 CBNA 50 15.0 30 019dba8d-8d91-76bd-5bac-05a1c88be6e1
83 20260325144228 ADAS_S751NX0Y800506T_20260402120500514190_154ac0410795 CBNA 50 15.0 30 019dba8d-9280-78e1-4f43-21e7f891ef13
84 20260325142826 ADAS_S751NX0Y800506T_20260402120500514190_25b1c474d0bb CBNA 50 15.0 30 019dba8d-9876-75ca-6228-3852a33be169
85 20260325142109 ADAS_S751NX0Y800506T_20260402120500514190_83ab0ea00dc7 CBNA 50 15.0 20 019dba8d-9f36-7a3c-5528-a3e87a3ff57a
86 20260325141355 ADAS_S751NX0Y800506T_20260402120500514190_369491fcade7 CBNA 50 15.0 20 019dba8d-a510-7f61-6e11-41b6a1365217
87 20260325140126 ADAS_S751NX0Y800506T_20260402120500514190_57283841b369 CBNA 50 15.0 20 019dba8d-ab06-74df-7b01-7fe7576c7888
88 20260326181430 ADAS_S751NX0Y601865J_20260328113450259688_1e9541a7d2c7 CPLA 50 5.0 50 019dba8d-bf15-777f-4952-c6680aca4c1e
89 20260326180301 ADAS_S751NX0Y601865J_20260328113450259688_713766bcf1f2 CPLA 50 5.0 50 019dba8d-c3ff-7f5b-7ced-a19828dbdd94
90 20260326175733 ADAS_S751NX0Y601865J_20260328113450259688_43fbd00148aa CPLA 50 5.0 50 019dba8d-c87a-70bc-480f-e37a9c2c6a0c
91 20260326174803 ADAS_S751NX0Y601865J_20260328113450259688_1ced9e7a5ff4 CBLA-CN21 50 15.0 60 019dba8d-cd58-783e-5ef9-fd9c655a8ada
92 20260326174513 ADAS_S751NX0Y601865J_20260328113450259688_183e46d60337 CBLA-CN21 50 15.0 60 019dba8d-d21e-7ef7-5e82-6e0df2672823
93 20260326173610 ADAS_S751NX0Y601865J_20260328113450259688_559e79696f59 CBLA-CN21 50 15.0 60 019dba8d-d707-7b92-796c-e9efb20c179d
94 20260326171109 ADAS_S751NX0Y601865J_20260328113450259688_490ba9b95ba9 CBLA-CN21 50 15.0 50 019dba8d-dc89-7f13-493e-ca1d492ad142
95 20260326170202 ADAS_S751NX0Y601865J_20260328113450259688_347a11543c73 CBLA-CN21 50 15.0 50 019dba8d-e0ff-731d-6ee9-b6d77b1a89f4
96 20260326164438 ADAS_S751NX0Y601865J_20260328113450259688_5241e2ff36e4 CBLA-CN21 50 15.0 50 019dba8d-e717-74bc-7616-4cd4feb90dea
97 20260326164202 ADAS_S751NX0Y601865J_20260328113450259688_10e68e264ee3 CBLA-CN21 50 15.0 40 019dba8d-ec33-75e6-784b-6b652685bd1a
98 20260326162358 ADAS_S751NX0Y601865J_20260328113450259688_2b77ce9a349e CBLA-CN21 50 15.0 40 019dba8d-f191-7302-7488-9f1fda4f8bba
99 20260326162136 ADAS_S751NX0Y601865J_20260328113450259688_900166524e3b CBLA-CN21 50 15.0 40 019dba8d-f5ec-756f-7f21-3367acc845a3
100 20260326161852 ADAS_S751NX0Y601865J_20260328113450259688_67fd2a079d1d CBLA-CN21 50 15.0 30 019dba8d-fc3c-73dd-582b-1399182fd5bc
101 20260326161642 ADAS_S751NX0Y601865J_20260328113450259688_fd8ae38ed3ef CBLA-CN21 50 15.0 30 019dba8e-02d0-7c88-49fb-085e3437eada
102 20260326161154 ADAS_S751NX0Y601865J_20260328113450259688_8d0bdc3af3ad CBLA-CN21 50 15.0 30 019dba8e-08e7-7519-7dc7-f4a077a7a73d
103 20260326160814 ADAS_S751NX0Y601865J_20260328113450259688_46197d491ed8 CBLA-CN21 50 15.0 20 019dba8e-1062-7f53-702d-ff7c593e020e
104 20260326155847 ADAS_S751NX0Y601865J_20260328113450259688_f55db8debcca CBLA-CN21 50 15.0 20 019dba8e-189b-72b8-612a-9504d52fab99
105 20260326153031 ADAS_S751NX0Y601865J_20260328113450259688_336615afba11 CPLA 50 5.0 60 019dba8e-1ea1-709e-52ed-95d228e800d1
106 20260326152808 ADAS_S751NX0Y601865J_20260328113450259688_740131f6e72c CPLA 50 5.0 60 019dba8e-274b-75e0-7f9e-adfd1a86b923
107 20260326152355 ADAS_S751NX0Y601865J_20260328113450259688_1f80da22f45a CPLA 50 5.0 60 019dba8e-3255-7ba6-689e-0df1a6329004
108 20260326144728 ADAS_S751NX0Y601865J_20260328113450259688_010690530eb1 CPLA 50 5.0 40 019dba8e-4d61-717b-5331-405c302917da
109 20260326144521 ADAS_S751NX0Y601865J_20260328113450259688_88f480b20482 CPLA 50 5.0 40 019dba8e-53ad-7fc8-4112-5fec894af7d9
110 20260326144301 ADAS_S751NX0Y601865J_20260328113450259688_11edf0db8552 CPLA 50 5.0 40 019dba8e-5864-761c-7e3c-6778151f6515
111 20260326143953 ADAS_S751NX0Y601865J_20260328113450259688_31374e23ea52 CPLA 50 5.0 30 019dba8e-5e3e-7f71-4bf4-42d174dda454
112 20260326143553 ADAS_S751NX0Y601865J_20260328113450259688_208c31032ab7 CPLA 50 5.0 30 019dba8e-653e-7350-7f96-54bf58ecd18d
113 20260326143325 ADAS_S751NX0Y601865J_20260328113450259688_890e13a19330 CPLA 50 5.0 30 019dba8e-6bcb-7b38-42f0-821b34cf3881
114 20260326143002 ADAS_S751NX0Y601865J_20260328113450259688_253cc2246a46 CPLA 50 5.0 20 019dba8e-7358-7062-6dc4-6d75f763f51c
115 20260326141816 ADAS_S751NX0Y601865J_20260328113450259688_968bbf10d481 CPLA 50 5.0 20 019dba8e-7ecd-7010-765a-37ff228578bb
116 20260326141456 ADAS_S751NX0Y601865J_20260328113450259688_7089abe3283f CPLA 50 5.0 20 019dba8e-8260-7436-7560-c44860a34ddb
117 20260326121348 ADAS_S751NX0Y601865J_20260328113450259688_434da435af46 CPLA 25 5.0 40 019dba8e-892e-7527-59df-97eb0cd6ba13
118 20260326120929 ADAS_S751NX0Y601865J_20260328113450259688_19aa5768291c CPLA 25 5.0 40 019dba8e-8e70-7609-6e15-004dd8b4e3c5
119 20260326113327 ADAS_S751NX0Y601865J_20260328113450259688_cf29bc58f910 CPLA 25 5.0 40 019dba8e-9518-7a09-599b-5064d89540f2
120 20260327164844 ADAS_S751NX0Y601739V_20260330104120600319_b8ffb91ad5b3 CCRS -50 0.0 20 019dba8e-a1eb-759c-5e99-d91414dbcb65
121 20260327164715 ADAS_S751NX0Y601739V_20260330104120600319_25960516b170 CCRS -50 0.0 20 019dba8e-a70f-72ac-7996-79cec1bab193
122 20260327163408 ADAS_S751NX0Y601739V_20260330104120600319_2bcd36764fdc CCRS -50 0.0 20 019dba8e-adc1-7a3f-4e2a-bdfa804aa9a1
123 20260327160636 ADAS_S751NX0Y601739V_20260330104120600319_5e14779592f2 CCRS 100 0.0 40 019dba8e-b4be-739a-5297-d7b60f37f030
124 20260327155725 ADAS_S751NX0Y601739V_20260330104120600319_44d7b1f69620 CCRS 100 0.0 40 019dba8e-b913-7be7-4071-4e349a8bb241
125 20260327155538 ADAS_S751NX0Y601739V_20260330104120600319_eb4efa485513 CCRS 100 0.0 40 019dba8e-be43-7519-589e-a06a5e71a75d
126 20260327153617 ADAS_S751NX0Y601739V_20260330104120600319_4f029dbe74a6 CCRS 100 0.0 30 019dba8e-c22f-7a21-4b8c-a4828bc3bd5a
127 20260327152708 ADAS_S751NX0Y601739V_20260330104120600319_c84cd8106f77 CCRS 100 0.0 30 019dba8e-c6ac-7d85-7c7d-64e4dfb6b36a
128 20260327151710 ADAS_S751NX0Y601739V_20260330104120600319_eb5e6353a9b5 CCRS 100 0.0 30 019dba8e-cccf-7893-48ea-3325a5c5ab52
129 20260327150850 ADAS_S751NX0Y601739V_20260330104120600319_96c7a7f2338c CCRS 100 0.0 20 019dba8e-d206-713a-69d8-0c350ff48f24
130 20260327150639 ADAS_S751NX0Y601739V_20260330104120600319_c06f5150f502 CCRS 100 0.0 20 019dba8e-d61d-7256-536b-e6b1dbf769c4
131 20260327150038 ADAS_S751NX0Y601739V_20260330104120600319_4b079fa4769c CCRS 100 0.0 20 019dba8e-dae4-7c57-40c8-da652cb563eb
132 20260327115408 ADAS_S751NX0Y601739V_20260330104120600319_89971a38a795 CCRM 100 20.0 40 019dba8e-dfa7-79b3-76d7-ea9ef016e0fe
133 20260327115052 ADAS_S751NX0Y601739V_20260330104120600319_9fde171dd0c5 CCRM 100 20.0 40 019dba8e-e685-75e5-5a4e-a0555eecf3aa
134 20260327113709 ADAS_S751NX0Y601739V_20260330104120600319_310c2fb9e063 CCRM 100 20.0 40 019dba8e-eb36-79a9-56dc-5a777e892f92
135 20260327112148 ADAS_S751NX0Y601739V_20260330104120600319_71c00fa5c46c CCRM 100 20.0 30 019dba8e-effd-731c-481d-0e8c2bd318e3
136 20260327111430 ADAS_S751NX0Y601739V_20260330104120600319_49f67f0f4c84 CCRM 100 20.0 30 019dba8e-f43e-7095-4bd1-83e7a1623df2
137 20260327110922 ADAS_S751NX0Y601739V_20260330104120600319_d9c5e242cd43 CCRM 100 20.0 30 019dba8e-f9e8-7230-7426-8beae71bc750
138 20260329154913 ADAS_S5STNF0T504465N_20260330162214124146_0491e7efbd55 CCRS 100 0.0 60 019dba8e-fe8c-74b0-5020-04219d015632
139 20260329154719 ADAS_S5STNF0T504465N_20260330162214124146_6bc547d69cf8 CCRS 100 0.0 60 019dba8f-036c-7eaf-6636-653468b7bb3b
140 20260329154536 ADAS_S5STNF0T504465N_20260330162214124146_a82545a4fac4 CCRS 100 0.0 50 019dba8f-0896-7317-6a4e-ae75c0ebab7c
141 20260329154203 ADAS_S5STNF0T504465N_20260330162214124146_e0dfc76d03a5 CCRS 100 0.0 50 019dba8f-0ccb-71d4-5be7-b8cfb15bb6f0
142 20260329142003 ADAS_S5STNF0T504465N_20260330162214124146_c74af4cc5253 CCRS -50 0.0 40 019dba8f-3e92-70ab-408c-7ffce13cd657
143 20260329141813 ADAS_S5STNF0T504465N_20260330162214124146_370de986d132 CCRS -50 0.0 40 019dba8f-4244-7d9f-6c58-6888367f5ffd
144 20260329120223 ADAS_S5STNF0T504465N_20260330162214124146_28f2102c8b7d CCRS -50 0.0 40 019dba8f-4864-7226-6921-6248ac3e0cb7
145 20260329115326 ADAS_S5STNF0T504465N_20260330162214124146_73d6bf86aabf CCRS 50 0.0 30 019dba8f-54d6-7cdf-4702-c00b0e1ee340
146 20260329115057 ADAS_S5STNF0T504465N_20260330162214124146_22ec55135ffb CCRS 50 0.0 30 019dba8f-5945-75a8-6bf2-ecd05a34755f
147 20260329114336 ADAS_S5STNF0T504465N_20260330162214124146_c68c2ee15588 CCRS 50 0.0 30 019dba8f-5d2f-7a1d-6bad-78ead7afc89d
148 20260331175331 ADAS_S5STNF0T406280R_20260402104850269428_d22b22f0957c CPNA 25 5.0 60 019dba8f-873f-7bba-6f02-448274ca1cfd
149 20260331163715 ADAS_S5STNF0T406280R_20260402104850269428_53960b821f6f CPNA 75 5.0 40 019dba8f-a46a-7861-45f4-4366c3a1851c
150 20260331151454 ADAS_S5STNF0T406280R_20260402104850269428_98e24c39222d CPNA 25 5.0 50 019dba8f-d397-79d5-7e79-cdb2b84dd620
151 20260331151250 ADAS_S5STNF0T406280R_20260402104850269428_f0cf082bc503 CPNA 25 5.0 50 019dba8f-d8e8-7886-5c86-b70a49d7cf07
152 20260401105643 ADAS_S5STNF0T504465N_20260402191154995992_22c18553e90d CBNA 50 15.0 60 019dba7e-fede-7b33-5088-856cadb9f663
153 20260402163705 ADAS_S751NX0Y601865J_20260404102607981812_a61254e06e07 CCRM 100 20.0 FCW70 019dba82-192f-7a87-5d00-ab7caf376a6c
154 20260402161029 ADAS_S751NX0Y601865J_20260404102607981812_8e62c1e285e4 CCRM 50 20.0 50 019dba82-21c1-7551-4315-9753aaf80d19
155 20260402160740 ADAS_S751NX0Y601865J_20260404102607981812_88676757d6a7 CCRM 50 20.0 50 019dba82-2bc2-7045-7f2d-3471a81da6c5
156 20260402160313 ADAS_S751NX0Y601865J_20260404102607981812_85683577a86c CCRM 50 20.0 50 019dba82-3312-7a73-670b-b0a071570a7c
157 20260402155719 ADAS_S751NX0Y601865J_20260404102607981812_59d8b2bb7b26 CCRM 100 20.0 50 019dba82-3db1-7c70-7f71-00aac10e069f
158 20260402155441 ADAS_S751NX0Y601865J_20260404102607981812_83a21145e104 CCRM 100 20.0 50 019dba82-474f-7d9b-4930-a6da99da2524
159 20260402140527 ADAS_S751NX0Y601865J_20260404102607981812_94a82a4fc7ed CCRM 100 20.0 50 019dba82-4fbc-7403-457b-29842a656fa3
160 20260402112926 ADAS_S751NX0Y601865J_20260404102607981812_9d1774bc6384 CCRM -50 20.0 40 019dba82-761b-7d10-4499-5a77b88cc146
161 20260402112746 ADAS_S751NX0Y601865J_20260404102607981812_66692e40d317 CCRM -50 20.0 40 019dba82-7c59-76ec-5d20-6327cf819094
162 20260402112422 ADAS_S751NX0Y601865J_20260404102607981812_169c8d652d38 CCRM -50 20.0 40 019dba82-81a0-7252-43d2-9f4b1d9a497f
163 20260402104850 ADAS_S751NX0Y601865J_20260404102607981812_9d2cab2c0acc CCRM 50 20.0 30 019dba82-9f89-728e-7730-8c6a71cdd37f
164 20260402104654 ADAS_S751NX0Y601865J_20260404102607981812_6dc1ef0b9205 CCRM 50 20.0 30 019dba82-a6d3-73e1-7ec1-32c4a371507d
165 20260402104227 ADAS_S751NX0Y601865J_20260404102607981812_440893f8545b CCRM 50 20.0 30 019dba82-acf6-7c89-6855-f1d4920fcacc
166 20260403111717 ADAS_S751NX0Y601739V_20260404180449233610_5e1c121e3173 CPLA 25 5.0 FCW80 019dba84-a4fc-793c-5e97-c56d370aa46f
167 20260403111530 ADAS_S751NX0Y601739V_20260404180449233610_60322c693233 CPLA 25 5.0 FCW80 019dba84-a828-7b0b-6dbb-5426ddd3f782
168 20260403111209 ADAS_S751NX0Y601739V_20260404180449233610_0090dd8e218e CPLA 25 5.0 FCW80 019dba84-ac55-7507-793f-6b1b83c171c9
169 20260403110410 ADAS_S751NX0Y601739V_20260404180449233610_5e216b122d19 CPLA 25 5.0 FCW70 019dba84-afb5-7412-6f5a-0f209e51e0be
170 20260403110146 ADAS_S751NX0Y601739V_20260404180449233610_0af677bafa70 CPLA 25 5.0 FCW70 019dba84-b302-7a2f-55b1-55d74ca34b97
171 20260403105607 ADAS_S751NX0Y601739V_20260404180449233610_77171219d205 CPLA 25 5.0 FCW70 019dba84-b659-73f9-6f2d-2bfbf4e2b661
172 20260403105245 ADAS_S751NX0Y601739V_20260404180449233610_d69464e39b14 CPLA 25 5.0 FCW60 019dba84-ba6b-76da-4ccc-99233bcff685
173 20260403105025 ADAS_S751NX0Y601739V_20260404180449233610_e29f23ae0340 CPLA 25 5.0 FCW60 019dba84-bd90-70bc-619f-b8dde6b730e8
174 20260403104553 ADAS_S751NX0Y601739V_20260404180449233610_2bcd8b998839 CPLA 25 5.0 FCW60 019dba84-c0c7-7183-5e8d-870fc4d04964
175 20260403104107 ADAS_S751NX0Y601739V_20260404180449233610_c1e13502a0e1 CPLA 25 5.0 FCW50 019dba84-c4af-7d97-7e6d-b6239722ec96
176 20260403103901 ADAS_S751NX0Y601739V_20260404180449233610_9ba0984bad5a CPLA 25 5.0 FCW50 019dba84-c809-743e-5080-1de74eb35b5a
177 20260403103238 ADAS_S751NX0Y601739V_20260404180449233610_349b6b6c98d3 CPLA 25 5.0 FCW50 019dba84-cb24-71cb-47cf-0fb636fe7071
178 20260407235712 ADAS_S5STNF0T406280R_20260409152111002995_efab4f9a5f9e CPLA-夜晚 50.0 5.0 40 019d9aa9-076e-7b24-5f16-a4774edf4093
179 20260407235601 ADAS_S5STNF0T406280R_20260409152111002995_cfeadccd6caf CPLA-夜晚 50.0 5.0 40 019d9aa9-0f61-7497-7d99-c5748212bfc8
180 20260407235425 ADAS_S5STNF0T406280R_20260409152111002995_49e7f088e808 CPLA-夜晚 50.0 5.0 30 019d9aa9-15e1-7e51-41cc-c6a705f1dd9a
181 20260407235247 ADAS_S5STNF0T406280R_20260409152111002995_3c85c3558988 CPLA-夜晚 50.0 5.0 30 019d9aa9-1b86-72f8-5625-626e1d10850a
182 20260407235041 ADAS_S5STNF0T406280R_20260409152111002995_24f188716448 CPLA-夜晚 50.0 5.0 20 019d9aa9-21b4-7853-54b1-bf3e6771ffc2
183 20260407234858 ADAS_S5STNF0T406280R_20260409152111002995_5b39e9130eb2 CPLA-夜晚 50.0 5.0 20 019d9aa9-26b6-7452-51e8-a185ef8f03f9
184 20260407234222 ADAS_S5STNF0T406280R_20260409152111002995_425ba64c99f3 CPLA-夜晚 25.0 5.0 FCW80 019d9aa9-2b19-73e6-4765-3c7d280b3ee6
185 20260407234024 ADAS_S5STNF0T406280R_20260409152111002995_bb954963fead CPLA-夜晚 25.0 5.0 FCW80 019d9aa9-30c5-7636-549f-81144cc4f62e
186 20260407233737 ADAS_S5STNF0T406280R_20260409152111002995_409f58cad2b1 CPLA-夜晚 25.0 5.0 FCW70 019d9aa9-3496-7948-5037-2a02204cc43e
187 20260407233549 ADAS_S5STNF0T406280R_20260409152111002995_dd98b096d792 CPLA-夜晚 25.0 5.0 FCW70 019d9aa9-3977-7d5b-652d-66a266e6c60a
188 20260407233339 ADAS_S5STNF0T406280R_20260409152111002995_c105bad6812b CPLA-夜晚 25.0 5.0 FCW60 019d9aa9-4051-7b14-5e87-20cd3532ef90
189 20260407233159 ADAS_S5STNF0T406280R_20260409152111002995_8065a4b59db6 CPLA-夜晚 25.0 5.0 FCW60 019d9aa9-4536-7af2-6562-40e4b9c89ccc
190 20260407232758 ADAS_S5STNF0T406280R_20260409152111002995_851306838843 CPLA-夜晚 25.0 5.0 FCW50 019d9aa9-48a9-7e39-6d1d-9ed1732bfbb9
191 20260407232406 ADAS_S5STNF0T406280R_20260409152111002995_877fb48c53e8 CPLA-夜晚 25.0 5.0 FCW50 019d9aa9-4cd4-77d7-7aa5-0b4314a7fd3e
192 20260407231753 ADAS_S5STNF0T406280R_20260409152111002995_d89ac36f740c CPLA-夜晚 25.0 5.0 FCW50 019d9aa9-5140-7c6c-5cc1-ae1058843056
193 20260407225130 ADAS_S5STNF0T406280R_20260409152111002995_92dd871fc3bd CPFAO-夜晚 25.0 6.5 60 019d9aa9-556c-7ab5-5d3f-6e63014ce80b
194 20260407224321 ADAS_S5STNF0T406280R_20260409152111002995_797f2a520f7f CPFAO-夜晚 25.0 6.5 60 019d9aa9-5aaa-7b33-6455-8489710518a9
195 20260407224125 ADAS_S5STNF0T406280R_20260409152111002995_955748274b43 CPFAO-夜晚 25.0 6.5 60 019d9aa9-6119-7cc4-7699-7f644dc2a964
196 20260407223853 ADAS_S5STNF0T406280R_20260409152111002995_f5829f94e220 CPFAO-夜晚 25.0 6.5 40 019d9aa9-65aa-7748-63fd-6b9ada70eef2
197 20260407223726 ADAS_S5STNF0T406280R_20260409152111002995_9dd57efb9e3f CPFAO-夜晚 25.0 6.5 40 019d9aa9-6a50-79cf-76fd-a98eb8d5f5a8
198 20260407223528 ADAS_S5STNF0T406280R_20260409152111002995_53a024ff00b0 CPFAO-夜晚 25.0 6.5 40 019d9aa9-7016-793e-44de-b79af7e1456b
199 20260407223054 ADAS_S5STNF0T406280R_20260409152111002995_1f4fb829d5c1 CPFAO-夜晚 25.0 6.5 20 019d9aa9-7472-764a-545a-99cbb25f9835
200 20260407222854 ADAS_S5STNF0T406280R_20260409152111002995_65df5c754a08 CPFAO-夜晚 25.0 6.5 20 019d9aa9-7865-74d7-7e59-093438dc3388
201 20260407222417 ADAS_S5STNF0T406280R_20260409152111002995_cf1dfc5751fb CPFAO-夜晚 25.0 6.5 20 019d9aa9-7c27-729c-4d7b-3713e76ef75b
202 20260407221421 ADAS_S5STNF0T406280R_20260409152111002995_79ead953a267 CPFA-夜晚 25.0 6.5 60 019d9aa9-827d-7a37-78e5-4ea0ec992c77
203 20260407215247 ADAS_S5STNF0T406280R_20260409152111002995_a345faf933c1 CPFA-夜晚 25.0 6.5 60 019d9aa9-8986-7e12-6f1c-7b4541a5c438
204 20260407214759 ADAS_S5STNF0T406280R_20260409152111002995_3c626bbc7af6 CPFA-夜晚 25.0 6.5 50 019d9aa9-8e5d-7bae-7fa6-a1243ad252b1
205 20260407214009 ADAS_S5STNF0T406280R_20260409152111002995_bc6c0c01e193 CPFA-夜晚 25.0 6.5 50 019d9aa9-91e3-7a04-77dd-d1fec1704486
206 20260407213801 ADAS_S5STNF0T406280R_20260409152111002995_48410cc6c373 CPFA-夜晚 25.0 6.5 50 019d9aa9-9842-7b06-643f-a6d3c27fdb4a
207 20260407212845 ADAS_S5STNF0T406280R_20260409152111002995_f81455ea3eed CPFA-夜晚 25.0 6.5 40 019d9aa9-9e5a-761b-71ee-2c0daebc363a
208 20260407211000 ADAS_S5STNF0T406280R_20260409152111002995_bc6ff7c44071 CPFA-夜晚 25.0 6.5 40 019d9aa9-a2ea-729b-61da-46dc65e0f2c9
209 20260407210630 ADAS_S5STNF0T406280R_20260409152111002995_aa33868a5965 CPFA-夜晚 25.0 6.5 30 019d9aa9-a8a0-748d-612c-77c42f99428c
210 20260407205653 ADAS_S5STNF0T406280R_20260409152111002995_2264933415a6 CPFA-夜晚 25.0 6.5 30 019d9aa9-b0a4-7dd1-5fb1-4bd3842b0a0d
211 20260407203248 ADAS_S5STNF0T406280R_20260409152111002995_51b93fb7cf53 CPFA-夜晚 25.0 6.5 30 019d9aa9-b6b3-7abb-6f43-815eb75834a8
212 20260407203003 ADAS_S5STNF0T406280R_20260409152111002995_ddada7c982c6 CPFA-夜晚 25.0 6.5 20 019d9aa9-bd6e-746b-556d-0c089251cc57
213 20260407202812 ADAS_S5STNF0T406280R_20260409152111002995_4779e10c3a5b CPFA-夜晚 25.0 6.5 20 019d9aa9-c38e-7e79-70b1-615b22a4f86b
214 20260407202502 ADAS_S5STNF0T406280R_20260409152111002995_bf0967499ed6 CPFA-夜晚 25.0 6.5 20 019d9aa9-c752-7a92-44e6-69411b6e44aa
215 20260407182536 ADAS_S5STNF0T406280R_20260409152111002995_4f1437a97128 CPFAO 25.0 6.5 60 019d9aa9-cb33-7375-4f41-2a8282140d9a
216 20260407181809 ADAS_S5STNF0T406280R_20260409152111002995_bfa7f306290b CPFAO 25.0 6.5 60 019d9aa9-cff8-7e52-4e27-eecdd74e70c4
217 20260407181450 ADAS_S5STNF0T406280R_20260409152111002995_716c2b09c740 CPFAO 25.0 6.5 40 019d9aa9-d4d7-7a5d-7eac-fadf6fb9d2ea
218 20260407181122 ADAS_S5STNF0T406280R_20260409152111002995_da621561033c CPFAO 25.0 6.5 40 019d9aa9-ecfb-73fb-4b6b-743b7bbb2b08
219 20260407180720 ADAS_S5STNF0T406280R_20260409152111002995_9f26c651c46d CPFAO 25.0 6.5 40 019d9aa9-f13a-7b1a-5760-09e35fc5d834
220 20260407150403 ADAS_S5STNF0T406280R_20260409152111002995_9c12dd965fc5 CPFAO 25.0 6.5 20 019d9aaa-0ccb-70bc-45e1-85a75961a5ee
221 20260407145705 ADAS_S5STNF0T406280R_20260409152111002995_eb1aa8b08248 CPFAO 25.0 6.5 20 019d9aaa-127b-78ef-57df-f568d78eeab5
222 20260407115528 ADAS_S5STNF0T406280R_20260409152111002995_7254e457ef67 CBLA 25.0 15.0 FCW80 019d9aaa-18f2-75d9-59e2-25649bb25498
223 20260407115335 ADAS_S5STNF0T406280R_20260409152111002995_6325ec39b751 CBLA 25.0 15.0 FCW80 019d9aaa-1ccc-70e2-4a60-07216d9dd359
224 20260407115155 ADAS_S5STNF0T406280R_20260409152111002995_b51fdac11ab8 CBLA 25.0 15.0 FCW80 019d9aaa-21bb-7429-6b35-a725a9993bdd
225 20260407114731 ADAS_S5STNF0T406280R_20260409152111002995_44c27781ddc3 CBLA 25.0 15.0 FCW70 019d9aaa-2891-7960-7681-84be2eac02d1
226 20260407114555 ADAS_S5STNF0T406280R_20260409152111002995_33b078bf6216 CBLA 25.0 15.0 FCW70 019d9aaa-2d9b-7b10-54bd-88503a0ed61b
227 20260407114352 ADAS_S5STNF0T406280R_20260409152111002995_ecfd3b259961 CBLA 25.0 15.0 FCW60 019d9aaa-3150-7366-774b-946d68a529f8
228 20260407114204 ADAS_S5STNF0T406280R_20260409152111002995_562404e71005 CBLA 25.0 15.0 FCW60 019d9aaa-37bb-7b90-788b-66a42a574474
229 20260407114023 ADAS_S5STNF0T406280R_20260409152111002995_7071743abdf9 CBLA 25.0 15.0 FCW60 019d9aaa-3d58-7acb-73f3-444d666e03e7
230 20260407113824 ADAS_S5STNF0T406280R_20260409152111002995_f016eafc886a CBLA 25.0 15.0 FCW50 019d9aaa-4167-7eeb-4715-7892f58a5271
231 20260407113633 ADAS_S5STNF0T406280R_20260409152111002995_14b6fffb9346 CBLA 25.0 15.0 FCW50 019d9aaa-48af-7840-4f34-59a83f60ae4f
232 20260407113402 ADAS_S5STNF0T406280R_20260409152111002995_2db981f7c452 CBLA 25.0 15.0 FCW50 019d9aaa-4e92-743e-673b-19ca695f6571
233 20260407112549 ADAS_S5STNF0T406280R_20260409152111002995_915cffcc1584 CBLA 50.0 15.0 60 019d9aaa-524c-7950-5d38-965c8a7044b5
234 20260407112334 ADAS_S5STNF0T406280R_20260409152111002995_72cb0932d90e CBLA 50.0 15.0 60 019d9aaa-590d-77a4-7db2-923118c55be9
235 20260407112214 ADAS_S5STNF0T406280R_20260409152111002995_2ac2047ca290 CBLA 50.0 15.0 60 019d9aaa-5e44-7fc5-6e5b-8c43a352ccb7
236 20260407112037 ADAS_S5STNF0T406280R_20260409152111002995_3aaeea19a547 CBLA 50.0 15.0 50 019d9aaa-630d-77f1-5bdd-d09431e1e161
237 20260407111922 ADAS_S5STNF0T406280R_20260409152111002995_4deb6874a615 CBLA 50.0 15.0 50 019d9aaa-67ec-7410-5d97-7f3371866c7c
238 20260407111812 ADAS_S5STNF0T406280R_20260409152111002995_d39a5d1c908f CBLA 50.0 15.0 50 019d9aaa-6b63-73bf-73bb-5a3f96ace7b3
239 20260407111307 ADAS_S5STNF0T406280R_20260409152111002995_7a5e67352e0e CBLA 50.0 15.0 40 019d9aaa-70a3-748e-6d05-0c2d1a31dcae
240 20260407111122 ADAS_S5STNF0T406280R_20260409152111002995_d3ab196e744a CBLA 50.0 15.0 40 019d9aaa-88a0-7970-4ceb-15bb8ab3b1ff
241 20260407110751 ADAS_S5STNF0T406280R_20260409152111002995_5c50e575f464 CBLA 50.0 15.0 40 019d9aaa-8fd9-7ab1-6a49-72b63397588c
242 20260407110422 ADAS_S5STNF0T406280R_20260409152111002995_4045be63fc22 CBLA 50.0 15.0 30 019d9aaa-b385-753d-5faa-1ad2759f5a5f
243 20260407110300 ADAS_S5STNF0T406280R_20260409152111002995_ea8e031bb31e CBLA 50.0 15.0 30 019d9aaa-b8bb-7da2-4d44-23f067e0d663
244 20260407110130 ADAS_S5STNF0T406280R_20260409152111002995_6e0a4c97c8c1 CBLA 50.0 15.0 30 019d9aaa-bee0-7dab-4651-4c3915a8c5cd
245 20260407105941 ADAS_S5STNF0T406280R_20260409152111002995_621325fdf415 CBLA 50.0 15.0 20 019d9aaa-c31f-7e26-75c6-e02b1700a8a8
246 20260407105753 ADAS_S5STNF0T406280R_20260409152111002995_069a2c13319e CBLA 50.0 15.0 20 019d9aaa-c7f4-7027-50c2-58b40e941188
247 20260407105535 ADAS_S5STNF0T406280R_20260409152111002995_0e1ce93501ef CBLA 50.0 15.0 20 019d9aaa-cb54-7853-7393-0d3928f895f9
248 20260407102008 ADAS_S5STNF0T406280R_20260409152111002995_ef2816221a27 CPLA 50.0 5.0 60 019d9aaa-cf01-761f-690c-7f2090d7277d
249 20260407101706 ADAS_S5STNF0T406280R_20260409152111002995_2249a6c9c868 CPLA 50.0 5.0 60 019d9aaa-d4af-7f14-5347-005312fcbb02
250 20260407101455 ADAS_S5STNF0T406280R_20260409152111002995_3aec82d2ae5b CPLA 50.0 5.0 60 019d9aaa-dc19-7189-7ea1-1c6b2bb3a963
251 20260407100842 ADAS_S5STNF0T406280R_20260409152111002995_a33d9aa63d97 CPLA 50.0 5.0 50 019d9aaa-df67-7cea-7ac6-b5783b3aeab8
252 20260407100530 ADAS_S5STNF0T406280R_20260409152111002995_a3fd722c219d CPLA 50.0 5.0 50 019d9aaa-e4a6-7293-71ed-bd5ffeae3cbf
253 20260407100321 ADAS_S5STNF0T406280R_20260409152111002995_0a59f61cc73e CPLA 50.0 5.0 50 019d9aaa-e9bc-72a1-511e-051af8249f39
254 20260407095827 ADAS_S5STNF0T406280R_20260409152111002995_522b6859b7cc CPLA 50.0 5.0 40 019d9aaa-ed4f-7c64-734b-853b64feafdf
255 20260407095546 ADAS_S5STNF0T406280R_20260409152111002995_f45e8cd87f19 CPLA 50.0 5.0 40 019d9aaa-f24d-7e7f-513b-50bbd4dde342
256 20260407095253 ADAS_S5STNF0T406280R_20260409152111002995_d635dca3a188 CPLA 50.0 5.0 40 019d9aaa-f79c-7528-63f5-3d6592aedbfb
257 20260408161638 ADAS_S5STNF0T504465N_20260409152139658693_8dbfcbfeb5ee CBNAO 50.0 15.0 60 019d9aa4-e596-73a3-563e-91eff907fc5f
258 20260408161312 ADAS_S5STNF0T504465N_20260409152139658693_552b57bd437a CBNAO 50.0 15.0 60 019d9aa4-e97b-7f4c-71fe-27fb3e92820c
259 20260408161043 ADAS_S5STNF0T504465N_20260409152139658693_159245c0434e CBNAO 50.0 15.0 60 019d9aa4-eddd-77f5-6ce3-9eb75c9e126c
260 20260408160836 ADAS_S5STNF0T504465N_20260409152139658693_235d852f9406 CBNAO 50.0 15.0 40 019d9aa4-f55c-7254-6da3-9371446494a2
261 20260408160613 ADAS_S5STNF0T504465N_20260409152139658693_dbb8344a1203 CBNAO 50.0 15.0 40 019d9aa4-fa8b-7cdf-51c3-118b7c34368e
262 20260408160358 ADAS_S5STNF0T504465N_20260409152139658693_6c96ac950cc5 CBNAO 50.0 15.0 40 019d9aa4-ff05-79fb-58c4-c719f7dc6e07
263 20260408160123 ADAS_S5STNF0T504465N_20260409152139658693_259ff1913329 CBNAO 50.0 15.0 20 019d9aa5-049f-7bb1-5e03-978f6b092895
264 20260408155917 ADAS_S5STNF0T504465N_20260409152139658693_7f68037838f3 CBNAO 50.0 15.0 20 019d9aa5-09c3-78fc-73b5-7aa4c811f39a
265 20260408155451 ADAS_S5STNF0T504465N_20260409152139658693_0a7f2b349464 CBNAO 50.0 15.0 20 019d9aa5-0dcf-7135-4e96-d516559ebc9e
266 20260408152655 ADAS_S5STNF0T504465N_20260409152139658693_6d37a9755ccc CPNCO 25.0 5.0 60 019d9aa5-11b0-7f7b-79ff-9a433fc42aef
267 20260408151807 ADAS_S5STNF0T504465N_20260409152139658693_0d829e9357a4 CPNCO 25.0 5.0 60 019d9aa5-18c9-724e-7f73-8fe42bd39b5b
268 20260408150258 ADAS_S5STNF0T504465N_20260409152139658693_7a94940f5d03 CPNCO 25.0 5.0 60 019d9aa5-1d67-79ab-6805-059001b21a42
269 20260408145812 ADAS_S5STNF0T504465N_20260409152139658693_750011a9dfe4 CPNCO 25.0 5.0 40 019d9aa5-24e4-79fe-549c-19e449a23c53
270 20260408145424 ADAS_S5STNF0T504465N_20260409152139658693_ea7728a2697d CPNCO 25.0 5.0 40 019d9aa5-2aa5-7d7c-75b8-2b60ef3eed08
271 20260408145214 ADAS_S5STNF0T504465N_20260409152139658693_4948b709cf5d CPNCO 25.0 5.0 40 019d9aa5-31da-7d88-4f99-11dd0d0f8499
272 20260408141857 ADAS_S5STNF0T504465N_20260409152139658693_4eb92c8fee57 CPNCO 25.0 5.0 20 019d9aa5-4eca-7f08-635b-2fa3bc598c09
273 20260408141334 ADAS_S5STNF0T504465N_20260409152139658693_b0faffa9dc30 CPNCO 25.0 5.0 20 019d9aa5-538a-772a-494d-35f736399e65
274 20260408134743 ADAS_S5STNF0T504465N_20260409152139658693_b5876596c9d1 CPNCO 25.0 5.0 20 019d9aa5-5802-7924-6ce0-ffb4967f13bd
275 20260408002949 ADAS_S5STNF0T406280R_20260409152111002995_45d2787fbc67 CPLA-夜晚 25.0 5.0 FCW80 019d9aa5-5bf7-7fb2-6efc-6d8161e18c1b
276 20260408002550 ADAS_S5STNF0T406280R_20260409152111002995_5e07f54bbb10 CPLA-夜晚 25.0 5.0 FCW60 019d9aa5-63e8-711a-417e-c616fe4e5eda
277 20260408002023 ADAS_S5STNF0T406280R_20260409152111002995_0b5d60209c57 CPLA-夜晚 25.0 5.0 40 019d9aa5-6c4f-7ebf-5b32-53e5c680be0a
278 20260408001902 ADAS_S5STNF0T406280R_20260409152111002995_edda23ef80bd CPLA-夜晚 25.0 5.0 40 019d9aa5-701a-7bf6-4e38-45d884353a70
279 20260408001653 ADAS_S5STNF0T406280R_20260409152111002995_b29f5723b2c0 CPLA-夜晚 25.0 5.0 20 019d9aa5-735a-75f3-5ba4-93902a277d59
280 20260408001434 ADAS_S5STNF0T406280R_20260409152111002995_c14dc9bae519 CPLA-夜晚 25.0 5.0 20 019d9aa5-76fe-7d1f-598b-5e7dd61280e9
281 20260408000623 ADAS_S5STNF0T406280R_20260409152111002995_46815deac491 CPLA-夜晚 50.0 5.0 60 019d9aa5-7b0e-75c8-4334-61c3ab70abbb
282 20260408000446 ADAS_S5STNF0T406280R_20260409152111002995_c62ef90d053e CPLA-夜晚 50.0 5.0 60 019d9aa5-7e74-7664-6f81-427fa818ade0
283 20260408000248 ADAS_S5STNF0T406280R_20260409152111002995_543e826a5e70 CPLA-夜晚 50.0 5.0 50 019d9aa5-8200-7f80-46a0-02307e146cfa
284 20260408000108 ADAS_S5STNF0T406280R_20260409152111002995_4086a9a63200 CPLA-夜晚 50.0 5.0 50 019d9aa5-8a5a-7798-53ee-8ebecd6efac0
285 20260410183944 ADAS_S751NX0Y601865J_20260412195842469563_433f140b95d6 CCRS -50.0 0.0 FCW80 019d9a96-c1d6-7326-728e-02a54fd8e225
286 20260410183322 ADAS_S751NX0Y601865J_20260412195842469563_a7973f1e9bb1 CCRS 100.0 0.0 FCW80 019d9a96-cb3d-7c97-7ea5-b3f748d9eb5e
287 20260410183032 ADAS_S751NX0Y601865J_20260412195842469563_ef2acadfb2bd CCRS 100.0 0.0 FCW80 019d9a96-d38c-7078-46fe-d780744cb909
288 20260410182651 ADAS_S751NX0Y601865J_20260412195842469563_62b3ba276352 CCRS 50.0 0.0 FCW70 019d9a96-da33-7c3b-6246-61da039dfa20
289 20260410182102 ADAS_S751NX0Y601865J_20260412195842469563_cbcfff9884b1 CCRS 50.0 0.0 FCW70 019d9a96-dff9-7b8f-4705-38c5c58c2599
290 20260410180809 ADAS_S751NX0Y601865J_20260412195842469563_1f2727954bca CCRS 50.0 0.0 FCW70 019d9a96-e5e5-782c-65d1-48036de2d14a
291 20260410180043 ADAS_S751NX0Y601865J_20260412195842469563_9e2611ec8323 CCRS 100.0 0.0 FCW70 019d9a97-02a2-7ad2-6658-aa217ab89e55
292 20260410175829 ADAS_S751NX0Y601865J_20260412195842469563_042f5636d4f4 CCRS 100.0 0.0 FCW70 019d9a97-08a2-71ca-7a1a-4bec6e69a901
293 20260410175602 ADAS_S751NX0Y601865J_20260412195842469563_7787aecfa77f CCRS 100.0 0.0 FCW70 019d9a97-0d8d-7a20-489c-f90e4ce10e22
294 20260410175256 ADAS_S751NX0Y601865J_20260412195842469563_13f6d65d0058 CCRS -50.0 0.0 FCW60 019d9a97-11c1-742b-5d71-2074250c8b5f
295 20260410174813 ADAS_S751NX0Y601865J_20260412195842469563_74864ef9dfac CCRS 100.0 0.0 FCW60 019d9a97-1719-70e0-6008-7ca16945ea6b
296 20260410174417 ADAS_S751NX0Y601865J_20260412195842469563_fb97c4371e87 CCRS 100.0 0.0 FCW60 019d9a97-1c3b-74fa-4273-514b875c17ad
297 20260410172805 ADAS_S751NX0Y601865J_20260412195842469563_ca74d9bf7865 CCRS 100.0 0.0 FCW60 019d9a97-1fe2-7480-417b-a86fbb036b09
298 20260410171831 ADAS_S751NX0Y601865J_20260412195842469563_3299757de161 CCRS -50.0 0.0 FCW60 019d9a97-2bee-7107-401d-4d872729a179
299 20260410171425 ADAS_S751NX0Y601865J_20260412195842469563_9cae1d226719 CCRS -50.0 0.0 FCW60 019d9a97-3091-7993-662c-cd6a5a2ec208
300 20260410135043 ADAS_S751NX0Y601865J_20260412195842469563_5a853fcb203a CCRS 50.0 0.0 FCW50 019d9a97-5715-7df7-79f8-bee1114b0445
301 20260410134822 ADAS_S751NX0Y601865J_20260412195842469563_32bc05a9d954 CCRS 50.0 0.0 FCW50 019d9a97-5b96-76ad-6af6-261e504f4b6a
302 20260410134541 ADAS_S751NX0Y601865J_20260412195842469563_7110684c2ec6 CCRS 50.0 0.0 FCW50 019d9a97-5f4c-7d07-6fd5-6301296712e0
303 20260410121059 ADAS_S751NX0Y601865J_20260412195842469563_2f056f43e537 CCRS 100.0 0.0 FCW50 019d9a97-646e-749d-78fc-7c1177a082e4
304 20260410120748 ADAS_S751NX0Y601865J_20260412195842469563_f719a9f14f03 CCRS 100.0 0.0 FCW50 019d9a97-6c15-71d7-7ca4-8aa861b4f657
305 20260410120327 ADAS_S751NX0Y601865J_20260412195842469563_b1089228c2a7 CCRS 100.0 0.0 FCW50 019d9a97-707f-7b4c-6f73-bfdca7b99135
306 20260410111646 ADAS_S751NX0Y601865J_20260412195842469563_c5d7494583d0 CSFAO 50.0 20.0 60 019d9a97-7721-744b-6f9d-3e7f33022481
307 20260410104110 ADAS_S751NX0Y601865J_20260412195842469563_99948185a04d CSFAO 50.0 20.0 60 019d9a97-7c0c-7a18-6c44-0245ab8bf1ad
308 20260410103025 ADAS_S751NX0Y601865J_20260412195842469563_09a490787dad CSFAO 50.0 20.0 60 019d9a97-8221-7aa2-49ac-411ab9a7b24a
309 20260410102715 ADAS_S751NX0Y601865J_20260412195842469563_5e4f95ca5ba9 CSFAO 50.0 20.0 40 019d9a97-86f6-711a-68e0-69a9b8e9b359
310 20260410102527 ADAS_S751NX0Y601865J_20260412195842469563_e88c82463dde CSFAO 50.0 20.0 40 019d9a97-8bb3-7007-7c41-c7edd0edb95e
311 20260410102252 ADAS_S751NX0Y601865J_20260412195842469563_e12a5bd21c7b CSFAO 50.0 20.0 40 019d9a97-9152-7292-7210-da999124e35f
312 20260410102018 ADAS_S751NX0Y601865J_20260412195842469563_02d5dd72de6e CSFAO 50.0 20.0 20 019d9a97-96f8-7f2d-7675-481089eac2c7
313 20260410101810 ADAS_S751NX0Y601865J_20260412195842469563_f4a683d9d4db CSFAO 50.0 20.0 20 019d9a97-9ba9-75da-6e53-b4e8575ac660
314 20260410101534 ADAS_S751NX0Y601865J_20260412195842469563_cda9e45c8fd1 CSFAO 50.0 20.0 20 019d9a97-9fb4-76a5-5fa4-3bdfcdf3da32
315 20260411183829 ADAS_S751NX0Y601739V_20260413155723466116_a04db0919eec CCRS -50.0 0.0 FCW80 019d9a7c-a893-7ebe-44fc-88658f70c9a2
316 20260411182247 ADAS_S751NX0Y601739V_20260413155723466116_d1186bf4a065 CCRS -50.0 0.0 FCW80 019d9a7c-af31-7626-5765-81fc0f62c50b
317 20260411180919 ADAS_S751NX0Y601739V_20260413155723466116_9a6876a65dca CCRS 100.0 0.0 FCW80 019d9a7c-b749-77a4-57a0-8db9b20ff808
318 20260411175300 ADAS_S751NX0Y601739V_20260413155723466116_d852ebd5465e CCRM -50.0 20.0 FCW80 019d9a7c-c5e4-7e00-7abc-0b61af7b34d2
319 20260411174303 ADAS_S751NX0Y601739V_20260413155723466116_434fdd766056 CCRM -50.0 20.0 FCW80 019d9a7c-c955-7e81-4d13-eb44371e532a
320 20260411173124 ADAS_S751NX0Y601739V_20260413155723466116_97ec63da982a CCRM -50.0 20.0 FCW80 019d9a7c-cd7f-78f7-5c70-131af26cc440
321 20260411172605 ADAS_S751NX0Y601739V_20260413155723466116_71bcb435e71c CCRM 100.0 20.0 FCW80 019d9a7c-d846-741b-7597-41b66b95e10a
322 20260411172410 ADAS_S751NX0Y601739V_20260413155723466116_6d8d13f750fc CCRM 100.0 20.0 FCW80 019d9a7c-dc76-7635-5934-90774c92ed6d
323 20260411172142 ADAS_S751NX0Y601739V_20260413155723466116_723bebf4506d CCRM 100.0 20.0 FCW80 019d9a7c-e374-7a08-41df-cb22895e85e9
324 20260411171702 ADAS_S751NX0Y601739V_20260413155723466116_8f574aa74cca CCRM 50.0 20.0 FCW70 019d9a7c-e985-7d35-73d6-3c32a44ef500
325 20260411171447 ADAS_S751NX0Y601739V_20260413155723466116_5c3cb97938c5 CCRM 50.0 20.0 FCW70 019d9a7c-ed45-704a-56af-2fee6afc2bb7
326 20260411171038 ADAS_S751NX0Y601739V_20260413155723466116_d8fc43891af6 CCRM 50.0 20.0 FCW70 019d9a7c-f0ef-7ec9-5285-16661cc3be7c
327 20260411170537 ADAS_S751NX0Y601739V_20260413155723466116_0c1194076828 CCRM 100.0 20.0 FCW70 019d9a7c-f5c8-76c5-5dcb-0ab62615959e
328 20260411170231 ADAS_S751NX0Y601739V_20260413155723466116_4f8d3c73fffa CCRM 100.0 20.0 FCW70 019d9a7c-fb91-766b-4c07-18323de8251c
329 20260411165955 ADAS_S751NX0Y601739V_20260413155723466116_a3fe89de5059 CCRM 100.0 20.0 FCW70 019d9a7d-0105-7b5e-4b10-da65ba7b2306
330 20260411165255 ADAS_S751NX0Y601739V_20260413155723466116_2481817963a5 CCRM -50.0 20.0 FCW60 019d9a7d-04b7-74fb-75ff-d8cc08b2e6b5
331 20260411164856 ADAS_S751NX0Y601739V_20260413155723466116_a591780712a5 CCRM -50.0 20.0 FCW60 019d9a7d-0989-7b0c-46a1-e621003a415e
332 20260411164604 ADAS_S751NX0Y601739V_20260413155723466116_a570cbea0f8c CCRM -50.0 20.0 FCW60 019d9a7d-0e02-7c5f-4163-756d1d22c96b
333 20260411164110 ADAS_S751NX0Y601739V_20260413155723466116_1c8ce6be64a0 CCRM 100.0 20.0 FCW60 019d9a7d-12b7-7c15-46a5-256d59cba379
334 20260411163351 ADAS_S751NX0Y601739V_20260413155723466116_c5c8b22ad3dc CCRM 100.0 20.0 FCW60 019d9a7d-16fa-7aaf-44ff-9516a0d5684e
335 20260411162856 ADAS_S751NX0Y601739V_20260413155723466116_45a1708bd6e7 CCRM 100.0 20.0 FCW60 019d9a7d-1ba0-7648-61c9-bcc36579b627
336 20260413184006 ADAS_S5STNF0T504465N_20260414163318204977_94d493ef794c CPTA-LN 50.0 5.0 20 019d9a5d-b50f-75d1-79cd-6450dfebdd5d
337 20260413182950 ADAS_S5STNF0T504465N_20260414163318204977_65588ce02434 CPTA-LF 50.0 6.5 20 019d9a5d-bc97-7015-4292-587775914bad
338 20260413182735 ADAS_S5STNF0T504465N_20260414163318204977_e9c68de37ce5 CPTA-LF 50.0 6.5 20 019d9a5d-c404-7ec9-463d-bc3ccd120447
339 20260413181209 ADAS_S5STNF0T504465N_20260414163318204977_731fe43b77a4 CPTA-LF 50.0 6.5 10 019d9a5d-ca7c-7e1c-5065-445b231ab139
340 20260413180557 ADAS_S5STNF0T504465N_20260414163318204977_ab161275fcdd CPTA-LF 50.0 6.5 10 019d9a5d-cf2a-700e-426b-4834795e46e4
341 20260413155722 ADAS_S5STNF0T504465N_20260414163318204977_de1770ab54a4 CPTA-LF 50.0 6.5 10 019d9a5d-d6a3-7582-7ec1-e15fbd30314f
342 20260413152044 ADAS_S5STNF0T504465N_20260414163318204977_2c16f786a458 CPTA-LN 50.0 5.0 20 019d9a5d-daa6-7d0b-6040-634b0adc26d5
343 20260413144918 ADAS_S5STNF0T504465N_20260414163318204977_311e2e4f3469 CPTA-LN 50.0 5.0 20 019d9a5d-e12b-77ed-795b-a177a975d2d8
344 20260413143117 ADAS_S5STNF0T504465N_20260414163318204977_912131df3c3f CPTA-LN 50.0 5.0 10 019d9a5d-e9f7-75fb-70c7-d966c6229458
345 20260413142635 ADAS_S5STNF0T504465N_20260414163318204977_c83b9a3226dd CPTA-LN 50.0 5.0 10 019d9a5d-f0bf-7b9f-40d2-7e37931ed680
346 20260413141932 ADAS_S5STNF0T504465N_20260414163318204977_0c640c814bc3 CPTA-LN 50.0 5.0 10 019d9a5d-f609-786e-7cac-da37ebc1ae67
347 20260414182041 ADAS_S5STNF0T406280R_20260415153614565776_6717025a2999 CPTA-RF 50.0 6.5 20 019d9a51-ae0f-7c50-6dfb-9ebe3bd45849
348 20260414181827 ADAS_S5STNF0T406280R_20260415153614565776_a6af70bdfa52 CPTA-RF 50.0 6.5 20 019d9a51-b50b-7acf-6c49-f52dc69a2850
349 20260414181027 ADAS_S5STNF0T406280R_20260415153614565776_ac6a27726e5c CPTA-RF 50.0 6.5 20 019d9a51-b8cf-7339-595c-1dde3419ee32
350 20260414175932 ADAS_S5STNF0T406280R_20260415153614565776_641a01713a60 CPTA-RF 50.0 6.5 10 019d9a51-cc24-7989-4be4-e3ad8d2aa724
351 20260414175703 ADAS_S5STNF0T406280R_20260415153614565776_2ddbe4a780d2 CPTA-RF 50.0 6.5 10 019d9a51-d078-7764-4942-78794b5f6907
352 20260414175324 ADAS_S5STNF0T406280R_20260415153614565776_423750bdef2c CPTA-RF 50.0 6.5 10 019d9a51-d672-7605-4f29-b37caa9eae1c
353 20260414173141 ADAS_S5STNF0T406280R_20260415153614565776_6304fc524d71 CSTA-LN 50.0 20.0 10 019d9a51-de91-792b-5301-78dc8837a22a
354 20260414172819 ADAS_S5STNF0T406280R_20260415153614565776_7b6bcdb90977 CSTA-LN 50.0 20.0 10 019d9a51-e518-7bef-6d16-c7ba8b8a2aab
355 20260414171833 ADAS_S5STNF0T406280R_20260415153614565776_0ae4e25121ec CSTA-LN 50.0 20.0 20 019d9a51-e91f-7b43-7e4d-c687d932dba0
356 20260414170603 ADAS_S5STNF0T406280R_20260415153614565776_c66607e24083 CSTA-LN 50.0 20.0 20 019d9a51-ef9e-7b48-4a73-df674f472c55
357 20260414170224 ADAS_S5STNF0T406280R_20260415153614565776_db50a7ab7485 CSTA-LN 50.0 20.0 20 019d9a51-f683-7a5e-5364-1896e1ca6598
358 20260414165228 ADAS_S5STNF0T406280R_20260415153614565776_94db38de8391 CSTA-LN 50.0 20.0 30 019d9a51-ff2c-7cc2-58c8-05cae8d4ec9e
359 20260414164728 ADAS_S5STNF0T406280R_20260415153614565776_c0b75572b138 CSTA-LN 50.0 20.0 30 019d9a52-04fd-75e5-57f7-54b7dc96246c
360 20260414151451 ADAS_S5STNF0T406280R_20260415153614565776_672a18ed480a CSTA-LN 50.0 20.0 30 019d9a52-0afa-71e8-6e1c-e534a2850eff
361 20260414141804 ADAS_S5STNF0T406280R_20260415153614565776_593e8310f18f CSTA-LN 50.0 20.0 10 019d9a52-2237-7843-4407-6cac5ae39635
362 20260414103823 ADAS_S5STNF0T406280R_20260415153614565776_e3a569188ace CPTA-LF 50.0 6.5 30 019d9a52-5247-719d-6774-a834bc949e33
363 20260414103041 ADAS_S5STNF0T406280R_20260415153614565776_d357ca15a359 CPTA-LF 50.0 6.5 30 019d9a52-5694-7c91-7a0e-072b54ee0879
364 20260414101728 ADAS_S5STNF0T406280R_20260415153614565776_8b3b17c2bee2 CPTA-LN 50.0 5.0 30 019d9a52-5a9a-738a-531b-2e60fa91338a
365 20260414100312 ADAS_S5STNF0T406280R_20260415153614565776_1cd9b9feba23 CPTA-LN 50.0 5.0 30 019d9a52-5e3c-77fc-7644-8b46ab7c192f
366 20260415182950 ADAS_S751NX0Y601865J_20260417101159978228_f3c4f45b6d78 SCPO 40.0 FCW50 019d9ad0-974c-72b2-6576-d90453782b51
367 20260415181728 ADAS_S751NX0Y601865J_20260417101159978228_2dcca16a3b4a SCPO 50.0 FCW60 019d9ad0-9f8a-791b-47b1-572744314e8d
368 20260415181449 ADAS_S751NX0Y601865J_20260417101159978228_349202d868d0 SCPO 50.0 FCW60 019d9ad0-a733-7e52-4dc3-5974dde5ad99
369 20260415181218 ADAS_S751NX0Y601865J_20260417101159978228_8f80b1fd043d SCPO 50.0 FCW60 019d9ad0-c235-74dc-4c71-dbd7bf6a42fb
370 20260415175852 ADAS_S751NX0Y601865J_20260417101159978228_9ec3b55f6845 SCPO 40.0 FCW50 019d9ad0-c6b4-75f7-49ac-215a534b203e
371 20260415175352 ADAS_S751NX0Y601865J_20260417101159978228_66569e4b4cb2 SCPO 40.0 FCW50 019d9ad0-cd9a-7dbf-49b5-3f9fb8a2b943
372 20260415170215 ADAS_S751NX0Y601865J_20260417101159978228_a058dd06c98c SCP 40.0 FCW50 019d9ad0-d40c-7f86-4f01-c92465e0cde5
373 20260415161100 ADAS_S751NX0Y601865J_20260417101159978228_56ea31bafe02 SCP 50.0 FCW60 019d9ad0-da51-773d-557f-4684de8f8593
374 20260415160711 ADAS_S751NX0Y601865J_20260417101159978228_46aa39158604 SCP 50.0 FCW60 019d9ad0-df57-78ff-4590-ebcaaec53aab
375 20260415160405 ADAS_S751NX0Y601865J_20260417101159978228_bee8068c98fc SCP 50.0 FCW60 019d9ad0-e30f-79ed-7a0d-884a4f6c1cd0
376 20260415154024 ADAS_S751NX0Y601865J_20260417101159978228_2f1ade039337 SCP 40.0 FCW50 019d9ad0-e757-741a-5156-6385fc72f938
377 20260415153332 ADAS_S751NX0Y601865J_20260417101159978228_3af6ab7e3d9d SCP 40.0 FCW50 019d9ad0-ff56-74ec-7f7a-ca0ea75f8957
378 20260415152337 ADAS_S751NX0Y601865J_20260417101159978228_04a9c20fdd89 SCP 30.0 40 019d9ad1-02de-7ebf-7adf-a12148a9ee51
379 20260415152009 ADAS_S751NX0Y601865J_20260417101159978228_6d4572f106f9 SCP 30.0 40 019d9ad1-06e0-7a20-4613-411bd3ac6621
380 20260415151432 ADAS_S751NX0Y601865J_20260417101159978228_747d58ffa48f SCP 20.0 30 019d9ad1-0a91-71ea-5da9-c9d7d7dc91b8
381 20260415150905 ADAS_S751NX0Y601865J_20260417101159978228_3e31d0688fc8 SCP 20.0 30 019d9ad1-11d0-7099-76b0-aaf48cfd3794
382 20260415104410 ADAS_S751NX0Y601865J_20260417101159978228_ba06434aae58 SCP 30.0 40 019d9ad1-1ba5-730a-4504-896c892f8486
383 20260415102130 ADAS_S751NX0Y601865J_20260417101159978228_01906cac8a3a SCP 20.0 30 019d9ad1-300a-7509-7f94-984b56ab2f8b
384 20260416151630 ADAS_S751NX0Y601739V_20260418160638633646_496ebb0a2ff1 CBLA-CN24 25 15.0 FCW80 019db3f6-1d15-718a-724d-bed4c91ba628
385 20260416151431 ADAS_S751NX0Y601739V_20260418160638633646_22612682b9c9 CBLA-CN24 25 15.0 FCW80 019db3f6-2443-7632-47c8-410071836c58
386 20260416151047 ADAS_S751NX0Y601739V_20260418160638633646_8a773af16606 CBLA-CN24 25 15.0 FCW80 019db3f6-2b30-79d4-708d-4b239be1acf2
387 20260416150314 ADAS_S751NX0Y601739V_20260418160638633646_ae0b94f3324a CBLA-CN24 25 15.0 FCW60 019db3f6-4031-7053-6ba9-b9ff190b8f0c
388 20260416145925 ADAS_S751NX0Y601739V_20260418160638633646_05bb8a06451c CBLA-CN24 25 15.0 FCW60 019db3f6-47d7-75e8-6251-fd30d96e2abc
389 20260416145727 ADAS_S751NX0Y601739V_20260418160638633646_3a1fb37781a4 CBLA-CN24 25 15.0 FCW60 019db3f6-5171-7b48-5c29-f20016206acf
390 20260416143538 ADAS_S751NX0Y601739V_20260418160638633646_74c05ab76327 CBLA-CN21 25 15.0 FCW80 019db3f6-58e5-767b-72c7-ea46de3a19fe
391 20260416143214 ADAS_S751NX0Y601739V_20260418160638633646_b5a9cd0663a3 CBLA-CN21 25 15.0 FCW80 019db3f6-646a-7e0b-54b1-c6f31a4bc344
392 20260416142947 ADAS_S751NX0Y601739V_20260418160638633646_b4ba81b4492d CBLA-CN21 25 15.0 FCW80 019db3f6-6db0-70b6-5602-b61e51fb6b00
393 20260416142739 ADAS_S751NX0Y601739V_20260418160638633646_d007dbd1fef6 CBLA-CN21 25 15.0 FCW70 019db3f6-768c-7955-4db7-82fcdc8ecf11
394 20260416142527 ADAS_S751NX0Y601739V_20260418160638633646_cea22e9fc4b2 CBLA-CN21 25 15.0 FCW70 019db3f6-7ceb-7b0d-513e-ddfafe62acc2
395 20260416142206 ADAS_S751NX0Y601739V_20260418160638633646_cea65402d2f0 CBLA-CN21 25 15.0 FCW70 019db3f6-868f-7ceb-6169-86d01d3e09ae
396 20260416141321 ADAS_S751NX0Y601739V_20260418160638633646_9b2070e30a94 CBLA-CN21 25 15.0 FCW60 019db3f6-9c95-7da4-5f42-a598dee5935c
397 20260416141056 ADAS_S751NX0Y601739V_20260418160638633646_05e29a63c4c5 CBLA-CN21 25 15.0 FCW60 019db3f6-a785-77de-6fd3-f841e40d90d9
398 20260416140906 ADAS_S751NX0Y601739V_20260418160638633646_443fc0fdce22 CBLA-CN21 25 15.0 FCW60 019db3f6-b875-77ad-533c-dc77dc3745a2
399 20260416140653 ADAS_S751NX0Y601739V_20260418160638633646_915c24c91174 CBLA-CN21 25 15.0 FCW50 019db3f6-c0e8-714a-7ead-cf6fa750249c
400 20260416140423 ADAS_S751NX0Y601739V_20260418160638633646_3727f5ceb78c CBLA-CN21 25 15.0 FCW50 019db3f6-c84c-7b3a-4cf3-65ebf97ca2db
401 20260416140135 ADAS_S751NX0Y601739V_20260418160638633646_aad58490855a CBLA-CN21 25 15.0 FCW50 019db3f6-ce3f-707c-718b-b7c1cd4c072b

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
datetime,rawid,scene,offset,gvt_speed,vut_speed,event_uuid
20260421165302,ADAS_S5STNF0T406280R_20260424143102910957_204c5679f12e,CCRH,1,0,FCW120,019dbea9-1a38-7b40-7f39-314eb07bb76d
20260421165124,ADAS_S5STNF0T406280R_20260424143102910957_9ee9ec2148e8,CCRH,1,0,FCW120,019dbea9-3cdf-7953-719f-bdd635eaffa4
20260421164943,ADAS_S5STNF0T406280R_20260424143102910957_860409653c26,CCRH,1,0,FCW120,019dbea9-53fc-75a6-6178-0696b63de01b
20260421163804,ADAS_S5STNF0T406280R_20260424143102910957_0939f3645d9c,CCRH,1,0,FCW80,019dbea9-6851-7511-44ce-36554aac6a91
20260421163319,ADAS_S5STNF0T406280R_20260424143102910957_7a307c148cd7,CCRH,1,0,FCW80,019dbea9-7ef5-73fd-5eb4-5761dd42efa8
20260421163154,ADAS_S5STNF0T406280R_20260424143102910957_8af71c24686e,CCRH,1,0,FCW80,019dbea9-9726-776f-7b82-5e47ac6e3e1a
20260422170800,ADAS_S5STNF0T406280R_20260424143102910957_3528d22515d5,CCRS,100,0,60,019dbeaf-da0e-7a1f-6a2a-969f12e4f13a
20260422170403,ADAS_S5STNF0T406280R_20260424143102910957_4f20967658ae,CCRS,100,0,60,019dbeaf-dee9-741e-7ca9-1ba865c1f42e
20260422170238,ADAS_S5STNF0T406280R_20260424143102910957_ce36b7f1153a,CCRS,100,0,60,019dbea9-b946-7511-43c3-dfbbbf251e52
20260422170012,ADAS_S5STNF0T406280R_20260424143102910957_6a5f70646a16,CCRS,100,0,50,019dbea9-cf85-7fad-5974-6901a134cd38
20260422165842,ADAS_S5STNF0T406280R_20260424143102910957_e674d9eb9568,CCRS,100,0,50,019dbea9-e0b6-7c9b-7aae-71cf080d1d3f
20260422165644,ADAS_S5STNF0T406280R_20260424143102910957_80c60d6f3899,CCRS,100,0,50,019dbea9-f321-7d7d-7907-7306457108bf
20260422164009,ADAS_S5STNF0T406280R_20260424143102910957_aa662fd0c24f,CCRS,100,0,40,019dbeaf-e3a0-756b-569d-fa627af56012
20260422163835,ADAS_S5STNF0T406280R_20260424143102910957_d284665c509f,CCRS,100,0,40,019dbeaf-e894-7f6a-7124-e8d7fbb05a27
20260422163615,ADAS_S5STNF0T406280R_20260424143102910957_b29f69764a66,CCRS,100,0,40,019dbeaa-1d36-77ee-4f61-80890f46d39c
20260422161227,ADAS_S5STNF0T406280R_20260424143102910957_62a21a126fce,CCFT,50,20,10,019dbeaa-32bf-7cb9-6e82-d07fcb21f35a
20260422160038,ADAS_S5STNF0T406280R_20260424143102910957_756cc10c0a71,CCFT,50,50,30,019dbeaa-413d-75ab-4282-686838393490
20260422144136,ADAS_S5STNF0T406280R_20260424143102910957_25e2161254d7,CCFT,50,50,30,019dbeaa-4c1f-7c61-7690-6cfd14ef779c
20260422143535,ADAS_S5STNF0T406280R_20260424143102910957_938ec4fd825a,CCFT,50,40,20,019dbeaa-58a1-7223-5799-940f1fab38ba
20260422143045,ADAS_S5STNF0T406280R_20260424143102910957_8ccfd8c3fadd,CCFT,50,40,20,019dbeaa-707b-7bc3-778f-bed824c3f151
20260422141143,ADAS_S5STNF0T406280R_20260424143102910957_6e6acb788fea,CCFT,50,20,10,019dbeaa-80d4-7a80-6d84-b805e7b8c0e6
20260422114602,ADAS_S5STNF0T406280R_20260424143102910957_b52d53dd07cb,CCFT,50,20,10,019dbeaa-966c-7486-4d54-8856c274ce50
20260423165539,ADAS_S751NX0Y601865J_20260425160638282353_5bdad74f0035,CBLA-CN21,25,15,FCW70,019dccc4-42ba-78f2-437c-cead7d452568
20260423165159,ADAS_S751NX0Y601865J_20260425160638282353_a75bd09b1591,CBLA-CN21,25,15,FCW70,019dccc4-4f20-74d5-5edf-eb7d119270f6
20260423164643,ADAS_S751NX0Y601865J_20260425160638282353_f02011f6fb51,CBLA-CN21,25,15,FCW50,019dccc4-5631-7267-6580-8f55c03f3269
20260423164406,ADAS_S751NX0Y601865J_20260425160638282353_33f47ad79ea4,CBLA-CN21,25,15,FCW50,019dccc4-5b35-7459-4097-554fc6c58621
20260423164220,ADAS_S751NX0Y601865J_20260425160638282353_3422d076b4b4,CBLA-cn21,50,15,60,019dccc9-2623-7a08-5135-e78a8ece105c
20260423163827,ADAS_S751NX0Y601865J_20260425160638282353_8552d0859d87,CBLA-cn21,50,15,60,019dccc9-2d6d-799b-6d2d-6bb572d2a18a
20260423163640,ADAS_S751NX0Y601865J_20260425160638282353_2516f29f235f,CBLA-cn21,50,15,50,019dccc9-33f1-7629-4370-462c8a5453ab
20260423162521,ADAS_S751NX0Y601865J_20260425160638282353_44e04f0525e9,CBLA-cn21,50,15,50,019dccc9-3a1c-7c5c-67aa-40d06b7b2555
20260423161011,ADAS_S751NX0Y601865J_20260425160638282353_3c486812721a,CBLA-cn24,25,15,40,019dccc9-4260-7ada-54fb-d395c275092b
20260423160753,ADAS_S751NX0Y601865J_20260425160638282353_eb521054a5e7,CBLA-cn24,25,15,40,019dccc9-46d3-7e58-5c42-8ee8778fb98b
20260423160611,ADAS_S751NX0Y601865J_20260425160638282353_805ec2d6dfb9,CBLA-cn24,25,15,40,019dccc9-4aeb-7fdf-5a01-1c4da8d9c268
20260423160427,ADAS_S751NX0Y601865J_20260425160638282353_45d1afad713c,CBLA-cn24,25,15,20,019dccc9-4f0c-7a16-6f4a-8d9801f93347
20260423160241,ADAS_S751NX0Y601865J_20260425160638282353_6281b7a1ec03,CBLA-cn24,25,15,20,019dccc9-5ab3-7a88-4fb6-fafd066195ae
20260423160005,ADAS_S751NX0Y601865J_20260425160638282353_3499529a30c5,CBLA-cn24,25,15,20,019dccc9-6081-76fa-6fe3-3bc9870efadd
20260423152501,ADAS_S751NX0Y601865J_20260425160638282353_7fe834d1e141,CCRM,-50,20,FCW80,019dccc9-64bd-760d-5587-e2d5c0557773
20260423152049,ADAS_S751NX0Y601865J_20260425160638282353_5583953c59cd,CCRM,-50,20,FCW80,019dccc9-6b06-7bac-7867-82ff6caf6f8b
20260423151903,ADAS_S751NX0Y601865J_20260425160638282353_45bdf88fa7e2,CCRM,-50,20,FCW80,019dccc9-6f22-7790-538b-7eb0bba8e8a7
20260423151053,ADAS_S751NX0Y601865J_20260425160638282353_6921d44c9df1,CCRS,-50,0,FCW80,019dccc9-74e3-781f-5d3f-70bdb67ec4b6
20260423145748,ADAS_S751NX0Y601865J_20260425160638282353_2a6786176fb4,CCRS,-50,0,FCW80,019dccc9-78c5-7a99-44c5-20d499c1ad1b
20260424165609,ADAS_S751NX0Y601739V_20260426105646474483_8e3ef1dd2b95,CPLA,50,5,50,019dccc9-a412-7274-4b69-3dfcf9b1c751
20260424165355,ADAS_S751NX0Y601739V_20260426105646474483_d71e1fcdd716,CPLA,50,5,50,019dccc9-a7c9-7911-6c96-1b3a8e53e08a
20260424164838,ADAS_S751NX0Y601739V_20260426105646474483_8674df9f7e6c,CPLA,25,5,FCW50,019dccc9-abad-7dc9-5311-d4b4cfc6c996
20260424163138,ADAS_S751NX0Y601739V_20260426105646474483_d56ab481858d,CPLA,25,5,FCW50,019dccc9-b70a-7a64-79d4-7d74b3c29504
20260424161735,ADAS_S751NX0Y601739V_20260426105646474483_f40e70b67ad5,CPLA-cn24,25,5,FCW80,019dccda-0a48-775a-4b49-31e4f52ac800
20260424160918,ADAS_S751NX0Y601739V_20260426105646474483_c3ab74ad2582,CPLA-cn24,25,5,FCW80,019dccda-0fb5-7040-60fb-5b6eb0340c90
20260424160557,ADAS_S751NX0Y601739V_20260426105646474483_280ec474f1e7,CPLA-cn24,25,5,FCW80,019dccda-1b52-7d2c-4e20-ba87c5fb8906
20260424160317,ADAS_S751NX0Y601739V_20260426105646474483_3c471e2b551e,CPLA-cn24,25,5,FCW60,019dccda-22b4-7590-5a90-9d93d91a62a2
20260424155607,ADAS_S751NX0Y601739V_20260426105646474483_b13af5e369e4,CPLA-cn24,25,5,FCW60,019dccda-2b1b-7ce0-5f11-067ff68c180c
20260424155333,ADAS_S751NX0Y601739V_20260426105646474483_37703d761455,CPLA-cn24,25,5,FCW60,019dccda-2fa3-7c8a-5efc-9c1a06ab60df
20260424151547,ADAS_S751NX0Y601739V_20260426105646474483_9c30cae5f806,CPLA-cn24,25,5,40,019dccda-3b7a-7225-6d4a-3549aec142a2
20260424151208,ADAS_S751NX0Y601739V_20260426105646474483_03d95f1a0bea,CPLA-cn24,25,5,40,019dccda-4335-7c87-6432-c8a061772dcf
20260424150237,ADAS_S751NX0Y601739V_20260426105646474483_68b9be51b240,CPLA-cn24,25,5,40,019dccda-4853-7b14-79a3-686c976fec99
20260424145815,ADAS_S751NX0Y601739V_20260426105646474483_ab99d7f496b7,CPLA-cn24,25,5,20,019dccda-4be8-7f2e-474c-83483bb86d61
20260424145646,ADAS_S751NX0Y601739V_20260426105646474483_9d9f4f81d58b,CPLA-cn24,25,5,20,019dccda-4ff1-7e09-79bc-0248f385c3a3
20260424145409,ADAS_S751NX0Y601739V_20260426105646474483_6ed854132275,CPLA-cn24,25,5,20,019dccda-56e1-74eb-59b8-bbdef5b2eebd
20260424103224,ADAS_S751NX0Y601739V_20260426105646474483_dea4e64065d5,SCP,,20,30,019dccc9-bc95-7c6f-7252-394628471d0b
20260425170806,ADAS_S5STNF0T504465N_20260427141205368130_fa832c22f1d0,CPTA-LN,50,5,20,019dd420-c6c2-730a-6c14-f4513669fe8d
20260425170149,ADAS_S5STNF0T504465N_20260427141205368130_a199460fdb86,CPTA-LN,50,5,20,019dd420-cbaa-7367-5680-dd3cbbebfabc
20260425150005,ADAS_S5STNF0T504465N_20260427141205368130_66e67c5c39be,SCP,,20,30,019dd420-d37c-7f00-7fa5-b50f8ed72220
20260425145813,ADAS_S5STNF0T504465N_20260427141205368130_67fee0b894e5,SCP,,20,30,019dd420-dbca-73d4-632b-e5f65ee08add
20260425144953,ADAS_S5STNF0T504465N_20260427141205368130_30d3364724be,SCP,,50,FCW60,019dd420-e730-7c1b-6a2a-1f28c5abdb31
20260425144737,ADAS_S5STNF0T504465N_20260427141205368130_50a3ef4039ec,SCP,,50,FCW60,019dd420-ebf5-7295-7605-ee83309a5f9a
20260425114942,ADAS_S5STNF0T504465N_20260427141205368130_3f7cd5c01537,SCP,,40,FCW50,019dd420-f18a-7452-7541-0c5b8d67bfd8
20260425111856,ADAS_S5STNF0T504465N_20260427141205368130_992eed63acec,SCP,,40,FCW50,019dd420-f854-7547-7783-f5ea609d92ca
20260425111443,ADAS_S5STNF0T504465N_20260427141205368130_de3c37dc6e75,SCP,,30,40,019dd420-fd1f-7b3c-6e3f-8f7bcea6321a
20260425111027,ADAS_S5STNF0T504465N_20260427141205368130_2cc5c5469141,SCP,,30,40,019dd421-0260-749a-7b6a-5fdac9e9be44
20260425105940,ADAS_S5STNF0T504465N_20260427141205368130_680a33a5f78d,SCP,,30,40,019dd421-0cb0-7578-62fc-7c2e0d42510b
20260426161459,ADAS_S751NX0Y800506T_20260428123042509470_29327584d51d,CBLA-CN21,25,15,FCW70,019dd421-4b69-71ac-6a32-ec788393fe4f
20260426160008,ADAS_S751NX0Y800506T_20260428123042509470_d69768e25615,CBLA-CN21,25,15,FCW50,019dd421-645f-739b-4fcb-863735ace841
20260426154615,ADAS_S751NX0Y800506T_20260428123042509470_f2c5d47738ad,CBLA-cn21,50,15,60,019dd421-8101-7018-57ce-9bcae8c008fc
20260426153534,ADAS_S751NX0Y800506T_20260428123042509470_0b8deed3ca4d,CBLA-cn21,50,15,50,019dd421-94b9-7cd3-4834-5592601312c0
20260426141443,ADAS_S751NX0Y800506T_20260428123042509470_4f816e7e320a,CCFT,50,50,30,019dd421-bf6a-74e2-68ca-a2909e8b8a35
20260426114522,ADAS_S751NX0Y800506T_20260428123042509470_3d725df8d10d,CCFT,50,40,20,019dd421-e1cb-7419-51dc-df1018d64664
20260426104816,ADAS_S751NX0Y800506T_20260428123042509470_a7a13aaeb441,CCRS,-50,0,FCW80,019dd422-12d1-70f3-6418-629a09bf7d03
20260429180444,ADAS_S751NX0Y601739V_20260503105236841267_2c1473b10dc6,CPLA,25,5,FCW50,019df6ed-cd2f-7d2a-688c-713c0cd6307b
20260429165306,ADAS_S751NX0Y601739V_20260503105236841267_f18094de4d8a,CPLA,50,5,50,019df6ed-e11b-7e3b-5f6b-0f23c224f66a
20260429161841,ADAS_S751NX0Y601739V_20260503105236841267_8e07fc3208b9,CPTA-LF,50,6.5,10,019df6ee-0264-79f2-57fd-83608f1eaac6
20260429161528,ADAS_S751NX0Y601739V_20260503105236841267_7123bd12f35b,CPTA-LF,50,6.5,10,019df6ee-0867-7e44-5000-7873beef8dbf
20260429161021,ADAS_S751NX0Y601739V_20260503105236841267_f06682f85f33,CPTA-LF,50,6.5,10,019df6ee-0f73-7c90-6196-7fc08cad2f73
20260429155038,ADAS_S751NX0Y601739V_20260503105236841267_4ef26aabdfae,CPTA-RF,50,6.5,20,019df6ee-14d6-7a13-44dc-63f353943186
20260429154600,ADAS_S751NX0Y601739V_20260503105236841267_0d79d3d7a9d6,CPTA-RF,50,6.5,20,019df6ee-1d07-776e-72ed-af1ba59c76cd
20260429153237,ADAS_S751NX0Y601739V_20260503105236841267_9d1716a5f582,CPTA-RF,50,6.5,20,019df6ee-24e0-776f-7ddd-0c65b8c01d24
20260429144733,ADAS_S751NX0Y601739V_20260503105236841267_6f3c74447dec,CPTA-RF,50,6.5,10,019df6ee-35ea-7bb1-6be8-2497aa23f1ad
20260429114321,ADAS_S751NX0Y601739V_20260503105236841267_6ffeb9a156eb,CPTA-RF,50,6.5,10,019df6ee-4aa8-7aa6-5523-8d0fa6384228
20260429113635,ADAS_S751NX0Y601739V_20260503105236841267_5b68e94bafac,CPTA-RF,50,6.5,10,019df6ee-540f-7bcc-5f7d-7ef249177de0
20260429111506,ADAS_S751NX0Y601739V_20260503105236841267_0457ce74ada2,CPTA-LF,50,6.5,30,019df6ee-5ba6-7db0-7a20-561fe03286eb
20260429110130,ADAS_S751NX0Y601739V_20260503105236841267_f41dbf7a1fe0,CPTA-LF,50,6.5,30,019df6ee-60a1-77ad-4835-dc7259d65576
20260429105306,ADAS_S751NX0Y601739V_20260503105236841267_ffd6b1c17fb7,CPTA-LF,50,6.5,20,019df6ee-6875-7fd8-75de-9bf342def9c8
20260429105051,ADAS_S751NX0Y601739V_20260503105236841267_5f6244be6752,CPTA-LF,50,6.5,20,019df6ee-6e42-74f3-5be5-ca793f9ee226
20260429104840,ADAS_S751NX0Y601739V_20260503105236841267_040dab1b6462,CPTA-LF,50,6.5,20,019df6ee-7437-7302-4e6b-706646d57c53
20260430005758,ADAS_S751NX0Y601739V_20260503105236841267_d43542536f95,CPLA-夜晚CN24,25,5,FCW80,019df6ee-a134-7901-60db-81d81b60998d
20260430005628,ADAS_S751NX0Y601739V_20260503105236841267_068362143e80,CPLA-夜晚CN24,25,5,FCW80,019df6ee-a686-7c25-563d-67b25298af0b
20260430005353,ADAS_S751NX0Y601739V_20260503105236841267_4e13f3cedc71,CPLA-夜晚CN24,25,5,FCW80,019df6ee-ab74-7a6c-4f75-97bcb5245fda
20260430005034,ADAS_S751NX0Y601739V_20260503105236841267_99a915ec4784,CPLA-夜晚CN24,25,5,FCW60,019df6ee-b2f0-7a73-74c6-80c472bcc5df
20260430004703,ADAS_S751NX0Y601739V_20260503105236841267_0061760569c9,CPLA-夜晚CN24,25,5,FCW60,019df6ee-b7ee-78e6-7ae0-3ae241457e06
20260430004432,ADAS_S751NX0Y601739V_20260503105236841267_07bca13ed759,CPLA-夜晚CN24,25,5,FCW60,019df6ee-be7e-7a34-61e5-b77877c546eb
20260430004247,ADAS_S751NX0Y601739V_20260503105236841267_1f3320ce38ac,CPLA-夜晚CN24,25,5,40,019df6ee-c4de-7e59-4f5c-16b4261d77f4
20260430003934,ADAS_S751NX0Y601739V_20260503105236841267_82443933fdee,CPLA-夜晚CN24,25,5,40,019df6ee-d00c-7e28-45c3-b1d1890ec640
20260430003725,ADAS_S751NX0Y601739V_20260503105236841267_bd901e7e8041,CPLA-夜晚CN24,25,5,20,019df6ee-d6e5-7e20-642d-7921e54619e2
20260430003547,ADAS_S751NX0Y601739V_20260503105236841267_070e814ef27e,CPLA-夜晚CN24,25,5,20,019df6ee-db3c-764a-46e5-5a2a8495b08a
20260430003302,ADAS_S751NX0Y601739V_20260503105236841267_dc73a4d2ec69,CPLA-夜晚CN24,25,5,20,019df6ee-e1ba-7c15-7559-2f32ecf76326
20260430002426,ADAS_S751NX0Y601739V_20260503105236841267_1506a8d8eda5,CPLA-夜晚,25,5,FCW80,019df6ee-e7fc-785e-65c0-39403838db31
20260430002127,ADAS_S751NX0Y601739V_20260503105236841267_04b9a81743fc,CPLA-夜晚,25,5,FCW80,019df6ee-efae-7fed-7023-82bf07447393
20260430001509,ADAS_S751NX0Y601739V_20260503105236841267_6df59d151cb4,CPLA-夜晚,25,5,FCW70,019df6ee-f551-7a5b-78c6-4f03848a2b68
20260430001258,ADAS_S751NX0Y601739V_20260503105236841267_8b8b37938873,CPLA-夜晚,25,5,FCW70,019df6ee-f985-7317-4f86-c5fdd56f8f48
20260430000414,ADAS_S751NX0Y601739V_20260503105236841267_b8fed19cc042,CPLA-夜晚,25,5,FCW60,019df6ee-fef4-7d3c-4a4c-c52f722c8e00
1 datetime rawid scene offset gvt_speed vut_speed event_uuid
2 20260421165302 ADAS_S5STNF0T406280R_20260424143102910957_204c5679f12e CCRH 1 0 FCW120 019dbea9-1a38-7b40-7f39-314eb07bb76d
3 20260421165124 ADAS_S5STNF0T406280R_20260424143102910957_9ee9ec2148e8 CCRH 1 0 FCW120 019dbea9-3cdf-7953-719f-bdd635eaffa4
4 20260421164943 ADAS_S5STNF0T406280R_20260424143102910957_860409653c26 CCRH 1 0 FCW120 019dbea9-53fc-75a6-6178-0696b63de01b
5 20260421163804 ADAS_S5STNF0T406280R_20260424143102910957_0939f3645d9c CCRH 1 0 FCW80 019dbea9-6851-7511-44ce-36554aac6a91
6 20260421163319 ADAS_S5STNF0T406280R_20260424143102910957_7a307c148cd7 CCRH 1 0 FCW80 019dbea9-7ef5-73fd-5eb4-5761dd42efa8
7 20260421163154 ADAS_S5STNF0T406280R_20260424143102910957_8af71c24686e CCRH 1 0 FCW80 019dbea9-9726-776f-7b82-5e47ac6e3e1a
8 20260422170800 ADAS_S5STNF0T406280R_20260424143102910957_3528d22515d5 CCRS 100 0 60 019dbeaf-da0e-7a1f-6a2a-969f12e4f13a
9 20260422170403 ADAS_S5STNF0T406280R_20260424143102910957_4f20967658ae CCRS 100 0 60 019dbeaf-dee9-741e-7ca9-1ba865c1f42e
10 20260422170238 ADAS_S5STNF0T406280R_20260424143102910957_ce36b7f1153a CCRS 100 0 60 019dbea9-b946-7511-43c3-dfbbbf251e52
11 20260422170012 ADAS_S5STNF0T406280R_20260424143102910957_6a5f70646a16 CCRS 100 0 50 019dbea9-cf85-7fad-5974-6901a134cd38
12 20260422165842 ADAS_S5STNF0T406280R_20260424143102910957_e674d9eb9568 CCRS 100 0 50 019dbea9-e0b6-7c9b-7aae-71cf080d1d3f
13 20260422165644 ADAS_S5STNF0T406280R_20260424143102910957_80c60d6f3899 CCRS 100 0 50 019dbea9-f321-7d7d-7907-7306457108bf
14 20260422164009 ADAS_S5STNF0T406280R_20260424143102910957_aa662fd0c24f CCRS 100 0 40 019dbeaf-e3a0-756b-569d-fa627af56012
15 20260422163835 ADAS_S5STNF0T406280R_20260424143102910957_d284665c509f CCRS 100 0 40 019dbeaf-e894-7f6a-7124-e8d7fbb05a27
16 20260422163615 ADAS_S5STNF0T406280R_20260424143102910957_b29f69764a66 CCRS 100 0 40 019dbeaa-1d36-77ee-4f61-80890f46d39c
17 20260422161227 ADAS_S5STNF0T406280R_20260424143102910957_62a21a126fce CCFT 50 20 10 019dbeaa-32bf-7cb9-6e82-d07fcb21f35a
18 20260422160038 ADAS_S5STNF0T406280R_20260424143102910957_756cc10c0a71 CCFT 50 50 30 019dbeaa-413d-75ab-4282-686838393490
19 20260422144136 ADAS_S5STNF0T406280R_20260424143102910957_25e2161254d7 CCFT 50 50 30 019dbeaa-4c1f-7c61-7690-6cfd14ef779c
20 20260422143535 ADAS_S5STNF0T406280R_20260424143102910957_938ec4fd825a CCFT 50 40 20 019dbeaa-58a1-7223-5799-940f1fab38ba
21 20260422143045 ADAS_S5STNF0T406280R_20260424143102910957_8ccfd8c3fadd CCFT 50 40 20 019dbeaa-707b-7bc3-778f-bed824c3f151
22 20260422141143 ADAS_S5STNF0T406280R_20260424143102910957_6e6acb788fea CCFT 50 20 10 019dbeaa-80d4-7a80-6d84-b805e7b8c0e6
23 20260422114602 ADAS_S5STNF0T406280R_20260424143102910957_b52d53dd07cb CCFT 50 20 10 019dbeaa-966c-7486-4d54-8856c274ce50
24 20260423165539 ADAS_S751NX0Y601865J_20260425160638282353_5bdad74f0035 CBLA-CN21 25 15 FCW70 019dccc4-42ba-78f2-437c-cead7d452568
25 20260423165159 ADAS_S751NX0Y601865J_20260425160638282353_a75bd09b1591 CBLA-CN21 25 15 FCW70 019dccc4-4f20-74d5-5edf-eb7d119270f6
26 20260423164643 ADAS_S751NX0Y601865J_20260425160638282353_f02011f6fb51 CBLA-CN21 25 15 FCW50 019dccc4-5631-7267-6580-8f55c03f3269
27 20260423164406 ADAS_S751NX0Y601865J_20260425160638282353_33f47ad79ea4 CBLA-CN21 25 15 FCW50 019dccc4-5b35-7459-4097-554fc6c58621
28 20260423164220 ADAS_S751NX0Y601865J_20260425160638282353_3422d076b4b4 CBLA-cn21 50 15 60 019dccc9-2623-7a08-5135-e78a8ece105c
29 20260423163827 ADAS_S751NX0Y601865J_20260425160638282353_8552d0859d87 CBLA-cn21 50 15 60 019dccc9-2d6d-799b-6d2d-6bb572d2a18a
30 20260423163640 ADAS_S751NX0Y601865J_20260425160638282353_2516f29f235f CBLA-cn21 50 15 50 019dccc9-33f1-7629-4370-462c8a5453ab
31 20260423162521 ADAS_S751NX0Y601865J_20260425160638282353_44e04f0525e9 CBLA-cn21 50 15 50 019dccc9-3a1c-7c5c-67aa-40d06b7b2555
32 20260423161011 ADAS_S751NX0Y601865J_20260425160638282353_3c486812721a CBLA-cn24 25 15 40 019dccc9-4260-7ada-54fb-d395c275092b
33 20260423160753 ADAS_S751NX0Y601865J_20260425160638282353_eb521054a5e7 CBLA-cn24 25 15 40 019dccc9-46d3-7e58-5c42-8ee8778fb98b
34 20260423160611 ADAS_S751NX0Y601865J_20260425160638282353_805ec2d6dfb9 CBLA-cn24 25 15 40 019dccc9-4aeb-7fdf-5a01-1c4da8d9c268
35 20260423160427 ADAS_S751NX0Y601865J_20260425160638282353_45d1afad713c CBLA-cn24 25 15 20 019dccc9-4f0c-7a16-6f4a-8d9801f93347
36 20260423160241 ADAS_S751NX0Y601865J_20260425160638282353_6281b7a1ec03 CBLA-cn24 25 15 20 019dccc9-5ab3-7a88-4fb6-fafd066195ae
37 20260423160005 ADAS_S751NX0Y601865J_20260425160638282353_3499529a30c5 CBLA-cn24 25 15 20 019dccc9-6081-76fa-6fe3-3bc9870efadd
38 20260423152501 ADAS_S751NX0Y601865J_20260425160638282353_7fe834d1e141 CCRM -50 20 FCW80 019dccc9-64bd-760d-5587-e2d5c0557773
39 20260423152049 ADAS_S751NX0Y601865J_20260425160638282353_5583953c59cd CCRM -50 20 FCW80 019dccc9-6b06-7bac-7867-82ff6caf6f8b
40 20260423151903 ADAS_S751NX0Y601865J_20260425160638282353_45bdf88fa7e2 CCRM -50 20 FCW80 019dccc9-6f22-7790-538b-7eb0bba8e8a7
41 20260423151053 ADAS_S751NX0Y601865J_20260425160638282353_6921d44c9df1 CCRS -50 0 FCW80 019dccc9-74e3-781f-5d3f-70bdb67ec4b6
42 20260423145748 ADAS_S751NX0Y601865J_20260425160638282353_2a6786176fb4 CCRS -50 0 FCW80 019dccc9-78c5-7a99-44c5-20d499c1ad1b
43 20260424165609 ADAS_S751NX0Y601739V_20260426105646474483_8e3ef1dd2b95 CPLA 50 5 50 019dccc9-a412-7274-4b69-3dfcf9b1c751
44 20260424165355 ADAS_S751NX0Y601739V_20260426105646474483_d71e1fcdd716 CPLA 50 5 50 019dccc9-a7c9-7911-6c96-1b3a8e53e08a
45 20260424164838 ADAS_S751NX0Y601739V_20260426105646474483_8674df9f7e6c CPLA 25 5 FCW50 019dccc9-abad-7dc9-5311-d4b4cfc6c996
46 20260424163138 ADAS_S751NX0Y601739V_20260426105646474483_d56ab481858d CPLA 25 5 FCW50 019dccc9-b70a-7a64-79d4-7d74b3c29504
47 20260424161735 ADAS_S751NX0Y601739V_20260426105646474483_f40e70b67ad5 CPLA-cn24 25 5 FCW80 019dccda-0a48-775a-4b49-31e4f52ac800
48 20260424160918 ADAS_S751NX0Y601739V_20260426105646474483_c3ab74ad2582 CPLA-cn24 25 5 FCW80 019dccda-0fb5-7040-60fb-5b6eb0340c90
49 20260424160557 ADAS_S751NX0Y601739V_20260426105646474483_280ec474f1e7 CPLA-cn24 25 5 FCW80 019dccda-1b52-7d2c-4e20-ba87c5fb8906
50 20260424160317 ADAS_S751NX0Y601739V_20260426105646474483_3c471e2b551e CPLA-cn24 25 5 FCW60 019dccda-22b4-7590-5a90-9d93d91a62a2
51 20260424155607 ADAS_S751NX0Y601739V_20260426105646474483_b13af5e369e4 CPLA-cn24 25 5 FCW60 019dccda-2b1b-7ce0-5f11-067ff68c180c
52 20260424155333 ADAS_S751NX0Y601739V_20260426105646474483_37703d761455 CPLA-cn24 25 5 FCW60 019dccda-2fa3-7c8a-5efc-9c1a06ab60df
53 20260424151547 ADAS_S751NX0Y601739V_20260426105646474483_9c30cae5f806 CPLA-cn24 25 5 40 019dccda-3b7a-7225-6d4a-3549aec142a2
54 20260424151208 ADAS_S751NX0Y601739V_20260426105646474483_03d95f1a0bea CPLA-cn24 25 5 40 019dccda-4335-7c87-6432-c8a061772dcf
55 20260424150237 ADAS_S751NX0Y601739V_20260426105646474483_68b9be51b240 CPLA-cn24 25 5 40 019dccda-4853-7b14-79a3-686c976fec99
56 20260424145815 ADAS_S751NX0Y601739V_20260426105646474483_ab99d7f496b7 CPLA-cn24 25 5 20 019dccda-4be8-7f2e-474c-83483bb86d61
57 20260424145646 ADAS_S751NX0Y601739V_20260426105646474483_9d9f4f81d58b CPLA-cn24 25 5 20 019dccda-4ff1-7e09-79bc-0248f385c3a3
58 20260424145409 ADAS_S751NX0Y601739V_20260426105646474483_6ed854132275 CPLA-cn24 25 5 20 019dccda-56e1-74eb-59b8-bbdef5b2eebd
59 20260424103224 ADAS_S751NX0Y601739V_20260426105646474483_dea4e64065d5 SCP 20 30 019dccc9-bc95-7c6f-7252-394628471d0b
60 20260425170806 ADAS_S5STNF0T504465N_20260427141205368130_fa832c22f1d0 CPTA-LN 50 5 20 019dd420-c6c2-730a-6c14-f4513669fe8d
61 20260425170149 ADAS_S5STNF0T504465N_20260427141205368130_a199460fdb86 CPTA-LN 50 5 20 019dd420-cbaa-7367-5680-dd3cbbebfabc
62 20260425150005 ADAS_S5STNF0T504465N_20260427141205368130_66e67c5c39be SCP 20 30 019dd420-d37c-7f00-7fa5-b50f8ed72220
63 20260425145813 ADAS_S5STNF0T504465N_20260427141205368130_67fee0b894e5 SCP 20 30 019dd420-dbca-73d4-632b-e5f65ee08add
64 20260425144953 ADAS_S5STNF0T504465N_20260427141205368130_30d3364724be SCP 50 FCW60 019dd420-e730-7c1b-6a2a-1f28c5abdb31
65 20260425144737 ADAS_S5STNF0T504465N_20260427141205368130_50a3ef4039ec SCP 50 FCW60 019dd420-ebf5-7295-7605-ee83309a5f9a
66 20260425114942 ADAS_S5STNF0T504465N_20260427141205368130_3f7cd5c01537 SCP 40 FCW50 019dd420-f18a-7452-7541-0c5b8d67bfd8
67 20260425111856 ADAS_S5STNF0T504465N_20260427141205368130_992eed63acec SCP 40 FCW50 019dd420-f854-7547-7783-f5ea609d92ca
68 20260425111443 ADAS_S5STNF0T504465N_20260427141205368130_de3c37dc6e75 SCP 30 40 019dd420-fd1f-7b3c-6e3f-8f7bcea6321a
69 20260425111027 ADAS_S5STNF0T504465N_20260427141205368130_2cc5c5469141 SCP 30 40 019dd421-0260-749a-7b6a-5fdac9e9be44
70 20260425105940 ADAS_S5STNF0T504465N_20260427141205368130_680a33a5f78d SCP 30 40 019dd421-0cb0-7578-62fc-7c2e0d42510b
71 20260426161459 ADAS_S751NX0Y800506T_20260428123042509470_29327584d51d CBLA-CN21 25 15 FCW70 019dd421-4b69-71ac-6a32-ec788393fe4f
72 20260426160008 ADAS_S751NX0Y800506T_20260428123042509470_d69768e25615 CBLA-CN21 25 15 FCW50 019dd421-645f-739b-4fcb-863735ace841
73 20260426154615 ADAS_S751NX0Y800506T_20260428123042509470_f2c5d47738ad CBLA-cn21 50 15 60 019dd421-8101-7018-57ce-9bcae8c008fc
74 20260426153534 ADAS_S751NX0Y800506T_20260428123042509470_0b8deed3ca4d CBLA-cn21 50 15 50 019dd421-94b9-7cd3-4834-5592601312c0
75 20260426141443 ADAS_S751NX0Y800506T_20260428123042509470_4f816e7e320a CCFT 50 50 30 019dd421-bf6a-74e2-68ca-a2909e8b8a35
76 20260426114522 ADAS_S751NX0Y800506T_20260428123042509470_3d725df8d10d CCFT 50 40 20 019dd421-e1cb-7419-51dc-df1018d64664
77 20260426104816 ADAS_S751NX0Y800506T_20260428123042509470_a7a13aaeb441 CCRS -50 0 FCW80 019dd422-12d1-70f3-6418-629a09bf7d03
78 20260429180444 ADAS_S751NX0Y601739V_20260503105236841267_2c1473b10dc6 CPLA 25 5 FCW50 019df6ed-cd2f-7d2a-688c-713c0cd6307b
79 20260429165306 ADAS_S751NX0Y601739V_20260503105236841267_f18094de4d8a CPLA 50 5 50 019df6ed-e11b-7e3b-5f6b-0f23c224f66a
80 20260429161841 ADAS_S751NX0Y601739V_20260503105236841267_8e07fc3208b9 CPTA-LF 50 6.5 10 019df6ee-0264-79f2-57fd-83608f1eaac6
81 20260429161528 ADAS_S751NX0Y601739V_20260503105236841267_7123bd12f35b CPTA-LF 50 6.5 10 019df6ee-0867-7e44-5000-7873beef8dbf
82 20260429161021 ADAS_S751NX0Y601739V_20260503105236841267_f06682f85f33 CPTA-LF 50 6.5 10 019df6ee-0f73-7c90-6196-7fc08cad2f73
83 20260429155038 ADAS_S751NX0Y601739V_20260503105236841267_4ef26aabdfae CPTA-RF 50 6.5 20 019df6ee-14d6-7a13-44dc-63f353943186
84 20260429154600 ADAS_S751NX0Y601739V_20260503105236841267_0d79d3d7a9d6 CPTA-RF 50 6.5 20 019df6ee-1d07-776e-72ed-af1ba59c76cd
85 20260429153237 ADAS_S751NX0Y601739V_20260503105236841267_9d1716a5f582 CPTA-RF 50 6.5 20 019df6ee-24e0-776f-7ddd-0c65b8c01d24
86 20260429144733 ADAS_S751NX0Y601739V_20260503105236841267_6f3c74447dec CPTA-RF 50 6.5 10 019df6ee-35ea-7bb1-6be8-2497aa23f1ad
87 20260429114321 ADAS_S751NX0Y601739V_20260503105236841267_6ffeb9a156eb CPTA-RF 50 6.5 10 019df6ee-4aa8-7aa6-5523-8d0fa6384228
88 20260429113635 ADAS_S751NX0Y601739V_20260503105236841267_5b68e94bafac CPTA-RF 50 6.5 10 019df6ee-540f-7bcc-5f7d-7ef249177de0
89 20260429111506 ADAS_S751NX0Y601739V_20260503105236841267_0457ce74ada2 CPTA-LF 50 6.5 30 019df6ee-5ba6-7db0-7a20-561fe03286eb
90 20260429110130 ADAS_S751NX0Y601739V_20260503105236841267_f41dbf7a1fe0 CPTA-LF 50 6.5 30 019df6ee-60a1-77ad-4835-dc7259d65576
91 20260429105306 ADAS_S751NX0Y601739V_20260503105236841267_ffd6b1c17fb7 CPTA-LF 50 6.5 20 019df6ee-6875-7fd8-75de-9bf342def9c8
92 20260429105051 ADAS_S751NX0Y601739V_20260503105236841267_5f6244be6752 CPTA-LF 50 6.5 20 019df6ee-6e42-74f3-5be5-ca793f9ee226
93 20260429104840 ADAS_S751NX0Y601739V_20260503105236841267_040dab1b6462 CPTA-LF 50 6.5 20 019df6ee-7437-7302-4e6b-706646d57c53
94 20260430005758 ADAS_S751NX0Y601739V_20260503105236841267_d43542536f95 CPLA-夜晚CN24 25 5 FCW80 019df6ee-a134-7901-60db-81d81b60998d
95 20260430005628 ADAS_S751NX0Y601739V_20260503105236841267_068362143e80 CPLA-夜晚CN24 25 5 FCW80 019df6ee-a686-7c25-563d-67b25298af0b
96 20260430005353 ADAS_S751NX0Y601739V_20260503105236841267_4e13f3cedc71 CPLA-夜晚CN24 25 5 FCW80 019df6ee-ab74-7a6c-4f75-97bcb5245fda
97 20260430005034 ADAS_S751NX0Y601739V_20260503105236841267_99a915ec4784 CPLA-夜晚CN24 25 5 FCW60 019df6ee-b2f0-7a73-74c6-80c472bcc5df
98 20260430004703 ADAS_S751NX0Y601739V_20260503105236841267_0061760569c9 CPLA-夜晚CN24 25 5 FCW60 019df6ee-b7ee-78e6-7ae0-3ae241457e06
99 20260430004432 ADAS_S751NX0Y601739V_20260503105236841267_07bca13ed759 CPLA-夜晚CN24 25 5 FCW60 019df6ee-be7e-7a34-61e5-b77877c546eb
100 20260430004247 ADAS_S751NX0Y601739V_20260503105236841267_1f3320ce38ac CPLA-夜晚CN24 25 5 40 019df6ee-c4de-7e59-4f5c-16b4261d77f4
101 20260430003934 ADAS_S751NX0Y601739V_20260503105236841267_82443933fdee CPLA-夜晚CN24 25 5 40 019df6ee-d00c-7e28-45c3-b1d1890ec640
102 20260430003725 ADAS_S751NX0Y601739V_20260503105236841267_bd901e7e8041 CPLA-夜晚CN24 25 5 20 019df6ee-d6e5-7e20-642d-7921e54619e2
103 20260430003547 ADAS_S751NX0Y601739V_20260503105236841267_070e814ef27e CPLA-夜晚CN24 25 5 20 019df6ee-db3c-764a-46e5-5a2a8495b08a
104 20260430003302 ADAS_S751NX0Y601739V_20260503105236841267_dc73a4d2ec69 CPLA-夜晚CN24 25 5 20 019df6ee-e1ba-7c15-7559-2f32ecf76326
105 20260430002426 ADAS_S751NX0Y601739V_20260503105236841267_1506a8d8eda5 CPLA-夜晚 25 5 FCW80 019df6ee-e7fc-785e-65c0-39403838db31
106 20260430002127 ADAS_S751NX0Y601739V_20260503105236841267_04b9a81743fc CPLA-夜晚 25 5 FCW80 019df6ee-efae-7fed-7023-82bf07447393
107 20260430001509 ADAS_S751NX0Y601739V_20260503105236841267_6df59d151cb4 CPLA-夜晚 25 5 FCW70 019df6ee-f551-7a5b-78c6-4f03848a2b68
108 20260430001258 ADAS_S751NX0Y601739V_20260503105236841267_8b8b37938873 CPLA-夜晚 25 5 FCW70 019df6ee-f985-7317-4f86-c5fdd56f8f48
109 20260430000414 ADAS_S751NX0Y601739V_20260503105236841267_b8fed19cc042 CPLA-夜晚 25 5 FCW60 019df6ee-fef4-7d3c-4a4c-c52f722c8e00

View File

@@ -0,0 +1,896 @@
{
"CCRH": [
{
"datetime": "20260421165302",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_204c5679f12e",
"offset": "1",
"gvt_speed": "0",
"vut_speed": "FCW120",
"event_uuid": "019dbea9-1a38-7b40-7f39-314eb07bb76d"
},
{
"datetime": "20260421165124",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_9ee9ec2148e8",
"offset": "1",
"gvt_speed": "0",
"vut_speed": "FCW120",
"event_uuid": "019dbea9-3cdf-7953-719f-bdd635eaffa4"
},
{
"datetime": "20260421164943",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_860409653c26",
"offset": "1",
"gvt_speed": "0",
"vut_speed": "FCW120",
"event_uuid": "019dbea9-53fc-75a6-6178-0696b63de01b"
},
{
"datetime": "20260421163804",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_0939f3645d9c",
"offset": "1",
"gvt_speed": "0",
"vut_speed": "FCW80",
"event_uuid": "019dbea9-6851-7511-44ce-36554aac6a91"
},
{
"datetime": "20260421163319",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_7a307c148cd7",
"offset": "1",
"gvt_speed": "0",
"vut_speed": "FCW80",
"event_uuid": "019dbea9-7ef5-73fd-5eb4-5761dd42efa8"
},
{
"datetime": "20260421163154",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_8af71c24686e",
"offset": "1",
"gvt_speed": "0",
"vut_speed": "FCW80",
"event_uuid": "019dbea9-9726-776f-7b82-5e47ac6e3e1a"
}
],
"CCRS": [
{
"datetime": "20260422170800",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_3528d22515d5",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "60",
"event_uuid": "019dbeaf-da0e-7a1f-6a2a-969f12e4f13a"
},
{
"datetime": "20260422170403",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_4f20967658ae",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "60",
"event_uuid": "019dbeaf-dee9-741e-7ca9-1ba865c1f42e"
},
{
"datetime": "20260422170238",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_ce36b7f1153a",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "60",
"event_uuid": "019dbea9-b946-7511-43c3-dfbbbf251e52"
},
{
"datetime": "20260422170012",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_6a5f70646a16",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "50",
"event_uuid": "019dbea9-cf85-7fad-5974-6901a134cd38"
},
{
"datetime": "20260422165842",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_e674d9eb9568",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "50",
"event_uuid": "019dbea9-e0b6-7c9b-7aae-71cf080d1d3f"
},
{
"datetime": "20260422165644",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_80c60d6f3899",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "50",
"event_uuid": "019dbea9-f321-7d7d-7907-7306457108bf"
},
{
"datetime": "20260422164009",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_aa662fd0c24f",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "40",
"event_uuid": "019dbeaf-e3a0-756b-569d-fa627af56012"
},
{
"datetime": "20260422163835",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_d284665c509f",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "40",
"event_uuid": "019dbeaf-e894-7f6a-7124-e8d7fbb05a27"
},
{
"datetime": "20260422163615",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_b29f69764a66",
"offset": "100",
"gvt_speed": "0",
"vut_speed": "40",
"event_uuid": "019dbeaa-1d36-77ee-4f61-80890f46d39c"
},
{
"datetime": "20260423151053",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_6921d44c9df1",
"offset": "-50",
"gvt_speed": "0",
"vut_speed": "FCW80",
"event_uuid": "019dccc9-74e3-781f-5d3f-70bdb67ec4b6"
},
{
"datetime": "20260423145748",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_2a6786176fb4",
"offset": "-50",
"gvt_speed": "0",
"vut_speed": "FCW80",
"event_uuid": "019dccc9-78c5-7a99-44c5-20d499c1ad1b"
},
{
"datetime": "20260426104816",
"rawid": "ADAS_S751NX0Y800506T_20260428123042509470_a7a13aaeb441",
"offset": "-50",
"gvt_speed": "0",
"vut_speed": "FCW80",
"event_uuid": "019dd422-12d1-70f3-6418-629a09bf7d03"
}
],
"CCFT": [
{
"datetime": "20260422161227",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_62a21a126fce",
"offset": "50",
"gvt_speed": "20",
"vut_speed": "10",
"event_uuid": "019dbeaa-32bf-7cb9-6e82-d07fcb21f35a"
},
{
"datetime": "20260422160038",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_756cc10c0a71",
"offset": "50",
"gvt_speed": "50",
"vut_speed": "30",
"event_uuid": "019dbeaa-413d-75ab-4282-686838393490"
},
{
"datetime": "20260422144136",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_25e2161254d7",
"offset": "50",
"gvt_speed": "50",
"vut_speed": "30",
"event_uuid": "019dbeaa-4c1f-7c61-7690-6cfd14ef779c"
},
{
"datetime": "20260422143535",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_938ec4fd825a",
"offset": "50",
"gvt_speed": "40",
"vut_speed": "20",
"event_uuid": "019dbeaa-58a1-7223-5799-940f1fab38ba"
},
{
"datetime": "20260422143045",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_8ccfd8c3fadd",
"offset": "50",
"gvt_speed": "40",
"vut_speed": "20",
"event_uuid": "019dbeaa-707b-7bc3-778f-bed824c3f151"
},
{
"datetime": "20260422141143",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_6e6acb788fea",
"offset": "50",
"gvt_speed": "20",
"vut_speed": "10",
"event_uuid": "019dbeaa-80d4-7a80-6d84-b805e7b8c0e6"
},
{
"datetime": "20260422114602",
"rawid": "ADAS_S5STNF0T406280R_20260424143102910957_b52d53dd07cb",
"offset": "50",
"gvt_speed": "20",
"vut_speed": "10",
"event_uuid": "019dbeaa-966c-7486-4d54-8856c274ce50"
},
{
"datetime": "20260426141443",
"rawid": "ADAS_S751NX0Y800506T_20260428123042509470_4f816e7e320a",
"offset": "50",
"gvt_speed": "50",
"vut_speed": "30",
"event_uuid": "019dd421-bf6a-74e2-68ca-a2909e8b8a35"
},
{
"datetime": "20260426114522",
"rawid": "ADAS_S751NX0Y800506T_20260428123042509470_3d725df8d10d",
"offset": "50",
"gvt_speed": "40",
"vut_speed": "20",
"event_uuid": "019dd421-e1cb-7419-51dc-df1018d64664"
}
],
"CBLA-CN21": [
{
"datetime": "20260423165539",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_5bdad74f0035",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "FCW70",
"event_uuid": "019dccc4-42ba-78f2-437c-cead7d452568"
},
{
"datetime": "20260423165159",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_a75bd09b1591",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "FCW70",
"event_uuid": "019dccc4-4f20-74d5-5edf-eb7d119270f6"
},
{
"datetime": "20260423164643",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_f02011f6fb51",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "FCW50",
"event_uuid": "019dccc4-5631-7267-6580-8f55c03f3269"
},
{
"datetime": "20260423164406",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_33f47ad79ea4",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "FCW50",
"event_uuid": "019dccc4-5b35-7459-4097-554fc6c58621"
},
{
"datetime": "20260426161459",
"rawid": "ADAS_S751NX0Y800506T_20260428123042509470_29327584d51d",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "FCW70",
"event_uuid": "019dd421-4b69-71ac-6a32-ec788393fe4f"
},
{
"datetime": "20260426160008",
"rawid": "ADAS_S751NX0Y800506T_20260428123042509470_d69768e25615",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "FCW50",
"event_uuid": "019dd421-645f-739b-4fcb-863735ace841"
}
],
"CBLA-cn21": [
{
"datetime": "20260423164220",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_3422d076b4b4",
"offset": "50",
"gvt_speed": "15",
"vut_speed": "60",
"event_uuid": "019dccc9-2623-7a08-5135-e78a8ece105c"
},
{
"datetime": "20260423163827",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_8552d0859d87",
"offset": "50",
"gvt_speed": "15",
"vut_speed": "60",
"event_uuid": "019dccc9-2d6d-799b-6d2d-6bb572d2a18a"
},
{
"datetime": "20260423163640",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_2516f29f235f",
"offset": "50",
"gvt_speed": "15",
"vut_speed": "50",
"event_uuid": "019dccc9-33f1-7629-4370-462c8a5453ab"
},
{
"datetime": "20260423162521",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_44e04f0525e9",
"offset": "50",
"gvt_speed": "15",
"vut_speed": "50",
"event_uuid": "019dccc9-3a1c-7c5c-67aa-40d06b7b2555"
},
{
"datetime": "20260426154615",
"rawid": "ADAS_S751NX0Y800506T_20260428123042509470_f2c5d47738ad",
"offset": "50",
"gvt_speed": "15",
"vut_speed": "60",
"event_uuid": "019dd421-8101-7018-57ce-9bcae8c008fc"
},
{
"datetime": "20260426153534",
"rawid": "ADAS_S751NX0Y800506T_20260428123042509470_0b8deed3ca4d",
"offset": "50",
"gvt_speed": "15",
"vut_speed": "50",
"event_uuid": "019dd421-94b9-7cd3-4834-5592601312c0"
}
],
"CBLA-cn24": [
{
"datetime": "20260423161011",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_3c486812721a",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "40",
"event_uuid": "019dccc9-4260-7ada-54fb-d395c275092b"
},
{
"datetime": "20260423160753",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_eb521054a5e7",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "40",
"event_uuid": "019dccc9-46d3-7e58-5c42-8ee8778fb98b"
},
{
"datetime": "20260423160611",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_805ec2d6dfb9",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "40",
"event_uuid": "019dccc9-4aeb-7fdf-5a01-1c4da8d9c268"
},
{
"datetime": "20260423160427",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_45d1afad713c",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "20",
"event_uuid": "019dccc9-4f0c-7a16-6f4a-8d9801f93347"
},
{
"datetime": "20260423160241",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_6281b7a1ec03",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "20",
"event_uuid": "019dccc9-5ab3-7a88-4fb6-fafd066195ae"
},
{
"datetime": "20260423160005",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_3499529a30c5",
"offset": "25",
"gvt_speed": "15",
"vut_speed": "20",
"event_uuid": "019dccc9-6081-76fa-6fe3-3bc9870efadd"
}
],
"CCRM": [
{
"datetime": "20260423152501",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_7fe834d1e141",
"offset": "-50",
"gvt_speed": "20",
"vut_speed": "FCW80",
"event_uuid": "019dccc9-64bd-760d-5587-e2d5c0557773"
},
{
"datetime": "20260423152049",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_5583953c59cd",
"offset": "-50",
"gvt_speed": "20",
"vut_speed": "FCW80",
"event_uuid": "019dccc9-6b06-7bac-7867-82ff6caf6f8b"
},
{
"datetime": "20260423151903",
"rawid": "ADAS_S751NX0Y601865J_20260425160638282353_45bdf88fa7e2",
"offset": "-50",
"gvt_speed": "20",
"vut_speed": "FCW80",
"event_uuid": "019dccc9-6f22-7790-538b-7eb0bba8e8a7"
}
],
"CPLA": [
{
"datetime": "20260424165609",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_8e3ef1dd2b95",
"offset": "50",
"gvt_speed": "5",
"vut_speed": "50",
"event_uuid": "019dccc9-a412-7274-4b69-3dfcf9b1c751"
},
{
"datetime": "20260424165355",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_d71e1fcdd716",
"offset": "50",
"gvt_speed": "5",
"vut_speed": "50",
"event_uuid": "019dccc9-a7c9-7911-6c96-1b3a8e53e08a"
},
{
"datetime": "20260424164838",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_8674df9f7e6c",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW50",
"event_uuid": "019dccc9-abad-7dc9-5311-d4b4cfc6c996"
},
{
"datetime": "20260424163138",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_d56ab481858d",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW50",
"event_uuid": "019dccc9-b70a-7a64-79d4-7d74b3c29504"
},
{
"datetime": "20260429180444",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_2c1473b10dc6",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW50",
"event_uuid": "019df6ed-cd2f-7d2a-688c-713c0cd6307b"
},
{
"datetime": "20260429165306",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_f18094de4d8a",
"offset": "50",
"gvt_speed": "5",
"vut_speed": "50",
"event_uuid": "019df6ed-e11b-7e3b-5f6b-0f23c224f66a"
}
],
"CPLA-cn24": [
{
"datetime": "20260424161735",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_f40e70b67ad5",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW80",
"event_uuid": "019dccda-0a48-775a-4b49-31e4f52ac800"
},
{
"datetime": "20260424160918",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_c3ab74ad2582",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW80",
"event_uuid": "019dccda-0fb5-7040-60fb-5b6eb0340c90"
},
{
"datetime": "20260424160557",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_280ec474f1e7",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW80",
"event_uuid": "019dccda-1b52-7d2c-4e20-ba87c5fb8906"
},
{
"datetime": "20260424160317",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_3c471e2b551e",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW60",
"event_uuid": "019dccda-22b4-7590-5a90-9d93d91a62a2"
},
{
"datetime": "20260424155607",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_b13af5e369e4",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW60",
"event_uuid": "019dccda-2b1b-7ce0-5f11-067ff68c180c"
},
{
"datetime": "20260424155333",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_37703d761455",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW60",
"event_uuid": "019dccda-2fa3-7c8a-5efc-9c1a06ab60df"
},
{
"datetime": "20260424151547",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_9c30cae5f806",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "40",
"event_uuid": "019dccda-3b7a-7225-6d4a-3549aec142a2"
},
{
"datetime": "20260424151208",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_03d95f1a0bea",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "40",
"event_uuid": "019dccda-4335-7c87-6432-c8a061772dcf"
},
{
"datetime": "20260424150237",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_68b9be51b240",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "40",
"event_uuid": "019dccda-4853-7b14-79a3-686c976fec99"
},
{
"datetime": "20260424145815",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_ab99d7f496b7",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "20",
"event_uuid": "019dccda-4be8-7f2e-474c-83483bb86d61"
},
{
"datetime": "20260424145646",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_9d9f4f81d58b",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "20",
"event_uuid": "019dccda-4ff1-7e09-79bc-0248f385c3a3"
},
{
"datetime": "20260424145409",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_6ed854132275",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "20",
"event_uuid": "019dccda-56e1-74eb-59b8-bbdef5b2eebd"
}
],
"SCP": [
{
"datetime": "20260424103224",
"rawid": "ADAS_S751NX0Y601739V_20260426105646474483_dea4e64065d5",
"offset": "无",
"gvt_speed": "20",
"vut_speed": "30",
"event_uuid": "019dccc9-bc95-7c6f-7252-394628471d0b"
},
{
"datetime": "20260425150005",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_66e67c5c39be",
"offset": "无",
"gvt_speed": "20",
"vut_speed": "30",
"event_uuid": "019dd420-d37c-7f00-7fa5-b50f8ed72220"
},
{
"datetime": "20260425145813",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_67fee0b894e5",
"offset": "无",
"gvt_speed": "20",
"vut_speed": "30",
"event_uuid": "019dd420-dbca-73d4-632b-e5f65ee08add"
},
{
"datetime": "20260425144953",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_30d3364724be",
"offset": "无",
"gvt_speed": "50",
"vut_speed": "FCW60",
"event_uuid": "019dd420-e730-7c1b-6a2a-1f28c5abdb31"
},
{
"datetime": "20260425144737",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_50a3ef4039ec",
"offset": "无",
"gvt_speed": "50",
"vut_speed": "FCW60",
"event_uuid": "019dd420-ebf5-7295-7605-ee83309a5f9a"
},
{
"datetime": "20260425114942",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_3f7cd5c01537",
"offset": "无",
"gvt_speed": "40",
"vut_speed": "FCW50",
"event_uuid": "019dd420-f18a-7452-7541-0c5b8d67bfd8"
},
{
"datetime": "20260425111856",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_992eed63acec",
"offset": "无",
"gvt_speed": "40",
"vut_speed": "FCW50",
"event_uuid": "019dd420-f854-7547-7783-f5ea609d92ca"
},
{
"datetime": "20260425111443",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_de3c37dc6e75",
"offset": "无",
"gvt_speed": "30",
"vut_speed": "40",
"event_uuid": "019dd420-fd1f-7b3c-6e3f-8f7bcea6321a"
},
{
"datetime": "20260425111027",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_2cc5c5469141",
"offset": "无",
"gvt_speed": "30",
"vut_speed": "40",
"event_uuid": "019dd421-0260-749a-7b6a-5fdac9e9be44"
},
{
"datetime": "20260425105940",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_680a33a5f78d",
"offset": "无",
"gvt_speed": "30",
"vut_speed": "40",
"event_uuid": "019dd421-0cb0-7578-62fc-7c2e0d42510b"
}
],
"CPTA-LN": [
{
"datetime": "20260425170806",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_fa832c22f1d0",
"offset": "50",
"gvt_speed": "5",
"vut_speed": "20",
"event_uuid": "019dd420-c6c2-730a-6c14-f4513669fe8d"
},
{
"datetime": "20260425170149",
"rawid": "ADAS_S5STNF0T504465N_20260427141205368130_a199460fdb86",
"offset": "50",
"gvt_speed": "5",
"vut_speed": "20",
"event_uuid": "019dd420-cbaa-7367-5680-dd3cbbebfabc"
}
],
"CPTA-LF": [
{
"datetime": "20260429161841",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_8e07fc3208b9",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "10",
"event_uuid": "019df6ee-0264-79f2-57fd-83608f1eaac6"
},
{
"datetime": "20260429161528",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_7123bd12f35b",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "10",
"event_uuid": "019df6ee-0867-7e44-5000-7873beef8dbf"
},
{
"datetime": "20260429161021",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_f06682f85f33",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "10",
"event_uuid": "019df6ee-0f73-7c90-6196-7fc08cad2f73"
},
{
"datetime": "20260429111506",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_0457ce74ada2",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "30",
"event_uuid": "019df6ee-5ba6-7db0-7a20-561fe03286eb"
},
{
"datetime": "20260429110130",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_f41dbf7a1fe0",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "30",
"event_uuid": "019df6ee-60a1-77ad-4835-dc7259d65576"
},
{
"datetime": "20260429105306",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_ffd6b1c17fb7",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "20",
"event_uuid": "019df6ee-6875-7fd8-75de-9bf342def9c8"
},
{
"datetime": "20260429105051",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_5f6244be6752",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "20",
"event_uuid": "019df6ee-6e42-74f3-5be5-ca793f9ee226"
},
{
"datetime": "20260429104840",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_040dab1b6462",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "20",
"event_uuid": "019df6ee-7437-7302-4e6b-706646d57c53"
}
],
"CPTA-RF": [
{
"datetime": "20260429155038",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_4ef26aabdfae",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "20",
"event_uuid": "019df6ee-14d6-7a13-44dc-63f353943186"
},
{
"datetime": "20260429154600",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_0d79d3d7a9d6",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "20",
"event_uuid": "019df6ee-1d07-776e-72ed-af1ba59c76cd"
},
{
"datetime": "20260429153237",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_9d1716a5f582",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "20",
"event_uuid": "019df6ee-24e0-776f-7ddd-0c65b8c01d24"
},
{
"datetime": "20260429144733",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_6f3c74447dec",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "10",
"event_uuid": "019df6ee-35ea-7bb1-6be8-2497aa23f1ad"
},
{
"datetime": "20260429114321",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_6ffeb9a156eb",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "10",
"event_uuid": "019df6ee-4aa8-7aa6-5523-8d0fa6384228"
},
{
"datetime": "20260429113635",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_5b68e94bafac",
"offset": "50",
"gvt_speed": "6.5",
"vut_speed": "10",
"event_uuid": "019df6ee-540f-7bcc-5f7d-7ef249177de0"
}
],
"CPLA-夜晚CN24": [
{
"datetime": "20260430005758",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_d43542536f95",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW80",
"event_uuid": "019df6ee-a134-7901-60db-81d81b60998d"
},
{
"datetime": "20260430005628",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_068362143e80",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW80",
"event_uuid": "019df6ee-a686-7c25-563d-67b25298af0b"
},
{
"datetime": "20260430005353",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_4e13f3cedc71",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW80",
"event_uuid": "019df6ee-ab74-7a6c-4f75-97bcb5245fda"
},
{
"datetime": "20260430005034",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_99a915ec4784",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW60",
"event_uuid": "019df6ee-b2f0-7a73-74c6-80c472bcc5df"
},
{
"datetime": "20260430004703",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_0061760569c9",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW60",
"event_uuid": "019df6ee-b7ee-78e6-7ae0-3ae241457e06"
},
{
"datetime": "20260430004432",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_07bca13ed759",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW60",
"event_uuid": "019df6ee-be7e-7a34-61e5-b77877c546eb"
},
{
"datetime": "20260430004247",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_1f3320ce38ac",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "40",
"event_uuid": "019df6ee-c4de-7e59-4f5c-16b4261d77f4"
},
{
"datetime": "20260430003934",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_82443933fdee",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "40",
"event_uuid": "019df6ee-d00c-7e28-45c3-b1d1890ec640"
},
{
"datetime": "20260430003725",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_bd901e7e8041",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "20",
"event_uuid": "019df6ee-d6e5-7e20-642d-7921e54619e2"
},
{
"datetime": "20260430003547",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_070e814ef27e",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "20",
"event_uuid": "019df6ee-db3c-764a-46e5-5a2a8495b08a"
},
{
"datetime": "20260430003302",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_dc73a4d2ec69",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "20",
"event_uuid": "019df6ee-e1ba-7c15-7559-2f32ecf76326"
}
],
"CPLA-夜晚": [
{
"datetime": "20260430002426",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_1506a8d8eda5",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW80",
"event_uuid": "019df6ee-e7fc-785e-65c0-39403838db31"
},
{
"datetime": "20260430002127",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_04b9a81743fc",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW80",
"event_uuid": "019df6ee-efae-7fed-7023-82bf07447393"
},
{
"datetime": "20260430001509",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_6df59d151cb4",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW70",
"event_uuid": "019df6ee-f551-7a5b-78c6-4f03848a2b68"
},
{
"datetime": "20260430001258",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_8b8b37938873",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW70",
"event_uuid": "019df6ee-f985-7317-4f86-c5fdd56f8f48"
},
{
"datetime": "20260430000414",
"rawid": "ADAS_S751NX0Y601739V_20260503105236841267_b8fed19cc042",
"offset": "25",
"gvt_speed": "5",
"vut_speed": "FCW60",
"event_uuid": "019df6ee-fef4-7d3c-4a4c-c52f722c8e00"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
scene,offset,gvt_speed,vut_speed,datetime,rawid,data_path
CPFA,25,6.5,20,20260323113612 ,ADAS_S751NX0Y800506T_20260327120535206279_a18b17bc1454,019d4e3a-78d3-7dc4-4e33-e871f9c3e15a
CPFA,25,6.5,20,20260323113832 ,ADAS_S751NX0Y800506T_20260327120535206279_ff61c208d184,019d4e3a-8f48-77d9-5f70-43bee3eab1c5
CPFA,25,6.5,30,20260323114629 ,ADAS_S751NX0Y800506T_20260327120535206279_2f11a63355c7,019d4e3a-90ad-7f00-7798-5551095fb4b5
CPFA,25,6.5,30,20260323114938 ,ADAS_S751NX0Y800506T_20260327120535206279_eba8998fb8a3,019d4e3a-9441-7d17-63dc-b773bd467ae5
CPFA,25,6.5,40,20260323140108 ,ADAS_S751NX0Y800506T_20260327120535206279_6429dd74f911,019d4e3a-974f-751c-5b3b-46c0a9364466
CPFA,25,6.5,40,20260323140816 ,ADAS_S751NX0Y800506T_20260327120535206279_2a6aca204419,019d4e3a-99de-7e5a-56d4-83547bd8ac34
CPFA,25,6.5,40,20260323141946 ,ADAS_S751NX0Y800506T_20260327120535206279_b527f4357559,019d4e3a-9bb0-7755-66c9-8fdd3770f67f
CPFA,25,6.5,50,20260323142206 ,ADAS_S751NX0Y800506T_20260327120535206279_468f64aaaaed,019d4e3a-9cf4-7d35-4e0c-52952c05537d
CPFA,25,6.5,50,20260323142435 ,ADAS_S751NX0Y800506T_20260327120535206279_72e20dc77396,019d4e3a-9f08-7500-6382-44bacad5f1ed
CPFA,25,6.5,50,20260323142614 ,ADAS_S751NX0Y800506T_20260327120535206279_f0a4e2c2f8de,019d4e3a-a07a-7aa1-5981-8977d03402dc
CPFA,25,6.5,60,20260323150051 ,ADAS_S751NX0Y800506T_20260327120535206279_8c30e32b75da,019d4e3a-ac12-74ae-5d1b-7ddca8db7feb
CPFA,25,6.5,60,20260323150956 ,ADAS_S751NX0Y800506T_20260327120535206279_597b22308c0c,019d4e3a-af07-7d2b-79ed-cce2054427b2
CPFA,25,6.5,60,20260323151226 ,ADAS_S751NX0Y800506T_20260327120535206279_920d06aa0c83,019d4e3a-b05e-7499-7cc0-c3b75d576e8c
CPFA,50,6.5,20,20260322152509 ,ADAS_S751NX0Y800506T_20260327120535206279_1b6644577499,019d4e3a-b72a-702f-7485-de4f36c19291
CPFA,50,6.5,20,20260322152819 ,ADAS_S751NX0Y800506T_20260327120535206279_3f4043e7c43b,019d4e3a-b87b-7ba7-770a-56ab7e461dd2
CPFA,50,6.5,20,20260322153301 ,ADAS_S751NX0Y800506T_20260327120535206279_f00ed7674617,019d4e3a-bb94-77e0-6de8-aa85930f28e8
CPFA,50,6.5,30,20260322153555 ,ADAS_S751NX0Y800506T_20260327120535206279_8fc6b6b738b3,019d4e3a-c417-7fe5-7eea-e1096344665b
CPFA,50,6.5,30,20260322153820 ,ADAS_S751NX0Y800506T_20260327120535206279_55177e3ae374,019d4e3a-c676-76d2-77b1-d498fad94160
CPFA,50,6.5,30,20260322154017 ,ADAS_S751NX0Y800506T_20260327120535206279_82b9ead31ef0,019d4e3a-c989-7b2f-67f3-08cabcfa7a97
CPFA,50,6.5,40,20260323111334 ,ADAS_S751NX0Y800506T_20260327120535206279_7ec23297755f,019d4e3a-d5b5-7cbb-7add-b81d9d6da22f
CPFA,50,6.5,40,20260323111522 ,ADAS_S751NX0Y800506T_20260327120535206279_2f655a7f3faa,019d4e3a-d858-72f8-6e5a-4de5471314f0
CPFA,50,6.5,40,20260323111755 ,ADAS_S751NX0Y800506T_20260327120535206279_00dd9a4dda13,019d4e3a-db87-7799-66c7-96a11b425725
CPFA,50,6.5,50,20260323112055 ,ADAS_S751NX0Y800506T_20260327120535206279_08404d05ab99,019d4e3a-ddc1-749a-523f-bfa54c6ab4b9
CPFA,50,6.5,50,20260323112255 ,ADAS_S751NX0Y800506T_20260327120535206279_7bda3d59284b,019d4e3a-e154-7114-4619-a60849eb771a
CPFA,50,6.5,50,20260323112515 ,ADAS_S751NX0Y800506T_20260327120535206279_523828701c91,019d4e3a-e764-7634-765c-6178bb27739d
CPFA,50,6.5,60,20260323112758 ,ADAS_S751NX0Y800506T_20260327120535206279_5c77b0c2fc61,019d4e3a-ea48-7eb9-6720-7ba5e0a38877
CPFA,50,6.5,60,20260323113007 ,ADAS_S751NX0Y800506T_20260327120535206279_16986d99d73c,019d4e3a-ed5d-7426-7143-8cb7870c8a53
CPFA,50,6.5,60,20260323113249 ,ADAS_S751NX0Y800506T_20260327120535206279_7fa179422fa9,019d4e3a-f0d1-760d-64c4-0bf331a399f7
CPNA,25,5,20,20260322160034 ,ADAS_S751NX0Y800506T_20260327120535206279_bfa3bdb3ecfa,019d4e3a-f35c-7f56-6350-fdae7d030520
CPNA,25,5,20,20260322161344 ,ADAS_S751NX0Y800506T_20260327120535206279_4d845a8f0558,019d4e3a-f744-7cd1-7260-2a17dc2fd996
CPNA,25,5,20,20260322162319 ,ADAS_S751NX0Y800506T_20260327120535206279_bb2b77bf7e71,019d4e3a-fa3c-7bc2-75b0-d676f2d12eaa
CPNA,25,5,30,20260322162901 ,ADAS_S751NX0Y800506T_20260327120535206279_a4e2d3b50dfc,019d4e3b-0c47-76bc-6f13-9bac1a818536
CPNA,25,5,30,20260322163412 ,ADAS_S751NX0Y800506T_20260327120535206279_34ec8bc7c628,019d4e3b-0e7c-7347-49c1-b70b0caa6010
CPNA,25,5,30,20260322163631 ,ADAS_S751NX0Y800506T_20260327120535206279_a398a2f1d31d,019d4e3b-1077-77d3-570a-71463fe4e9c8
CPNA,25,5,40,20260322172726 ,ADAS_S751NX0Y800506T_20260327120535206279_62a7fe51f78a,019d4e3b-2f89-775e-6fb8-1de28a664495
CPNA,25,5,40,20260322173110 ,ADAS_S751NX0Y800506T_20260327120535206279_525d3358ef99,019d4e3b-337f-714b-60b4-8e87df7f7a51
CPNA,25,5,40,20260322173530 ,ADAS_S751NX0Y800506T_20260327120535206279_2926f0bbdeb6,019d4e3b-3606-7e91-7816-2b9d0ad07dcd
CPNA,25,5,50,20260324161933 ,ADAS_S751NX0Y800506T_20260327120535206279_d74d2d3f578d,019d4e3b-4fba-707b-4a28-1ac6277145ba
CPNA,25,5,50,20260331151009 ,ADAS_S5STNF0T406280R_20260402104850269428_0785a9b23943,019d4e3b-5213-7f0d-7fc9-18a3051690f7
CPNA,25,5,50,20260331151250 ,ADAS_S5STNF0T406280R_20260402104850269428_f0cf082bc503,019d4e3b-541b-787d-6ae6-3da8fb8e1139
CPNA,25,5,60,20260324164151 ,ADAS_S751NX0Y800506T_20260327120535206279_7b3031a15f43,019d4e3b-5bf2-7e3a-49df-56bc4f07fb62
CPNA,25,5,60,20260324165218 ,ADAS_S751NX0Y800506T_20260327120535206279_ef49250e9812,019d4e3b-5e24-7249-4bb6-bdd243110001
CPNA,25,5,60,20260331151834 ,ADAS_S5STNF0T406280R_20260402104850269428_f8705c0133fa,019d4e3b-6076-7ede-73a3-afdfd283b7b4
CPNA,75,5,20,20260322173859 ,ADAS_S751NX0Y800506T_20260327120535206279_f91ce01108fe,019d4e3b-6900-71f3-4685-a4332df5f883
CPNA,75,5,20,20260322174119 ,ADAS_S751NX0Y800506T_20260327120535206279_ab63c70e43b8,019d4e3b-6b7c-72e8-56ea-2d6eac52ab30
CPNA,75,5,20,20260322174325 ,ADAS_S751NX0Y800506T_20260327120535206279_56c1d30ff57b,019d4e3b-70f6-76a1-5812-f8db1c73e627
CPNA,75,5,30,20260322175205 ,ADAS_S751NX0Y800506T_20260327120535206279_fdada52e9fa5,019d4e3b-92d0-7fd2-66c2-f2a1d1e81e6f
CPNA,75,5,30,20260322175649 ,ADAS_S751NX0Y800506T_20260327120535206279_89d41fb8d2e8,019d4e3b-9663-7d48-55b8-2af349c18284
CPNA,75,5,30,20260322175850 ,ADAS_S751NX0Y800506T_20260327120535206279_bbe31db90e0a,019d4e3b-9acb-7387-6b18-466c0534a3bc
CPNA,75,5,40,20260324171844 ,ADAS_S751NX0Y800506T_20260327120535206279_44a743580dac,019d4e3b-a6ff-7af5-6b3b-38fcdf52e12b
CPNA,75,5,40,20260324172117 ,ADAS_S751NX0Y800506T_20260327120535206279_51afa9e84ca0,019d4e3b-a8c6-736e-7dea-bfbdd73fd93a
CPNA,75,5,40,20260331163021 ,ADAS_S5STNF0T406280R_20260402104850269428_5c97beda0356,019d4e3b-ac9d-7dd8-41a7-f7c7838e4471
CPNA,75,5,50,20260324172350 ,ADAS_S751NX0Y800506T_20260327120535206279_1e84d8ee3c5e,019d4e3b-b426-7c52-70ec-4433ffa93589
CPNA,75,5,50,20260324172558 ,ADAS_S751NX0Y800506T_20260327120535206279_e9d1fb808bed,019d4e3b-b6ec-74ca-533a-d50dd4c6bc76
CPNA,75,5,50,20260324172833 ,ADAS_S751NX0Y800506T_20260327120535206279_16007a77b8e3,019d4e3b-cd62-7eb6-7a95-60a64da7c7ce
CPNA,75,5,60,20260324173139 ,ADAS_S751NX0Y800506T_20260327120535206279_ef6e0008db8a,019d4e3b-da82-7e0d-4d74-b59da953ecff
CPNA,75,5,60,20260324173924 ,ADAS_S751NX0Y800506T_20260327120535206279_84ce75f29b5b,019d4e3b-df7a-7e7b-44a7-226205b4213f
CPNA,75,5,60,20260324174238 ,ADAS_S751NX0Y800506T_20260327120535206279_76553de00e52,019d4e3b-e195-75cc-687b-e6c9c642ee54
CBNA,50,15,20,20260325112105 ,ADAS_S751NX0Y800506T_20260327120535206279_c7ff38958fa1,019d4e3b-ea01-7a92-63ee-4854e139ed23
CBNA,50,15,20,20260325120919 ,ADAS_S751NX0Y800506T_20260327120535206279_aaa5e92f1b8d,019d4e3b-ee98-7208-7e05-184f40aad9c6
CBNA,50,15,20,20260325140126 ,ADAS_S751NX0Y800506T_20260327120535206279_72d0b390d41b,019d4e3b-f52d-702d-49bd-86c2a007937f
CBNA,50,15,30,20260325142826 ,ADAS_S751NX0Y800506T_20260327120535206279_d3da82eff0a1,019d4e3c-03d5-72ff-5fdc-d798dafc0689
CBNA,50,15,30,20260325144228 ,ADAS_S751NX0Y800506T_20260327120535206279_81bd7a6856f8,019d4e3c-06ff-7af8-4b52-45705976b906
CBNA,50,15,30,20260325144443 ,ADAS_S751NX0Y800506T_20260327120535206279_e07712df8814,019d4e3c-08e9-72f3-721c-460d3da8b41c
CBNA,50,15,40,20260325145316 ,ADAS_S751NX0Y800506T_20260327120535206279_5f75b8004ae5,019d4e3c-39e9-760e-428f-80a856bbb683
CBNA,50,15,40,20260325145539 ,ADAS_S751NX0Y800506T_20260327120535206279_b3de854ceea1,019d4e3c-3e78-765c-5f1c-672330e51957
CBNA,50,15,40,20260325145759 ,ADAS_S751NX0Y800506T_20260327120535206279_4c2cc3a4581f,019d4e3c-403d-73af-7310-dc91edbc687a
CBNA,50,15,50,20260325150059 ,ADAS_S751NX0Y800506T_20260327120535206279_3ab5c9fb09e8,019d4e3c-4a59-70ac-5799-76424e4a5926
CBNA,50,15,50,20260325150516 ,ADAS_S751NX0Y800506T_20260327120535206279_c548265438c0,019d4e3c-4cce-7267-5cab-81c5a8147465
CBNA,50,15,50,20260325151329 ,ADAS_S751NX0Y800506T_20260327120535206279_56ec7f3f0a9f,019d4e3c-5023-7469-594c-0aca8726e58f
CBNA,50,15,60,20260325153201 ,ADAS_S751NX0Y800506T_20260327120535206279_079e46de1e69,019d4e3c-5bee-7dd7-5ca1-d6bc06862db6
CBNA,50,15,60,20260325153627 ,ADAS_S751NX0Y800506T_20260327120535206279_e7bd46fa5526,019d4e3c-5dc6-710b-616c-56a91c34b928
CBNA,50,15,60,20260401105118 ,ADAS_S5STNF0T504465N_20260402191154995992_98b65d35a0e8,019d4e3c-60fa-7d56-61ab-078cd6e38af5
CSFA,50,20,30,20260325160450 ,ADAS_S751NX0Y800506T_20260327120535206279_3db3d3c5f75e,019d4e3c-6e6e-7d1a-79af-39cd8a4a54d8
CSFA,50,20,30,20260325163344 ,ADAS_S751NX0Y800506T_20260327120535206279_8b26b8678563,019d4e3c-70c7-7a72-5dac-25eb86983968
CSFA,50,20,30,20260325163640 ,ADAS_S751NX0Y800506T_20260327120535206279_048ca75c2b68,019d4e3c-7352-738d-47ab-2ea8eca8d7ad
CSFA,50,20,30,20260401112255 ,ADAS_S5STNF0T504465N_20260402191154995992_8c840c39ed44,019d4e3c-7a18-7597-71b1-31f9ece82944
CSFA,50,20,40,20260325164019 ,ADAS_S751NX0Y800506T_20260327120535206279_71ba721054d2,019d4e3c-7cd2-7485-64a3-52d954e956fe
CSFA,50,20,40,20260325164557 ,ADAS_S751NX0Y800506T_20260327120535206279_101c937f632e,019d4e3c-8191-7c57-64a2-b21ce84ecc08
CSFA,50,20,40,20260325165101 ,ADAS_S751NX0Y800506T_20260327120535206279_0039e9c4f44c,019d4e3c-84d1-7496-4cf5-55f849f06c6d
CSFA,50,20,50,20260325165344 ,ADAS_S751NX0Y800506T_20260327120535206279_35f7055b3936,019d4e3c-9254-795a-5d2c-e1c38b47f6f1
CSFA,50,20,50,20260325165620 ,ADAS_S751NX0Y800506T_20260327120535206279_cae0b056a639,019d4e3c-95e3-7c5c-6c3e-0d97a6aa300e
CSFA,50,20,50,20260325170106 ,ADAS_S751NX0Y800506T_20260327120535206279_a3b60a4417f1,019d4e3c-9881-768a-447c-063b27c49a4d
CSFA,50,20,60,20260325170448 ,ADAS_S751NX0Y800506T_20260327120535206279_9cf23dfe1aa7,019d4e3c-a794-7de1-70b6-cf64d043298a
CSFA,50,20,60,20260325171905 ,ADAS_S751NX0Y800506T_20260327120535206279_f05823ea3fb0,019d4e3c-aa4d-7285-60da-b503786e136d
CSFA,50,20,60,20260325172254 ,ADAS_S751NX0Y800506T_20260327120535206279_095c61152216,019d4e3c-ae93-7858-6a24-810c5f1e62db
CCRM,100,20,30,20260327110922 ,ADAS_S751NX0Y601739V_20260330104120600319_d9c5e242cd43,019d4e3c-bb28-73bc-5211-83d63bdf0ca9
CCRM,100,20,30,20260327111430 ,ADAS_S751NX0Y601739V_20260330104120600319_49f67f0f4c84,019d4e3c-becf-7df4-6697-fd1e7359b44e
CCRM,100,20,30,20260327112148 ,ADAS_S751NX0Y601739V_20260330104120600319_71c00fa5c46c,019d4e3c-c0e6-7ada-63e8-f2e7cd2ee7fa
CCRM,100,20,40,20260327113709 ,ADAS_S751NX0Y601739V_20260330104120600319_310c2fb9e063,019d4e3c-c8a5-7b63-5fb9-f9847ca1baa9
CCRM,100,20,40,20260327115052 ,ADAS_S751NX0Y601739V_20260330104120600319_9fde171dd0c5,019d4e3c-cb80-712f-46e5-36af2aad17f8
CCRM,100,20,40,20260327115408 ,ADAS_S751NX0Y601739V_20260330104120600319_89971a38a795,019d4e3c-cd63-776f-7608-9f922d1902d2
CPLA,25,5,20,20260325175106 ,ADAS_S751NX0Y800506T_20260327120535206279_67c2c4cfdcfa,019d4e3c-d4b2-79f9-4ed1-4ecb7b0194c8
CPLA,25,5,20,20260325180145 ,ADAS_S751NX0Y800506T_20260327120535206279_6c216f1d5e73,019d4e3c-d864-7799-5a0b-28bb4f33acb4
CPLA,25,5,20,20260325180337 ,ADAS_S751NX0Y800506T_20260327120535206279_42d78cae79e4,019d4e3c-da58-73c5-491e-6974c7368238
CPLA,25,5,30,20260325180602 ,ADAS_S751NX0Y800506T_20260327120535206279_305900bb160b,019d4e3c-dc9f-704f-5b1a-2fe724439ca6
CPLA,25,5,30,20260325180857 ,ADAS_S751NX0Y800506T_20260327120535206279_d72d2f1eab33,019d4e3c-df35-7734-69cb-a4d0c67e80d9
CPLA,25,5,30,20260325181249 ,ADAS_S751NX0Y800506T_20260327120535206279_e65e2e8bb2c3,019d4e3c-e27f-739a-7823-ae3a8cf49aba
CPLA,25,5,40,20260326112939 ,ADAS_S751NX0Y601865J_20260328113450259688_7e273228d47b,019d4e3c-e3c2-73ee-6b22-fb2ac8a75c73
CPLA,25,5,40,20260326113327 ,ADAS_S751NX0Y601865J_20260328113450259688_cf29bc58f910,019d4e3c-e511-7249-7c25-e69e8452d486
CPLA,25,5,40,20260326120929 ,ADAS_S751NX0Y601865J_20260328113450259688_19aa5768291c,019d4e3c-e781-7c8d-4873-f1d931f483d6
CPLA,50,5,20,20260326141456 ,ADAS_S751NX0Y601865J_20260328113450259688_7089abe3283f,019d4e3c-ee0a-7f12-6936-b8f2fd8f17ad
CPLA,50,5,20,20260326141816 ,ADAS_S751NX0Y601865J_20260328113450259688_968bbf10d481,
CPLA,50,5,20,20260326143002 ,ADAS_S751NX0Y601865J_20260328113450259688_253cc2246a46,019d4e3c-f166-7b61-46eb-6b2c216bfff8
CPLA,50,5,30,20260326143325 ,ADAS_S751NX0Y601865J_20260328113450259688_890e13a19330,019d4e3c-f4c9-7b4a-4c86-0ffd3898c96f
CPLA,50,5,30,20260326143553 ,ADAS_S751NX0Y601865J_20260328113450259688_208c31032ab7,019d4e3c-f78b-77e7-53c3-ae06b3ae3b66
CPLA,50,5,30,20260326143953 ,ADAS_S751NX0Y601865J_20260328113450259688_31374e23ea52,019d4e3c-f8e0-74f6-461a-e2b03ec26f0b
CPLA,50,5,40,20260326144301 ,ADAS_S751NX0Y601865J_20260328113450259688_11edf0db8552,019d4e3c-fac9-7171-6894-a4a295f2aee3
CPLA,50,5,40,20260326144521 ,ADAS_S751NX0Y601865J_20260328113450259688_88f480b20482,019d4e3c-fc5e-76c8-783e-c95921d6db7c
CPLA,50,5,40,20260326144728 ,ADAS_S751NX0Y601865J_20260328113450259688_010690530eb1,019d4e3c-fe9d-7724-5895-96d271ac56b4
CPLA,50,5,50,20260326145318 ,ADAS_S751NX0Y601865J_20260328113450259688_e8f3c0c2d8e7,019d4e3d-0304-7a98-47bf-a2123c57756e
CPLA,50,5,50,20260326150327 ,ADAS_S751NX0Y601865J_20260328113450259688_a44f950ae272,019d4e3d-0714-7346-4218-45001f0df930
CPLA,50,5,50,20260326152042 ,ADAS_S751NX0Y601865J_20260328113450259688_13132ea06b7c,019d4e3d-097c-7c4e-6f7a-a5514e19ae85
CPLA,50,5,60,20260326152355 ,ADAS_S751NX0Y601865J_20260328113450259688_1f80da22f45a,019d4e3d-1265-72f9-5136-f47ea119947d
CPLA,50,5,60,20260326152808 ,ADAS_S751NX0Y601865J_20260328113450259688_740131f6e72c,019d4e3d-1648-7d56-6fed-02716eb149a1
CPLA,50,5,60,20260326153031 ,ADAS_S751NX0Y601865J_20260328113450259688_336615afba11,019d4e3d-1868-7ca0-40e5-9ff09ddffe7f
CBLA,50,15,20,20260326155847 ,ADAS_S751NX0Y601865J_20260328113450259688_f55db8debcca,019d4e3d-19f8-705e-4947-c5c339ea3a7e
CBLA,50,15,20,20260326160617 ,ADAS_S751NX0Y601865J_20260328113450259688_399b4adafe58,
CBLA,50,15,20,20260326160814 ,ADAS_S751NX0Y601865J_20260328113450259688_46197d491ed8,019d4e3d-1df4-7038-410e-a74a438c8492
CBLA,50,15,30,20260326161154 ,ADAS_S751NX0Y601865J_20260328113450259688_8d0bdc3af3ad,019d4e3d-2067-7e9f-5385-c9f53102dc7a
CBLA,50,15,30,20260326161642 ,ADAS_S751NX0Y601865J_20260328113450259688_fd8ae38ed3ef,019d4e3d-21e5-7ba9-4216-1c9ec4f957b1
CBLA,50,15,30,20260326161852 ,ADAS_S751NX0Y601865J_20260328113450259688_67fd2a079d1d,019d4e3d-252c-767d-6427-7d463f865b10
CBLA,50,15,40,20260326162136 ,ADAS_S751NX0Y601865J_20260328113450259688_900166524e3b,019d4e3d-26b5-7856-4050-a96f6d200ebf
CBLA,50,15,40,20260326162358 ,ADAS_S751NX0Y601865J_20260328113450259688_2b77ce9a349e,019d4e3d-285b-7116-6873-8216f98b58eb
CBLA,50,15,40,20260326164202 ,ADAS_S751NX0Y601865J_20260328113450259688_10e68e264ee3,019d4e3d-2cb1-710f-7f59-be9ef1322f47
CBLA,50,15,50,20260326164438 ,ADAS_S751NX0Y601865J_20260328113450259688_5241e2ff36e4,019d4e3d-2fbc-7e19-4ed4-c295ad9c20ac
CBLA,50,15,50,20260326170202 ,ADAS_S751NX0Y601865J_20260328113450259688_347a11543c73,019d4e3d-31d4-71d1-4caa-34a546a296d1
CBLA,50,15,50,20260326171109 ,ADAS_S751NX0Y601865J_20260328113450259688_490ba9b95ba9,019d4e3d-34d6-7187-7af0-e97fe079a772
CBLA,50,15,60,20260326173610 ,ADAS_S751NX0Y601865J_20260328113450259688_559e79696f59,019d4e3d-36bf-7f87-6320-146481b08c2d
CBLA,50,15,60,20260326174513 ,ADAS_S751NX0Y601865J_20260328113450259688_183e46d60337,019d4e3d-3da9-79fc-4523-a80b6d5d9bb9
CBLA,50,15,60,20260326174803 ,ADAS_S751NX0Y601865J_20260328113450259688_1ced9e7a5ff4,019d4e3d-3f8f-7736-5f1c-ce5b7bebe985
CCRS,100,0,20,20260327150038 ,ADAS_S751NX0Y601739V_20260330104120600319_4b079fa4769c,019d4e3d-40e4-7952-5bb1-61a7bcc26ffb
CCRS,100,0,20,20260327150639 ,ADAS_S751NX0Y601739V_20260330104120600319_c06f5150f502,019d4e3d-44be-7fc4-47b9-93647ce7ba13
CCRS,100,0,20,20260327150850 ,ADAS_S751NX0Y601739V_20260330104120600319_96c7a7f2338c,019d4e3d-468a-7907-7be3-089462e21801
CCRS,100,0,30,20260327151710 ,ADAS_S751NX0Y601739V_20260330104120600319_eb5e6353a9b5,019d4e3d-47c3-75b5-4f06-ccfaddeea596
CCRS,100,0,30,20260327152708 ,ADAS_S751NX0Y601739V_20260330104120600319_c84cd8106f77,019d4e3d-494d-7344-74d1-727fd772dcc1
CCRS,100,0,30,20260327153617 ,ADAS_S751NX0Y601739V_20260330104120600319_4f029dbe74a6,019d4e3d-4a66-7f48-67ca-80af46768fe1
CCRS,100,0,40,20260327155538 ,ADAS_S751NX0Y601739V_20260330104120600319_eb4efa485513,019d4e3d-4c25-7fba-5495-c3c37583bbd8
CCRS,100,0,40,20260327155725 ,ADAS_S751NX0Y601739V_20260330104120600319_44d7b1f69620,019d4e3d-4d42-7371-68d9-ca2c9aabf4e1
CCRS,100,0,40,20260327160636 ,ADAS_S751NX0Y601739V_20260330104120600319_5e14779592f2,019d4e3d-4f36-7b47-646a-e95d51125e0a
CCRS,-50,0,20,20260327163408 ,ADAS_S751NX0Y601739V_20260330104120600319_2bcd36764fdc,019d4e3d-508d-7ec6-7cfd-29f4aa246b5c
CCRS,-50,0,20,20260327164715 ,ADAS_S751NX0Y601739V_20260330104120600319_25960516b170,019d4e3d-51ce-7b1d-4f14-d1d4fad73a00
CCRS,-50,0,20,20260327164844 ,ADAS_S751NX0Y601739V_20260330104120600319_b8ffb91ad5b3,019d4e3d-531b-7ae0-4080-72022af1d85c
CCRS,50,0,30,20260329094430 ,ADAS_S5STNF0T504465N_20260330162214124146_420efd665249,019d4e3d-54d6-7380-7e9d-11e13181980b
CCRS,50,0,30,20260329100613 ,ADAS_S5STNF0T504465N_20260330162214124146_64601c7323b8,019d4e3d-5668-7402-6156-3331c9cbb71f
CCRS,50,0,30,20260329114336 ,ADAS_S5STNF0T504465N_20260330162214124146_c68c2ee15588,019d4e3d-5960-7d08-58b4-2f72cd3c7b77
CCRS,50,0,30,20260329115057 ,ADAS_S5STNF0T504465N_20260330162214124146_22ec55135ffb,019d4e3d-5bec-763f-663a-7dd9be2d546c
CCRS,50,0,30,20260329115326 ,ADAS_S5STNF0T504465N_20260330162214124146_73d6bf86aabf,019d4e3d-5d6d-7c5c-479c-7e86d4ab824a
CCRS,-50,0,40,20260329115744 ,ADAS_S5STNF0T504465N_20260330162214124146_7d8bc5e99bd8,019d4e3d-605b-75a0-68cb-347da7344e2d
CCRS,-50,0,40,20260329115942 ,ADAS_S5STNF0T504465N_20260330162214124146_544d794c895a,019d4e3d-629e-78d2-5f06-c7a8339aa887
CCRS,-50,0,40,20260329120223 ,ADAS_S5STNF0T504465N_20260330162214124146_28f2102c8b7d,019d4e3d-65e2-71da-7a8a-bf3a11b84ea4
CCRS,100,0,40,20260329152947 ,ADAS_S5STNF0T504465N_20260330162214124146_8dcc9b350e60,019d4e3d-6cae-7d7f-4116-51f1ad23650e
CCRS,100,0,40,20260329153103 ,ADAS_S5STNF0T504465N_20260330162214124146_d0ab7bbf15e6,019d4e3d-6f92-7051-57ea-3a0ab52f7f9b
CCRS,100,0,40,20260329153211 ,ADAS_S5STNF0T504465N_20260330162214124146_942230bcc8f5,019d4e3d-714a-7d3e-400a-a13ca0391193
CCRS,100,0,50,20260329154203 ,ADAS_S5STNF0T504465N_20260330162214124146_e0dfc76d03a5,019d4e3d-7594-7679-5955-52a47aa749a2
CCRS,100,0,50,20260329154536 ,ADAS_S5STNF0T504465N_20260330162214124146_a82545a4fac4,019d4e3d-78ea-7eb9-6861-84dec1bda1a5
CCRS,100,0,60,20260329154719 ,ADAS_S5STNF0T504465N_20260330162214124146_6bc547d69cf8,019d4e3d-7f2a-7f1f-5631-91ff2c42af27
CCRS,100,0,60,20260329154913 ,ADAS_S5STNF0T504465N_20260330162214124146_0491e7efbd55,019d4e3d-8410-77cd-6dae-e0bf501b5304
1 scene offset gvt_speed vut_speed datetime rawid data_path
2 CPFA 25 6.5 20 20260323113612 ADAS_S751NX0Y800506T_20260327120535206279_a18b17bc1454 019d4e3a-78d3-7dc4-4e33-e871f9c3e15a
3 CPFA 25 6.5 20 20260323113832 ADAS_S751NX0Y800506T_20260327120535206279_ff61c208d184 019d4e3a-8f48-77d9-5f70-43bee3eab1c5
4 CPFA 25 6.5 30 20260323114629 ADAS_S751NX0Y800506T_20260327120535206279_2f11a63355c7 019d4e3a-90ad-7f00-7798-5551095fb4b5
5 CPFA 25 6.5 30 20260323114938 ADAS_S751NX0Y800506T_20260327120535206279_eba8998fb8a3 019d4e3a-9441-7d17-63dc-b773bd467ae5
6 CPFA 25 6.5 40 20260323140108 ADAS_S751NX0Y800506T_20260327120535206279_6429dd74f911 019d4e3a-974f-751c-5b3b-46c0a9364466
7 CPFA 25 6.5 40 20260323140816 ADAS_S751NX0Y800506T_20260327120535206279_2a6aca204419 019d4e3a-99de-7e5a-56d4-83547bd8ac34
8 CPFA 25 6.5 40 20260323141946 ADAS_S751NX0Y800506T_20260327120535206279_b527f4357559 019d4e3a-9bb0-7755-66c9-8fdd3770f67f
9 CPFA 25 6.5 50 20260323142206 ADAS_S751NX0Y800506T_20260327120535206279_468f64aaaaed 019d4e3a-9cf4-7d35-4e0c-52952c05537d
10 CPFA 25 6.5 50 20260323142435 ADAS_S751NX0Y800506T_20260327120535206279_72e20dc77396 019d4e3a-9f08-7500-6382-44bacad5f1ed
11 CPFA 25 6.5 50 20260323142614 ADAS_S751NX0Y800506T_20260327120535206279_f0a4e2c2f8de 019d4e3a-a07a-7aa1-5981-8977d03402dc
12 CPFA 25 6.5 60 20260323150051 ADAS_S751NX0Y800506T_20260327120535206279_8c30e32b75da 019d4e3a-ac12-74ae-5d1b-7ddca8db7feb
13 CPFA 25 6.5 60 20260323150956 ADAS_S751NX0Y800506T_20260327120535206279_597b22308c0c 019d4e3a-af07-7d2b-79ed-cce2054427b2
14 CPFA 25 6.5 60 20260323151226 ADAS_S751NX0Y800506T_20260327120535206279_920d06aa0c83 019d4e3a-b05e-7499-7cc0-c3b75d576e8c
15 CPFA 50 6.5 20 20260322152509 ADAS_S751NX0Y800506T_20260327120535206279_1b6644577499 019d4e3a-b72a-702f-7485-de4f36c19291
16 CPFA 50 6.5 20 20260322152819 ADAS_S751NX0Y800506T_20260327120535206279_3f4043e7c43b 019d4e3a-b87b-7ba7-770a-56ab7e461dd2
17 CPFA 50 6.5 20 20260322153301 ADAS_S751NX0Y800506T_20260327120535206279_f00ed7674617 019d4e3a-bb94-77e0-6de8-aa85930f28e8
18 CPFA 50 6.5 30 20260322153555 ADAS_S751NX0Y800506T_20260327120535206279_8fc6b6b738b3 019d4e3a-c417-7fe5-7eea-e1096344665b
19 CPFA 50 6.5 30 20260322153820 ADAS_S751NX0Y800506T_20260327120535206279_55177e3ae374 019d4e3a-c676-76d2-77b1-d498fad94160
20 CPFA 50 6.5 30 20260322154017 ADAS_S751NX0Y800506T_20260327120535206279_82b9ead31ef0 019d4e3a-c989-7b2f-67f3-08cabcfa7a97
21 CPFA 50 6.5 40 20260323111334 ADAS_S751NX0Y800506T_20260327120535206279_7ec23297755f 019d4e3a-d5b5-7cbb-7add-b81d9d6da22f
22 CPFA 50 6.5 40 20260323111522 ADAS_S751NX0Y800506T_20260327120535206279_2f655a7f3faa 019d4e3a-d858-72f8-6e5a-4de5471314f0
23 CPFA 50 6.5 40 20260323111755 ADAS_S751NX0Y800506T_20260327120535206279_00dd9a4dda13 019d4e3a-db87-7799-66c7-96a11b425725
24 CPFA 50 6.5 50 20260323112055 ADAS_S751NX0Y800506T_20260327120535206279_08404d05ab99 019d4e3a-ddc1-749a-523f-bfa54c6ab4b9
25 CPFA 50 6.5 50 20260323112255 ADAS_S751NX0Y800506T_20260327120535206279_7bda3d59284b 019d4e3a-e154-7114-4619-a60849eb771a
26 CPFA 50 6.5 50 20260323112515 ADAS_S751NX0Y800506T_20260327120535206279_523828701c91 019d4e3a-e764-7634-765c-6178bb27739d
27 CPFA 50 6.5 60 20260323112758 ADAS_S751NX0Y800506T_20260327120535206279_5c77b0c2fc61 019d4e3a-ea48-7eb9-6720-7ba5e0a38877
28 CPFA 50 6.5 60 20260323113007 ADAS_S751NX0Y800506T_20260327120535206279_16986d99d73c 019d4e3a-ed5d-7426-7143-8cb7870c8a53
29 CPFA 50 6.5 60 20260323113249 ADAS_S751NX0Y800506T_20260327120535206279_7fa179422fa9 019d4e3a-f0d1-760d-64c4-0bf331a399f7
30 CPNA 25 5 20 20260322160034 ADAS_S751NX0Y800506T_20260327120535206279_bfa3bdb3ecfa 019d4e3a-f35c-7f56-6350-fdae7d030520
31 CPNA 25 5 20 20260322161344 ADAS_S751NX0Y800506T_20260327120535206279_4d845a8f0558 019d4e3a-f744-7cd1-7260-2a17dc2fd996
32 CPNA 25 5 20 20260322162319 ADAS_S751NX0Y800506T_20260327120535206279_bb2b77bf7e71 019d4e3a-fa3c-7bc2-75b0-d676f2d12eaa
33 CPNA 25 5 30 20260322162901 ADAS_S751NX0Y800506T_20260327120535206279_a4e2d3b50dfc 019d4e3b-0c47-76bc-6f13-9bac1a818536
34 CPNA 25 5 30 20260322163412 ADAS_S751NX0Y800506T_20260327120535206279_34ec8bc7c628 019d4e3b-0e7c-7347-49c1-b70b0caa6010
35 CPNA 25 5 30 20260322163631 ADAS_S751NX0Y800506T_20260327120535206279_a398a2f1d31d 019d4e3b-1077-77d3-570a-71463fe4e9c8
36 CPNA 25 5 40 20260322172726 ADAS_S751NX0Y800506T_20260327120535206279_62a7fe51f78a 019d4e3b-2f89-775e-6fb8-1de28a664495
37 CPNA 25 5 40 20260322173110 ADAS_S751NX0Y800506T_20260327120535206279_525d3358ef99 019d4e3b-337f-714b-60b4-8e87df7f7a51
38 CPNA 25 5 40 20260322173530 ADAS_S751NX0Y800506T_20260327120535206279_2926f0bbdeb6 019d4e3b-3606-7e91-7816-2b9d0ad07dcd
39 CPNA 25 5 50 20260324161933 ADAS_S751NX0Y800506T_20260327120535206279_d74d2d3f578d 019d4e3b-4fba-707b-4a28-1ac6277145ba
40 CPNA 25 5 50 20260331151009 ADAS_S5STNF0T406280R_20260402104850269428_0785a9b23943 019d4e3b-5213-7f0d-7fc9-18a3051690f7
41 CPNA 25 5 50 20260331151250 ADAS_S5STNF0T406280R_20260402104850269428_f0cf082bc503 019d4e3b-541b-787d-6ae6-3da8fb8e1139
42 CPNA 25 5 60 20260324164151 ADAS_S751NX0Y800506T_20260327120535206279_7b3031a15f43 019d4e3b-5bf2-7e3a-49df-56bc4f07fb62
43 CPNA 25 5 60 20260324165218 ADAS_S751NX0Y800506T_20260327120535206279_ef49250e9812 019d4e3b-5e24-7249-4bb6-bdd243110001
44 CPNA 25 5 60 20260331151834 ADAS_S5STNF0T406280R_20260402104850269428_f8705c0133fa 019d4e3b-6076-7ede-73a3-afdfd283b7b4
45 CPNA 75 5 20 20260322173859 ADAS_S751NX0Y800506T_20260327120535206279_f91ce01108fe 019d4e3b-6900-71f3-4685-a4332df5f883
46 CPNA 75 5 20 20260322174119 ADAS_S751NX0Y800506T_20260327120535206279_ab63c70e43b8 019d4e3b-6b7c-72e8-56ea-2d6eac52ab30
47 CPNA 75 5 20 20260322174325 ADAS_S751NX0Y800506T_20260327120535206279_56c1d30ff57b 019d4e3b-70f6-76a1-5812-f8db1c73e627
48 CPNA 75 5 30 20260322175205 ADAS_S751NX0Y800506T_20260327120535206279_fdada52e9fa5 019d4e3b-92d0-7fd2-66c2-f2a1d1e81e6f
49 CPNA 75 5 30 20260322175649 ADAS_S751NX0Y800506T_20260327120535206279_89d41fb8d2e8 019d4e3b-9663-7d48-55b8-2af349c18284
50 CPNA 75 5 30 20260322175850 ADAS_S751NX0Y800506T_20260327120535206279_bbe31db90e0a 019d4e3b-9acb-7387-6b18-466c0534a3bc
51 CPNA 75 5 40 20260324171844 ADAS_S751NX0Y800506T_20260327120535206279_44a743580dac 019d4e3b-a6ff-7af5-6b3b-38fcdf52e12b
52 CPNA 75 5 40 20260324172117 ADAS_S751NX0Y800506T_20260327120535206279_51afa9e84ca0 019d4e3b-a8c6-736e-7dea-bfbdd73fd93a
53 CPNA 75 5 40 20260331163021 ADAS_S5STNF0T406280R_20260402104850269428_5c97beda0356 019d4e3b-ac9d-7dd8-41a7-f7c7838e4471
54 CPNA 75 5 50 20260324172350 ADAS_S751NX0Y800506T_20260327120535206279_1e84d8ee3c5e 019d4e3b-b426-7c52-70ec-4433ffa93589
55 CPNA 75 5 50 20260324172558 ADAS_S751NX0Y800506T_20260327120535206279_e9d1fb808bed 019d4e3b-b6ec-74ca-533a-d50dd4c6bc76
56 CPNA 75 5 50 20260324172833 ADAS_S751NX0Y800506T_20260327120535206279_16007a77b8e3 019d4e3b-cd62-7eb6-7a95-60a64da7c7ce
57 CPNA 75 5 60 20260324173139 ADAS_S751NX0Y800506T_20260327120535206279_ef6e0008db8a 019d4e3b-da82-7e0d-4d74-b59da953ecff
58 CPNA 75 5 60 20260324173924 ADAS_S751NX0Y800506T_20260327120535206279_84ce75f29b5b 019d4e3b-df7a-7e7b-44a7-226205b4213f
59 CPNA 75 5 60 20260324174238 ADAS_S751NX0Y800506T_20260327120535206279_76553de00e52 019d4e3b-e195-75cc-687b-e6c9c642ee54
60 CBNA 50 15 20 20260325112105 ADAS_S751NX0Y800506T_20260327120535206279_c7ff38958fa1 019d4e3b-ea01-7a92-63ee-4854e139ed23
61 CBNA 50 15 20 20260325120919 ADAS_S751NX0Y800506T_20260327120535206279_aaa5e92f1b8d 019d4e3b-ee98-7208-7e05-184f40aad9c6
62 CBNA 50 15 20 20260325140126 ADAS_S751NX0Y800506T_20260327120535206279_72d0b390d41b 019d4e3b-f52d-702d-49bd-86c2a007937f
63 CBNA 50 15 30 20260325142826 ADAS_S751NX0Y800506T_20260327120535206279_d3da82eff0a1 019d4e3c-03d5-72ff-5fdc-d798dafc0689
64 CBNA 50 15 30 20260325144228 ADAS_S751NX0Y800506T_20260327120535206279_81bd7a6856f8 019d4e3c-06ff-7af8-4b52-45705976b906
65 CBNA 50 15 30 20260325144443 ADAS_S751NX0Y800506T_20260327120535206279_e07712df8814 019d4e3c-08e9-72f3-721c-460d3da8b41c
66 CBNA 50 15 40 20260325145316 ADAS_S751NX0Y800506T_20260327120535206279_5f75b8004ae5 019d4e3c-39e9-760e-428f-80a856bbb683
67 CBNA 50 15 40 20260325145539 ADAS_S751NX0Y800506T_20260327120535206279_b3de854ceea1 019d4e3c-3e78-765c-5f1c-672330e51957
68 CBNA 50 15 40 20260325145759 ADAS_S751NX0Y800506T_20260327120535206279_4c2cc3a4581f 019d4e3c-403d-73af-7310-dc91edbc687a
69 CBNA 50 15 50 20260325150059 ADAS_S751NX0Y800506T_20260327120535206279_3ab5c9fb09e8 019d4e3c-4a59-70ac-5799-76424e4a5926
70 CBNA 50 15 50 20260325150516 ADAS_S751NX0Y800506T_20260327120535206279_c548265438c0 019d4e3c-4cce-7267-5cab-81c5a8147465
71 CBNA 50 15 50 20260325151329 ADAS_S751NX0Y800506T_20260327120535206279_56ec7f3f0a9f 019d4e3c-5023-7469-594c-0aca8726e58f
72 CBNA 50 15 60 20260325153201 ADAS_S751NX0Y800506T_20260327120535206279_079e46de1e69 019d4e3c-5bee-7dd7-5ca1-d6bc06862db6
73 CBNA 50 15 60 20260325153627 ADAS_S751NX0Y800506T_20260327120535206279_e7bd46fa5526 019d4e3c-5dc6-710b-616c-56a91c34b928
74 CBNA 50 15 60 20260401105118 ADAS_S5STNF0T504465N_20260402191154995992_98b65d35a0e8 019d4e3c-60fa-7d56-61ab-078cd6e38af5
75 CSFA 50 20 30 20260325160450 ADAS_S751NX0Y800506T_20260327120535206279_3db3d3c5f75e 019d4e3c-6e6e-7d1a-79af-39cd8a4a54d8
76 CSFA 50 20 30 20260325163344 ADAS_S751NX0Y800506T_20260327120535206279_8b26b8678563 019d4e3c-70c7-7a72-5dac-25eb86983968
77 CSFA 50 20 30 20260325163640 ADAS_S751NX0Y800506T_20260327120535206279_048ca75c2b68 019d4e3c-7352-738d-47ab-2ea8eca8d7ad
78 CSFA 50 20 30 20260401112255 ADAS_S5STNF0T504465N_20260402191154995992_8c840c39ed44 019d4e3c-7a18-7597-71b1-31f9ece82944
79 CSFA 50 20 40 20260325164019 ADAS_S751NX0Y800506T_20260327120535206279_71ba721054d2 019d4e3c-7cd2-7485-64a3-52d954e956fe
80 CSFA 50 20 40 20260325164557 ADAS_S751NX0Y800506T_20260327120535206279_101c937f632e 019d4e3c-8191-7c57-64a2-b21ce84ecc08
81 CSFA 50 20 40 20260325165101 ADAS_S751NX0Y800506T_20260327120535206279_0039e9c4f44c 019d4e3c-84d1-7496-4cf5-55f849f06c6d
82 CSFA 50 20 50 20260325165344 ADAS_S751NX0Y800506T_20260327120535206279_35f7055b3936 019d4e3c-9254-795a-5d2c-e1c38b47f6f1
83 CSFA 50 20 50 20260325165620 ADAS_S751NX0Y800506T_20260327120535206279_cae0b056a639 019d4e3c-95e3-7c5c-6c3e-0d97a6aa300e
84 CSFA 50 20 50 20260325170106 ADAS_S751NX0Y800506T_20260327120535206279_a3b60a4417f1 019d4e3c-9881-768a-447c-063b27c49a4d
85 CSFA 50 20 60 20260325170448 ADAS_S751NX0Y800506T_20260327120535206279_9cf23dfe1aa7 019d4e3c-a794-7de1-70b6-cf64d043298a
86 CSFA 50 20 60 20260325171905 ADAS_S751NX0Y800506T_20260327120535206279_f05823ea3fb0 019d4e3c-aa4d-7285-60da-b503786e136d
87 CSFA 50 20 60 20260325172254 ADAS_S751NX0Y800506T_20260327120535206279_095c61152216 019d4e3c-ae93-7858-6a24-810c5f1e62db
88 CCRM 100 20 30 20260327110922 ADAS_S751NX0Y601739V_20260330104120600319_d9c5e242cd43 019d4e3c-bb28-73bc-5211-83d63bdf0ca9
89 CCRM 100 20 30 20260327111430 ADAS_S751NX0Y601739V_20260330104120600319_49f67f0f4c84 019d4e3c-becf-7df4-6697-fd1e7359b44e
90 CCRM 100 20 30 20260327112148 ADAS_S751NX0Y601739V_20260330104120600319_71c00fa5c46c 019d4e3c-c0e6-7ada-63e8-f2e7cd2ee7fa
91 CCRM 100 20 40 20260327113709 ADAS_S751NX0Y601739V_20260330104120600319_310c2fb9e063 019d4e3c-c8a5-7b63-5fb9-f9847ca1baa9
92 CCRM 100 20 40 20260327115052 ADAS_S751NX0Y601739V_20260330104120600319_9fde171dd0c5 019d4e3c-cb80-712f-46e5-36af2aad17f8
93 CCRM 100 20 40 20260327115408 ADAS_S751NX0Y601739V_20260330104120600319_89971a38a795 019d4e3c-cd63-776f-7608-9f922d1902d2
94 CPLA 25 5 20 20260325175106 ADAS_S751NX0Y800506T_20260327120535206279_67c2c4cfdcfa 019d4e3c-d4b2-79f9-4ed1-4ecb7b0194c8
95 CPLA 25 5 20 20260325180145 ADAS_S751NX0Y800506T_20260327120535206279_6c216f1d5e73 019d4e3c-d864-7799-5a0b-28bb4f33acb4
96 CPLA 25 5 20 20260325180337 ADAS_S751NX0Y800506T_20260327120535206279_42d78cae79e4 019d4e3c-da58-73c5-491e-6974c7368238
97 CPLA 25 5 30 20260325180602 ADAS_S751NX0Y800506T_20260327120535206279_305900bb160b 019d4e3c-dc9f-704f-5b1a-2fe724439ca6
98 CPLA 25 5 30 20260325180857 ADAS_S751NX0Y800506T_20260327120535206279_d72d2f1eab33 019d4e3c-df35-7734-69cb-a4d0c67e80d9
99 CPLA 25 5 30 20260325181249 ADAS_S751NX0Y800506T_20260327120535206279_e65e2e8bb2c3 019d4e3c-e27f-739a-7823-ae3a8cf49aba
100 CPLA 25 5 40 20260326112939 ADAS_S751NX0Y601865J_20260328113450259688_7e273228d47b 019d4e3c-e3c2-73ee-6b22-fb2ac8a75c73
101 CPLA 25 5 40 20260326113327 ADAS_S751NX0Y601865J_20260328113450259688_cf29bc58f910 019d4e3c-e511-7249-7c25-e69e8452d486
102 CPLA 25 5 40 20260326120929 ADAS_S751NX0Y601865J_20260328113450259688_19aa5768291c 019d4e3c-e781-7c8d-4873-f1d931f483d6
103 CPLA 50 5 20 20260326141456 ADAS_S751NX0Y601865J_20260328113450259688_7089abe3283f 019d4e3c-ee0a-7f12-6936-b8f2fd8f17ad
104 CPLA 50 5 20 20260326141816 ADAS_S751NX0Y601865J_20260328113450259688_968bbf10d481
105 CPLA 50 5 20 20260326143002 ADAS_S751NX0Y601865J_20260328113450259688_253cc2246a46 019d4e3c-f166-7b61-46eb-6b2c216bfff8
106 CPLA 50 5 30 20260326143325 ADAS_S751NX0Y601865J_20260328113450259688_890e13a19330 019d4e3c-f4c9-7b4a-4c86-0ffd3898c96f
107 CPLA 50 5 30 20260326143553 ADAS_S751NX0Y601865J_20260328113450259688_208c31032ab7 019d4e3c-f78b-77e7-53c3-ae06b3ae3b66
108 CPLA 50 5 30 20260326143953 ADAS_S751NX0Y601865J_20260328113450259688_31374e23ea52 019d4e3c-f8e0-74f6-461a-e2b03ec26f0b
109 CPLA 50 5 40 20260326144301 ADAS_S751NX0Y601865J_20260328113450259688_11edf0db8552 019d4e3c-fac9-7171-6894-a4a295f2aee3
110 CPLA 50 5 40 20260326144521 ADAS_S751NX0Y601865J_20260328113450259688_88f480b20482 019d4e3c-fc5e-76c8-783e-c95921d6db7c
111 CPLA 50 5 40 20260326144728 ADAS_S751NX0Y601865J_20260328113450259688_010690530eb1 019d4e3c-fe9d-7724-5895-96d271ac56b4
112 CPLA 50 5 50 20260326145318 ADAS_S751NX0Y601865J_20260328113450259688_e8f3c0c2d8e7 019d4e3d-0304-7a98-47bf-a2123c57756e
113 CPLA 50 5 50 20260326150327 ADAS_S751NX0Y601865J_20260328113450259688_a44f950ae272 019d4e3d-0714-7346-4218-45001f0df930
114 CPLA 50 5 50 20260326152042 ADAS_S751NX0Y601865J_20260328113450259688_13132ea06b7c 019d4e3d-097c-7c4e-6f7a-a5514e19ae85
115 CPLA 50 5 60 20260326152355 ADAS_S751NX0Y601865J_20260328113450259688_1f80da22f45a 019d4e3d-1265-72f9-5136-f47ea119947d
116 CPLA 50 5 60 20260326152808 ADAS_S751NX0Y601865J_20260328113450259688_740131f6e72c 019d4e3d-1648-7d56-6fed-02716eb149a1
117 CPLA 50 5 60 20260326153031 ADAS_S751NX0Y601865J_20260328113450259688_336615afba11 019d4e3d-1868-7ca0-40e5-9ff09ddffe7f
118 CBLA 50 15 20 20260326155847 ADAS_S751NX0Y601865J_20260328113450259688_f55db8debcca 019d4e3d-19f8-705e-4947-c5c339ea3a7e
119 CBLA 50 15 20 20260326160617 ADAS_S751NX0Y601865J_20260328113450259688_399b4adafe58
120 CBLA 50 15 20 20260326160814 ADAS_S751NX0Y601865J_20260328113450259688_46197d491ed8 019d4e3d-1df4-7038-410e-a74a438c8492
121 CBLA 50 15 30 20260326161154 ADAS_S751NX0Y601865J_20260328113450259688_8d0bdc3af3ad 019d4e3d-2067-7e9f-5385-c9f53102dc7a
122 CBLA 50 15 30 20260326161642 ADAS_S751NX0Y601865J_20260328113450259688_fd8ae38ed3ef 019d4e3d-21e5-7ba9-4216-1c9ec4f957b1
123 CBLA 50 15 30 20260326161852 ADAS_S751NX0Y601865J_20260328113450259688_67fd2a079d1d 019d4e3d-252c-767d-6427-7d463f865b10
124 CBLA 50 15 40 20260326162136 ADAS_S751NX0Y601865J_20260328113450259688_900166524e3b 019d4e3d-26b5-7856-4050-a96f6d200ebf
125 CBLA 50 15 40 20260326162358 ADAS_S751NX0Y601865J_20260328113450259688_2b77ce9a349e 019d4e3d-285b-7116-6873-8216f98b58eb
126 CBLA 50 15 40 20260326164202 ADAS_S751NX0Y601865J_20260328113450259688_10e68e264ee3 019d4e3d-2cb1-710f-7f59-be9ef1322f47
127 CBLA 50 15 50 20260326164438 ADAS_S751NX0Y601865J_20260328113450259688_5241e2ff36e4 019d4e3d-2fbc-7e19-4ed4-c295ad9c20ac
128 CBLA 50 15 50 20260326170202 ADAS_S751NX0Y601865J_20260328113450259688_347a11543c73 019d4e3d-31d4-71d1-4caa-34a546a296d1
129 CBLA 50 15 50 20260326171109 ADAS_S751NX0Y601865J_20260328113450259688_490ba9b95ba9 019d4e3d-34d6-7187-7af0-e97fe079a772
130 CBLA 50 15 60 20260326173610 ADAS_S751NX0Y601865J_20260328113450259688_559e79696f59 019d4e3d-36bf-7f87-6320-146481b08c2d
131 CBLA 50 15 60 20260326174513 ADAS_S751NX0Y601865J_20260328113450259688_183e46d60337 019d4e3d-3da9-79fc-4523-a80b6d5d9bb9
132 CBLA 50 15 60 20260326174803 ADAS_S751NX0Y601865J_20260328113450259688_1ced9e7a5ff4 019d4e3d-3f8f-7736-5f1c-ce5b7bebe985
133 CCRS 100 0 20 20260327150038 ADAS_S751NX0Y601739V_20260330104120600319_4b079fa4769c 019d4e3d-40e4-7952-5bb1-61a7bcc26ffb
134 CCRS 100 0 20 20260327150639 ADAS_S751NX0Y601739V_20260330104120600319_c06f5150f502 019d4e3d-44be-7fc4-47b9-93647ce7ba13
135 CCRS 100 0 20 20260327150850 ADAS_S751NX0Y601739V_20260330104120600319_96c7a7f2338c 019d4e3d-468a-7907-7be3-089462e21801
136 CCRS 100 0 30 20260327151710 ADAS_S751NX0Y601739V_20260330104120600319_eb5e6353a9b5 019d4e3d-47c3-75b5-4f06-ccfaddeea596
137 CCRS 100 0 30 20260327152708 ADAS_S751NX0Y601739V_20260330104120600319_c84cd8106f77 019d4e3d-494d-7344-74d1-727fd772dcc1
138 CCRS 100 0 30 20260327153617 ADAS_S751NX0Y601739V_20260330104120600319_4f029dbe74a6 019d4e3d-4a66-7f48-67ca-80af46768fe1
139 CCRS 100 0 40 20260327155538 ADAS_S751NX0Y601739V_20260330104120600319_eb4efa485513 019d4e3d-4c25-7fba-5495-c3c37583bbd8
140 CCRS 100 0 40 20260327155725 ADAS_S751NX0Y601739V_20260330104120600319_44d7b1f69620 019d4e3d-4d42-7371-68d9-ca2c9aabf4e1
141 CCRS 100 0 40 20260327160636 ADAS_S751NX0Y601739V_20260330104120600319_5e14779592f2 019d4e3d-4f36-7b47-646a-e95d51125e0a
142 CCRS -50 0 20 20260327163408 ADAS_S751NX0Y601739V_20260330104120600319_2bcd36764fdc 019d4e3d-508d-7ec6-7cfd-29f4aa246b5c
143 CCRS -50 0 20 20260327164715 ADAS_S751NX0Y601739V_20260330104120600319_25960516b170 019d4e3d-51ce-7b1d-4f14-d1d4fad73a00
144 CCRS -50 0 20 20260327164844 ADAS_S751NX0Y601739V_20260330104120600319_b8ffb91ad5b3 019d4e3d-531b-7ae0-4080-72022af1d85c
145 CCRS 50 0 30 20260329094430 ADAS_S5STNF0T504465N_20260330162214124146_420efd665249 019d4e3d-54d6-7380-7e9d-11e13181980b
146 CCRS 50 0 30 20260329100613 ADAS_S5STNF0T504465N_20260330162214124146_64601c7323b8 019d4e3d-5668-7402-6156-3331c9cbb71f
147 CCRS 50 0 30 20260329114336 ADAS_S5STNF0T504465N_20260330162214124146_c68c2ee15588 019d4e3d-5960-7d08-58b4-2f72cd3c7b77
148 CCRS 50 0 30 20260329115057 ADAS_S5STNF0T504465N_20260330162214124146_22ec55135ffb 019d4e3d-5bec-763f-663a-7dd9be2d546c
149 CCRS 50 0 30 20260329115326 ADAS_S5STNF0T504465N_20260330162214124146_73d6bf86aabf 019d4e3d-5d6d-7c5c-479c-7e86d4ab824a
150 CCRS -50 0 40 20260329115744 ADAS_S5STNF0T504465N_20260330162214124146_7d8bc5e99bd8 019d4e3d-605b-75a0-68cb-347da7344e2d
151 CCRS -50 0 40 20260329115942 ADAS_S5STNF0T504465N_20260330162214124146_544d794c895a 019d4e3d-629e-78d2-5f06-c7a8339aa887
152 CCRS -50 0 40 20260329120223 ADAS_S5STNF0T504465N_20260330162214124146_28f2102c8b7d 019d4e3d-65e2-71da-7a8a-bf3a11b84ea4
153 CCRS 100 0 40 20260329152947 ADAS_S5STNF0T504465N_20260330162214124146_8dcc9b350e60 019d4e3d-6cae-7d7f-4116-51f1ad23650e
154 CCRS 100 0 40 20260329153103 ADAS_S5STNF0T504465N_20260330162214124146_d0ab7bbf15e6 019d4e3d-6f92-7051-57ea-3a0ab52f7f9b
155 CCRS 100 0 40 20260329153211 ADAS_S5STNF0T504465N_20260330162214124146_942230bcc8f5 019d4e3d-714a-7d3e-400a-a13ca0391193
156 CCRS 100 0 50 20260329154203 ADAS_S5STNF0T504465N_20260330162214124146_e0dfc76d03a5 019d4e3d-7594-7679-5955-52a47aa749a2
157 CCRS 100 0 50 20260329154536 ADAS_S5STNF0T504465N_20260330162214124146_a82545a4fac4 019d4e3d-78ea-7eb9-6861-84dec1bda1a5
158 CCRS 100 0 60 20260329154719 ADAS_S5STNF0T504465N_20260330162214124146_6bc547d69cf8 019d4e3d-7f2a-7f1f-5631-91ff2c42af27
159 CCRS 100 0 60 20260329154913 ADAS_S5STNF0T504465N_20260330162214124146_0491e7efbd55 019d4e3d-8410-77cd-6dae-e0bf501b5304

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
#!/bin/bash
# Batch inference over all cases in a mined eval dataset directory.
#
# Directory layout expected (produced by mine_balanced_eval_subset.py):
# EVAL_DIR/<date>/<case_uuid>/images/
# EVAL_DIR/<date>/<case_uuid>/calib/L2_calib/camera4.json
#
# Output mirrors the same structure under OUTPUT_DIR:
# OUTPUT_DIR/<date>/<case_uuid>/visualizations/
# OUTPUT_DIR/<date>/<case_uuid>/predictions/
# OUTPUT_DIR/<date>/<case_uuid>/predictions.json
#
# Usage:
# bash tools/model_inference/scripts/run_evalset_infer.sh
#
# Override defaults with environment variables:
# EVAL_DIR=... EXPORTED_MODEL=... OUTPUT_DIR=... bash tools/model_inference/scripts/run_evalset_infer.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
EVAL_DIR="${EVAL_DIR:-/data1/dongying/Mono3d/G1M3/data_for_alignment/mono3d_mining_val300}"
EXPORTED_MODEL="${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_202603291430-raw-fuse/merged_model.torchscript}"
OUTPUT_DIR="${OUTPUT_DIR:-${PROJECT_ROOT}/runs/test/evalset_infer_$(basename "${EVAL_DIR}")_new}"
ENABLE_ATTR="${ENABLE_ATTR:-1}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-0}"
ENABLE_VRU_MERGE="${ENABLE_VRU_MERGE:-1}"
if [[ ! -d "${EVAL_DIR}" ]]; then
echo "ERROR: EVAL_DIR does not exist: ${EVAL_DIR}" >&2
exit 1
fi
if [[ ! -f "${EXPORTED_MODEL}" ]]; then
echo "ERROR: EXPORTED_MODEL does not exist: ${EXPORTED_MODEL}" >&2
exit 1
fi
echo "Eval dir: ${EVAL_DIR}"
echo "Model : ${EXPORTED_MODEL}"
echo "Output : ${OUTPUT_DIR}"
echo ""
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/core/run_two_roi_exported_onnx_infer.py"
--eval-dir "${EVAL_DIR}"
--exported-model "${EXPORTED_MODEL}"
--output-dir "${OUTPUT_DIR}"
)
if [[ "${ENABLE_ATTR}" == "1" ]]; then
CMD+=(--enable-attr)
fi
if [[ "${ENABLE_CROSS_CLASS_MERGE_PRIOR}" == "1" ]]; then
CMD+=(--enable-cross-class-merge-prior)
fi
if [[ "${ENABLE_VRU_MERGE}" == "1" ]]; then
CMD+=(--enable-vru-merge)
fi
"${CMD[@]}"

View File

@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for Excel/CSV column extraction.
#
# Usage:
# bash tools/model_inference/scripts/run_extract_excel_column.sh
#
# Common env overrides:
# INPUT_FILE, COLUMN_NAME, SHEET_NAME, OUTPUT_FILE, JSON_FILE,
# DEDUPE, LIST_COLUMNS, EXTRA_ARGS
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
INPUT_FILE="${INPUT_FILE:-${MODEL_INFERENCE_DIR}/examples/cncap/G1M3_AFS1616_CNCAP-2024_11月_0306.xlsx}"
COLUMN_NAME="${COLUMN_NAME:-原始数据地址}"
SHEET_NAME="${SHEET_NAME:-}"
OUTPUT_FILE="${OUTPUT_FILE:-}"
JSON_FILE="${JSON_FILE:-}"
DEDUPE="${DEDUPE:-0}"
LIST_COLUMNS="${LIST_COLUMNS:-0}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/data_tools/extract_excel_column.py"
--input-file "${INPUT_FILE}"
--column-name "${COLUMN_NAME}"
)
if [[ -n "${SHEET_NAME}" ]]; then
CMD+=(--sheet-name "${SHEET_NAME}")
fi
if [[ -n "${OUTPUT_FILE}" ]]; then
CMD+=(--output-file "${OUTPUT_FILE}")
fi
if [[ -n "${JSON_FILE}" ]]; then
CMD+=(--json-file "${JSON_FILE}")
fi
if [[ "${DEDUPE}" == "1" ]]; then
CMD+=(--dedupe)
fi
if [[ "${LIST_COLUMNS}" == "1" ]]; then
CMD+=(--list-columns)
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
CMD+=("$@")
"${CMD[@]}"

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for scene-keyed CSV -> JSON conversion.
#
# Usage:
# bash tools/model_inference/scripts/run_parse_scene_csv_to_json.sh
#
# Common env overrides:
# INPUT_FILE, SCENE_COLUMN, OUTPUT_FILE, KEEP_SCENE_FIELD, EXTRA_ARGS
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
INPUT_FILE="${INPUT_FILE:-${MODEL_INFERENCE_DIR}/examples/events/G1Q3_场地评测数据集_0418.csv}"
SCENE_COLUMN="${SCENE_COLUMN:-scene}"
OUTPUT_FILE="${OUTPUT_FILE:-}"
KEEP_SCENE_FIELD="${KEEP_SCENE_FIELD:-0}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/data_tools/parse_scene_csv_to_json.py"
--input-file "${INPUT_FILE}"
--scene-column "${SCENE_COLUMN}"
)
if [[ -n "${OUTPUT_FILE}" ]]; then
CMD+=(--output-file "${OUTPUT_FILE}")
fi
if [[ "${KEEP_SCENE_FIELD}" == "1" ]]; then
CMD+=(--keep-scene-field)
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
CMD+=("$@")
"${CMD[@]}"

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
# Navigation launcher kept for convenience.
#
# Prefer using one of the mode-specific scripts directly:
# bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer_case.sh
# bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer_clip_list.sh
# bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer_cncap_json.sh
# bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer_event_json.sh
# bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer_video_case.sh
# bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer_video_root.sh
# bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer_mcap.sh
cat <<'EOF'
Available launchers:
1. run_two_roi_exported_onnx_infer_case.sh
2. run_two_roi_exported_onnx_infer_clip_list.sh
3. run_two_roi_exported_onnx_infer_cncap_json.sh
4. run_two_roi_exported_onnx_infer_event_json.sh
5. run_two_roi_exported_onnx_infer_video_case.sh
6. run_two_roi_exported_onnx_infer_video_root.sh
7. run_two_roi_exported_onnx_infer_mcap.sh
EOF

View File

@@ -0,0 +1,461 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for single case / eval-dir inference.
#
# Supported modes:
# 1. CASE_DIR=<case-dir>
# 2. EVAL_DIR=<eval-root>
# 3. INPUT_DIR=<case-dir-or-eval-root>
# 4. POSTPROCESS_ONLY=1 OUTPUT_DIR=<inference-output-root>
# 5. ENABLE_PARALLEL=1 GPU_IDS="0 1" INPUT_DIR=<eval-root>
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
CASE_DIR="${CASE_DIR:-}"
EVAL_DIR="${EVAL_DIR:-}"
# /data1/dongying/Mono3d/G1Q3/dataset_for_evaluation/DL_KPI_SCENE
# /data1/dongying/Mono3d/G1Q3/dataset_for_evaluation/OP_KPI_SCENE
# /data1/dongying/Mono3d/G1Q3/dataset_for_evaluation/OP_KPI_TRAFFIC_SCENARIO
# /data1/xdzhu/Testdata_0129
# /data1/xdzhu/Testdata_0129019b4415-d171-7ae9-88ed-0065c4c6e1e0
INPUT_DIR="${INPUT_DIR:-${EVAL_DIR:-/data1/dongying/Mono3d/G1Q3/dataset_for_evaluation/OP_KPI_SCENE}}"
# INPUT_DIR="${INPUT_DIR:-${CASE_DIR}}"
# The core inference script now auto-detects whether the exported model keeps the edge branch.
EXPORTED_MODEL="${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_20260506-keep_fake_3d_branch/merged_model.torchscript}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/KPI/OP_KPI_SCENE/model_20260506_all_cases}"
ENABLE_ATTR="${ENABLE_ATTR:-1}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}"
ENABLE_VRU_MERGE="${ENABLE_VRU_MERGE:-0}"
DEVICE="${DEVICE:-}"
ATTR_DEVICE="${ATTR_DEVICE:-}"
VIS_CLASSES="${VIS_CLASSES:-}"
VIS_CLASS_NAMES="${VIS_CLASS_NAMES:-}"
SAVE_VISUALIZATION="${SAVE_VISUALIZATION:-0}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
POSTPROCESS_ONLY="${POSTPROCESS_ONLY:-1}"
ENABLE_PARALLEL="${ENABLE_PARALLEL:-0}"
GPU_IDS="${GPU_IDS:-}"
NUM_SHARDS="${NUM_SHARDS:-1}"
SHARD_INDEX="${SHARD_INDEX:-0}"
SHARD_STRATEGY="${SHARD_STRATEGY:-round_robin}"
CASE_INDEX_START="${CASE_INDEX_START:-}"
CASE_INDEX_END="${CASE_INDEX_END:-}"
PARALLEL_LOG_DIR="${PARALLEL_LOG_DIR:-${OUTPUT_DIR%/}/parallel_logs}"
FORWARD_ARGS=("$@")
# Optional post-inference tracking stage. When enabled, the launcher reuses
# the exported-inference tracking wrapper, which runs track_objects.py over
# predictions/{roi0,roi1,merge} and merges the results per case.
ENABLE_TRACKING="${ENABLE_TRACKING:-0}"
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING:-0}"
TRACK_STRICT="${TRACK_STRICT:-1}"
TRACK_RESULTS_ROOT="${TRACK_RESULTS_ROOT:-${OUTPUT_DIR}}"
TRACK_CLASSES="${TRACK_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12}"
TRACK_IOU_THRESH="${TRACK_IOU_THRESH:-0.3}"
TRACK_MAX_AGE="${TRACK_MAX_AGE:-5}"
TRACK_MIN_HITS="${TRACK_MIN_HITS:-1}"
TRACK_DIST_THRESH="${TRACK_DIST_THRESH:-100}"
TRACK_ENABLE_USE_3D="${TRACK_ENABLE_USE_3D:-0}"
TRACK_MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE:-10.0}"
TRACK_MAX_FRAMES="${TRACK_MAX_FRAMES:-}"
TRACK_MODEL_VERSION="${TRACK_MODEL_VERSION:-20260506}"
TRACK_FILE_PATTERN="${TRACK_FILE_PATTERN:-*.json}"
TRACK_MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME:-combined_tracking.json}"
TRACK_PARALLEL_JOBS="${TRACK_PARALLEL_JOBS:-4}"
TRACKING_WRAPPER="${PROJECT_ROOT}/tools/temporal_analysis/track_objects_exported_onnx_infer_case.sh"
# Optional post-tracking protocol-conversion stage.
# Runs convert_merge_tracking_exported_onnx_infer_case.sh on the tracked
# case/eval-root output tree. By default, each case writes converted protocol
# artifacts into its own objectlist/ subdirectory. Set CONVERT_OUTPUT_ROOT to
# write only converted artifacts into a separate root while preserving case
# relative paths.
ENABLE_CONVERT="${ENABLE_CONVERT:-1}"
CONVERT_STRICT="${CONVERT_STRICT:-1}"
CONVERT_RESULTS_ROOT="${CONVERT_RESULTS_ROOT:-${TRACK_RESULTS_ROOT}}"
CONVERT_OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT:-/data1/dongying/Mono3d/G1Q3/model_inference/KPI/OP_KPI_SCENE/model_20260506_objectlist}"
if [[ -z "${CONVERT_OUTPUT_LAYOUT+x}" ]]; then
if [[ -n "${CONVERT_OUTPUT_ROOT}" ]]; then
CONVERT_OUTPUT_LAYOUT="parallel_root"
else
CONVERT_OUTPUT_LAYOUT="case_subdir"
fi
else
CONVERT_OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT:-case_subdir}"
fi
CONVERT_OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME:-objectlist}"
CONVERT_MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME:-${TRACK_MERGE_OUTPUT_NAME}}"
CONVERT_CAM_ID="${CONVERT_CAM_ID:-}"
CONVERT_CASE_LIST_FILE="${CONVERT_CASE_LIST_FILE:-}"
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS:-8}"
CONVERT_WRAPPER="${PROJECT_ROOT}/tools/convert_merge_tracking_bundle/convert_merge_tracking_exported_onnx_infer_case.sh"
is_eval_case_dir() {
local case_dir="$1"
[[ -d "${case_dir}/images" ]] || return 1
[[ -f "${case_dir}/calib/L2_calib/camera4.json" || -f "${case_dir}/calib/camera4.json" ]]
}
collect_eval_case_dirs() {
local eval_root="${1%/}"
local first_level_dir
local second_level_dir
while IFS= read -r -d '' first_level_dir; do
if is_eval_case_dir "${first_level_dir}"; then
printf '%s\n' "${first_level_dir}"
continue
fi
while IFS= read -r -d '' second_level_dir; do
if is_eval_case_dir "${second_level_dir}"; then
printf '%s\n' "${second_level_dir}"
fi
done < <(find "${first_level_dir}" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z)
done < <(find "${eval_root}" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z)
}
write_convert_case_list() {
local target_mode="$1"
local convert_root="${2%/}"
local list_file="$3"
local eval_root="${EVAL_DIR:-${INPUT_DIR}}"
local -a case_dirs=()
local case_index_start="${CASE_INDEX_START:-0}"
local case_index_end="${CASE_INDEX_END:-}"
local total_cases
local relative_case_dir
local case_dir
local index
mkdir -p "$(dirname "${list_file}")"
: > "${list_file}"
if [[ "${target_mode}" == "case" ]]; then
printf '%s\n' "${convert_root}" > "${list_file}"
return 0
fi
mapfile -t case_dirs < <(collect_eval_case_dirs "${eval_root}")
total_cases="${#case_dirs[@]}"
if [[ -z "${case_index_end}" ]]; then
case_index_end="${total_cases}"
fi
for ((index = case_index_start; index < case_index_end; index++)); do
case_dir="${case_dirs[${index}]}"
relative_case_dir="${case_dir#${eval_root%/}/}"
printf '%s\n' "${convert_root}/${relative_case_dir}" >> "${list_file}"
done
}
resolve_target_mode() {
if [[ -n "${CASE_DIR}" ]]; then
printf 'case\n'
elif [[ -n "${EVAL_DIR}" ]]; then
printf 'eval\n'
elif [[ -d "${INPUT_DIR}/images" ]]; then
printf 'case\n'
else
printf 'eval\n'
fi
}
launch_parallel_eval_workers() {
local target_mode="$1"
local num_shards="${NUM_SHARDS}"
local failed=0
local -a gpu_ids_arr=()
local -a pids=()
local -a log_files=()
if [[ "${target_mode}" != "eval" ]]; then
echo "ENABLE_PARALLEL=1 only supports eval-root inference." >&2
echo "Please point INPUT_DIR/EVAL_DIR to an eval root instead of a single case." >&2
exit 1
fi
if [[ -z "${GPU_IDS}" ]]; then
echo "ENABLE_PARALLEL=1 requires GPU_IDS, for example: GPU_IDS=\"0 1 2 3\"." >&2
exit 1
fi
# shellcheck disable=SC2206
gpu_ids_arr=(${GPU_IDS})
if [[ "${num_shards}" == "1" ]]; then
num_shards="${#gpu_ids_arr[@]}"
fi
if [[ "${num_shards}" -lt 2 ]]; then
echo "Parallel mode requires at least 2 shards, got NUM_SHARDS=${num_shards}." >&2
exit 1
fi
if [[ "${#gpu_ids_arr[@]}" -ne "${num_shards}" ]]; then
echo "GPU_IDS count (${#gpu_ids_arr[@]}) must match NUM_SHARDS (${num_shards}) in ENABLE_PARALLEL mode." >&2
exit 1
fi
mkdir -p "${PARALLEL_LOG_DIR}"
echo ""
echo "######################################################################"
echo "# Parallel eval-dir inference"
echo "######################################################################"
echo "Eval root : ${INPUT_DIR}"
echo "Output root : ${OUTPUT_DIR}"
echo "Shards : ${num_shards}"
echo "Shard strategy : ${SHARD_STRATEGY}"
echo "GPU ids : ${GPU_IDS}"
echo "Worker logs : ${PARALLEL_LOG_DIR}"
for shard_index in "${!gpu_ids_arr[@]}"; do
local gpu_id="${gpu_ids_arr[${shard_index}]}"
local device="cuda:${gpu_id}"
local attr_device="${ATTR_DEVICE:-${device}}"
local log_file="${PARALLEL_LOG_DIR}/shard_${shard_index}_gpu_${gpu_id}.log"
echo "Launching shard ${shard_index}/${num_shards} on ${device} -> ${log_file}"
ENABLE_PARALLEL=0 \
ENABLE_TRACKING=0 \
ENABLE_CONVERT=0 \
NUM_SHARDS="${num_shards}" \
SHARD_INDEX="${shard_index}" \
SHARD_STRATEGY="${SHARD_STRATEGY}" \
DEVICE="${device}" \
ATTR_DEVICE="${attr_device}" \
bash "${BASH_SOURCE[0]}" "${FORWARD_ARGS[@]}" >"${log_file}" 2>&1 &
pids+=("$!")
log_files+=("${log_file}")
done
for shard_index in "${!pids[@]}"; do
if wait "${pids[${shard_index}]}"; then
echo "Shard ${shard_index}/${num_shards} finished successfully. Log: ${log_files[${shard_index}]}"
else
echo "[ERROR] Shard ${shard_index}/${num_shards} failed. Log: ${log_files[${shard_index}]}" >&2
failed=1
fi
done
if [[ "${failed}" == "1" ]]; then
echo "Parallel inference did not finish cleanly. Postprocess was skipped." >&2
exit 1
fi
}
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/core/run_two_roi_exported_onnx_infer.py"
--exported-model "${EXPORTED_MODEL}"
--output-dir "${OUTPUT_DIR}"
)
if [[ -n "${DEVICE}" ]]; then
CMD+=(--device "${DEVICE}")
fi
if [[ -n "${ATTR_DEVICE}" ]]; then
CMD+=(--attr-device "${ATTR_DEVICE}")
fi
if [[ -n "${CASE_INDEX_START}" ]]; then
CMD+=(--case-index-start "${CASE_INDEX_START}")
fi
if [[ -n "${CASE_INDEX_END}" ]]; then
CMD+=(--case-index-end "${CASE_INDEX_END}")
fi
if [[ "${ENABLE_ATTR}" == "1" ]]; then
CMD+=(--enable-attr)
fi
if [[ "${ENABLE_CROSS_CLASS_MERGE_PRIOR}" == "1" ]]; then
CMD+=(--enable-cross-class-merge-prior)
fi
if [[ "${ENABLE_VRU_MERGE}" == "1" ]]; then
CMD+=(--enable-vru-merge)
fi
if [[ -n "${VIS_CLASSES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASSES_ARR=(${VIS_CLASSES})
CMD+=(--vis-classes "${VIS_CLASSES_ARR[@]}")
fi
if [[ -n "${VIS_CLASS_NAMES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASS_NAMES_ARR=(${VIS_CLASS_NAMES})
CMD+=(--vis-class-names "${VIS_CLASS_NAMES_ARR[@]}")
fi
if [[ "${NUM_SHARDS}" != "1" ]] || [[ "${SHARD_INDEX}" != "0" ]] || [[ "${SHARD_STRATEGY}" != "round_robin" ]]; then
CMD+=(--num-shards "${NUM_SHARDS}" --shard-index "${SHARD_INDEX}" --shard-strategy "${SHARD_STRATEGY}")
fi
if [[ -n "${CASE_DIR}" ]]; then
CMD+=(--case-dir "${CASE_DIR}")
elif [[ -n "${EVAL_DIR}" ]]; then
CMD+=(--eval-dir "${EVAL_DIR}")
elif [[ -d "${INPUT_DIR}/images" ]]; then
CMD+=(--case-dir "${INPUT_DIR}")
else
CMD+=(--eval-dir "${INPUT_DIR}")
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
if [[ "${SAVE_VISUALIZATION}" != "1" ]]; then
CMD+=(--skip-visualizations)
fi
CMD+=("$@")
TARGET_MODE="$(resolve_target_mode)"
if [[ "${ENABLE_PARALLEL}" == "1" ]] && [[ "${POSTPROCESS_ONLY}" != "1" ]]; then
launch_parallel_eval_workers "${TARGET_MODE}"
POSTPROCESS_ONLY="1"
fi
if [[ "${POSTPROCESS_ONLY}" == "1" ]]; then
echo ""
echo "######################################################################"
echo "# POSTPROCESS_ONLY=1, skipping inference"
echo "######################################################################"
echo "Postprocess root: ${OUTPUT_DIR}"
else
"${CMD[@]}"
fi
if [[ "${ENABLE_TRACKING}" == "1" ]]; then
echo ""
echo "######################################################################"
echo "# Post-inference tracking for exported case/eval-root outputs"
echo "######################################################################"
echo "Tracking root: ${TRACK_RESULTS_ROOT}"
if [[ "${TRACK_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
RESULTS_ROOT="${TRACK_RESULTS_ROOT}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
IOU_THRESH="${TRACK_IOU_THRESH}" \
MAX_AGE="${TRACK_MAX_AGE}" \
MIN_HITS="${TRACK_MIN_HITS}" \
DIST_THRESH="${TRACK_DIST_THRESH}" \
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
MAX_FRAMES="${TRACK_MAX_FRAMES}" \
MODEL_VERSION="${TRACK_MODEL_VERSION}" \
FILE_PATTERN="${TRACK_FILE_PATTERN}" \
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
TRACK_PARALLEL_JOBS="${TRACK_PARALLEL_JOBS}" \
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}" \
bash "${TRACKING_WRAPPER}" "${TRACK_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
RESULTS_ROOT="${TRACK_RESULTS_ROOT}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
IOU_THRESH="${TRACK_IOU_THRESH}" \
MAX_AGE="${TRACK_MAX_AGE}" \
MIN_HITS="${TRACK_MIN_HITS}" \
DIST_THRESH="${TRACK_DIST_THRESH}" \
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
MAX_FRAMES="${TRACK_MAX_FRAMES}" \
MODEL_VERSION="${TRACK_MODEL_VERSION}" \
FILE_PATTERN="${TRACK_FILE_PATTERN}" \
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
TRACK_PARALLEL_JOBS="${TRACK_PARALLEL_JOBS}" \
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}" \
bash "${TRACKING_WRAPPER}" "${TRACK_RESULTS_ROOT}"; then
echo "[WARN] Tracking failed, but inference outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi
elif [[ "${ENABLE_CONVERT}" != "1" ]]; then
exit 0
fi
if [[ "${ENABLE_CONVERT}" != "1" ]]; then
exit 0
fi
CONVERT_OUTPUT_ROOT_EFFECTIVE="${CONVERT_OUTPUT_ROOT}"
CONVERT_OUTPUT_LAYOUT_EFFECTIVE="${CONVERT_OUTPUT_LAYOUT}"
CONVERT_CASE_LIST_FILE_EFFECTIVE="${CONVERT_CASE_LIST_FILE}"
case "${CONVERT_OUTPUT_LAYOUT}" in
same_dir)
if [[ -f "${CONVERT_RESULTS_ROOT}" ]] || [[ "$(basename "${CONVERT_RESULTS_ROOT}")" == "${CONVERT_MERGE_JSON_NAME}" ]]; then
CONVERT_OUTPUT_ROOT_EFFECTIVE="$(dirname "${CONVERT_RESULTS_ROOT}")"
else
CONVERT_OUTPUT_ROOT_EFFECTIVE="${CONVERT_RESULTS_ROOT%/}"
fi
CONVERT_OUTPUT_LAYOUT_EFFECTIVE="parallel_root"
;;
case_subdir|parallel_root)
;;
*)
echo "Unsupported CONVERT_OUTPUT_LAYOUT: ${CONVERT_OUTPUT_LAYOUT}" >&2
echo "Expected one of: same_dir, case_subdir, parallel_root" >&2
exit 1
;;
esac
echo ""
echo "######################################################################"
echo "# Post-tracking protocol conversion for exported case/eval-root outputs"
echo "######################################################################"
echo "Conversion target: ${CONVERT_RESULTS_ROOT}"
echo "Conversion layout: ${CONVERT_OUTPUT_LAYOUT}"
if [[ "${CONVERT_OUTPUT_LAYOUT}" == "same_dir" ]]; then
echo "Conversion output: same directory as tracking results"
elif [[ "${CONVERT_OUTPUT_LAYOUT}" == "case_subdir" ]]; then
echo "Conversion subdir: ${CONVERT_OUTPUT_DIR_NAME}"
elif [[ -n "${CONVERT_OUTPUT_ROOT_EFFECTIVE}" ]]; then
echo "Conversion output root: ${CONVERT_OUTPUT_ROOT_EFFECTIVE}"
fi
if [[ -z "${CONVERT_CASE_LIST_FILE_EFFECTIVE}" ]]; then
CONVERT_CASE_LIST_FILE_EFFECTIVE="${OUTPUT_DIR%/}/_status/convert_case_list.txt"
fi
if [[ -d "${CONVERT_RESULTS_ROOT}" ]]; then
write_convert_case_list "${TARGET_MODE}" "${CONVERT_RESULTS_ROOT}" "${CONVERT_CASE_LIST_FILE_EFFECTIVE}"
echo "Conversion case list: ${CONVERT_CASE_LIST_FILE_EFFECTIVE}"
fi
if [[ "${CONVERT_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
CASE_LIST_FILE="${CONVERT_CASE_LIST_FILE_EFFECTIVE}" \
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT_EFFECTIVE}" \
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT_EFFECTIVE}" \
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
CASE_LIST_FILE="${CONVERT_CASE_LIST_FILE_EFFECTIVE}" \
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT_EFFECTIVE}" \
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT_EFFECTIVE}" \
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"; then
echo "[WARN] Protocol conversion failed, but tracking outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi

View File

@@ -0,0 +1,77 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for PDCL clip-list batch inference.
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
CLIP_LIST_FILE="${CLIP_LIST_FILE:-${MODEL_INFERENCE_DIR}/examples/clip_lists/clips_aeb.txt}"
EXPORT_ROOT="${EXPORT_ROOT:-/data1/dongying/Mono3d/G1Q3/model_inference/test/clips_aeb_export}"
OUTPUT_PREFIX="${OUTPUT_PREFIX:-clip_export}"
CAMERA_TOPIC="${CAMERA_TOPIC:-camera4}"
MAX_FRAMES_PER_CLIP="${MAX_FRAMES_PER_CLIP:-0}"
LIMIT_CLIPS="${LIMIT_CLIPS:-0}"
SKIP_DONE="${SKIP_DONE:-1}"
EXPORTED_MODEL="${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_20260413-raw/merged_model.torchscript}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/test/clips_aeb_no_cls}"
ENABLE_ATTR="${ENABLE_ATTR:-0}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}"
ENABLE_VRU_MERGE="${ENABLE_VRU_MERGE:-1}"
VIS_CLASSES="${VIS_CLASSES:-9 10 11 12}"
VIS_CLASS_NAMES="${VIS_CLASS_NAMES:-}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/core/run_two_roi_exported_onnx_infer.py"
--clip-list-file "${CLIP_LIST_FILE}"
--export-root "${EXPORT_ROOT}"
--output-prefix "${OUTPUT_PREFIX}"
--camera-topic "${CAMERA_TOPIC}"
--max-frames-per-clip "${MAX_FRAMES_PER_CLIP}"
--exported-model "${EXPORTED_MODEL}"
--output-dir "${OUTPUT_DIR}"
)
if [[ "${ENABLE_ATTR}" == "1" ]]; then
CMD+=(--enable-attr)
fi
if [[ "${ENABLE_CROSS_CLASS_MERGE_PRIOR}" == "1" ]]; then
CMD+=(--enable-cross-class-merge-prior)
fi
if [[ "${ENABLE_VRU_MERGE}" == "1" ]]; then
CMD+=(--enable-vru-merge)
fi
if [[ -n "${VIS_CLASSES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASSES_ARR=(${VIS_CLASSES})
CMD+=(--vis-classes "${VIS_CLASSES_ARR[@]}")
fi
if [[ -n "${VIS_CLASS_NAMES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASS_NAMES_ARR=(${VIS_CLASS_NAMES})
CMD+=(--vis-class-names "${VIS_CLASS_NAMES_ARR[@]}")
fi
if [[ "${LIMIT_CLIPS}" != "0" ]]; then
CMD+=(--limit-clips "${LIMIT_CLIPS}")
fi
if [[ "${SKIP_DONE}" == "1" ]]; then
CMD+=(--skip-done)
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
CMD+=("$@")
"${CMD[@]}"

View File

@@ -0,0 +1,141 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for CNCAP JSON batch video inference.
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
CNCAP_JSON_FILE="${CNCAP_JSON_FILE:-${MODEL_INFERENCE_DIR}/examples/cncap/G1M3_AFS1616_CNCAP-202411.json}"
CNCAP_VALUES_KEY="${CNCAP_VALUES_KEY:-values}"
CNCAP_PATH_PREFIX_SRC="${CNCAP_PATH_PREFIX_SRC:-/mnt/hfs/project-G1M3}"
CNCAP_PATH_PREFIX_DST="${CNCAP_PATH_PREFIX_DST:-/mnt/G1M3}"
VIDEO_STRIDE="${VIDEO_STRIDE:-1}"
EXPORTED_MODEL="${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_20260506-keep_fake_3d_branch/merged_model.torchscript}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/cncap/cncap_2024_with_cls_ego/model_20260506_keep_fake3d_validate}"
MAX_IMAGES="${MAX_IMAGES:-0}"
ENABLE_ATTR="${ENABLE_ATTR:-1}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}"
ENABLE_VRU_MERGE="${ENABLE_VRU_MERGE:-0}"
DEVICE="${DEVICE:-cuda:2}"
VIS_CLASSES="${VIS_CLASSES:-}"
VIS_CLASS_NAMES="${VIS_CLASS_NAMES:-}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
# ---------------------------------------------------------------------------
# Auto-tracking: run tracking immediately after inference completes.
# Set AUTO_TRACK=1 to enable. All TRACK_* variables mirror the defaults in
# track_objects_exported_onnx_infer_cncap_json.sh and can be overridden.
# ---------------------------------------------------------------------------
AUTO_TRACK="${AUTO_TRACK:-1}"
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING:-0}"
TRACK_CLASSES="${TRACK_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12 17 18 19}"
TRACK_IOU_THRESH="${TRACK_IOU_THRESH:-0.3}"
TRACK_MAX_AGE="${TRACK_MAX_AGE:-5}"
TRACK_MIN_HITS="${TRACK_MIN_HITS:-1}"
TRACK_DIST_THRESH="${TRACK_DIST_THRESH:-100}"
TRACK_MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE:-10.0}"
TRACK_MAX_FRAMES="${TRACK_MAX_FRAMES:-}"
TRACK_MODEL_VERSION="${TRACK_MODEL_VERSION:-20260506}"
TRACK_FILE_PATTERN="${TRACK_FILE_PATTERN:-*.json}"
TRACK_ENABLE_USE_3D="${TRACK_ENABLE_USE_3D:-0}"
TRACK_MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME:-combined_tracking.json}"
if [[ -z "${CNCAP_JSON_FILE}" ]]; then
echo "CNCAP_JSON_FILE is required." >&2
exit 1
fi
# /data1/dongying/Mono3d/G1Q3/model_inference/cncap/cncap_2024_with_cls_ego/model_20260407/20251115/CVE/CPLA_RL_AEB_20_5_1_20251115140740/predictions/roi0/camera4_345630.json
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/core/run_two_roi_exported_onnx_infer.py"
--cncap-json-file "${CNCAP_JSON_FILE}"
--cncap-values-key "${CNCAP_VALUES_KEY}"
--cncap-path-prefix-src "${CNCAP_PATH_PREFIX_SRC}"
--cncap-path-prefix-dst "${CNCAP_PATH_PREFIX_DST}"
--video-stride "${VIDEO_STRIDE}"
--exported-model "${EXPORTED_MODEL}"
--output-dir "${OUTPUT_DIR}"
--device "${DEVICE}"
)
if [[ "${ENABLE_ATTR}" == "1" ]]; then
CMD+=(--enable-attr)
fi
if [[ "${ENABLE_CROSS_CLASS_MERGE_PRIOR}" == "1" ]]; then
CMD+=(--enable-cross-class-merge-prior)
fi
if [[ "${ENABLE_VRU_MERGE}" == "1" ]]; then
CMD+=(--enable-vru-merge)
fi
if [[ -n "${VIS_CLASSES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASSES_ARR=(${VIS_CLASSES})
CMD+=(--vis-classes "${VIS_CLASSES_ARR[@]}")
fi
if [[ -n "${VIS_CLASS_NAMES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASS_NAMES_ARR=(${VIS_CLASS_NAMES})
CMD+=(--vis-class-names "${VIS_CLASS_NAMES_ARR[@]}")
fi
if [[ "${MAX_IMAGES}" != "0" ]]; then
CMD+=(--max-images "${MAX_IMAGES}")
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
CMD+=("$@")
"${CMD[@]}"
# ---------------------------------------------------------------------------
# Auto-tracking step
# ---------------------------------------------------------------------------
if [[ "${AUTO_TRACK}" == "1" ]]; then
TRACKING_SCRIPT="${PROJECT_ROOT}/tools/temporal_analysis/track_objects_exported_onnx_infer_cncap_json.sh"
if [[ ! -f "${TRACKING_SCRIPT}" ]]; then
echo "[AUTO_TRACK] ERROR: tracking script not found: ${TRACKING_SCRIPT}" >&2
exit 1
fi
echo ""
echo "######################################################################"
echo "# AUTO_TRACK=1 — starting CNCAP tracking on ${OUTPUT_DIR}"
echo "######################################################################"
TRACK_ENV=(
PYTHON_BIN="${PYTHON_BIN}"
RESULTS_ROOT="${OUTPUT_DIR}"
TRACK_CLASSES="${TRACK_CLASSES}"
IOU_THRESH="${TRACK_IOU_THRESH}"
MAX_AGE="${TRACK_MAX_AGE}"
MIN_HITS="${TRACK_MIN_HITS}"
DIST_THRESH="${TRACK_DIST_THRESH}"
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}"
FILE_PATTERN="${TRACK_FILE_PATTERN}"
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}"
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}"
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}"
)
if [[ -n "${TRACK_MAX_FRAMES}" ]]; then
TRACK_ENV+=(MAX_FRAMES="${TRACK_MAX_FRAMES}")
fi
if [[ -n "${TRACK_MODEL_VERSION}" ]]; then
TRACK_ENV+=(MODEL_VERSION="${TRACK_MODEL_VERSION}")
fi
env "${TRACK_ENV[@]}" bash "${TRACKING_SCRIPT}"
fi

View File

@@ -0,0 +1,218 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
BASE_SCRIPT="${SCRIPT_DIR}/run_two_roi_exported_onnx_infer_event_json.sh"
# Launcher for CNCAP scene/rawid batch inference based on scene-grouped JSON
# records that contain direct clip-id lists.
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
EVENT_JSON_FILE="${EVENT_JSON_FILE:-${MODEL_INFERENCE_DIR}/examples/cncap/aeb_clips-20260429.json}"
SCENE="${SCENE:-SCP}"
EVENT_ID_FIELD="${EVENT_ID_FIELD:-rawid}"
EVENT_CLIP_IDS_FIELD="${EVENT_CLIP_IDS_FIELD:-clips}"
CONDITION_FIELDS="${CONDITION_FIELDS:-偏置 目标速度 自车速度}"
MAX_RECORDS_PER_CONDITION="${MAX_RECORDS_PER_CONDITION:-1}"
CONDITION_SELECT_STRATEGY="${CONDITION_SELECT_STRATEGY:-first}"
SELECTION_ONLY="${SELECTION_ONLY:-0}"
MAX_EVENTS="${MAX_EVENTS:-0}"
EVENT_CACHE_FILE="${EVENT_CACHE_FILE:-${MODEL_INFERENCE_DIR}/.cache/event_clip_cache.json}"
EVENT_RESOLVE_WORKERS="${EVENT_RESOLVE_WORKERS:-4}"
EVENT_REQUEST_TIMEOUT="${EVENT_REQUEST_TIMEOUT:-60}"
EVENT_REQUEST_RETRIES="${EVENT_REQUEST_RETRIES:-3}"
EVENT_REQUEST_RETRY_BACKOFF_SEC="${EVENT_REQUEST_RETRY_BACKOFF_SEC:-2.0}"
EXPORT_ROOT="${EXPORT_ROOT:-/data1/dongying/Mono3d/G1Q3/model_inference/cncap/aeb_clips_20260429_selected/event_exports}"
OUTPUT_PREFIX="${OUTPUT_PREFIX:-clip}"
CAMERA_TOPIC="${CAMERA_TOPIC:-camera4}"
MAX_FRAMES_PER_CLIP="${MAX_FRAMES_PER_CLIP:-0}"
LIMIT_CLIPS="${LIMIT_CLIPS:-0}"
SKIP_DONE="${SKIP_DONE:-1}"
EXPORTED_MODEL="${EXPORTED_MODEL:-${MODEL_INFERENCE_DIR}/../../runs/export/train_mono3d_two_roi_20260506-drop_fake_3d_branch/merged_model.torchscript}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/cncap/aeb_clips_20260429_selected/model_20260506_vis_distance}"
ENABLE_ATTR="${ENABLE_ATTR:-0}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}"
SHOW_DISTANCE_LABEL="${SHOW_DISTANCE_LABEL:-1}"
DISTANCE_LABEL_MODE="${DISTANCE_LABEL_MODE:-depth_lateral}"
DISTANCE_LABEL_PANELS="${DISTANCE_LABEL_PANELS:-3d}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
# Optional rawid L2 package download through mdi.
ENABLE_RAW_L2_DOWNLOAD="${ENABLE_RAW_L2_DOWNLOAD:-1}"
RAW_L2_DOWNLOAD_ONLY="${RAW_L2_DOWNLOAD_ONLY:-0}"
RAW_L2_DOWNLOAD_ROOT="${RAW_L2_DOWNLOAD_ROOT:-/data1/dongying/Mono3d/G1Q3/model_inference/cncap/aeb_clips_20260429_selected/raw_l2}"
RAW_L2_DOWNLOAD_MANIFEST="${RAW_L2_DOWNLOAD_MANIFEST:-${RAW_L2_DOWNLOAD_ROOT}/download_manifest.json}"
RAW_L2_DOWNLOAD_DRY_RUN="${RAW_L2_DOWNLOAD_DRY_RUN:-0}"
RAW_L2_DOWNLOAD_SKIP_DONE="${RAW_L2_DOWNLOAD_SKIP_DONE:-1}"
RAW_L2_DOWNLOAD_STRICT="${RAW_L2_DOWNLOAD_STRICT:-1}"
# Auto-tracking is delegated to the shared event-json launcher.
# Set TRACK_ONLY=1 to skip clip export/inference and run tracking on OUTPUT_DIR.
# Set CONVERT_ONLY=1 to skip clip export/inference and tracking, then convert.
TRACK_ONLY="${TRACK_ONLY:-0}"
CONVERT_ONLY="${CONVERT_ONLY:-0}"
AUTO_TRACK="${AUTO_TRACK:-1}"
TRACK_CLASSES="${TRACK_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12 17 18 19}"
TRACK_IOU_THRESH="${TRACK_IOU_THRESH:-0.3}"
TRACK_MAX_AGE="${TRACK_MAX_AGE:-5}"
TRACK_MIN_HITS="${TRACK_MIN_HITS:-1}"
TRACK_DIST_THRESH="${TRACK_DIST_THRESH:-100}"
TRACK_MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE:-10.0}"
TRACK_MODEL_VERSION="${TRACK_MODEL_VERSION:-20260506}"
TRACK_FILE_PATTERN="${TRACK_FILE_PATTERN:-*.json}"
TRACK_ENABLE_USE_3D="${TRACK_ENABLE_USE_3D:-0}"
TRACK_MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME:-combined_tracking.json}"
TRACK_MANIFEST_NAME="${TRACK_MANIFEST_NAME:-frame_order_manifest.json}"
TRACK_EVENT_TRACKING_DIRNAME="${TRACK_EVENT_TRACKING_DIRNAME:-}"
# Post-tracking protocol conversion. This scene launcher converts only the
# event-level merge.json by default.
ENABLE_CONVERT="${ENABLE_CONVERT:-1}"
CONVERT_STRICT="${CONVERT_STRICT:-1}"
CONVERT_RESULTS_ROOT="${CONVERT_RESULTS_ROOT:-${OUTPUT_DIR}}"
CONVERT_OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT:-${OUTPUT_DIR%/}_objectlist}"
CONVERT_OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT:-parallel_root}"
CONVERT_OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME:-objectlist}"
CONVERT_MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME:-merge.json}"
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS:-4}"
CONVERT_CAM_ID="${CONVERT_CAM_ID:-}"
if [[ ! -f "${BASE_SCRIPT}" ]]; then
echo "Base launcher not found: ${BASE_SCRIPT}" >&2
exit 1
fi
run_raw_l2_download() {
local downloader="${MODEL_INFERENCE_DIR}/core/download_rawid_l2_by_event_json.py"
if [[ ! -f "${downloader}" ]]; then
echo "Raw L2 downloader not found: ${downloader}" >&2
exit 1
fi
local -a cmd=(
"${PYTHON_BIN}" "${downloader}"
--event-json-file "${EVENT_JSON_FILE}"
--event-id-field "${EVENT_ID_FIELD}"
--event-clip-ids-field "${EVENT_CLIP_IDS_FIELD}"
--event-cache-file "${EVENT_CACHE_FILE}"
--event-resolve-workers "${EVENT_RESOLVE_WORKERS}"
--event-request-timeout "${EVENT_REQUEST_TIMEOUT}"
--event-request-retries "${EVENT_REQUEST_RETRIES}"
--event-request-retry-backoff-sec "${EVENT_REQUEST_RETRY_BACKOFF_SEC}"
--output-root "${RAW_L2_DOWNLOAD_ROOT}"
--manifest-path "${RAW_L2_DOWNLOAD_MANIFEST}"
)
if [[ -n "${SCENE}" ]]; then
cmd+=(--scene "${SCENE}")
fi
if [[ -n "${CONDITION_FIELDS}" ]]; then
# shellcheck disable=SC2206
CONDITION_FIELDS_ARR=(${CONDITION_FIELDS})
cmd+=(--condition-fields "${CONDITION_FIELDS_ARR[@]}")
fi
if [[ "${MAX_RECORDS_PER_CONDITION}" != "0" ]]; then
cmd+=(--max-records-per-condition "${MAX_RECORDS_PER_CONDITION}")
fi
if [[ -n "${CONDITION_SELECT_STRATEGY}" ]]; then
cmd+=(--condition-select-strategy "${CONDITION_SELECT_STRATEGY}")
fi
if [[ "${MAX_EVENTS}" != "0" ]]; then
cmd+=(--max-events "${MAX_EVENTS}")
fi
if [[ "${RAW_L2_DOWNLOAD_DRY_RUN}" == "1" ]]; then
cmd+=(--dry-run)
fi
if [[ "${RAW_L2_DOWNLOAD_SKIP_DONE}" == "1" ]]; then
cmd+=(--skip-done)
fi
if [[ "${RAW_L2_DOWNLOAD_STRICT}" == "1" ]]; then
cmd+=(--strict)
fi
echo ""
echo "######################################################################"
echo "# Rawid L2 package download through mdi"
echo "######################################################################"
echo "Download root : ${RAW_L2_DOWNLOAD_ROOT}"
echo "Manifest : ${RAW_L2_DOWNLOAD_MANIFEST}"
"${cmd[@]}"
}
if [[ "${ENABLE_RAW_L2_DOWNLOAD}" == "1" || "${RAW_L2_DOWNLOAD_ONLY}" == "1" ]]; then
if [[ "${RAW_L2_DOWNLOAD_STRICT}" == "1" ]]; then
run_raw_l2_download
else
if ! run_raw_l2_download; then
echo "[WARN] Raw L2 download failed, continuing because RAW_L2_DOWNLOAD_STRICT=0" >&2
fi
fi
fi
if [[ "${RAW_L2_DOWNLOAD_ONLY}" == "1" ]]; then
exit 0
fi
env \
PYTHON_BIN="${PYTHON_BIN}" \
EVENT_JSON_FILE="${EVENT_JSON_FILE}" \
SCENE="${SCENE}" \
EVENT_ID_FIELD="${EVENT_ID_FIELD}" \
EVENT_CLIP_IDS_FIELD="${EVENT_CLIP_IDS_FIELD}" \
CONDITION_FIELDS="${CONDITION_FIELDS}" \
MAX_RECORDS_PER_CONDITION="${MAX_RECORDS_PER_CONDITION}" \
CONDITION_SELECT_STRATEGY="${CONDITION_SELECT_STRATEGY}" \
SELECTION_ONLY="${SELECTION_ONLY}" \
MAX_EVENTS="${MAX_EVENTS}" \
EVENT_CACHE_FILE="${EVENT_CACHE_FILE}" \
EVENT_RESOLVE_WORKERS="${EVENT_RESOLVE_WORKERS}" \
EVENT_REQUEST_TIMEOUT="${EVENT_REQUEST_TIMEOUT}" \
EVENT_REQUEST_RETRIES="${EVENT_REQUEST_RETRIES}" \
EVENT_REQUEST_RETRY_BACKOFF_SEC="${EVENT_REQUEST_RETRY_BACKOFF_SEC}" \
EXPORT_ROOT="${EXPORT_ROOT}" \
OUTPUT_PREFIX="${OUTPUT_PREFIX}" \
CAMERA_TOPIC="${CAMERA_TOPIC}" \
MAX_FRAMES_PER_CLIP="${MAX_FRAMES_PER_CLIP}" \
LIMIT_CLIPS="${LIMIT_CLIPS}" \
SKIP_DONE="${SKIP_DONE}" \
EXPORTED_MODEL="${EXPORTED_MODEL}" \
OUTPUT_DIR="${OUTPUT_DIR}" \
ENABLE_ATTR="${ENABLE_ATTR}" \
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR}" \
SHOW_DISTANCE_LABEL="${SHOW_DISTANCE_LABEL}" \
DISTANCE_LABEL_MODE="${DISTANCE_LABEL_MODE}" \
DISTANCE_LABEL_PANELS="${DISTANCE_LABEL_PANELS}" \
EXTRA_ARGS="${EXTRA_ARGS}" \
TRACK_ONLY="${TRACK_ONLY}" \
CONVERT_ONLY="${CONVERT_ONLY}" \
AUTO_TRACK="${AUTO_TRACK}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
TRACK_IOU_THRESH="${TRACK_IOU_THRESH}" \
TRACK_MAX_AGE="${TRACK_MAX_AGE}" \
TRACK_MIN_HITS="${TRACK_MIN_HITS}" \
TRACK_DIST_THRESH="${TRACK_DIST_THRESH}" \
TRACK_MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
TRACK_MODEL_VERSION="${TRACK_MODEL_VERSION}" \
TRACK_FILE_PATTERN="${TRACK_FILE_PATTERN}" \
TRACK_ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
TRACK_MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
TRACK_MANIFEST_NAME="${TRACK_MANIFEST_NAME}" \
TRACK_EVENT_TRACKING_DIRNAME="${TRACK_EVENT_TRACKING_DIRNAME}" \
ENABLE_CONVERT="${ENABLE_CONVERT}" \
CONVERT_STRICT="${CONVERT_STRICT}" \
CONVERT_RESULTS_ROOT="${CONVERT_RESULTS_ROOT}" \
CONVERT_OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT}" \
CONVERT_OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT}" \
CONVERT_OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
CONVERT_MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS}" \
CONVERT_CAM_ID="${CONVERT_CAM_ID}" \
bash "${BASE_SCRIPT}" "$@"

View File

@@ -0,0 +1,287 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for scene event-json batch inference.
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
EVENT_JSON_FILE="${EVENT_JSON_FILE:-${MODEL_INFERENCE_DIR}/examples/events/G1Q3_场地评测数据集.json}"
SCENE="${SCENE:-}"
EVENT_ID_FIELD="${EVENT_ID_FIELD:-data_path}"
EVENT_CLIP_IDS_FIELD="${EVENT_CLIP_IDS_FIELD:-clips}"
CONDITION_FIELDS="${CONDITION_FIELDS:-}"
MAX_RECORDS_PER_CONDITION="${MAX_RECORDS_PER_CONDITION:-0}"
CONDITION_SELECT_STRATEGY="${CONDITION_SELECT_STRATEGY:-first}"
SELECTION_ONLY="${SELECTION_ONLY:-0}"
MAX_EVENTS="${MAX_EVENTS:-0}"
EVENT_CACHE_FILE="${EVENT_CACHE_FILE:-${MODEL_INFERENCE_DIR}/.cache/event_clip_cache.json}"
EVENT_RESOLVE_WORKERS="${EVENT_RESOLVE_WORKERS:-4}"
EVENT_REQUEST_TIMEOUT="${EVENT_REQUEST_TIMEOUT:-60}"
EVENT_REQUEST_RETRIES="${EVENT_REQUEST_RETRIES:-3}"
EVENT_REQUEST_RETRY_BACKOFF_SEC="${EVENT_REQUEST_RETRY_BACKOFF_SEC:-2.0}"
EXPORT_ROOT="${EXPORT_ROOT:-/data1/dongying/Mono3d/G1Q3/model_inference/cncap/cncap_2021_with_cls_ego/event_exports}"
OUTPUT_PREFIX="${OUTPUT_PREFIX:-clip}"
CAMERA_TOPIC="${CAMERA_TOPIC:-camera4}"
MAX_FRAMES_PER_CLIP="${MAX_FRAMES_PER_CLIP:-0}"
LIMIT_CLIPS="${LIMIT_CLIPS:-0}"
SKIP_DONE="${SKIP_DONE:-1}"
EXPORTED_MODEL="${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_20260506-keep_fake_3d_branch/merged_model.torchscript}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/cncap/cncap_2021_with_cls_ego/model_20260506_keep_fake3d_validate}"
ENABLE_ATTR="${ENABLE_ATTR:-1}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}"
ENABLE_VRU_MERGE="${ENABLE_VRU_MERGE:-0}"
VIS_CLASSES="${VIS_CLASSES:-}"
VIS_CLASS_NAMES="${VIS_CLASS_NAMES:-}"
SHOW_DISTANCE_LABEL="${SHOW_DISTANCE_LABEL:-0}"
DISTANCE_LABEL_MODE="${DISTANCE_LABEL_MODE:-depth}"
DISTANCE_LABEL_PANELS="${DISTANCE_LABEL_PANELS:-3d}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
# ---------------------------------------------------------------------------
# Auto-tracking: run tracking immediately after inference completes, or set
# TRACK_ONLY=1 to skip clip export/inference and run tracking on OUTPUT_DIR.
# Set CONVERT_ONLY=1 to skip clip export/inference and tracking, then convert.
# Set AUTO_TRACK=1 to enable. All TRACK_* variables mirror the defaults in
# track_objects_exported_onnx_infer_event_json.sh and can be overridden.
# ---------------------------------------------------------------------------
TRACK_ONLY="${TRACK_ONLY:-0}"
CONVERT_ONLY="${CONVERT_ONLY:-0}"
AUTO_TRACK="${AUTO_TRACK:-1}"
if [[ "${TRACK_ONLY}" == "1" ]] && [[ "${CONVERT_ONLY}" != "1" ]]; then
AUTO_TRACK="1"
fi
if [[ "${CONVERT_ONLY}" == "1" ]]; then
AUTO_TRACK="0"
fi
TRACK_CLASSES="${TRACK_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12 17 18 19}"
TRACK_IOU_THRESH="${TRACK_IOU_THRESH:-0.3}"
TRACK_MAX_AGE="${TRACK_MAX_AGE:-5}"
TRACK_MIN_HITS="${TRACK_MIN_HITS:-1}"
TRACK_DIST_THRESH="${TRACK_DIST_THRESH:-100}"
TRACK_MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE:-10.0}"
TRACK_MODEL_VERSION="${TRACK_MODEL_VERSION:-20260506}"
TRACK_FILE_PATTERN="${TRACK_FILE_PATTERN:-*.json}"
TRACK_ENABLE_USE_3D="${TRACK_ENABLE_USE_3D:-0}"
TRACK_MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME:-combined_tracking.json}"
TRACK_MANIFEST_NAME="${TRACK_MANIFEST_NAME:-frame_order_manifest.json}"
TRACK_EVENT_TRACKING_DIRNAME="${TRACK_EVENT_TRACKING_DIRNAME:-}"
# ---------------------------------------------------------------------------
# Post-tracking protocol conversion.
# Only merge.json is converted by default; override CONVERT_MERGE_JSON_NAME if
# another tracking result needs conversion.
# ---------------------------------------------------------------------------
ENABLE_CONVERT="${ENABLE_CONVERT:-0}"
if [[ "${CONVERT_ONLY}" == "1" ]]; then
ENABLE_CONVERT="1"
fi
CONVERT_STRICT="${CONVERT_STRICT:-1}"
CONVERT_RESULTS_ROOT="${CONVERT_RESULTS_ROOT:-${OUTPUT_DIR}}"
CONVERT_OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT:-${OUTPUT_DIR%/}_objectlist}"
CONVERT_OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT:-parallel_root}"
CONVERT_OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME:-objectlist}"
CONVERT_MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME:-merge.json}"
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS:-4}"
CONVERT_CAM_ID="${CONVERT_CAM_ID:-}"
CONVERT_WRAPPER="${PROJECT_ROOT}/tools/convert_merge_tracking_bundle/convert_merge_tracking_exported_onnx_infer_case.sh"
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/core/run_two_roi_exported_onnx_infer.py"
--event-json-file "${EVENT_JSON_FILE}"
--event-id-field "${EVENT_ID_FIELD}"
--event-clip-ids-field "${EVENT_CLIP_IDS_FIELD}"
--event-cache-file "${EVENT_CACHE_FILE}"
--event-resolve-workers "${EVENT_RESOLVE_WORKERS}"
--event-request-timeout "${EVENT_REQUEST_TIMEOUT}"
--event-request-retries "${EVENT_REQUEST_RETRIES}"
--event-request-retry-backoff-sec "${EVENT_REQUEST_RETRY_BACKOFF_SEC}"
--export-root "${EXPORT_ROOT}"
--output-prefix "${OUTPUT_PREFIX}"
--camera-topic "${CAMERA_TOPIC}"
--max-frames-per-clip "${MAX_FRAMES_PER_CLIP}"
--exported-model "${EXPORTED_MODEL}"
--output-dir "${OUTPUT_DIR}"
)
if [[ "${ENABLE_ATTR}" == "1" ]]; then
CMD+=(--enable-attr)
fi
if [[ "${ENABLE_CROSS_CLASS_MERGE_PRIOR}" == "1" ]]; then
CMD+=(--enable-cross-class-merge-prior)
fi
if [[ "${ENABLE_VRU_MERGE}" == "1" ]]; then
CMD+=(--enable-vru-merge)
fi
if [[ -n "${VIS_CLASSES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASSES_ARR=(${VIS_CLASSES})
CMD+=(--vis-classes "${VIS_CLASSES_ARR[@]}")
fi
if [[ -n "${VIS_CLASS_NAMES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASS_NAMES_ARR=(${VIS_CLASS_NAMES})
CMD+=(--vis-class-names "${VIS_CLASS_NAMES_ARR[@]}")
fi
if [[ "${SHOW_DISTANCE_LABEL}" == "1" ]]; then
CMD+=(--show-distance-label)
if [[ -n "${DISTANCE_LABEL_MODE}" ]]; then
CMD+=(--distance-label-mode "${DISTANCE_LABEL_MODE}")
fi
if [[ -n "${DISTANCE_LABEL_PANELS}" ]]; then
# shellcheck disable=SC2206
DISTANCE_LABEL_PANELS_ARR=(${DISTANCE_LABEL_PANELS})
CMD+=(--distance-label-panels "${DISTANCE_LABEL_PANELS_ARR[@]}")
fi
fi
if [[ -n "${SCENE}" ]]; then
CMD+=(--scene "${SCENE}")
fi
if [[ -n "${CONDITION_FIELDS}" ]]; then
# shellcheck disable=SC2206
CONDITION_FIELDS_ARR=(${CONDITION_FIELDS})
CMD+=(--condition-fields "${CONDITION_FIELDS_ARR[@]}")
fi
if [[ "${MAX_RECORDS_PER_CONDITION}" != "0" ]]; then
CMD+=(--max-records-per-condition "${MAX_RECORDS_PER_CONDITION}")
fi
if [[ -n "${CONDITION_SELECT_STRATEGY}" ]]; then
CMD+=(--condition-select-strategy "${CONDITION_SELECT_STRATEGY}")
fi
if [[ "${SELECTION_ONLY}" == "1" ]]; then
CMD+=(--selection-only)
fi
if [[ "${MAX_EVENTS}" != "0" ]]; then
CMD+=(--max-events "${MAX_EVENTS}")
fi
if [[ "${LIMIT_CLIPS}" != "0" ]]; then
CMD+=(--limit-clips "${LIMIT_CLIPS}")
fi
if [[ "${SKIP_DONE}" == "1" ]]; then
CMD+=(--skip-done)
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
CMD+=("$@")
if [[ "${CONVERT_ONLY}" == "1" ]]; then
echo ""
echo "######################################################################"
echo "# CONVERT_ONLY=1, skipping event-json clip export/inference and tracking"
echo "######################################################################"
echo "Conversion target: ${CONVERT_RESULTS_ROOT}"
elif [[ "${TRACK_ONLY}" == "1" ]]; then
echo ""
echo "######################################################################"
echo "# TRACK_ONLY=1, skipping event-json clip export/inference"
echo "######################################################################"
echo "Tracking root: ${OUTPUT_DIR}"
else
"${CMD[@]}"
fi
# ---------------------------------------------------------------------------
# Auto-tracking step
# ---------------------------------------------------------------------------
if [[ "${AUTO_TRACK}" == "1" ]]; then
TRACKING_SCRIPT="${PROJECT_ROOT}/tools/temporal_analysis/track_objects_exported_onnx_infer_event_json.sh"
if [[ ! -f "${TRACKING_SCRIPT}" ]]; then
echo "[AUTO_TRACK] ERROR: tracking script not found: ${TRACKING_SCRIPT}" >&2
exit 1
fi
echo ""
echo "######################################################################"
echo "# AUTO_TRACK=1 — starting event-level tracking on ${OUTPUT_DIR}"
echo "######################################################################"
TRACK_ENV=(
PYTHON_BIN="${PYTHON_BIN}"
RESULTS_ROOT="${OUTPUT_DIR}"
TRACK_CLASSES="${TRACK_CLASSES}"
IOU_THRESH="${TRACK_IOU_THRESH}"
MAX_AGE="${TRACK_MAX_AGE}"
MIN_HITS="${TRACK_MIN_HITS}"
DIST_THRESH="${TRACK_DIST_THRESH}"
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}"
FILE_PATTERN="${TRACK_FILE_PATTERN}"
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}"
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}"
MANIFEST_NAME="${TRACK_MANIFEST_NAME}"
)
if [[ -n "${TRACK_MODEL_VERSION}" ]]; then
TRACK_ENV+=(MODEL_VERSION="${TRACK_MODEL_VERSION}")
fi
if [[ -n "${TRACK_EVENT_TRACKING_DIRNAME}" ]]; then
TRACK_ENV+=(EVENT_TRACKING_DIRNAME="${TRACK_EVENT_TRACKING_DIRNAME}")
fi
# Propagate SCENE as SCENE_FILTER so tracking processes only the same scene.
if [[ -n "${SCENE}" ]]; then
TRACK_ENV+=(SCENE_FILTER="${SCENE}")
fi
env "${TRACK_ENV[@]}" bash "${TRACKING_SCRIPT}"
fi
# ---------------------------------------------------------------------------
# Post-tracking protocol conversion step
# ---------------------------------------------------------------------------
if [[ "${ENABLE_CONVERT}" == "1" ]]; then
if [[ ! -f "${CONVERT_WRAPPER}" ]]; then
echo "[ENABLE_CONVERT] ERROR: conversion script not found: ${CONVERT_WRAPPER}" >&2
exit 1
fi
echo ""
echo "######################################################################"
echo "# ENABLE_CONVERT=1 — converting tracking ${CONVERT_MERGE_JSON_NAME}"
echo "######################################################################"
echo "Conversion target: ${CONVERT_RESULTS_ROOT}"
echo "Conversion layout: ${CONVERT_OUTPUT_LAYOUT}"
if [[ "${CONVERT_OUTPUT_LAYOUT}" == "case_subdir" ]]; then
echo "Conversion subdir: ${CONVERT_OUTPUT_DIR_NAME}"
elif [[ -n "${CONVERT_OUTPUT_ROOT}" ]]; then
echo "Conversion output root: ${CONVERT_OUTPUT_ROOT}"
fi
CONVERT_ENV=(
PYTHON_BIN="${PYTHON_BIN}"
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT}"
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT}"
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}"
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}"
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS}"
CAM_ID="${CONVERT_CAM_ID}"
)
if [[ "${CONVERT_STRICT}" == "1" ]]; then
env "${CONVERT_ENV[@]}" bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"
else
if ! env "${CONVERT_ENV[@]}" bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"; then
echo "[WARN] Protocol conversion failed, but tracking outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi
fi

View File

@@ -0,0 +1,307 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Parallel launcher for event-json inference by scene.
#
# Strategy:
# 1. Read scene names from the top-level keys of EVENT_JSON_FILE.
# 2. Distribute scenes across GPU_IDS using round-robin or contiguous mode.
# 3. Each scene runs the existing event-json launcher in an isolated temp root.
# 4. After a scene succeeds, move scene artifacts into the final roots.
#
# This avoids concurrent writes to the same root-level manifest/status files while
# preserving the existing single-scene inference, tracking, and conversion logic.
WORKER_SCRIPT="${SCRIPT_DIR}/run_two_roi_exported_onnx_infer_event_json.sh"
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
EVENT_JSON_FILE="${EVENT_JSON_FILE:-${MODEL_INFERENCE_DIR}/examples/events/G1Q3_场地评测数据集.json}"
EVENT_ID_FIELD="${EVENT_ID_FIELD:-event_uuid}"
EVENT_CLIP_IDS_FIELD="${EVENT_CLIP_IDS_FIELD:-clips}"
GPU_IDS="${GPU_IDS:-0 1}"
SCENES="${SCENES:-}"
SCENE_REGEX="${SCENE_REGEX:-}"
MAX_SCENES="${MAX_SCENES:-0}"
SCENE_DISTRIBUTION="${SCENE_DISTRIBUTION:-round_robin}"
DRY_RUN="${DRY_RUN:-0}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/cncap/cncap_2021_with_cls_ego/model_20260506_keep_fake3d_validate}"
EXPORT_ROOT="${EXPORT_ROOT:-/data1/dongying/Mono3d/G1Q3/model_inference/cncap/cncap_2021_with_cls_ego/event_exports_new}"
CONVERT_OUTPUT_ROOT_BASE="${CONVERT_OUTPUT_ROOT:-${OUTPUT_DIR%/}_objectlist}"
PARALLEL_RUN_ID="${PARALLEL_RUN_ID:-$(date +%Y%m%d_%H%M%S)}"
PARALLEL_TMP_ROOT="${PARALLEL_TMP_ROOT:-${OUTPUT_DIR%/}/_parallel_scene_tmp/${PARALLEL_RUN_ID}}"
PARALLEL_LOG_DIR="${PARALLEL_LOG_DIR:-${OUTPUT_DIR%/}/parallel_scene_logs/${PARALLEL_RUN_ID}}"
SKIP_EXISTING_SCENES="${SKIP_EXISTING_SCENES:-0}"
FORWARD_ARGS=("$@")
discover_scenes() {
if [[ -n "${SCENES}" ]]; then
# shellcheck disable=SC2206
DISCOVERED_SCENES=(${SCENES})
else
mapfile -t DISCOVERED_SCENES < <(
"${PYTHON_BIN}" - "${EVENT_JSON_FILE}" <<'PY'
import json
import sys
json_path = sys.argv[1]
with open(json_path, encoding="utf-8") as file:
payload = json.load(file)
if not isinstance(payload, dict):
raise SystemExit(f"Expected top-level object in {json_path}, got {type(payload).__name__}")
for scene_name in sorted(payload):
print(scene_name)
PY
)
fi
if [[ -n "${SCENE_REGEX}" ]]; then
local -a filtered_scenes=()
local scene_name
for scene_name in "${DISCOVERED_SCENES[@]}"; do
if [[ "${scene_name}" =~ ${SCENE_REGEX} ]]; then
filtered_scenes+=("${scene_name}")
fi
done
DISCOVERED_SCENES=("${filtered_scenes[@]}")
fi
if [[ "${MAX_SCENES}" != "0" ]] && [[ "${MAX_SCENES}" -lt "${#DISCOVERED_SCENES[@]}" ]]; then
DISCOVERED_SCENES=("${DISCOVERED_SCENES[@]:0:${MAX_SCENES}}")
fi
if [[ "${#DISCOVERED_SCENES[@]}" -eq 0 ]]; then
echo "No scenes selected from ${EVENT_JSON_FILE}" >&2
exit 1
fi
}
scene_assigned_to_worker() {
local scene_index="$1"
local worker_index="$2"
local worker_count="$3"
case "${SCENE_DISTRIBUTION}" in
round_robin)
(( scene_index % worker_count == worker_index ))
;;
contiguous)
local start=$(( ${#DISCOVERED_SCENES[@]} * worker_index / worker_count ))
local end=$(( ${#DISCOVERED_SCENES[@]} * (worker_index + 1) / worker_count ))
(( scene_index >= start && scene_index < end ))
;;
*)
echo "Unsupported SCENE_DISTRIBUTION: ${SCENE_DISTRIBUTION}" >&2
exit 1
;;
esac
}
print_scene_plan() {
local worker_count="$1"
local worker_index
local scene_index
local scene_name
echo ""
echo "######################################################################"
echo "# Dry Run: scene to GPU assignment"
echo "######################################################################"
echo "Event JSON : ${EVENT_JSON_FILE}"
echo "Event id field : ${EVENT_ID_FIELD}"
echo "Clip ids field : ${EVENT_CLIP_IDS_FIELD}"
echo "Scenes : ${#DISCOVERED_SCENES[@]}"
echo "GPU ids : ${GPU_IDS}"
echo "Distribution : ${SCENE_DISTRIBUTION}"
echo "Output root : ${OUTPUT_DIR}"
echo "Export root : ${EXPORT_ROOT}"
echo "Convert root : ${CONVERT_OUTPUT_ROOT_BASE}"
echo "Temp root : ${PARALLEL_TMP_ROOT}"
echo "Worker logs : ${PARALLEL_LOG_DIR}"
for worker_index in "${!GPU_IDS_ARR[@]}"; do
echo ""
echo "[worker ${worker_index}] gpu=${GPU_IDS_ARR[${worker_index}]}"
for scene_index in "${!DISCOVERED_SCENES[@]}"; do
if ! scene_assigned_to_worker "${scene_index}" "${worker_index}" "${worker_count}"; then
continue
fi
scene_name="${DISCOVERED_SCENES[${scene_index}]}"
echo " - ${scene_name}"
done
done
}
move_scene_tree() {
local src_dir="$1"
local dst_dir="$2"
[[ -d "${src_dir}" ]] || return 0
if [[ -e "${dst_dir}" ]]; then
echo "Target already exists, refusing to overwrite: ${dst_dir}" >&2
return 1
fi
mkdir -p "$(dirname "${dst_dir}")"
mv "${src_dir}" "${dst_dir}"
}
run_one_scene() {
local gpu_id="$1"
local worker_index="$2"
local scene_name="$3"
local scene_tmp_root="${PARALLEL_TMP_ROOT%/}/worker_${worker_index}_gpu_${gpu_id}/${scene_name}"
local worker_output_root="${scene_tmp_root}/output_root"
local worker_export_root="${scene_tmp_root}/export_root"
local worker_convert_root="${scene_tmp_root}/convert_root"
local final_scene_output_dir="${OUTPUT_DIR%/}/${scene_name}"
local final_scene_export_dir="${EXPORT_ROOT%/}/${scene_name}"
local final_scene_convert_dir="${CONVERT_OUTPUT_ROOT_BASE%/}/${scene_name}"
local output_status_dir="${OUTPUT_DIR%/}/_status"
if [[ "${SKIP_EXISTING_SCENES}" == "1" ]] && [[ -d "${final_scene_output_dir}" ]]; then
echo "[GPU ${gpu_id}] skip existing scene: ${scene_name}"
return 0
fi
mkdir -p "${scene_tmp_root}"
echo "[GPU ${gpu_id}] start scene: ${scene_name}"
CUDA_VISIBLE_DEVICES="${gpu_id}" \
SCENE="${scene_name}" \
EVENT_ID_FIELD="${EVENT_ID_FIELD}" \
EVENT_CLIP_IDS_FIELD="${EVENT_CLIP_IDS_FIELD}" \
OUTPUT_DIR="${worker_output_root}" \
EXPORT_ROOT="${worker_export_root}" \
CONVERT_OUTPUT_ROOT="${worker_convert_root}" \
bash "${WORKER_SCRIPT}" "${FORWARD_ARGS[@]}"
move_scene_tree "${worker_output_root}/${scene_name}" "${final_scene_output_dir}"
move_scene_tree "${worker_export_root}/${scene_name}" "${final_scene_export_dir}"
if [[ "${CONVERT_OUTPUT_LAYOUT:-parallel_root}" == "parallel_root" ]]; then
move_scene_tree "${worker_convert_root}/${scene_name}" "${final_scene_convert_dir}"
fi
if [[ -f "${worker_output_root}/_status/event_scene_manifest.json" ]]; then
mkdir -p "${output_status_dir}"
cp "${worker_output_root}/_status/event_scene_manifest.json" \
"${output_status_dir}/${scene_name}_event_scene_manifest.json"
fi
echo "[GPU ${gpu_id}] finished scene: ${scene_name}"
}
launch_worker() {
local worker_index="$1"
local gpu_id="$2"
local worker_count="$3"
local log_file="${PARALLEL_LOG_DIR%/}/worker_${worker_index}_gpu_${gpu_id}.log"
local scene_index
local scene_name
local worker_failed=0
local worker_scene_count=0
for scene_index in "${!DISCOVERED_SCENES[@]}"; do
if scene_assigned_to_worker "${scene_index}" "${worker_index}" "${worker_count}"; then
((worker_scene_count+=1))
fi
done
echo "Launch worker ${worker_index} on GPU ${gpu_id}: ${worker_scene_count} scenes -> ${log_file}"
(
echo "Worker index : ${worker_index}"
echo "GPU id : ${gpu_id}"
echo "Scene count : ${worker_scene_count}"
echo "Distribution : ${SCENE_DISTRIBUTION}"
echo "Event JSON : ${EVENT_JSON_FILE}"
echo "Event id field : ${EVENT_ID_FIELD}"
echo "Clip ids field : ${EVENT_CLIP_IDS_FIELD}"
echo "Output root : ${OUTPUT_DIR}"
echo "Export root : ${EXPORT_ROOT}"
echo "Convert root : ${CONVERT_OUTPUT_ROOT_BASE}"
echo "Temp root : ${PARALLEL_TMP_ROOT}"
for scene_index in "${!DISCOVERED_SCENES[@]}"; do
if ! scene_assigned_to_worker "${scene_index}" "${worker_index}" "${worker_count}"; then
continue
fi
scene_name="${DISCOVERED_SCENES[${scene_index}]}"
if ! run_one_scene "${gpu_id}" "${worker_index}" "${scene_name}"; then
worker_failed=1
echo "[GPU ${gpu_id}] failed scene: ${scene_name}" >&2
fi
done
exit "${worker_failed}"
) >"${log_file}" 2>&1 &
WORKER_PIDS+=("$!")
WORKER_LOGS+=("${log_file}")
}
if [[ ! -f "${WORKER_SCRIPT}" ]]; then
echo "Worker script not found: ${WORKER_SCRIPT}" >&2
exit 1
fi
discover_scenes
# shellcheck disable=SC2206
GPU_IDS_ARR=(${GPU_IDS})
if [[ "${#GPU_IDS_ARR[@]}" -lt 1 ]]; then
echo "GPU_IDS must contain at least one GPU id." >&2
exit 1
fi
worker_count="${#GPU_IDS_ARR[@]}"
if [[ "${DRY_RUN}" == "1" ]]; then
print_scene_plan "${worker_count}"
exit 0
fi
mkdir -p "${PARALLEL_LOG_DIR}" "${OUTPUT_DIR}" "${EXPORT_ROOT}"
if [[ "${CONVERT_OUTPUT_LAYOUT:-parallel_root}" == "parallel_root" ]]; then
mkdir -p "${CONVERT_OUTPUT_ROOT_BASE}"
fi
echo ""
echo "######################################################################"
echo "# Parallel event-json inference by scene"
echo "######################################################################"
echo "Event JSON : ${EVENT_JSON_FILE}"
echo "Event id field : ${EVENT_ID_FIELD}"
echo "Clip ids field : ${EVENT_CLIP_IDS_FIELD}"
echo "Scenes : ${#DISCOVERED_SCENES[@]}"
echo "GPU ids : ${GPU_IDS}"
echo "Distribution : ${SCENE_DISTRIBUTION}"
echo "Output root : ${OUTPUT_DIR}"
echo "Export root : ${EXPORT_ROOT}"
echo "Convert root : ${CONVERT_OUTPUT_ROOT_BASE}"
echo "Temp root : ${PARALLEL_TMP_ROOT}"
echo "Worker logs : ${PARALLEL_LOG_DIR}"
WORKER_PIDS=()
WORKER_LOGS=()
for worker_index in "${!GPU_IDS_ARR[@]}"; do
launch_worker "${worker_index}" "${GPU_IDS_ARR[${worker_index}]}" "${worker_count}"
done
failed=0
for worker_index in "${!WORKER_PIDS[@]}"; do
if wait "${WORKER_PIDS[${worker_index}]}"; then
echo "Worker ${worker_index}/${worker_count} finished successfully. Log: ${WORKER_LOGS[${worker_index}]}"
else
echo "[ERROR] Worker ${worker_index}/${worker_count} failed. Log: ${WORKER_LOGS[${worker_index}]}" >&2
failed=1
fi
done
if [[ "${failed}" == "1" ]]; then
exit 1
fi
echo "All scene workers finished successfully."

View File

@@ -0,0 +1,280 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for one local .mcap file.
#
# Example:
# MCAP_FILE=/path/to/case.mcap bash tools/model_inference/scripts/run_two_roi_exported_onnx_infer_mcap.sh
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
MCAP_FILE="${MCAP_FILE:-/data1/dongying/Mono3d/G1Q3/tmp/mcap/20260428201929.mcap}"
MCAP_CLIP_ID="${MCAP_CLIP_ID:-}"
MCAP_DATE_NAME="${MCAP_DATE_NAME:-}"
MCAP_VEHICLE_NAME="${MCAP_VEHICLE_NAME:-local_mcap}"
EXPORT_ROOT="${EXPORT_ROOT:-/data1/dongying/Mono3d/G1Q3/model_inference/mcap/exports}"
OUTPUT_PREFIX="${OUTPUT_PREFIX:-mcap}"
CAMERA_TOPIC="${CAMERA_TOPIC:-camera4}"
CALIB_FILE="${CALIB_FILE:-}"
MAX_FRAMES_PER_CLIP="${MAX_FRAMES_PER_CLIP:-0}"
MAX_IMAGES="${MAX_IMAGES:-0}"
SKIP_DONE="${SKIP_DONE:-1}"
EXPORTED_MODEL="${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_20260423-raw_no_edge/merged_model.torchscript}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/mcap/model_20260423}"
DEVICE="${DEVICE:-}"
ATTR_DEVICE="${ATTR_DEVICE:-}"
ENABLE_ATTR="${ENABLE_ATTR:-0}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}"
ENABLE_VRU_MERGE="${ENABLE_VRU_MERGE:-1}"
VIS_CLASSES="${VIS_CLASSES:-}"
VIS_CLASS_NAMES="${VIS_CLASS_NAMES:-}"
SAVE_VISUALIZATION="${SAVE_VISUALIZATION:-1}"
SAVE_AGGREGATE_PREDICTIONS="${SAVE_AGGREGATE_PREDICTIONS:-0}"
SHOW_DISTANCE_LABEL="${SHOW_DISTANCE_LABEL:-1}"
DISTANCE_LABEL_MODE="${DISTANCE_LABEL_MODE:-depth}"
DISTANCE_LABEL_PANELS="${DISTANCE_LABEL_PANELS:-3d}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
# Optional post-inference tracking stage.
ENABLE_TRACKING="${ENABLE_TRACKING:-1}"
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING:-1}"
TRACK_STRICT="${TRACK_STRICT:-1}"
TRACK_RESULTS_ROOT="${TRACK_RESULTS_ROOT:-${OUTPUT_DIR}}"
TRACK_CLASSES="${TRACK_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12}"
TRACK_IOU_THRESH="${TRACK_IOU_THRESH:-0.3}"
TRACK_MAX_AGE="${TRACK_MAX_AGE:-5}"
TRACK_MIN_HITS="${TRACK_MIN_HITS:-1}"
TRACK_DIST_THRESH="${TRACK_DIST_THRESH:-100}"
TRACK_ENABLE_USE_3D="${TRACK_ENABLE_USE_3D:-0}"
TRACK_MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE:-10.0}"
TRACK_MAX_FRAMES="${TRACK_MAX_FRAMES:-}"
TRACK_MODEL_VERSION="${TRACK_MODEL_VERSION:-20260427}"
TRACK_FILE_PATTERN="${TRACK_FILE_PATTERN:-*.json}"
TRACK_MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME:-combined_tracking.json}"
TRACK_PARALLEL_JOBS="${TRACK_PARALLEL_JOBS:-1}"
TRACKING_WRAPPER="${PROJECT_ROOT}/tools/temporal_analysis/track_objects_exported_onnx_infer_case.sh"
# Optional post-tracking protocol conversion stage.
ENABLE_CONVERT="${ENABLE_CONVERT:-1}"
CONVERT_STRICT="${CONVERT_STRICT:-1}"
CONVERT_RESULTS_ROOT="${CONVERT_RESULTS_ROOT:-${TRACK_RESULTS_ROOT}}"
CONVERT_OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT:-}"
CONVERT_OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT:-case_subdir}"
CONVERT_OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME:-objectlist}"
CONVERT_MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME:-${TRACK_MERGE_OUTPUT_NAME}}"
CONVERT_CAM_ID="${CONVERT_CAM_ID:-}"
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS:-1}"
CONVERT_WRAPPER="${PROJECT_ROOT}/tools/convert_merge_tracking_bundle/convert_merge_tracking_exported_onnx_infer_case.sh"
if [[ -z "${MCAP_FILE}" ]]; then
echo "MCAP_FILE is required." >&2
exit 1
fi
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/core/run_two_roi_exported_onnx_infer.py"
--mcap-file "${MCAP_FILE}"
--export-root "${EXPORT_ROOT}"
--output-prefix "${OUTPUT_PREFIX}"
--camera-topic "${CAMERA_TOPIC}"
--max-frames-per-clip "${MAX_FRAMES_PER_CLIP}"
--exported-model "${EXPORTED_MODEL}"
--output-dir "${OUTPUT_DIR}"
)
if [[ -n "${MCAP_CLIP_ID}" ]]; then
CMD+=(--mcap-clip-id "${MCAP_CLIP_ID}")
fi
if [[ -n "${MCAP_DATE_NAME}" ]]; then
CMD+=(--mcap-date-name "${MCAP_DATE_NAME}")
fi
if [[ -n "${MCAP_VEHICLE_NAME}" ]]; then
CMD+=(--mcap-vehicle-name "${MCAP_VEHICLE_NAME}")
fi
if [[ -n "${CALIB_FILE}" ]]; then
CMD+=(--calib-file "${CALIB_FILE}")
fi
if [[ -n "${DEVICE}" ]]; then
CMD+=(--device "${DEVICE}")
fi
if [[ -n "${ATTR_DEVICE}" ]]; then
CMD+=(--attr-device "${ATTR_DEVICE}")
fi
if [[ "${ENABLE_ATTR}" == "1" ]]; then
CMD+=(--enable-attr)
fi
if [[ "${ENABLE_CROSS_CLASS_MERGE_PRIOR}" == "1" ]]; then
CMD+=(--enable-cross-class-merge-prior)
fi
if [[ "${ENABLE_VRU_MERGE}" == "1" ]]; then
CMD+=(--enable-vru-merge)
fi
if [[ -n "${VIS_CLASSES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASSES_ARR=(${VIS_CLASSES})
CMD+=(--vis-classes "${VIS_CLASSES_ARR[@]}")
fi
if [[ -n "${VIS_CLASS_NAMES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASS_NAMES_ARR=(${VIS_CLASS_NAMES})
CMD+=(--vis-class-names "${VIS_CLASS_NAMES_ARR[@]}")
fi
if [[ "${SHOW_DISTANCE_LABEL}" == "1" ]]; then
CMD+=(--show-distance-label)
CMD+=(--distance-label-mode "${DISTANCE_LABEL_MODE}")
if [[ -n "${DISTANCE_LABEL_PANELS}" ]]; then
# shellcheck disable=SC2206
DISTANCE_LABEL_PANELS_ARR=(${DISTANCE_LABEL_PANELS})
CMD+=(--distance-label-panels "${DISTANCE_LABEL_PANELS_ARR[@]}")
fi
fi
if [[ "${MAX_IMAGES}" != "0" ]]; then
CMD+=(--max-images "${MAX_IMAGES}")
fi
if [[ "${SKIP_DONE}" == "1" ]]; then
CMD+=(--skip-done)
fi
if [[ "${SAVE_VISUALIZATION}" != "1" ]]; then
CMD+=(--skip-visualizations)
fi
if [[ "${SAVE_AGGREGATE_PREDICTIONS}" == "1" ]]; then
CMD+=(--save-aggregate-predictions)
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
CMD+=("$@")
"${CMD[@]}"
if [[ "${ENABLE_TRACKING}" != "1" ]]; then
exit 0
fi
echo ""
echo "######################################################################"
echo "# Post-inference tracking for exported mcap output"
echo "######################################################################"
echo "Tracking target: ${TRACK_RESULTS_ROOT}"
if [[ "${TRACK_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
RESULTS_ROOT="${TRACK_RESULTS_ROOT}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
IOU_THRESH="${TRACK_IOU_THRESH}" \
MAX_AGE="${TRACK_MAX_AGE}" \
MIN_HITS="${TRACK_MIN_HITS}" \
DIST_THRESH="${TRACK_DIST_THRESH}" \
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
MAX_FRAMES="${TRACK_MAX_FRAMES}" \
MODEL_VERSION="${TRACK_MODEL_VERSION}" \
FILE_PATTERN="${TRACK_FILE_PATTERN}" \
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
TRACK_PARALLEL_JOBS="${TRACK_PARALLEL_JOBS}" \
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}" \
bash "${TRACKING_WRAPPER}" "${TRACK_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
RESULTS_ROOT="${TRACK_RESULTS_ROOT}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
IOU_THRESH="${TRACK_IOU_THRESH}" \
MAX_AGE="${TRACK_MAX_AGE}" \
MIN_HITS="${TRACK_MIN_HITS}" \
DIST_THRESH="${TRACK_DIST_THRESH}" \
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
MAX_FRAMES="${TRACK_MAX_FRAMES}" \
MODEL_VERSION="${TRACK_MODEL_VERSION}" \
FILE_PATTERN="${TRACK_FILE_PATTERN}" \
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
TRACK_PARALLEL_JOBS="${TRACK_PARALLEL_JOBS}" \
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}" \
bash "${TRACKING_WRAPPER}" "${TRACK_RESULTS_ROOT}"; then
echo "[WARN] Tracking failed, but inference outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi
if [[ "${ENABLE_CONVERT}" != "1" ]]; then
exit 0
fi
CONVERT_OUTPUT_ROOT_EFFECTIVE="${CONVERT_OUTPUT_ROOT}"
CONVERT_OUTPUT_LAYOUT_EFFECTIVE="${CONVERT_OUTPUT_LAYOUT}"
case "${CONVERT_OUTPUT_LAYOUT}" in
same_dir)
if [[ -f "${CONVERT_RESULTS_ROOT}" ]] || [[ "$(basename "${CONVERT_RESULTS_ROOT}")" == "${CONVERT_MERGE_JSON_NAME}" ]]; then
CONVERT_OUTPUT_ROOT_EFFECTIVE="$(dirname "${CONVERT_RESULTS_ROOT}")"
else
CONVERT_OUTPUT_ROOT_EFFECTIVE="${CONVERT_RESULTS_ROOT%/}"
fi
CONVERT_OUTPUT_LAYOUT_EFFECTIVE="parallel_root"
;;
case_subdir|parallel_root)
;;
*)
echo "Unsupported CONVERT_OUTPUT_LAYOUT: ${CONVERT_OUTPUT_LAYOUT}" >&2
echo "Expected one of: same_dir, case_subdir, parallel_root" >&2
exit 1
;;
esac
echo ""
echo "######################################################################"
echo "# Post-tracking protocol conversion for exported mcap output"
echo "######################################################################"
echo "Conversion target: ${CONVERT_RESULTS_ROOT}"
echo "Conversion layout: ${CONVERT_OUTPUT_LAYOUT}"
if [[ "${CONVERT_OUTPUT_LAYOUT}" == "same_dir" ]]; then
echo "Conversion output: same directory as tracking results"
elif [[ "${CONVERT_OUTPUT_LAYOUT}" == "case_subdir" ]]; then
echo "Conversion subdir: ${CONVERT_OUTPUT_DIR_NAME}"
elif [[ -n "${CONVERT_OUTPUT_ROOT_EFFECTIVE}" ]]; then
echo "Conversion output root: ${CONVERT_OUTPUT_ROOT_EFFECTIVE}"
fi
if [[ "${CONVERT_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT_EFFECTIVE}" \
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT_EFFECTIVE}" \
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT_EFFECTIVE}" \
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT_EFFECTIVE}" \
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CONVERT_PARALLEL_JOBS="${CONVERT_PARALLEL_JOBS}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"; then
echo "[WARN] Protocol conversion failed, but tracking outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi

View File

@@ -0,0 +1,232 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for single video-case inference.
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
VIDEO_CASE_DIR="${VIDEO_CASE_DIR:-/data1/dongying/Mono3d/G1Q3/tmp/20260507/20260507165034/sigmastar.1/camera4.bin}"
# VIDEO_CASE_DIR="${VIDEO_CASE_DIR:-/mnt/G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LF_AEB_30_4_20251118162753/sigmastar.1/camera4.bin}"
# VIDEO_CASE_DIR="${VIDEO_CASE_DIR:-/mnt/G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251118/CVE/CPTN_LN_AEB_30_1_20251118155909/sigmastar.1/camera4.bin}"
# VIDEO_CASE_DIR="${VIDEO_CASE_DIR:-/mnt/G1M3/gt_org_data/G1M3_AFS1616/CNCAP2024数采/20251121/CVE/CPLA_RL_FCW_NIGHT_60_1_20251120201141/sigmastar.1/camera4.bin}"
VIDEO_STRIDE="${VIDEO_STRIDE:-1}"
EXPORTED_MODEL="${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_20260427-raw_no_edge/merged_model.torchscript}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/tmp/20260507_results/model_20260427/20260507165034}"
# OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/tmp/20260416/CPLA_RL_FCW_NIGHT_60_1_20251120201141}"
MAX_IMAGES="${MAX_IMAGES:-1000}"
ENABLE_ATTR="${ENABLE_ATTR:-0}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}"
ENABLE_VRU_MERGE="${ENABLE_VRU_MERGE:-1}"
VIS_CLASSES="${VIS_CLASSES:-}"
VIS_CLASS_NAMES="${VIS_CLASS_NAMES:-}"
SHOW_DISTANCE_LABEL="${SHOW_DISTANCE_LABEL:-1}"
DISTANCE_LABEL_MODE="${DISTANCE_LABEL_MODE:-depth}"
DISTANCE_LABEL_PANELS="${DISTANCE_LABEL_PANELS:-3d}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
# Optional post-inference tracking stage. When enabled, the launcher reuses
# the exported-inference tracking wrapper, which runs track_objects.py over
# predictions/{roi0,roi1,merge} and merges the results for this case.
ENABLE_TRACKING="${ENABLE_TRACKING:-1}"
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING:-1}"
TRACK_STRICT="${TRACK_STRICT:-1}"
TRACK_RESULTS_ROOT="${TRACK_RESULTS_ROOT:-${OUTPUT_DIR}}"
TRACK_CLASSES="${TRACK_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12 17 18 19}"
TRACK_IOU_THRESH="${TRACK_IOU_THRESH:-0.3}"
TRACK_MAX_AGE="${TRACK_MAX_AGE:-5}"
TRACK_MIN_HITS="${TRACK_MIN_HITS:-1}"
TRACK_DIST_THRESH="${TRACK_DIST_THRESH:-100}"
TRACK_ENABLE_USE_3D="${TRACK_ENABLE_USE_3D:-0}"
TRACK_MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE:-10.0}"
TRACK_MAX_FRAMES="${TRACK_MAX_FRAMES:-}"
TRACK_MODEL_VERSION="${TRACK_MODEL_VERSION:-20260506}"
TRACK_FILE_PATTERN="${TRACK_FILE_PATTERN:-*.json}"
TRACK_MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME:-combined_tracking.json}"
TRACKING_WRAPPER="${PROJECT_ROOT}/tools/temporal_analysis/track_objects_exported_onnx_infer_case.sh"
# Optional post-tracking protocol-conversion stage.
# Runs convert_merge_tracking_exported_onnx_infer_case.sh on the case output
# directory to produce ObjectPerceptionObjectList.{data.json,bin,index.json}.
# By default, converted protocol files are written into the same directory as
# the tracking result. Override CONVERT_OUTPUT_LAYOUT=case_subdir to emit into
# {case_dir}/{CONVERT_OUTPUT_DIR_NAME}/, or use parallel_root with an explicit
# CONVERT_OUTPUT_ROOT to mirror outputs into another root.
ENABLE_CONVERT="${ENABLE_CONVERT:-1}"
CONVERT_STRICT="${CONVERT_STRICT:-1}"
CONVERT_RESULTS_ROOT="${CONVERT_RESULTS_ROOT:-${OUTPUT_DIR}}"
CONVERT_OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT:-}"
CONVERT_OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT:-case_subdir}"
CONVERT_OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME:-objectlist}"
CONVERT_MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME:-${TRACK_MERGE_OUTPUT_NAME}}"
CONVERT_CAM_ID="${CONVERT_CAM_ID:-}"
CONVERT_WRAPPER="${PROJECT_ROOT}/tools/convert_merge_tracking_bundle/convert_merge_tracking_exported_onnx_infer_case.sh"
if [[ -z "${VIDEO_CASE_DIR}" ]]; then
echo "VIDEO_CASE_DIR is required." >&2
exit 1
fi
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/core/run_two_roi_exported_onnx_infer.py"
--video-case-dir "${VIDEO_CASE_DIR}"
--video-stride "${VIDEO_STRIDE}"
--exported-model "${EXPORTED_MODEL}"
--output-dir "${OUTPUT_DIR}"
)
if [[ "${ENABLE_ATTR}" == "1" ]]; then
CMD+=(--enable-attr)
fi
if [[ "${ENABLE_CROSS_CLASS_MERGE_PRIOR}" == "1" ]]; then
CMD+=(--enable-cross-class-merge-prior)
fi
if [[ "${ENABLE_VRU_MERGE}" == "1" ]]; then
CMD+=(--enable-vru-merge)
fi
if [[ -n "${VIS_CLASSES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASSES_ARR=(${VIS_CLASSES})
CMD+=(--vis-classes "${VIS_CLASSES_ARR[@]}")
fi
if [[ -n "${VIS_CLASS_NAMES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASS_NAMES_ARR=(${VIS_CLASS_NAMES})
CMD+=(--vis-class-names "${VIS_CLASS_NAMES_ARR[@]}")
fi
if [[ "${SHOW_DISTANCE_LABEL}" == "1" ]]; then
CMD+=(--show-distance-label)
CMD+=(--distance-label-mode "${DISTANCE_LABEL_MODE}")
if [[ -n "${DISTANCE_LABEL_PANELS}" ]]; then
# shellcheck disable=SC2206
DISTANCE_LABEL_PANELS_ARR=(${DISTANCE_LABEL_PANELS})
CMD+=(--distance-label-panels "${DISTANCE_LABEL_PANELS_ARR[@]}")
fi
fi
if [[ "${MAX_IMAGES}" != "0" ]]; then
CMD+=(--max-images "${MAX_IMAGES}")
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
CMD+=("$@")
"${CMD[@]}"
if [[ "${ENABLE_TRACKING}" != "1" ]]; then
exit 0
fi
echo ""
echo "######################################################################"
echo "# Post-inference tracking for exported video-case output"
echo "######################################################################"
echo "Tracking target: ${TRACK_RESULTS_ROOT}"
if [[ "${TRACK_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
RESULTS_ROOT="${TRACK_RESULTS_ROOT}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
IOU_THRESH="${TRACK_IOU_THRESH}" \
MAX_AGE="${TRACK_MAX_AGE}" \
MIN_HITS="${TRACK_MIN_HITS}" \
DIST_THRESH="${TRACK_DIST_THRESH}" \
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
MAX_FRAMES="${TRACK_MAX_FRAMES}" \
MODEL_VERSION="${TRACK_MODEL_VERSION}" \
FILE_PATTERN="${TRACK_FILE_PATTERN}" \
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}" \
bash "${TRACKING_WRAPPER}" "${TRACK_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
RESULTS_ROOT="${TRACK_RESULTS_ROOT}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
IOU_THRESH="${TRACK_IOU_THRESH}" \
MAX_AGE="${TRACK_MAX_AGE}" \
MIN_HITS="${TRACK_MIN_HITS}" \
DIST_THRESH="${TRACK_DIST_THRESH}" \
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
MAX_FRAMES="${TRACK_MAX_FRAMES}" \
MODEL_VERSION="${TRACK_MODEL_VERSION}" \
FILE_PATTERN="${TRACK_FILE_PATTERN}" \
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}" \
bash "${TRACKING_WRAPPER}" "${TRACK_RESULTS_ROOT}"; then
echo "[WARN] Tracking failed, but inference outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi
if [[ "${ENABLE_CONVERT}" != "1" ]]; then
exit 0
fi
CONVERT_OUTPUT_ROOT_EFFECTIVE="${CONVERT_OUTPUT_ROOT}"
CONVERT_OUTPUT_LAYOUT_EFFECTIVE="${CONVERT_OUTPUT_LAYOUT}"
case "${CONVERT_OUTPUT_LAYOUT}" in
same_dir)
if [[ -f "${CONVERT_RESULTS_ROOT}" ]] || [[ "$(basename "${CONVERT_RESULTS_ROOT}")" == "${CONVERT_MERGE_JSON_NAME}" ]]; then
CONVERT_OUTPUT_ROOT_EFFECTIVE="$(dirname "${CONVERT_RESULTS_ROOT}")"
else
CONVERT_OUTPUT_ROOT_EFFECTIVE="${CONVERT_RESULTS_ROOT%/}"
fi
CONVERT_OUTPUT_LAYOUT_EFFECTIVE="parallel_root"
;;
case_subdir|parallel_root)
;;
*)
echo "Unsupported CONVERT_OUTPUT_LAYOUT: ${CONVERT_OUTPUT_LAYOUT}" >&2
echo "Expected one of: same_dir, case_subdir, parallel_root" >&2
exit 1
;;
esac
echo ""
echo "######################################################################"
echo "# Post-tracking protocol conversion for exported video-case output"
echo "######################################################################"
echo "Conversion target: ${CONVERT_RESULTS_ROOT}"
echo "Conversion layout: ${CONVERT_OUTPUT_LAYOUT}"
if [[ "${CONVERT_OUTPUT_LAYOUT}" == "same_dir" ]]; then
echo "Conversion output: same directory as tracking results"
elif [[ "${CONVERT_OUTPUT_LAYOUT}" == "case_subdir" ]]; then
echo "Conversion subdir: ${CONVERT_OUTPUT_DIR_NAME}"
elif [[ -n "${CONVERT_OUTPUT_ROOT_EFFECTIVE}" ]]; then
echo "Conversion output root: ${CONVERT_OUTPUT_ROOT_EFFECTIVE}"
fi
if [[ "${CONVERT_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT_EFFECTIVE}" \
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT_EFFECTIVE}" \
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT_EFFECTIVE}" \
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT_EFFECTIVE}" \
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"; then
echo "[WARN] Protocol conversion failed, but tracking outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi

View File

@@ -0,0 +1,262 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
# Launcher for batch video-root inference.
#
# Supported postprocess-only mode:
# POSTPROCESS_ONLY=1 OUTPUT_DIR=<inference-output-root> bash run_two_roi_exported_onnx_infer_video_root.sh
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
VIDEO_ROOT_DIR="${VIDEO_ROOT_DIR:-/data1/dongying/Mono3d/G1Q3/tmp/20260507}"
# VIDEO_ROOT_DIR="${VIDEO_ROOT_DIR:-/data1/dongying/Mono3d/G1Q3/dataset_for_evaluation/CNCAP/CSTA_LN}"
VIDEO_STRIDE="${VIDEO_STRIDE:-1}"
EXPORTED_MODEL="${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_20260506-drop_fake_3d_branch/merged_model.torchscript}"
# OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1M3/test_outputs/video_case_model_20260416_with_cls}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/tmp/20260507_results/model_20260507_drop_fake3d}"
MAX_IMAGES="${MAX_IMAGES:-0}"
ENABLE_ATTR="${ENABLE_ATTR:-1}"
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}"
ENABLE_VRU_MERGE="${ENABLE_VRU_MERGE:-1}"
VIS_CLASSES="${VIS_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12 17 18 19}"
VIS_CLASS_NAMES="${VIS_CLASS_NAMES:-}"
SHOW_DISTANCE_LABEL="${SHOW_DISTANCE_LABEL:-1}"
# depth_lateral keeps the existing longitudinal z label and adds signed
# camera-frame lateral x offset. Override with depth/lateral/xz/etc if needed.
DISTANCE_LABEL_MODE="${DISTANCE_LABEL_MODE:-depth_lateral}"
DISTANCE_LABEL_PANELS="${DISTANCE_LABEL_PANELS:-3d}"
EXTRA_ARGS="${EXTRA_ARGS:-}"
POSTPROCESS_ONLY="${POSTPROCESS_ONLY:-0}"
# Optional post-inference tracking stage. When enabled, the launcher reuses
# the exported-inference tracking wrapper, which runs track_objects.py over
# predictions/{roi0,roi1,merge} and merges the results per case.
ENABLE_TRACKING="${ENABLE_TRACKING:-1}"
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING:-0}"
TRACK_STRICT="${TRACK_STRICT:-1}"
TRACK_RESULTS_ROOT="${TRACK_RESULTS_ROOT:-${OUTPUT_DIR}}"
TRACK_CLASSES="${TRACK_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12 17 18 19}"
TRACK_IOU_THRESH="${TRACK_IOU_THRESH:-0.3}"
TRACK_MAX_AGE="${TRACK_MAX_AGE:-5}"
TRACK_MIN_HITS="${TRACK_MIN_HITS:-1}"
TRACK_DIST_THRESH="${TRACK_DIST_THRESH:-100}"
TRACK_ENABLE_USE_3D="${TRACK_ENABLE_USE_3D:-0}"
TRACK_MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE:-10.0}"
TRACK_MAX_FRAMES="${TRACK_MAX_FRAMES:-}"
TRACK_MODEL_VERSION="${TRACK_MODEL_VERSION:-20260427}"
TRACK_FILE_PATTERN="${TRACK_FILE_PATTERN:-*.json}"
TRACK_MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME:-combined_tracking.json}"
TRACKING_WRAPPER="${PROJECT_ROOT}/tools/temporal_analysis/track_objects_exported_onnx_infer_case.sh"
# Optional post-tracking protocol-conversion stage.
# Runs convert_merge_tracking_exported_onnx_infer_case.sh on the tracked
# video-root output tree. By default, each case writes converted protobuf
# artifacts into its own objectlist/ subdirectory.
ENABLE_CONVERT="${ENABLE_CONVERT:-1}"
CONVERT_STRICT="${CONVERT_STRICT:-1}"
CONVERT_RESULTS_ROOT="${CONVERT_RESULTS_ROOT:-${TRACK_RESULTS_ROOT}}"
CONVERT_OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT:-}"
CONVERT_OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT:-case_subdir}"
CONVERT_OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME:-objectlist}"
CONVERT_MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME:-${TRACK_MERGE_OUTPUT_NAME}}"
CONVERT_CAM_ID="${CONVERT_CAM_ID:-}"
CONVERT_WRAPPER="${PROJECT_ROOT}/tools/convert_merge_tracking_bundle/convert_merge_tracking_exported_onnx_infer_case.sh"
ENABLE_CONVERT_VRU="${ENABLE_CONVERT_VRU:-0}"
CONVERT_VRU_OUTPUT_ROOT="${CONVERT_VRU_OUTPUT_ROOT:-}"
CONVERT_VRU_OUTPUT_LAYOUT="${CONVERT_VRU_OUTPUT_LAYOUT:-case_subdir}"
CONVERT_VRU_OUTPUT_DIR_NAME="${CONVERT_VRU_OUTPUT_DIR_NAME:-objectlist_vru}"
CONVERT_VRU_MERGE_JSON_NAME="${CONVERT_VRU_MERGE_JSON_NAME:-merge_vru.json}"
if [[ "${POSTPROCESS_ONLY}" != "1" && -z "${VIDEO_ROOT_DIR}" ]]; then
echo "VIDEO_ROOT_DIR is required." >&2
exit 1
fi
CMD=(
"${PYTHON_BIN}" "${MODEL_INFERENCE_DIR}/core/run_two_roi_exported_onnx_infer.py"
--video-root-dir "${VIDEO_ROOT_DIR}"
--video-stride "${VIDEO_STRIDE}"
--exported-model "${EXPORTED_MODEL}"
--output-dir "${OUTPUT_DIR}"
)
if [[ "${ENABLE_ATTR}" == "1" ]]; then
CMD+=(--enable-attr)
fi
if [[ "${ENABLE_CROSS_CLASS_MERGE_PRIOR}" == "1" ]]; then
CMD+=(--enable-cross-class-merge-prior)
fi
if [[ "${ENABLE_VRU_MERGE}" == "1" ]]; then
CMD+=(--enable-vru-merge)
fi
if [[ -n "${VIS_CLASSES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASSES_ARR=(${VIS_CLASSES})
CMD+=(--vis-classes "${VIS_CLASSES_ARR[@]}")
fi
if [[ -n "${VIS_CLASS_NAMES}" ]]; then
# shellcheck disable=SC2206
VIS_CLASS_NAMES_ARR=(${VIS_CLASS_NAMES})
CMD+=(--vis-class-names "${VIS_CLASS_NAMES_ARR[@]}")
fi
if [[ "${SHOW_DISTANCE_LABEL}" == "1" ]]; then
CMD+=(--show-distance-label)
CMD+=(--distance-label-mode "${DISTANCE_LABEL_MODE}")
if [[ -n "${DISTANCE_LABEL_PANELS}" ]]; then
# shellcheck disable=SC2206
DISTANCE_LABEL_PANELS_ARR=(${DISTANCE_LABEL_PANELS})
CMD+=(--distance-label-panels "${DISTANCE_LABEL_PANELS_ARR[@]}")
fi
fi
if [[ "${MAX_IMAGES}" != "0" ]]; then
CMD+=(--max-images "${MAX_IMAGES}")
fi
if [[ -n "${EXTRA_ARGS}" ]]; then
# shellcheck disable=SC2206
EXTRA_ARR=(${EXTRA_ARGS})
CMD+=("${EXTRA_ARR[@]}")
fi
CMD+=("$@")
if [[ "${POSTPROCESS_ONLY}" == "1" ]]; then
echo ""
echo "######################################################################"
echo "# POSTPROCESS_ONLY=1, skipping inference"
echo "######################################################################"
echo "Postprocess root: ${OUTPUT_DIR}"
else
"${CMD[@]}"
fi
if [[ "${ENABLE_TRACKING}" == "1" ]]; then
echo ""
echo "######################################################################"
echo "# Post-inference tracking for exported video-root outputs"
echo "######################################################################"
echo "Tracking root: ${TRACK_RESULTS_ROOT}"
if [[ "${TRACK_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
RESULTS_ROOT="${TRACK_RESULTS_ROOT}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
IOU_THRESH="${TRACK_IOU_THRESH}" \
MAX_AGE="${TRACK_MAX_AGE}" \
MIN_HITS="${TRACK_MIN_HITS}" \
DIST_THRESH="${TRACK_DIST_THRESH}" \
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
MAX_FRAMES="${TRACK_MAX_FRAMES}" \
MODEL_VERSION="${TRACK_MODEL_VERSION}" \
FILE_PATTERN="${TRACK_FILE_PATTERN}" \
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}" \
bash "${TRACKING_WRAPPER}" "${TRACK_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
RESULTS_ROOT="${TRACK_RESULTS_ROOT}" \
TRACK_CLASSES="${TRACK_CLASSES}" \
IOU_THRESH="${TRACK_IOU_THRESH}" \
MAX_AGE="${TRACK_MAX_AGE}" \
MIN_HITS="${TRACK_MIN_HITS}" \
DIST_THRESH="${TRACK_DIST_THRESH}" \
ENABLE_USE_3D="${TRACK_ENABLE_USE_3D}" \
MAX_3D_DISTANCE="${TRACK_MAX_3D_DISTANCE}" \
MAX_FRAMES="${TRACK_MAX_FRAMES}" \
MODEL_VERSION="${TRACK_MODEL_VERSION}" \
FILE_PATTERN="${TRACK_FILE_PATTERN}" \
MERGE_OUTPUT_NAME="${TRACK_MERGE_OUTPUT_NAME}" \
ENABLE_VRU_TRACKING="${ENABLE_VRU_TRACKING}" \
bash "${TRACKING_WRAPPER}" "${TRACK_RESULTS_ROOT}"; then
echo "[WARN] Tracking failed, but inference outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi
elif [[ "${ENABLE_CONVERT}" != "1" ]]; then
exit 0
fi
if [[ "${ENABLE_CONVERT}" != "1" ]]; then
exit 0
fi
echo ""
echo "######################################################################"
echo "# Post-tracking protocol conversion for exported video-root outputs"
echo "######################################################################"
echo "Conversion target: ${CONVERT_RESULTS_ROOT}"
echo "Conversion layout: ${CONVERT_OUTPUT_LAYOUT}"
if [[ "${CONVERT_OUTPUT_LAYOUT}" == "case_subdir" ]]; then
echo "Conversion subdir: ${CONVERT_OUTPUT_DIR_NAME}"
elif [[ -n "${CONVERT_OUTPUT_ROOT}" ]]; then
echo "Conversion output root: ${CONVERT_OUTPUT_ROOT}"
fi
if [[ "${CONVERT_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT}" \
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT}" \
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
OUTPUT_ROOT="${CONVERT_OUTPUT_ROOT}" \
OUTPUT_LAYOUT="${CONVERT_OUTPUT_LAYOUT}" \
OUTPUT_DIR_NAME="${CONVERT_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_MERGE_JSON_NAME}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"; then
echo "[WARN] Protocol conversion failed, but tracking outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi
if [[ "${ENABLE_CONVERT_VRU}" == "1" ]]; then
echo ""
echo "######################################################################"
echo "# Post-tracking protocol conversion for VRU tracking outputs"
echo "######################################################################"
echo "VRU conversion target: ${CONVERT_RESULTS_ROOT}"
echo "VRU conversion layout: ${CONVERT_VRU_OUTPUT_LAYOUT}"
if [[ "${CONVERT_VRU_OUTPUT_LAYOUT}" == "case_subdir" ]]; then
echo "VRU conversion subdir: ${CONVERT_VRU_OUTPUT_DIR_NAME}"
elif [[ -n "${CONVERT_VRU_OUTPUT_ROOT}" ]]; then
echo "VRU conversion output root: ${CONVERT_VRU_OUTPUT_ROOT}"
fi
if [[ -d "${CONVERT_RESULTS_ROOT}" ]] && [[ -n "$(find "${CONVERT_RESULTS_ROOT}" -type f -name "${CONVERT_VRU_MERGE_JSON_NAME}" -print -quit)" ]]; then
if [[ "${CONVERT_STRICT}" == "1" ]]; then
PYTHON_BIN="${PYTHON_BIN}" \
OUTPUT_ROOT="${CONVERT_VRU_OUTPUT_ROOT}" \
OUTPUT_LAYOUT="${CONVERT_VRU_OUTPUT_LAYOUT}" \
OUTPUT_DIR_NAME="${CONVERT_VRU_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_VRU_MERGE_JSON_NAME}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"
else
if ! PYTHON_BIN="${PYTHON_BIN}" \
OUTPUT_ROOT="${CONVERT_VRU_OUTPUT_ROOT}" \
OUTPUT_LAYOUT="${CONVERT_VRU_OUTPUT_LAYOUT}" \
OUTPUT_DIR_NAME="${CONVERT_VRU_OUTPUT_DIR_NAME}" \
MERGE_JSON_NAME="${CONVERT_VRU_MERGE_JSON_NAME}" \
CAM_ID="${CONVERT_CAM_ID}" \
bash "${CONVERT_WRAPPER}" "${CONVERT_RESULTS_ROOT}"; then
echo "[WARN] VRU protocol conversion failed, but tracking outputs were kept under ${OUTPUT_DIR}" >&2
fi
fi
else
echo "Info: no ${CONVERT_VRU_MERGE_JSON_NAME} files found under ${CONVERT_RESULTS_ROOT}, skipping VRU protocol conversion"
fi
fi

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LAUNCHER="${SCRIPT_DIR}/run_two_roi_exported_onnx_infer_case.sh"
# 用途:在重跑 worker 全部完成后,统一执行 tracking 和 convert。
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/KPI/OP_KPI_SCENE/model_20260427-raw_no_edge}"
ENABLE_TRACKING="${ENABLE_TRACKING:-1}"
ENABLE_CONVERT="${ENABLE_CONVERT:-1}"
echo "Running postprocess only"
echo "Launcher : ${LAUNCHER}"
echo "Postprocess dir: ${OUTPUT_DIR}"
echo "Tracking : ${ENABLE_TRACKING}"
echo "Convert : ${ENABLE_CONVERT}"
env \
POSTPROCESS_ONLY=1 \
ENABLE_TRACKING="${ENABLE_TRACKING}" \
ENABLE_CONVERT="${ENABLE_CONVERT}" \
OUTPUT_DIR="${OUTPUT_DIR}" \
bash "${LAUNCHER}"

View File

@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LAUNCHER="${SCRIPT_DIR}/run_two_roi_exported_onnx_infer_case.sh"
# 用途:重跑最后 4 个未处理的 case且不保存 visualizations。
# 前置条件:
# 1. 已停止旧的推理进程
# 2. 已按步骤 3 清理目标 case 的旧输出目录
# 区间语义CASE_INDEX_START/END 使用 0-based 且为 [start, end)
# 当前默认区间对应 2026-04-28 的运行快照:
# - GPU0: 第 70 到第 71 个 case -> [69, 71)
# - GPU1: 第 72 到第 73 个 case -> [71, 73)
INPUT_DIR="${INPUT_DIR:-/data1/dongying/Mono3d/G1Q3/dataset_for_evaluation/OP_KPI_SCENE}"
OUTPUT_DIR="${OUTPUT_DIR:-/data1/dongying/Mono3d/G1Q3/model_inference/KPI/OP_KPI_SCENE/model_20260427-raw_no_edge}"
EXPORTED_MODEL="${EXPORTED_MODEL:-/deeplearning_team/ydong/dongying/projects/yolo26-3d/runs/export/train_mono3d_two_roi_20260427-raw_no_edge/merged_model.torchscript}"
PARALLEL_LOG_DIR="${PARALLEL_LOG_DIR:-${OUTPUT_DIR%/}/parallel_logs}"
GPU0_ID="${GPU0_ID:-0}"
GPU0_CASE_INDEX_START="${GPU0_CASE_INDEX_START:-69}"
GPU0_CASE_INDEX_END="${GPU0_CASE_INDEX_END:-71}"
GPU0_LOG="${GPU0_LOG:-${PARALLEL_LOG_DIR}/rerun_gpu${GPU0_ID}_${GPU0_CASE_INDEX_START}_${GPU0_CASE_INDEX_END}.log}"
GPU1_ID="${GPU1_ID:-1}"
GPU1_CASE_INDEX_START="${GPU1_CASE_INDEX_START:-71}"
GPU1_CASE_INDEX_END="${GPU1_CASE_INDEX_END:-73}"
GPU1_LOG="${GPU1_LOG:-${PARALLEL_LOG_DIR}/rerun_gpu${GPU1_ID}_${GPU1_CASE_INDEX_START}_${GPU1_CASE_INDEX_END}.log}"
mkdir -p "${PARALLEL_LOG_DIR}"
echo "Starting rerun workers with SAVE_VISUALIZATION=0"
echo "Launcher : ${LAUNCHER}"
echo "Input dir : ${INPUT_DIR}"
echo "Output dir : ${OUTPUT_DIR}"
echo "Exported model : ${EXPORTED_MODEL}"
echo "GPU${GPU0_ID} slice : [${GPU0_CASE_INDEX_START}, ${GPU0_CASE_INDEX_END}) -> ${GPU0_LOG}"
echo "GPU${GPU1_ID} slice : [${GPU1_CASE_INDEX_START}, ${GPU1_CASE_INDEX_END}) -> ${GPU1_LOG}"
nohup env \
SAVE_VISUALIZATION=0 \
ENABLE_TRACKING=0 \
ENABLE_CONVERT=0 \
DEVICE="cuda:${GPU0_ID}" \
ATTR_DEVICE="cuda:${GPU0_ID}" \
INPUT_DIR="${INPUT_DIR}" \
OUTPUT_DIR="${OUTPUT_DIR}" \
EXPORTED_MODEL="${EXPORTED_MODEL}" \
CASE_INDEX_START="${GPU0_CASE_INDEX_START}" \
CASE_INDEX_END="${GPU0_CASE_INDEX_END}" \
bash "${LAUNCHER}" \
>"${GPU0_LOG}" 2>&1 &
gpu0_pid=$!
nohup env \
SAVE_VISUALIZATION=0 \
ENABLE_TRACKING=0 \
ENABLE_CONVERT=0 \
DEVICE="cuda:${GPU1_ID}" \
ATTR_DEVICE="cuda:${GPU1_ID}" \
INPUT_DIR="${INPUT_DIR}" \
OUTPUT_DIR="${OUTPUT_DIR}" \
EXPORTED_MODEL="${EXPORTED_MODEL}" \
CASE_INDEX_START="${GPU1_CASE_INDEX_START}" \
CASE_INDEX_END="${GPU1_CASE_INDEX_END}" \
bash "${LAUNCHER}" \
>"${GPU1_LOG}" 2>&1 &
gpu1_pid=$!
echo "Started GPU${GPU0_ID} worker, PID=${gpu0_pid}"
echo "Started GPU${GPU1_ID} worker, PID=${gpu1_pid}"
echo "Use 'tail -f ${GPU0_LOG}' or 'tail -f ${GPU1_LOG}' to monitor progress."

View File

@@ -0,0 +1,346 @@
#!/usr/bin/env bash
set -euo pipefail
# 用法说明:
# 适配 run_two_roi_exported_onnx_infer_video_root.sh 的输出目录,对每个 case 执行:
# {case_dir}/merge.json -> {case_dir}/temporal_observation/stability_report.json
#
# 支持三种模式:
# 1) 批量模式(默认):遍历 RESULTS_ROOT 下所有包含 merge.json 的 case
# bash run_two_roi_exported_onnx_temporal_observe_video_root.sh
# 2) 指定根目录模式:第一个参数传推理/跟踪输出根目录
# bash run_two_roi_exported_onnx_temporal_observe_video_root.sh /path/to/inference_output_root
# 3) 单 case 模式:第一个参数传 case 目录,或直接传 case_dir/merge.json
# bash run_two_roi_exported_onnx_temporal_observe_video_root.sh /path/to/one_case --track-id 32
# bash run_two_roi_exported_onnx_temporal_observe_video_root.sh /path/to/one_case/merge.json --track-id 32
#
# 默认读取 merge.json因为 combined_tracking.json 会给不同 source 的 track_id 加偏移,
# 不利于按单个目标 track_id 做精确筛选。
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODEL_INFERENCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
PROJECT_ROOT="$(cd "${MODEL_INFERENCE_DIR}/../.." && pwd)"
export PYTHONPATH="${PROJECT_ROOT}:${PYTHONPATH:-}"
RESULTS_ROOT="${RESULTS_ROOT:-/data1/dongying/Mono3d/G1M3/test_data/cncap_20260414/20260416103945}"
OUTPUT_ROOT="${OUTPUT_ROOT:-}"
OUTPUT_DIR_NAME="${OUTPUT_DIR_NAME:-temporal_observation}"
PYTHON_BIN="${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}"
TEMPORAL_SCRIPT="${TEMPORAL_SCRIPT:-${PROJECT_ROOT}/tools/temporal_analysis/evaluate_temporal_stability.py}"
TRACKING_JSON_NAME="${TRACKING_JSON_NAME:-merge.json}"
TEMPORAL_MIN_LENGTH="${TEMPORAL_MIN_LENGTH:-3}"
TEMPORAL_CLASS_ID="${TEMPORAL_CLASS_ID:-}"
TEMPORAL_TRACK_IDS="${TEMPORAL_TRACK_IDS:-20}"
TEMPORAL_FRAME_ID_START="${TEMPORAL_FRAME_ID_START:-325000}"
TEMPORAL_FRAME_ID_END="${TEMPORAL_FRAME_ID_END:-325200}"
TEMPORAL_PLOTS="${TEMPORAL_PLOTS:-0}"
TEMPORAL_EXPORT_SERIES="${TEMPORAL_EXPORT_SERIES:-1}"
TEMPORAL_FOCUS_TRACK_PLOTS="${TEMPORAL_FOCUS_TRACK_PLOTS:-1}"
TEMPORAL_PREFER_EGO="${TEMPORAL_PREFER_EGO:-1}"
TEMPORAL_X_AXIS="${TEMPORAL_X_AXIS:-frame_id}"
TEMPORAL_HEADING_SOURCE="${TEMPORAL_HEADING_SOURCE:-camera_reg}"
TARGET_PATH="/data1/dongying/Mono3d/G1Q3/dataset_for_evaluation/CNCAP/CSTA_LN_outputs/model_20260416/CSTA-LN_AEB_10_20_20260414141804"
CLI_TRACK_IDS=()
CLI_CLASS_ID=""
CLI_FRAME_ID_START=""
CLI_FRAME_ID_END=""
while (($# > 0)); do
case "$1" in
--track-id)
if (($# < 2)); then
echo "Error: --track-id requires a value" >&2
exit 1
fi
CLI_TRACK_IDS+=("$2")
shift 2
;;
--track-id=*)
CLI_TRACK_IDS+=("${1#*=}")
shift
;;
--class-id)
if (($# < 2)); then
echo "Error: --class-id requires a value" >&2
exit 1
fi
CLI_CLASS_ID="$2"
shift 2
;;
--class-id=*)
CLI_CLASS_ID="${1#*=}"
shift
;;
--frame-id-start)
if (($# < 2)); then
echo "Error: --frame-id-start requires a value" >&2
exit 1
fi
CLI_FRAME_ID_START="$2"
shift 2
;;
--frame-id-start=*)
CLI_FRAME_ID_START="${1#*=}"
shift
;;
--frame-id-end)
if (($# < 2)); then
echo "Error: --frame-id-end requires a value" >&2
exit 1
fi
CLI_FRAME_ID_END="$2"
shift 2
;;
--frame-id-end=*)
CLI_FRAME_ID_END="${1#*=}"
shift
;;
-*)
echo "Error: unsupported option: $1" >&2
exit 1
;;
*)
if [[ -n "${TARGET_PATH}" ]]; then
echo "Error: multiple target paths provided: ${TARGET_PATH} and $1" >&2
exit 1
fi
TARGET_PATH="$1"
shift
;;
esac
done
if [[ -z "${TARGET_PATH}" ]]; then
TARGET_PATH="${RESULTS_ROOT}"
fi
if [[ ! -e "${TARGET_PATH}" ]]; then
echo "Error: target path does not exist: ${TARGET_PATH}" >&2
exit 1
fi
resolve_abs_path() {
local target_path="$1"
if [[ -d "${target_path}" ]]; then
(
cd "${target_path}"
pwd -P
)
return 0
fi
local parent_dir
parent_dir=$(
cd "$(dirname "${target_path}")"
pwd -P
)
printf '%s/%s\n' "${parent_dir}" "$(basename "${target_path}")"
}
RESULTS_ROOT_ABS="$(resolve_abs_path "${RESULTS_ROOT}")"
is_case_dir() {
local dir_path="$1"
[[ -d "${dir_path}" ]] && [[ -f "${dir_path}/${TRACKING_JSON_NAME}" ]]
}
resolve_case_dir() {
local target_path="$1"
if is_case_dir "${target_path}"; then
printf '%s\n' "${target_path}"
return 0
fi
if [[ -f "${target_path}" ]] && [[ "$(basename "${target_path}")" == "${TRACKING_JSON_NAME}" ]]; then
dirname "${target_path}"
return 0
fi
return 1
}
derive_output_dir() {
local case_dir="$1"
local case_abs
local rel_case_dir
case_abs="$(resolve_abs_path "${case_dir}")"
if [[ -n "${OUTPUT_ROOT}" ]]; then
if [[ "${case_abs}" == "${RESULTS_ROOT_ABS}" ]]; then
printf '%s\n' "${OUTPUT_ROOT}"
return 0
fi
if [[ "${case_abs}" == "${RESULTS_ROOT_ABS}"/* ]]; then
rel_case_dir="${case_abs#"${RESULTS_ROOT_ABS}/"}"
printf '%s/%s\n' "${OUTPUT_ROOT%/}" "${rel_case_dir}"
return 0
fi
printf '%s/%s\n' "${OUTPUT_ROOT%/}" "$(basename "${case_abs}")"
return 0
fi
printf '%s/%s\n' "${case_abs}" "${OUTPUT_DIR_NAME}"
}
build_track_id_args() {
local -n out_ref=$1
out_ref=()
if [[ "${#CLI_TRACK_IDS[@]}" -gt 0 ]]; then
for track_id in "${CLI_TRACK_IDS[@]}"; do
out_ref+=(--track-ids "${track_id}")
done
return 0
fi
if [[ -n "${TEMPORAL_TRACK_IDS}" ]]; then
# shellcheck disable=SC2206
local track_id_arr=(${TEMPORAL_TRACK_IDS})
for track_id in "${track_id_arr[@]}"; do
out_ref+=(--track-ids "${track_id}")
done
fi
}
run_single_case() {
local case_dir="$1"
local tracking_json="${case_dir}/${TRACKING_JSON_NAME}"
local output_dir
local cmd
local track_id_args
local class_id_value=""
local frame_id_start_value=""
local frame_id_end_value=""
if [[ ! -f "${tracking_json}" ]]; then
echo "[ERROR] ${TRACKING_JSON_NAME} not found in case directory: ${case_dir}" >&2
return 1
fi
output_dir="$(derive_output_dir "${case_dir}")"
build_track_id_args track_id_args
if [[ -n "${CLI_CLASS_ID}" ]]; then
class_id_value="${CLI_CLASS_ID}"
elif [[ -n "${TEMPORAL_CLASS_ID}" ]]; then
class_id_value="${TEMPORAL_CLASS_ID}"
fi
if [[ -n "${CLI_FRAME_ID_START}" ]]; then
frame_id_start_value="${CLI_FRAME_ID_START}"
elif [[ -n "${TEMPORAL_FRAME_ID_START}" ]]; then
frame_id_start_value="${TEMPORAL_FRAME_ID_START}"
fi
if [[ -n "${CLI_FRAME_ID_END}" ]]; then
frame_id_end_value="${CLI_FRAME_ID_END}"
elif [[ -n "${TEMPORAL_FRAME_ID_END}" ]]; then
frame_id_end_value="${TEMPORAL_FRAME_ID_END}"
fi
cmd=(
"${PYTHON_BIN}" "${TEMPORAL_SCRIPT}"
--input "${tracking_json}"
--output "${output_dir}/stability_report.json"
--min-length "${TEMPORAL_MIN_LENGTH}"
--x-axis "${TEMPORAL_X_AXIS}"
--heading-source "${TEMPORAL_HEADING_SOURCE}"
)
if [[ -n "${class_id_value}" ]]; then
cmd+=(--class-id "${class_id_value}")
fi
if [[ -n "${frame_id_start_value}" ]]; then
cmd+=(--frame-id-start "${frame_id_start_value}")
fi
if [[ -n "${frame_id_end_value}" ]]; then
cmd+=(--frame-id-end "${frame_id_end_value}")
fi
if [[ "${#track_id_args[@]}" -gt 0 ]]; then
cmd+=("${track_id_args[@]}")
fi
if [[ "${TEMPORAL_PLOTS}" == "1" ]]; then
cmd+=(--plots)
fi
if [[ "${TEMPORAL_EXPORT_SERIES}" == "1" ]]; then
cmd+=(--export-series)
fi
if [[ "${TEMPORAL_FOCUS_TRACK_PLOTS}" == "1" ]]; then
cmd+=(--focus-track-plots)
fi
if [[ "${TEMPORAL_PREFER_EGO}" == "1" ]]; then
cmd+=(--prefer-ego)
else
cmd+=(--no-prefer-ego)
fi
echo ""
echo "######################################################################"
echo "# Exported video-root temporal observation"
echo "######################################################################"
echo "Case : ${case_dir}"
echo "Track : ${tracking_json}"
echo "Output : ${output_dir}"
if [[ -n "${class_id_value}" ]]; then
echo "Class : ${class_id_value}"
fi
if [[ -n "${frame_id_start_value}" || -n "${frame_id_end_value}" ]]; then
echo "Frame ID Range: [${frame_id_start_value:-"-inf"}, ${frame_id_end_value:-"+inf"}]"
fi
echo "Heading Source: ${TEMPORAL_HEADING_SOURCE}"
if [[ "${#CLI_TRACK_IDS[@]}" -gt 0 ]]; then
echo "Track IDs: ${CLI_TRACK_IDS[*]}"
elif [[ -n "${TEMPORAL_TRACK_IDS}" ]]; then
echo "Track IDs: ${TEMPORAL_TRACK_IDS}"
fi
"${cmd[@]}"
}
run_batch_root() {
local batch_root="$1"
local total_cases=0
local success_cases=0
local failed_cases=0
while IFS= read -r -d '' tracking_json; do
local case_dir
case_dir="$(dirname "${tracking_json}")"
((total_cases += 1))
if run_single_case "${case_dir}"; then
((success_cases += 1))
else
((failed_cases += 1))
printf '[FAIL] case=%s\n' "${case_dir}" >&2
fi
done < <(
find "${batch_root}" -type f -name "${TRACKING_JSON_NAME}" -print0 | sort -z
)
if [[ "${total_cases}" -eq 0 ]]; then
echo "[ERROR] No ${TRACKING_JSON_NAME} files were found under: ${batch_root}" >&2
return 1
fi
echo ""
printf '[DONE] cases=%d success=%d failed=%d\n' \
"${total_cases}" "${success_cases}" "${failed_cases}"
[[ "${failed_cases}" -eq 0 ]]
}
if RESOLVED_CASE_DIR="$(resolve_case_dir "${TARGET_PATH}")"; then
run_single_case "${RESOLVED_CASE_DIR}"
elif [[ -d "${TARGET_PATH}" ]]; then
run_batch_root "${TARGET_PATH}"
else
echo "Error: unsupported target path: ${TARGET_PATH}" >&2
exit 1
fi