mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-16 10:02:08 +00:00
fix(training): always emit flight-telemetry info keys, not just when nonzero
VecMonitor's info_keywords does a bare info[key] lookup on a completed episode's terminal info dict and raises KeyError -- crashing the whole training run -- if a key is ever absent. get_info() was only including airborne_fraction/mean_altitude/vertical_thrust_mean when _telemetry_ticks was nonzero and air_touch_fraction when _touches was nonzero; an episode with zero ball touches (common, especially early in training) crashed on the very first rollout in a smoke-test run. All four now always default to 0.0 rather than being conditionally present. Found via TRAINING.md's Generation 4 validation ladder (rung 2, a 60k-step smoke run) -- confirmed fixed by rerunning the same smoke run clean, then export/evaluate parity (rungs 2-3) against Game/bots/promoted/easy.json.
This commit is contained in:
@@ -180,16 +180,22 @@ func get_reward() -> float:
|
|||||||
# TRAINING.md). Flight telemetry fields are leading indicators for
|
# TRAINING.md). Flight telemetry fields are leading indicators for
|
||||||
# generation 4's core hypothesis (see train.py's FlightTelemetryCallback).
|
# generation 4's core hypothesis (see train.py's FlightTelemetryCallback).
|
||||||
func get_info() -> Dictionary:
|
func get_info() -> Dictionary:
|
||||||
|
# The four telemetry keys must ALWAYS be present (not just when their
|
||||||
|
# denominator is nonzero) — VecMonitor's info_keywords does a bare
|
||||||
|
# info[key] lookup on whatever info dict is attached to a completed
|
||||||
|
# episode's terminal step (see train.py's VecMonitor(...,
|
||||||
|
# info_keywords=(...))) and raises KeyError, crashing the whole training
|
||||||
|
# run, if a key is ever missing. 0.0 is a reasonable default for "no
|
||||||
|
# touches/no ticks yet" (in practice _telemetry_ticks is >0 by the time
|
||||||
|
# any episode ends; _touches often legitimately is 0).
|
||||||
var info := {"goal_scored": goal_scored_this_episode}
|
var info := {"goal_scored": goal_scored_this_episode}
|
||||||
if truncated_this_episode:
|
if truncated_this_episode:
|
||||||
info["truncated"] = true
|
info["truncated"] = true
|
||||||
info["terminal_obs"] = terminal_obs
|
info["terminal_obs"] = terminal_obs
|
||||||
if _telemetry_ticks > 0:
|
info["airborne_fraction"] = float(_airborne_ticks) / _telemetry_ticks if _telemetry_ticks > 0 else 0.0
|
||||||
info["airborne_fraction"] = float(_airborne_ticks) / _telemetry_ticks
|
info["mean_altitude"] = _altitude_sum / _telemetry_ticks if _telemetry_ticks > 0 else 0.0
|
||||||
info["mean_altitude"] = _altitude_sum / _telemetry_ticks
|
info["vertical_thrust_mean"] = _thrust_y_sum / _telemetry_ticks if _telemetry_ticks > 0 else 0.0
|
||||||
info["vertical_thrust_mean"] = _thrust_y_sum / _telemetry_ticks
|
info["air_touch_fraction"] = float(_air_touches) / _touches if _touches > 0 else 0.0
|
||||||
if _touches > 0:
|
|
||||||
info["air_touch_fraction"] = float(_air_touches) / _touches
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user