mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-14 00:13:42 +08:00
22a8575199
Keep official openpilot ancestry and dependency licenses. Store resources directly in Git, remove LFS setup requirements, and leave the downloadable big model outside the source tree.
93 lines
3.0 KiB
Python
Executable File
93 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import importlib
|
|
import os
|
|
import re
|
|
from pathlib import Path
|
|
|
|
generator_path = os.path.dirname(os.path.realpath(__file__))
|
|
include_pattern = re.compile(r'CM_ "IMPORT (.*?)";\n')
|
|
|
|
|
|
def _read_dbc(src_dir: str, filename: str, extra_files: dict[str, str] | None = None) -> str:
|
|
if extra_files and filename in extra_files:
|
|
return extra_files[filename]
|
|
with open(os.path.join(src_dir, filename), encoding='utf-8') as file_in:
|
|
return file_in.read()
|
|
|
|
|
|
def _create_dbc_content(src_dir: str, filename: str, extra_files: dict[str, str] | None = None) -> str:
|
|
dbc_file_in = _read_dbc(src_dir, filename, extra_files)
|
|
includes = include_pattern.findall(dbc_file_in)
|
|
|
|
parts = ['CM_ "AUTOGENERATED FILE, DO NOT EDIT";\n']
|
|
for include_filename in includes:
|
|
parts.append(f'\n\nCM_ "Imported file {include_filename} starts here";\n')
|
|
parts.append(_read_dbc(src_dir, include_filename, extra_files))
|
|
|
|
parts.append(f'\nCM_ "{filename} starts here";\n')
|
|
core_dbc = include_pattern.sub('', dbc_file_in)
|
|
parts.append(core_dbc)
|
|
|
|
return ''.join(parts)
|
|
|
|
|
|
def _collect_script_outputs() -> dict[str, dict[str, str]]:
|
|
"""Import and call generate() from each sub-generator script.
|
|
Returns {dir_name: {filename: content}}."""
|
|
outputs: dict[str, dict[str, str]] = {}
|
|
|
|
for py_file in sorted(Path(generator_path).rglob("*.py")):
|
|
if py_file.name.startswith("test_") or py_file.name == "generator.py":
|
|
continue
|
|
|
|
dir_name = py_file.parent.name
|
|
module_name = f"opendbc.dbc.generator.{dir_name}.{py_file.stem}"
|
|
mod = importlib.import_module(module_name)
|
|
if hasattr(mod, 'generate'):
|
|
outputs.setdefault(dir_name, {}).update(mod.generate())
|
|
|
|
return outputs
|
|
|
|
|
|
def generate_all() -> dict[str, str]:
|
|
"""Generate all DBC content in memory. Returns {name: content} where name has no .dbc extension."""
|
|
script_outputs = _collect_script_outputs()
|
|
|
|
result = {}
|
|
for src_dir, _, filenames in os.walk(generator_path):
|
|
if src_dir == generator_path:
|
|
continue
|
|
|
|
dir_name = os.path.basename(src_dir)
|
|
extra = script_outputs.get(dir_name, {})
|
|
|
|
# all non-_ .dbc files: on-disk templates + script-generated
|
|
all_dbc_files = {f for f in filenames if f.endswith('.dbc') and not f.startswith('_')}
|
|
all_dbc_files |= {f for f in extra if not f.startswith('_')}
|
|
|
|
for filename in sorted(all_dbc_files):
|
|
output_name = filename.replace('.dbc', '_generated')
|
|
content = _create_dbc_content(src_dir, filename, extra)
|
|
result[output_name] = content
|
|
|
|
return result
|
|
|
|
|
|
def create_all(output_path: str):
|
|
"""Generate all DBC files and write them to output_path (for backward compatibility)."""
|
|
import glob
|
|
generated_suffix = '_generated.dbc'
|
|
|
|
# clear out old generated DBCs
|
|
for f in glob.glob(os.path.join(output_path, f"*{generated_suffix}")):
|
|
os.remove(f)
|
|
|
|
for name, content in generate_all().items():
|
|
with open(os.path.join(output_path, name + '.dbc'), 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
opendbc_root = os.path.join(generator_path, '../')
|
|
create_all(opendbc_root)
|