67 lines
2.3 KiB
Python
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()
|