chore(training): add air_touch_bonus_weight and restart stage-5 intercepts

air_approach_weight alone didn't move productive_air_touch_fraction after a
further 180M steps (360M cumulative across all six Stage-5 attempts): an
unredirected air-intercept ball falls short of the goal from gravity and
just lands on the floor, so the already-solved ground game collects the
same episode reward whether or not anything touched the ball in the air.
air_touch_bonus_weight adds a conjunctive event bonus on top of
ball_touch_reward for a touch that's both genuinely aerial and
goal-directed, targeting the actual measured behaviour instead of only the
approach to it.
This commit is contained in:
Josh Creek
2026-08-19 22:46:04 +01:00
parent 03f49e59c8
commit 602fa297d0
15 changed files with 100 additions and 260 deletions
+7
View File
@@ -360,6 +360,12 @@ def parse_args():
help="Aerial mirror of forward-velocity-to-ball-weight: high-altitude dense reward for "
"nose-led 3D closing speed toward the ball",
)
curriculum.add_argument(
"--air-touch-bonus-weight", type=float, default=None,
help="Event bonus on top of ball-touch-reward for a touch that is both genuinely aerial "
"(ball above AIR_TOUCH_HEIGHT) and goal-directed, scaled by the same alignment factor "
"as the base touch reward",
)
curriculum.add_argument(
"--ball-distance-penalty", type=float, default=None,
help="Overrides ShipAIController.ball_distance_penalty (dense per-tick cost scaled by distance to the ball)",
@@ -425,6 +431,7 @@ def _curriculum_kwargs(args) -> dict:
"ai_velocity_to_ball_weight": args.velocity_to_ball_weight,
"ai_forward_velocity_to_ball_weight": args.forward_velocity_to_ball_weight,
"ai_air_approach_weight": args.air_approach_weight,
"ai_air_touch_bonus_weight": args.air_touch_bonus_weight,
"ai_ball_distance_penalty": args.ball_distance_penalty,
"ai_ball_touch_reward": args.ball_touch_reward,
"ai_airborne_penalty": args.airborne_penalty,