"""Run a trained policy in the PyBullet sim with full curriculum progression. Usage: python ml/run_eval.py --model ml/checkpoints/ppo_joint_command.zip --episodes 5 --gui """ import argparse import sys from pathlib import Path ROOT_DIR = Path(__file__).resolve().parent.parent if str(ROOT_DIR) not in sys.path: sys.path.insert(0, str(ROOT_DIR)) from ml.evaluate import evaluate def main(): parser = argparse.ArgumentParser(description="JackBot Curriculum Policy Evaluator Wrapper") parser.add_argument("--model", type=str, required=True, help="Path to the trained model file (.zip)") parser.add_argument("--episodes", type=int, default=5, help="Number of evaluation episodes to run.") parser.add_argument("--gui", action="store_true", help="Show the PyBullet GUI during evaluation") parser.add_argument("--robot-spacing", type=float, default=0.5, help="Spacing between robots in meters") parser.add_argument("--start-pose", type=str, choices=["init_deg", "init90_deg"], default="init_deg", help="Initial robot pose at reset") parser.add_argument("--no-random-command", dest="random_command", action="store_false", help="Disable command sampling and lock to zero commands") parser.set_defaults(random_command=True) parser.add_argument("--save-metrics", type=str, default=None, help="Optional path to save JSON metrics report") args = parser.parse_args() evaluate( model_path=args.model, episodes=args.episodes, use_gui=args.gui, robot_spacing=args.robot_spacing, start_pose=args.start_pose, random_command=args.random_command, save_json=args.save_metrics, ) if __name__ == "__main__": main()