from __future__ import annotations import argparse from pathlib import Path from mapgen import configure_motif_mapgen, install_motif_mapgen from ppo import parse_curriculum, train from runtime import configure_threads, make_config from settings import ( ACTIVE_CHECKPOINT, DEFAULT_CURRICULUM, DEFAULT_TRAIN_RUN_NAME, ENV_DEFAULTS, MAPGEN_KWARGS, PHYSICS_DEFAULTS, TRAIN_DEFAULTS, ) DEFAULT_RESUME = ACTIVE_CHECKPOINT def train_default(name: str, fallback: float | int | str) -> float | int | str: return TRAIN_DEFAULTS.get(name, fallback) def env_default(name: str, fallback: float | int) -> float | int: return ENV_DEFAULTS.get(name, fallback) def map_default(name: str, fallback: float | int) -> float | int: return MAPGEN_KWARGS.get(name, fallback) def physics_default(name: str, fallback: float) -> float: return float(PHYSICS_DEFAULTS.get(name, fallback)) def main() -> None: parser = argparse.ArgumentParser(description="Train the active attention/direct motif-map parkour runner.") parser.add_argument("--run-name", default=DEFAULT_TRAIN_RUN_NAME) parser.add_argument("--device", default="cuda") parser.add_argument("--cpu-threads", type=int, default=64) parser.add_argument("--envs", type=int, default=int(train_default("envs", 196608))) parser.add_argument("--eval-envs", type=int, default=int(train_default("eval_envs", 8192))) parser.add_argument("--steps", type=int, default=int(train_default("steps", 64))) parser.add_argument("--epochs", type=int, default=int(train_default("epochs", 1))) parser.add_argument("--minibatches", type=int, default=int(train_default("minibatches", 48))) parser.add_argument("--hidden", type=int, default=int(train_default("hidden", 256))) parser.add_argument("--depth", type=int, default=int(train_default("depth", 3))) parser.add_argument("--policy-arch", choices=("mlp", "attention"), default=str(train_default("policy_arch", "mlp"))) parser.add_argument("--planner-hidden", type=int, default=128) parser.add_argument("--planner-depth", type=int, default=2) parser.add_argument("--planner-mode", choices=("local-beacon", "direct"), default=str(train_default("planner_mode", "direct"))) parser.add_argument("--planner-max-xy", type=float, default=8.0) parser.add_argument("--planner-max-z", type=float, default=1.2) parser.add_argument("--planner-blend-bias", type=float, default=-2.0) parser.add_argument("--reset-planner-head", action="store_true") parser.add_argument("--capture", type=int, default=int(train_default("capture", 8))) parser.add_argument("--log-every", type=int, default=int(train_default("log_every", 20))) parser.add_argument("--min-stage-updates", type=int, default=int(train_default("min_stage_updates", 20))) parser.add_argument("--lr", type=float, default=float(train_default("lr", 4.0e-5))) parser.add_argument("--entropy-coef", type=float, default=float(train_default("entropy_coef", 0.008))) parser.add_argument("--sil-coef", type=float, default=float(train_default("sil_coef", 0.030))) parser.add_argument("--resume-checkpoint", default=DEFAULT_RESUME) parser.add_argument("--anchor-checkpoint", default=None) parser.add_argument("--anchor-bc-coef", type=float, default=0.0) parser.add_argument("--no-resume", action="store_true") parser.add_argument("--sensor-mode", choices=("ray", "topk"), default=str(train_default("sensor_mode", "topk"))) parser.add_argument("--sensor-topk", type=int, default=int(train_default("sensor_topk", 16))) parser.add_argument("--sensor-token-range", type=float, default=float(train_default("sensor_token_range", 9.5))) parser.add_argument("--sensor-fov-degrees", type=float, default=float(train_default("sensor_fov_degrees", 120.0))) parser.add_argument("--sensor-token-sort", choices=("index", "distance", "bearing"), default=str(train_default("sensor_token_sort", "distance"))) parser.add_argument("--observe-progress", action=argparse.BooleanOptionalAction, default=bool(int(train_default("observe_progress", 0)))) parser.add_argument("--fragile-platforms", action="store_true") parser.add_argument("--fragile-delay-steps", type=int, default=14) parser.add_argument("--launch-pads", action="store_true") parser.add_argument("--launch-pad-fraction", type=float, default=0.24) parser.add_argument("--launch-pad-velocity", type=float, default=10.4) parser.add_argument("--launch-pad-gap-extra", type=float, default=0.0) parser.add_argument("--moving-platforms", action="store_true") parser.add_argument("--moving-platform-fraction", type=float, default=0.18) parser.add_argument("--moving-platform-amplitude", type=float, default=0.72) parser.add_argument("--moving-platform-period-steps", type=int, default=70) parser.add_argument("--moving-platform-transport", action="store_true") parser.add_argument("--moving-platform-force-every", type=int, default=0) parser.add_argument("--moving-platform-force-offset", type=int, default=3) parser.add_argument("--moving-platform-transport-span", type=float, default=5.35) parser.add_argument("--moving-platform-endpoint-gap", type=float, default=1.05) parser.add_argument("--unlock-platforms", action="store_true") parser.add_argument("--unlock-gate-count", type=int, default=1) parser.add_argument("--unlock-lock-span", type=int, default=2) parser.add_argument("--unlock-hold-steps", type=int, default=1) parser.add_argument("--unlock-reward", type=float, default=1.5) parser.add_argument("--map-height-offset", type=float, default=float(env_default("map_height_offset", 2.85))) parser.add_argument("--map-vertical-scale", type=float, default=float(env_default("map_vertical_scale", 1.35))) parser.add_argument("--map-max-height", type=float, default=float(env_default("map_max_height", 5.6))) parser.add_argument("--map-scenic-turn-scale", type=float, default=float(map_default("map_scenic_turn_scale", 0.48))) parser.add_argument("--map-scenic-island-radius", type=float, default=1.55) parser.add_argument("--map-scenic-vertical-step", type=float, default=0.46) parser.add_argument("--map-platform-min-scale", type=float, default=float(map_default("map_platform_min_scale", 0.68))) parser.add_argument("--map-platform-max-scale", type=float, default=float(map_default("map_platform_max_scale", 1.44))) parser.add_argument("--map-platform-tiny-fraction", type=float, default=float(map_default("map_platform_tiny_fraction", 0.08))) parser.add_argument("--map-platform-large-fraction", type=float, default=float(map_default("map_platform_large_fraction", 0.18))) parser.add_argument("--map-platform-aspect-jitter", type=float, default=float(map_default("map_platform_aspect_jitter", 0.32))) parser.add_argument("--start-forward-fraction", type=float, default=0.0) parser.add_argument("--gravity", type=float, default=physics_default("gravity", 30.0)) parser.add_argument("--accel", type=float, default=physics_default("accel", 65.0)) parser.add_argument("--ground-damping", type=float, default=physics_default("ground_damping", 0.55)) parser.add_argument("--air-damping", type=float, default=physics_default("air_damping", 0.91)) parser.add_argument("--air-control", type=float, default=physics_default("air_control", 0.10)) parser.add_argument("--max-speed", type=float, default=physics_default("max_speed", 4.3)) parser.add_argument("--jump-velocity", type=float, default=physics_default("jump_velocity", 7.2)) parser.add_argument("--sprint-speed-mult", type=float, default=physics_default("sprint_speed_mult", 1.35)) parser.add_argument("--sprint-accel-mult", type=float, default=physics_default("sprint_accel_mult", 1.25)) parser.add_argument("--turn-speed", type=float, default=physics_default("turn_speed", 3.2)) parser.add_argument("--landing-pad-scale", type=float, default=physics_default("landing_pad_scale", 0.25)) parser.add_argument("--landing-top-tolerance", type=float, default=physics_default("landing_top_tolerance", 0.03)) parser.add_argument("--landing-prev-slack", type=float, default=physics_default("landing_prev_slack", 0.12)) parser.add_argument("--map-edge-gap-min", type=float, default=float(map_default("map_edge_gap_min", 0.76))) parser.add_argument("--map-edge-gap-max", type=float, default=float(map_default("map_edge_gap_max", 1.24))) parser.add_argument("--map-route-gap-scale", type=float, default=float(map_default("map_route_gap_scale", 1.06))) parser.add_argument("--map-cleanup-iters", type=int, default=48) parser.add_argument("--map-illegal-decoy-fraction", type=float, default=0.0) parser.add_argument("--map-route-tiny-fraction", type=float, default=float(map_default("map_route_tiny_fraction", 0.0))) parser.add_argument("--map-route-tiny-min-scale", type=float, default=0.44) parser.add_argument("--map-route-tiny-max-scale", type=float, default=0.68) parser.add_argument("--map-momentum-jump-fraction", type=float, default=0.0) parser.add_argument("--map-momentum-gap-bias", type=float, default=0.82) parser.add_argument("--map-redirect-period", type=int, default=0) parser.add_argument("--map-redirect-angle", type=float, default=1.05) parser.add_argument("--map-direct-decoy-fraction", type=float, default=float(map_default("map_direct_decoy_fraction", 0.06))) parser.add_argument("--map-goal-xy-min", type=float, default=float(map_default("map_goal_xy_min", 7.5))) parser.add_argument("--map-goal-xy-per-jump-min", type=float, default=float(map_default("map_goal_xy_per_jump_min", 0.0))) parser.add_argument("--map-extra-span-min-frac", type=float, default=float(map_default("map_extra_span_min_frac", 0.05))) parser.add_argument("--map-extra-span-max-frac", type=float, default=float(map_default("map_extra_span_max_frac", 0.90))) parser.add_argument("--map-extra-span-end-margin", type=float, default=float(map_default("map_extra_span_end_margin", 1.10))) parser.add_argument("--map-route-edge-gap-floor", type=float, default=float(map_default("map_route_edge_gap_floor", 0.24))) parser.add_argument("--map-goal-vertical-bias", type=float, default=float(map_default("map_goal_vertical_bias", 0.0))) parser.add_argument("--map-goal-vertical-bias-min", type=float, default=float(map_default("map_goal_vertical_bias_min", 0.0))) parser.add_argument("--map-hairpin-period", type=int, default=int(map_default("map_hairpin_period", 0))) parser.add_argument("--map-hairpin-angle", type=float, default=float(map_default("map_hairpin_angle", 0.0))) parser.add_argument("--map-hairpin-depth", type=float, default=float(map_default("map_hairpin_depth", 0.0))) parser.add_argument("--map-cluster-extra-fraction", type=float, default=float(map_default("map_cluster_extra_fraction", 0.08))) parser.add_argument("--map-decoy-corridor-fraction", type=float, default=float(map_default("map_decoy_corridor_fraction", 0.06))) parser.add_argument("--map-unintuitive-depth", type=float, default=float(map_default("map_unintuitive_depth", 0.08))) parser.add_argument("--map-valley-period", type=int, default=int(map_default("map_valley_period", 0))) parser.add_argument("--map-valley-depth", type=float, default=float(map_default("map_valley_depth", 0.0))) parser.add_argument("--map-false-summit-fraction", type=float, default=float(map_default("map_false_summit_fraction", 0.03))) parser.add_argument("--map-false-branch-fraction", type=float, default=float(map_default("map_false_branch_fraction", 0.04))) parser.add_argument("--map-false-finish-fraction", type=float, default=float(map_default("map_false_finish_fraction", 0.02))) parser.add_argument("--map-greedy-trap-fraction", type=float, default=float(map_default("map_greedy_trap_fraction", 0.04))) parser.add_argument("--map-braid-bridge-fraction", type=float, default=float(map_default("map_braid_bridge_fraction", 0.06))) parser.add_argument("--map-braid-bridge-span", type=int, default=int(map_default("map_braid_bridge_span", 3))) parser.add_argument("--map-trap-jump-fraction", type=float, default=float(map_default("map_trap_jump_fraction", 0.10))) parser.add_argument("--map-trap-jump-drop", type=float, default=float(map_default("map_trap_jump_drop", 0.72))) parser.add_argument("--map-trap-jump-min-drop", type=float, default=float(map_default("map_trap_jump_min_drop", 0.34))) parser.add_argument("--map-trap-jump-edge-margin", type=float, default=float(map_default("map_trap_jump_edge_margin", 0.06))) parser.add_argument("--map-trap-jump-high-fraction", type=float, default=float(map_default("map_trap_jump_high_fraction", 0.04))) parser.add_argument("--map-trap-jump-high-min-up", type=float, default=float(map_default("map_trap_jump_high_min_up", 0.26))) parser.add_argument("--map-trap-jump-high-max-up", type=float, default=float(map_default("map_trap_jump_high_max_up", 0.78))) parser.add_argument("--map-trap-jump-disguise", type=float, default=float(map_default("map_trap_jump_disguise", 0.35))) parser.add_argument("--map-route-detour-period", type=int, default=int(map_default("map_route_detour_period", 8))) parser.add_argument("--map-route-detour-depth", type=float, default=float(map_default("map_route_detour_depth", 0.10))) parser.add_argument("--map-backtrack-period", type=int, default=int(map_default("map_backtrack_period", 0))) parser.add_argument("--map-backtrack-depth", type=float, default=float(map_default("map_backtrack_depth", 0.0))) parser.add_argument("--goal-progress-reward-scale", type=float, default=float(env_default("goal_progress_reward_scale", 2.4))) parser.add_argument("--first-visit-reward", type=float, default=float(env_default("first_visit_reward", 0.10))) parser.add_argument("--step-cost", type=float, default=float(env_default("step_cost", 0.0005))) parser.add_argument("--fall-penalty", type=float, default=float(env_default("fall_penalty", 4.0))) parser.add_argument("--success-time-bonus", type=float, default=float(env_default("success_time_bonus", 0.10))) parser.add_argument("--stagnation-patience-steps", type=int, default=0) parser.add_argument("--stagnation-warmup-steps", type=int, default=32) parser.add_argument("--stagnation-progress-epsilon", type=float, default=0.002) parser.add_argument("--stagnation-penalty", type=float, default=0.0) parser.add_argument("--run-dir", default="data/runs") parser.add_argument("--curriculum", default=DEFAULT_CURRICULUM) args = parser.parse_args() threads = configure_threads(int(args.cpu_threads)) mapgen_kwargs = dict( map_scenic_turn_scale=float(args.map_scenic_turn_scale), map_scenic_island_radius=float(args.map_scenic_island_radius), map_scenic_vertical_step=float(args.map_scenic_vertical_step), map_platform_min_scale=float(args.map_platform_min_scale), map_platform_max_scale=float(args.map_platform_max_scale), map_platform_tiny_fraction=float(args.map_platform_tiny_fraction), map_platform_large_fraction=float(args.map_platform_large_fraction), map_platform_aspect_jitter=float(args.map_platform_aspect_jitter), map_edge_gap_min=float(args.map_edge_gap_min), map_edge_gap_max=float(args.map_edge_gap_max), map_route_gap_scale=float(args.map_route_gap_scale), map_route_tiny_fraction=float(args.map_route_tiny_fraction), map_route_tiny_min_scale=float(args.map_route_tiny_min_scale), map_route_tiny_max_scale=float(args.map_route_tiny_max_scale), map_momentum_jump_fraction=float(args.map_momentum_jump_fraction), map_momentum_gap_bias=float(args.map_momentum_gap_bias), map_redirect_period=int(args.map_redirect_period), map_redirect_angle=float(args.map_redirect_angle), map_direct_decoy_fraction=float(args.map_direct_decoy_fraction), map_goal_xy_min=float(args.map_goal_xy_min), map_goal_xy_per_jump_min=float(args.map_goal_xy_per_jump_min), map_extra_span_min_frac=float(args.map_extra_span_min_frac), map_extra_span_max_frac=float(args.map_extra_span_max_frac), map_extra_span_end_margin=float(args.map_extra_span_end_margin), map_route_edge_gap_floor=float(args.map_route_edge_gap_floor), map_goal_vertical_bias=float(args.map_goal_vertical_bias), map_goal_vertical_bias_min=float(args.map_goal_vertical_bias_min), map_hairpin_period=int(args.map_hairpin_period), map_hairpin_angle=float(args.map_hairpin_angle), map_hairpin_depth=float(args.map_hairpin_depth), map_cluster_extra_fraction=float(args.map_cluster_extra_fraction), map_decoy_corridor_fraction=float(args.map_decoy_corridor_fraction), map_unintuitive_depth=float(args.map_unintuitive_depth), map_valley_period=int(args.map_valley_period), map_valley_depth=float(args.map_valley_depth), map_false_summit_fraction=float(args.map_false_summit_fraction), map_false_branch_fraction=float(args.map_false_branch_fraction), map_false_finish_fraction=float(args.map_false_finish_fraction), map_greedy_trap_fraction=float(args.map_greedy_trap_fraction), map_braid_bridge_fraction=float(args.map_braid_bridge_fraction), map_braid_bridge_span=int(args.map_braid_bridge_span), map_trap_jump_fraction=float(args.map_trap_jump_fraction), map_trap_jump_drop=float(args.map_trap_jump_drop), map_trap_jump_min_drop=float(args.map_trap_jump_min_drop), map_trap_jump_edge_margin=float(args.map_trap_jump_edge_margin), map_trap_jump_high_fraction=float(args.map_trap_jump_high_fraction), map_trap_jump_high_min_up=float(args.map_trap_jump_high_min_up), map_trap_jump_high_max_up=float(args.map_trap_jump_high_max_up), map_trap_jump_disguise=float(args.map_trap_jump_disguise), map_route_detour_period=int(args.map_route_detour_period), map_route_detour_depth=float(args.map_route_detour_depth), map_backtrack_period=int(args.map_backtrack_period), map_backtrack_depth=float(args.map_backtrack_depth), ) configure_motif_mapgen(**mapgen_kwargs) install_motif_mapgen() resume = None if not bool(args.no_resume): candidate = Path(str(args.resume_checkpoint)) if candidate.exists(): resume = str(candidate) else: print(f"resume_checkpoint_missing path={candidate}; training from scratch", flush=True) cfg = make_config( seed=17, device=str(args.device), envs=int(args.envs), eval_envs=int(args.eval_envs), ppo_steps=int(args.steps), ppo_epochs=int(args.epochs), minibatches=int(args.minibatches), hidden=int(args.hidden), lr=float(args.lr), gamma=0.992, gae_lambda=0.94, entropy_coef=float(args.entropy_coef), value_coef=0.55, max_steps_factor=24.0, run_dir=str(args.run_dir), sensor_mode=str(args.sensor_mode), sensor_topk=int(args.sensor_topk), sensor_token_range=float(args.sensor_token_range), sensor_fov_degrees=float(args.sensor_fov_degrees), sensor_token_sort=str(args.sensor_token_sort), observe_progress=bool(args.observe_progress), start_forward_fraction=float(args.start_forward_fraction), gravity=float(args.gravity), accel=float(args.accel), ground_damping=float(args.ground_damping), air_damping=float(args.air_damping), air_control=float(args.air_control), max_speed=float(args.max_speed), jump_velocity=float(args.jump_velocity), sprint_speed_mult=float(args.sprint_speed_mult), sprint_accel_mult=float(args.sprint_accel_mult), turn_speed=float(args.turn_speed), landing_pad_scale=float(args.landing_pad_scale), landing_top_tolerance=float(args.landing_top_tolerance), landing_prev_slack=float(args.landing_prev_slack), fragile_platforms=bool(args.fragile_platforms), fragile_delay_steps=int(args.fragile_delay_steps), launch_pads=bool(args.launch_pads), launch_pad_fraction=float(args.launch_pad_fraction), launch_pad_velocity=float(args.launch_pad_velocity), launch_pad_gap_extra=float(args.launch_pad_gap_extra), moving_platforms=bool(args.moving_platforms), moving_platform_fraction=float(args.moving_platform_fraction), moving_platform_amplitude=float(args.moving_platform_amplitude), moving_platform_period_steps=int(args.moving_platform_period_steps), moving_platform_transport=bool(args.moving_platform_transport), moving_platform_force_every=int(args.moving_platform_force_every), moving_platform_force_offset=int(args.moving_platform_force_offset), moving_platform_transport_span=float(args.moving_platform_transport_span), moving_platform_endpoint_gap=float(args.moving_platform_endpoint_gap), unlock_platforms=bool(args.unlock_platforms), unlock_gate_count=int(args.unlock_gate_count), unlock_lock_span=int(args.unlock_lock_span), unlock_hold_steps=int(args.unlock_hold_steps), unlock_reward=float(args.unlock_reward), route_jumps=10, distractors=8, pillar_platforms=False, map_height_offset=float(args.map_height_offset), map_vertical_scale=float(args.map_vertical_scale), map_max_height=float(args.map_max_height), map_overlap_cleanup_iters=int(args.map_cleanup_iters), map_illegal_decoy_fraction=float(args.map_illegal_decoy_fraction), map_route_tiny_fraction=float(args.map_route_tiny_fraction), map_route_tiny_min_scale=float(args.map_route_tiny_min_scale), map_route_tiny_max_scale=float(args.map_route_tiny_max_scale), map_momentum_jump_fraction=float(args.map_momentum_jump_fraction), map_momentum_gap_bias=float(args.map_momentum_gap_bias), map_redirect_period=int(args.map_redirect_period), map_redirect_angle=float(args.map_redirect_angle), map_direct_decoy_fraction=float(args.map_direct_decoy_fraction), map_goal_xy_min=float(args.map_goal_xy_min), map_goal_xy_per_jump_min=float(args.map_goal_xy_per_jump_min), map_extra_span_min_frac=float(args.map_extra_span_min_frac), map_extra_span_max_frac=float(args.map_extra_span_max_frac), map_extra_span_end_margin=float(args.map_extra_span_end_margin), map_route_edge_gap_floor=float(args.map_route_edge_gap_floor), map_goal_vertical_bias=float(args.map_goal_vertical_bias), map_goal_vertical_bias_min=float(args.map_goal_vertical_bias_min), map_hairpin_period=int(args.map_hairpin_period), map_hairpin_angle=float(args.map_hairpin_angle), map_hairpin_depth=float(args.map_hairpin_depth), map_cluster_extra_fraction=float(args.map_cluster_extra_fraction), map_decoy_corridor_fraction=float(args.map_decoy_corridor_fraction), map_unintuitive_depth=float(args.map_unintuitive_depth), map_valley_period=int(args.map_valley_period), map_valley_depth=float(args.map_valley_depth), map_false_summit_fraction=float(args.map_false_summit_fraction), map_false_branch_fraction=float(args.map_false_branch_fraction), map_false_finish_fraction=float(args.map_false_finish_fraction), map_greedy_trap_fraction=float(args.map_greedy_trap_fraction), map_braid_bridge_fraction=float(args.map_braid_bridge_fraction), map_braid_bridge_span=int(args.map_braid_bridge_span), map_trap_jump_fraction=float(args.map_trap_jump_fraction), map_trap_jump_drop=float(args.map_trap_jump_drop), map_trap_jump_min_drop=float(args.map_trap_jump_min_drop), map_trap_jump_edge_margin=float(args.map_trap_jump_edge_margin), map_trap_jump_high_fraction=float(args.map_trap_jump_high_fraction), map_trap_jump_high_min_up=float(args.map_trap_jump_high_min_up), map_trap_jump_high_max_up=float(args.map_trap_jump_high_max_up), map_trap_jump_disguise=float(args.map_trap_jump_disguise), map_route_detour_period=int(args.map_route_detour_period), map_route_detour_depth=float(args.map_route_detour_depth), map_backtrack_period=int(args.map_backtrack_period), map_backtrack_depth=float(args.map_backtrack_depth), goal_progress_reward_scale=float(args.goal_progress_reward_scale), first_visit_reward=float(args.first_visit_reward), step_cost=float(args.step_cost), fall_penalty=float(args.fall_penalty), success_time_bonus=float(args.success_time_bonus), stagnation_patience_steps=int(args.stagnation_patience_steps), stagnation_warmup_steps=int(args.stagnation_warmup_steps), stagnation_progress_epsilon=float(args.stagnation_progress_epsilon), stagnation_penalty=float(args.stagnation_penalty), ) print( f"v37_start arch={args.policy_arch} envs={cfg.envs} eval_envs={cfg.eval_envs} steps={cfg.ppo_steps} " f"minibatches={cfg.minibatches} cpu_threads={threads} mapgen=motif planner={args.planner_mode} " f"sensor={args.sensor_mode}:{args.sensor_topk}@{args.sensor_fov_degrees:.0f}deg/{args.sensor_token_sort} " f"observe_progress={bool(args.observe_progress)} launch={args.launch_pads} moving={args.moving_platforms} " f"physics=g{args.gravity:.1f}/j{args.jump_velocity:.1f}/v{args.max_speed:.1f}/air{args.air_control:.2f}/turn{args.turn_speed:.1f}/land{args.landing_pad_scale:.2f} " f"moving_transport={args.moving_platform_transport} unlock={args.unlock_platforms}:{args.unlock_gate_count}x{args.unlock_lock_span} " f"unlock_hold={args.unlock_hold_steps} momentum={args.map_momentum_jump_fraction:.3f} " f"start_forward={args.start_forward_fraction:.2f} " f"tiny_route={args.map_route_tiny_fraction:.3f} redirect_period={args.map_redirect_period} " f"direct_decoy={args.map_direct_decoy_fraction:.3f} goal_xy={args.map_goal_xy_min:.1f}+{args.map_goal_xy_per_jump_min:.2f}/jump " f"extra_span={args.map_extra_span_min_frac:.2f}-{args.map_extra_span_max_frac:.2f}@{args.map_extra_span_end_margin:.2f} " f"vertical_bias={args.map_goal_vertical_bias:.3f} " f"hairpin={args.map_hairpin_period}:{args.map_hairpin_angle:.2f}:{args.map_hairpin_depth:.2f} " f"cluster={args.map_cluster_extra_fraction:.3f} corridor={args.map_decoy_corridor_fraction:.3f} " f"unintuitive={args.map_unintuitive_depth:.2f} valley={args.map_valley_period}:{args.map_valley_depth:.2f} " f"false_summit={args.map_false_summit_fraction:.3f} false_branch={args.map_false_branch_fraction:.3f} " f"false_finish={args.map_false_finish_fraction:.3f} " f"greedy_trap={args.map_greedy_trap_fraction:.3f} braid_bridge={args.map_braid_bridge_fraction:.3f}:{args.map_braid_bridge_span} " f"trap_jump={args.map_trap_jump_fraction:.3f}:{args.map_trap_jump_min_drop:.2f}-{args.map_trap_jump_drop:.2f}@{args.map_trap_jump_edge_margin:.2f} " f"trap_high={args.map_trap_jump_high_fraction:.3f}:{args.map_trap_jump_high_min_up:.2f}-{args.map_trap_jump_high_max_up:.2f} " f"trap_disguise={args.map_trap_jump_disguise:.2f} " f"route_detour={args.map_route_detour_period}:{args.map_route_detour_depth:.2f} " f"backtrack={args.map_backtrack_period}:{args.map_backtrack_depth:.2f} " f"step_cost={args.step_cost:.4f} time_bonus={args.success_time_bonus:.2f} " f"stagnation={args.stagnation_patience_steps}@{args.stagnation_warmup_steps}/eps{args.stagnation_progress_epsilon:.4f}/pen{args.stagnation_penalty:.2f} " f"anchor_bc={args.anchor_bc_coef:.4f}:{args.anchor_checkpoint or ''} " f"resume={resume or 'none'}", flush=True, ) result = train( cfg, str(args.run_name), depth=int(args.depth), policy_arch=str(args.policy_arch), planner_mode=str(args.planner_mode), planner_hidden=int(args.planner_hidden), planner_depth=int(args.planner_depth), planner_max_xy=float(args.planner_max_xy), planner_max_z=float(args.planner_max_z), planner_blend_bias=float(args.planner_blend_bias), capture=int(args.capture), log_every=int(args.log_every), min_stage_updates=int(args.min_stage_updates), resume_checkpoint=resume, reset_planner_head=bool(args.reset_planner_head), curriculum=parse_curriculum(str(args.curriculum)), sil_coef=float(args.sil_coef), anchor_checkpoint=str(args.anchor_checkpoint) if args.anchor_checkpoint else None, anchor_bc_coef=float(args.anchor_bc_coef), ) print(result, flush=True) if __name__ == "__main__": main()