Files
mprim_gen/generate_mprim.py
2026-07-28 23:35:42 +07:00

67 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""
generate_mprim.py
------------------
CLI để sinh file .mprim từ 1 file config trong configs/.
Cách dùng:
python3 generate_mprim.py configs/differential.py
python3 generate_mprim.py configs/omnidirectional.py -o my_output.mprim
python3 generate_mprim.py configs/ackermann.py
Muốn thêm robot mới: copy 1 file trong configs/, đổi số liệu, chạy lại.
KHÔNG cần sửa code trong mprim_core.py / kinematics.py.
"""
import argparse
import importlib.util
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from mprim_config import KinematicType
from mprim_core import generate_mprim_file
from kinematics import unicycle_poses, holonomic_poses
# differential và ackermann dùng chung interpolator: đường đi của xe bánh lái theo
# cung tròn trùng với nghiệm unicycle (đoạn thẳng + cung); khác nhau chỉ ở tập
# primitive và ràng buộc min_turning_radius (mprim_core xử lý).
KINEMATICS_MAP = {
KinematicType.DIFFERENTIAL: unicycle_poses,
KinematicType.OMNIDIRECTIONAL: holonomic_poses,
KinematicType.ACKERMANN: unicycle_poses,
}
def load_config(config_path: str):
spec = importlib.util.spec_from_file_location("robot_config_module", config_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
if not hasattr(module, "config"):
raise ValueError(f"{config_path} phải định nghĩa biến `config = RobotConfig(...)`")
return module.config
def main():
parser = argparse.ArgumentParser(description="Sinh file .mprim từ config robot")
parser.add_argument("config", help="Đường dẫn tới file config Python (vd: configs/differential.py)")
parser.add_argument("-o", "--output", default=None, help="Đường dẫn file .mprim output")
args = parser.parse_args()
cfg = load_config(args.config)
kinematics_fn = KINEMATICS_MAP[cfg.kinematic_type]
output_path = args.output or f"{cfg.name}.mprim"
n, warnings = generate_mprim_file(cfg, kinematics_fn, output_path)
print(f"[OK] {cfg.kinematic_type.value}: đã sinh {n} primitives -> {output_path}")
if warnings:
print(f"[WARN] {len(warnings)} cảnh báo:")
for w in warnings:
print(f" - {w}")
if __name__ == "__main__":
main()