From b29818a144e7591e1728c1f7fa2b1fec0a026647 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Sat, 25 Apr 2026 17:05:46 +0200 Subject: [PATCH 01/96] docs: Clarify input space in more detail --- docs/design/input_action_spaces.md | 95 +++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 7 deletions(-) diff --git a/docs/design/input_action_spaces.md b/docs/design/input_action_spaces.md index 7860e16..8d24d37 100644 --- a/docs/design/input_action_spaces.md +++ b/docs/design/input_action_spaces.md @@ -5,13 +5,24 @@ space (outputs). The control models map these observations directly to physical **Inputs (state space)** -The observation space provides the agent with its current physical state and its objective. +The observation space provides the agent with its current physical state and its navigational objective. With a +decentralized control architecture in mind, we divide these inputs into global and local states. -- Joint positions: the current angles of all joints in the morphology. -- Joint velocities: the current moving speed of the joints. -- Goal vector: instad of just a scalar distance, the goal is represented asa a vector (distance and ange/direction) to +Global inputs, always broadcasted to all nodes: + +- Vertical orientation/tilt: A single, simplified metric representing the tilt or vertical alignment of the agent's + central body/disk, derived from the environment's raw disk rotation 3D vector $[roll, pitch, yaw]$: + $$tilt = sqrt(roll^2 + pitch^2)$$. This represents the deviation from the global Z-axis. +- Goal vector: Instead of just a scalar distance, the goal is represented asa a vector (distance and ange/direction) to the target. +Local inputs, routed directly to specific nodes: + +- Joint positions: The current angles of all joints within the morphology. +- Joint velocities: The current angular velocities of the joints. +- Joint actuator forces: The physical forces currently exerted at each specific joint. +- Segment contact: These values indicate whether each physical segment of the agent is currently touching the ground. + **Outputs (action space)** The action space defines how the agent interacts with the environment. @@ -26,15 +37,34 @@ When designing the state space, we must ask: *Could a human operator perform thi providing only the joint position is insufficient to determine the direction a limb is currently moving. By explicitly including joint velocities, the agent can immediately infer momentum and movement direction without needing to memorize past states. -- Goal Vector (Distance + Angle): Providing only the scalar "distance to the goal" as an input is akin to blindfolding - the robot and asking it to find a target by playing "hot or cold." By providing a full vector, the agent knows - exactly where the target is relative to its current orientation, allowing for directed and efficient locomotion. - Absolute Joint Offsets: The physical Brittle Star robot relies on servo motors (if we were to build this simulated robot), which are inherently position-controlled devices. (Continuous rotation servos exist, but they are less commonly used for joints.) If our network outputted continuous torques (forces), a significant portion of the reinforcement learning process would be wasted on learning low-level PID control dynamics (i.e., how much force to apply to hold a position). Abstracting this away forces the learning algorithm to focus entirely on higher-level gait generation and locomotion. +- Simplified vertical orientation: We drop the full 3D spatial rotation and angular velocity arrays in favor of a + single vertical orientation metric (tilt). For a brittle star moving accross a flat plane, this metric is sufficient + for the agent to sense if it is losing balance or flipping over. +- Force representation: We strictly retain the joint actuator forces and drop the more generic actuator force. Forces + that are explicitly tied to individual joints are significantly easier to route into decentralized, local limb nodes, + which is necessary for our message-passing architecture. +- Goal Vector (Distance + Angle): Providing only the scalar "distance to the goal" as an input is akin to blindfolding + the robot and asking it to find a target by playing "hot or cold." By providing a full vector, the agent knows + exactly where the target is relative to its current orientation, allowing for directed and efficient locomotion. + + The goal representation is explicitly divided into a directional vector and a scalar distance. Keeping the direction + as a normalized unit vector bounds the values to the $[-1, 1]$ range, which stabilizes neural network training. + Providing only a scalar "distance to the goal" would force the agent to learning localized searching behaviors (e.g. + random walks or spiraling) to deduce the direction, drastically increasing the difficulty of the learning task. +- Contact sensors: Segment contact detects external ground interaction and is biologically vital for timing gait + transitions. + + +Specifically, we do not include some available inputs: + +- Global position: Absolute spatial coordinates can cause the agent to overfit to a specific coordinate frame or map, + rather than learning general, adaptable locomotion strategies. ## Limitations and alternatives @@ -50,3 +80,54 @@ Alternative state and action formulations include: - Scalar Goal Distance: Giving the agent only the scalar distance to the target would force it to learn a localized searching behavior (e.g., spiraling or random walks) to determine the correct direction. While biologically plausible for simpler organisms following chemical gradients, it drastically increases the difficulty of the learning task. + +## MuJoCo + +This is what the filtered input vectors look like in MuJoCo, with $J$ joints and $S$ segments: + +- `joint_position`: shape=(J,), dtype=float64 +- `joint_velocity`: shape=(J,), dtype=float64 +- `joint_actuator_force`: shape=(J,), dtype=float64 +- `segment_contact`: shape=(S,), dtype=float64 +- `unit_xy_direction_to_target`: shape=(2,), dtype=float64 +- `xy_distance_to_target`: shape=(1,), dtype=float64 +- `disk_z_tilt`: shape=(1,), dtype=float64, derived from `disk_rotation` + +This brings the entire input space down to $3J + S + 4$ float64's, compared to $4J + S + 15$ float64's for the +unfiltered inputs. + +For reference, these are all the inputs that are available in the MuJoCo environment: + +``` +obs keys: ['joint_position', 'joint_velocity', 'joint_actuator_force', 'actuator_force', 'disk_position', 'disk_rotation', 'disk_linear_velocity', 'disk_angular_velocity', 'tendon_position', 'tendon_velocity', 'segment_contact', 'unit_xy_direction_to_target', 'xy_distance_to_target'] + +raw observations dict: +{'joint_position': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), + 'joint_velocity': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), + 'joint_actuator_force': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), + 'actuator_force': array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), + 'disk_position': array([0. , 0. , 0.11]), + 'disk_rotation': (0.0, -0.0, 0.0), + 'disk_linear_velocity': array([0., 0., 0.]), + 'disk_angular_velocity': array([0., 0., 0.]), + 'tendon_position': array([], dtype=float64), + 'tendon_velocity': array([], dtype=float64), + 'segment_contact': array([0., 0., 0., 0., 0., 0.]), + 'unit_xy_direction_to_target': array([-0.95333378, -0.30191837]), + 'xy_distance_to_target': array([3.])} + +(shapes) +joint_position: shape=(12,), dtype=float64, size=12 +joint_velocity: shape=(12,), dtype=float64, size=12 +joint_actuator_force: shape=(12,), dtype=float64, size=12 +actuator_force: shape=(12,), dtype=float64, size=12 +disk_position: shape=(3,), dtype=float64, size=3 +disk_rotation: shape=(3,), dtype=float64, size=3 +disk_linear_velocity: shape=(3,), dtype=float64, size=3 +disk_angular_velocity: shape=(3,), dtype=float64, size=3 +tendon_position: shape=(0,), dtype=float64, size=0 +tendon_velocity: shape=(0,), dtype=float64, size=0 +segment_contact: shape=(6,), dtype=float64, size=6 +unit_xy_direction_to_target: shape=(2,), dtype=float64, size=2 +xy_distance_to_target: shape=(1,), dtype=float64, size=1 +``` From 8830289992a1fd659ea7162fdec7676cc791c2b0 Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 28 Apr 2026 05:44:26 +0000 Subject: [PATCH 02/96] feat: made obs_dict handle morphology --- src/brittle_star_project/messager.py | 26 +++ .../trainers/PPOTrainer.py | 171 ++++++++++++++++-- 2 files changed, 181 insertions(+), 16 deletions(-) create mode 100644 src/brittle_star_project/messager.py diff --git a/src/brittle_star_project/messager.py b/src/brittle_star_project/messager.py new file mode 100644 index 0000000..7178527 --- /dev/null +++ b/src/brittle_star_project/messager.py @@ -0,0 +1,26 @@ +import jax +import jax.numpy as jnp + + +def message_passer(params, hidden, adjacency): + # take current hidden state per env, per agent, needs to communicate according to adjacency + # adjacency can be assumed to be the same per env? or mix it too idk + # rest is simple, use adjacency to make which hidden states we can combine + # repeat X times with the new combined vectors + # return result.. + # use jax lax scan stuff or vmap for speed + def per_env(h): + # compute messages per agent + def compute_messages(h_i, h_all): + # broadcast h_i with all neighbors + h_i_rep = jnp.repeat(h_i[None, :], h_all.shape[0], axis=0) + msg_input = jnp.concatenate([h_i_rep, h_all], axis=-1) + messages = messager_apply(params, msg_input) + return messages + + msgs = jax.vmap(compute_messages, in_axes=(0, None))(h, h) + msgs = msgs * adjacency[..., None] # mask neighbors + agg = msgs.sum(axis=1) + return agg + + return jax.vmap(per_env)(hidden) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 7cdc1ff..df2c571 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -24,6 +24,14 @@ from brittle_star_project.MLPs.mlps import ( Storage, ) from brittle_star_project.ppo import PPO +from enum import Enum + + +class ObsMode(Enum): + CENTRALIZED = "centralized" + ARM = "arm" + SEGMENT = "segment" + # TODO: move to config _ALLOWED_OBS_KEYS = { @@ -41,13 +49,6 @@ _ALLOWED_OBS_KEYS = { # TODO: clip scaled reward? -@jax.jit -def _get_xy_distance_to_target(obs_dict: dict) -> jnp.ndarray: - """Extract xy_distance_to_target for all environments.""" - # obs_dict is a dict of arrays with leading batch dimension (num_envs, ...) - return obs_dict["xy_distance_to_target"].squeeze(-1) # shape: (num_envs,) - - @jax.jit def _clip_action(action: jnp.ndarray, low: jnp.ndarray, high: jnp.ndarray) -> jnp.ndarray: return jnp.clip(action, low, high) @@ -70,18 +71,154 @@ def _normalize_obs(obs, mean, var, eps=1e-8): return jnp.clip((obs - mean) / jnp.sqrt(var + eps), -10.0, 10.0) -@jax.jit -def _convert_obs_dict_to_array(obs_dict: dict) -> jnp.ndarray: - """Convert the raw observation dict → flat array, filtering unwanted keys.""" +from enum import Enum - def _filter_and_flatten(o: dict) -> jnp.ndarray: + +class ObsMode(Enum): + CENTRALIZED = 0 + ARM = 1 + SEGMENT = 2 + + +@jax.jit +def _convert_obs_dict_to_array(obs_dict, obs_mode, segments_per_arm): + + num_segments = sum(segments_per_arm) + num_arms = len(segments_per_arm) + + def _filter_and_flatten(o): values = [] + for key in sorted(o.keys()): - if key in _ALLOWED_OBS_KEYS: # TODO: NORMALIZATION or .. of observations?? - v = o[key] - if v.size > 0: - values.append(jnp.asarray(v).flatten()) - return jnp.concatenate(values) + if key not in _ALLOWED_OBS_KEYS: + continue + + v = o[key] + if v.size == 0: + continue + + # -------- CENTRALIZED -------- + if obs_mode == 0: + values.append(v.reshape(v.shape[0], -1)) + continue + + # -------- SPLIT TO SEGMENTS -------- + if key in _JOINT_SCALED_KEYS: + v = v.reshape(v.shape[0], num_segments, 2) + + elif key in _SEGMENT_SCALED_KEYS: + v = v[..., None] # (env, segments, 1) + + else: + # global → broadcast + if obs_mode == 2: + v = jnp.repeat(v[:, None, :], num_segments, axis=1) + else: + v = jnp.repeat(v[:, None, :], num_arms, axis=1) + values.append(v) + continue + + # -------- SEGMENT MODE -------- + if obs_mode == 2: + values.append(v) + continue + + # -------- ARM MODE -------- + # reshape (segments → arms, seg_per_arm) + v = v.reshape(v.shape[0], num_arms, -1) + + values.append(v) + + # -------- CONCAT -------- + if obs_mode == 0: + return jnp.concatenate(values, axis=-1) + else: + return jnp.concatenate(values, axis=-1) + + return jax.vmap(_filter_and_flatten)(obs_dict) + + +from enum import Enum + + +class ObsMode(Enum): + CENTRALIZED = 0 # dirty dirty code, todo, mooove outta here + ARM = 1 + SEGMENT = 2 + + +# Observation keys whose size scales with the number of joints (2 per segment). +_JOINT_SCALED_KEYS = frozenset( + { + "joint_position", + "joint_velocity", + "joint_actuator_force", + "actuator_force", + } +) + +# Observation keys whose size scales with the number of segments (1 per segment). +_SEGMENT_SCALED_KEYS = frozenset( + { + "segment_contact", + } +) + + +@jax.jit +def _convert_obs_dict_to_array(obs_dict, obs_mode, segments_per_arm): + + num_segments = sum(segments_per_arm) + num_arms = len(segments_per_arm) + + def _filter_and_flatten(o): + values = [] + + for key in sorted(o.keys()): + if key not in _ALLOWED_OBS_KEYS: + continue + + v = o[key] + if v.size == 0: + continue + + # -------- CENTRALIZED -------- + if obs_mode == 0: + values.append(v.reshape(v.shape[0], -1)) + continue + + # -------- SPLIT TO SEGMENTS -------- + if key in _JOINT_SCALED_KEYS: + v = v.reshape(v.shape[0], num_segments, 2) + + elif key in _SEGMENT_SCALED_KEYS: + v = v[..., None] # (env, segments, 1) + + else: + # global → broadcast + if obs_mode == 2: + v = jnp.repeat(v[:, None, :], num_segments, axis=1) + else: + v = jnp.repeat(v[:, None, :], num_arms, axis=1) + values.append(v) + continue + + # -------- SEGMENT MODE -------- + if obs_mode == 2: + values.append(v) + continue + + # -------- ARM MODE -------- + # reshape (segments → arms, seg_per_arm) + v = v.reshape(v.shape[0], num_arms, -1) + + values.append(v) + + # -------- CONCAT -------- + if obs_mode == 0: + return jnp.concatenate(values, axis=-1) + else: + return jnp.concatenate(values, axis=-1) return jax.vmap(_filter_and_flatten)(obs_dict) @@ -367,6 +504,8 @@ class PPOTrainer: ) dummy_reset = self.env.reset(seed=0) + for k, v in dummy_reset.observations.items(): + print(k, v.shape) sample_obs = _convert_obs_dict_to_array(dummy_reset.observations)[0] # take first env self.obs_mean = jnp.zeros((len(sample_obs),)) self.obs_var = jnp.ones((len(sample_obs),)) From 2777d4f6daf48d7c8be0696251397194c9f05a0d Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 28 Apr 2026 06:46:26 +0000 Subject: [PATCH 03/96] feat: adjacency builder --- .../trainers/PPOTrainer.py | 83 ++++++++++++++++--- tests/test_adjacency.py | 79 ++++++++++++++++++ 2 files changed, 149 insertions(+), 13 deletions(-) create mode 100644 tests/test_adjacency.py diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index df2c571..2642446 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -27,10 +27,11 @@ from brittle_star_project.ppo import PPO from enum import Enum -class ObsMode(Enum): - CENTRALIZED = "centralized" - ARM = "arm" - SEGMENT = "segment" +class MorphMode(Enum): + CENTRALIZED = 0 + FULLY_CONNECTED = 1 + RING = 2 + SEGMENT = 3 # TODO: move to config @@ -49,6 +50,71 @@ _ALLOWED_OBS_KEYS = { # TODO: clip scaled reward? +def build_adjacency(segments_per_arm, mode: MorphMode): + num_arms = len(segments_per_arm) + num_segments = sum(segments_per_arm) + + # FOR NOW SEMI HARDCODE: + # CENTRALIZED: 1 agent, no stress, adja = 1,1 = [[1]] + # FULLY CONNECTED: 5 agents: adj = alle 1 + # CENTRAL DISK:#arms= 5 agents, only neighbor as adjacent so diagonal kinda.. + # ARM = #segments agents: diago kinda, but extra, center ring too, put center mlps first or.. + + if mode == MorphMode.CENTRALIZED: + return jnp.ones((1, 1)) + + if mode == MorphMode.FULLY_CONNECTED: + adj = jnp.ones((num_arms, num_arms)) # everybody adjacent everybody + return adj + + if mode == MorphMode.RING: # ring + adj = jnp.zeros((num_arms, num_arms)) + for i in range(num_arms): + adj = adj.at[i, i].set(1) # self + adj = adj.at[i, (i - 1) % num_arms].set(1) + adj = adj.at[i, (i + 1) % num_arms].set(1) # left and right.. + return adj + + if mode == MorphMode.SEGMENT: + num_nodes = num_arms + num_segments + adj = jnp.zeros((num_nodes, num_nodes)) + + # first ring + for i in range(num_arms): + # self + adj = adj.at[i, i].set(1) + + # ring neighbors + adj = adj.at[i, (i - 1) % num_arms].set(1) + adj = adj.at[i, (i + 1) % num_arms].set(1) + + # then segment chains + idx = 0 + for arm_idx, seg_count in enumerate(segments_per_arm): + for i in range(seg_count): + seg_node = num_arms + idx + i + + adj = adj.at[seg_node, seg_node].set(1) + if i > 0: + adj = adj.at[seg_node, seg_node - 1].set(1) + if i < seg_count - 1: + adj = adj.at[seg_node, seg_node + 1].set(1) + + idx += seg_count + + idx = 0 + for arm_idx, seg_count in enumerate(segments_per_arm): + first_seg = num_arms + idx # first segment of this arm + + # connect ring node first segment + adj = adj.at[arm_idx, first_seg].set(1) + adj = adj.at[first_seg, arm_idx].set(1) + + idx += seg_count + + return adj + + @jax.jit def _clip_action(action: jnp.ndarray, low: jnp.ndarray, high: jnp.ndarray) -> jnp.ndarray: return jnp.clip(action, low, high) @@ -71,15 +137,6 @@ def _normalize_obs(obs, mean, var, eps=1e-8): return jnp.clip((obs - mean) / jnp.sqrt(var + eps), -10.0, 10.0) -from enum import Enum - - -class ObsMode(Enum): - CENTRALIZED = 0 - ARM = 1 - SEGMENT = 2 - - @jax.jit def _convert_obs_dict_to_array(obs_dict, obs_mode, segments_per_arm): diff --git a/tests/test_adjacency.py b/tests/test_adjacency.py new file mode 100644 index 0000000..5c33038 --- /dev/null +++ b/tests/test_adjacency.py @@ -0,0 +1,79 @@ +import jax.numpy as jnp +import pytest + +from brittle_star_project.trainers.PPOTrainer import build_adjacency, MorphMode + + +def assert_symmetric(adj): + assert jnp.all(adj == adj.T) + + +def test_centralized(): + adj = build_adjacency([4, 4, 4, 4, 4], MorphMode.CENTRALIZED) + + assert adj.shape == (1, 1) + assert adj[0, 0] == 1 + + +def test_fully_connected(): + adj = build_adjacency([4, 4, 4, 4, 4], MorphMode.FULLY_CONNECTED) + + assert adj.shape == (5, 5) + assert jnp.all(adj == 1) + + +def test_ring(): + adj = build_adjacency([4, 4, 4, 4, 4], MorphMode.RING) + + assert adj.shape == (5, 5) + assert_symmetric(adj) + + # each node should connect to itself + 2 neighbors + for i in range(5): + assert adj[i, i] == 1 + assert jnp.sum(adj[i]) == 3 + + +def test_segment_structure(): + segments = [4, 4, 4, 4, 4] + adj = build_adjacency(segments, MorphMode.SEGMENT) + + num_arms = 5 + num_segments = sum(segments) + num_nodes = num_arms + num_segments + + assert adj.shape == (num_nodes, num_nodes) + + # --- ring connectivity --- + for i in range(num_arms): + assert adj[i, i] == 1 + assert adj[i, (i - 1) % num_arms] == 1 + assert adj[i, (i + 1) % num_arms] == 1 + + # --- segment chain checks --- + offset = num_arms + for arm in range(5): + for i in range(4): + node = offset + arm * 4 + i + + # self + assert adj[node, node] == 1 + + # chain neighbors + if i > 0: + assert adj[node, node - 1] == 1 + if i < 3: + assert adj[node, node + 1] == 1 + + # --- ring ↔ segment connections --- + for arm in range(5): + first_seg = num_arms + arm * 4 + assert adj[arm, first_seg] == 1 + assert adj[first_seg, arm] == 1 + + +def test_no_isolated_nodes(): + adj = build_adjacency([4, 4, 4, 4, 4], MorphMode.SEGMENT) + + # no node should be completely isolated + assert jnp.all(jnp.sum(adj, axis=0) > 0) From 39945e8821a464fa41ba35fc42237299c65e5997 Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 28 Apr 2026 07:27:08 +0000 Subject: [PATCH 04/96] feat: helper to visualize adjacency in a file --- tests/test_adjacency.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_adjacency.py b/tests/test_adjacency.py index 5c33038..5e8a129 100644 --- a/tests/test_adjacency.py +++ b/tests/test_adjacency.py @@ -1,5 +1,6 @@ import jax.numpy as jnp import pytest +import numpy as np from brittle_star_project.trainers.PPOTrainer import build_adjacency, MorphMode @@ -71,6 +72,20 @@ def test_segment_structure(): assert adj[arm, first_seg] == 1 assert adj[first_seg, arm] == 1 + save_adj(adj) + + +def save_adj(adj, name="adjacency_debug.txt"): + a = np.array(adj) + + with open(name, "w") as f: + f.write("\nAdjacency matrix:\n") + f.write(" " + " ".join([f"{i:2d}" for i in range(a.shape[0])]) + "\n") + + for i, row in enumerate(a): + line = f"{i:2d} " + " ".join(["█" if x > 0 else "." for x in row]) + f.write(line + "\n") + def test_no_isolated_nodes(): adj = build_adjacency([4, 4, 4, 4, 4], MorphMode.SEGMENT) From a005c0ccadc0d01c0e5cda3a8648125d2fd0faa9 Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 28 Apr 2026 08:20:00 +0000 Subject: [PATCH 05/96] feat: upgraded obs_to_array, now takes care of splitting for agents --- .../trainers/PPOTrainer.py | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 2642446..d431328 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -138,7 +138,7 @@ def _normalize_obs(obs, mean, var, eps=1e-8): @jax.jit -def _convert_obs_dict_to_array(obs_dict, obs_mode, segments_per_arm): +def _convert_obs_dict_to_array(obs_dict, morph_mode, segments_per_arm): num_segments = sum(segments_per_arm) num_arms = len(segments_per_arm) @@ -155,55 +155,54 @@ def _convert_obs_dict_to_array(obs_dict, obs_mode, segments_per_arm): continue # -------- CENTRALIZED -------- - if obs_mode == 0: + if morph_mode == 0: values.append(v.reshape(v.shape[0], -1)) continue # -------- SPLIT TO SEGMENTS -------- if key in _JOINT_SCALED_KEYS: + if morph_mode == 3: + B = v.shape[0] + + center_size = num_arms * 3 * 2 # 3 slots per arm, each slot has 2 values + + v_center = v[:, :center_size] + v_center = v_center.reshape(B, num_arms, 3, 2) + + v_segs = v[:, center_size:] + v_segs = v_segs.reshape(B, -1, 2) + + v = jnp.concatenate([v_center.reshape(B, -1, 2), v_segs], axis=1) + values.append(v) + continue v = v.reshape(v.shape[0], num_segments, 2) elif key in _SEGMENT_SCALED_KEYS: v = v[..., None] # (env, segments, 1) else: - # global → broadcast - if obs_mode == 2: - v = jnp.repeat(v[:, None, :], num_segments, axis=1) - else: + if morph_mode == 3: # segment + v = jnp.repeat(v[:, None, :], num_segments + num_arms, axis=1) + + else: # ring or fully connect v = jnp.repeat(v[:, None, :], num_arms, axis=1) values.append(v) continue # -------- SEGMENT MODE -------- - if obs_mode == 2: + if morph_mode == 3: values.append(v) continue # -------- ARM MODE -------- - # reshape (segments → arms, seg_per_arm) v = v.reshape(v.shape[0], num_arms, -1) - values.append(v) - # -------- CONCAT -------- - if obs_mode == 0: - return jnp.concatenate(values, axis=-1) - else: - return jnp.concatenate(values, axis=-1) + return jnp.concatenate(values, axis=-1) return jax.vmap(_filter_and_flatten)(obs_dict) -from enum import Enum - - -class ObsMode(Enum): - CENTRALIZED = 0 # dirty dirty code, todo, mooove outta here - ARM = 1 - SEGMENT = 2 - - # Observation keys whose size scales with the number of joints (2 per segment). _JOINT_SCALED_KEYS = frozenset( { @@ -480,7 +479,12 @@ class TrainingMeasurements: class PPOTrainer: def __init__( - self, cfg: BrittleStarConfig, env: BrittleStarJaxEnvWrapper, run_dir: str, run_name: str + self, + cfg: BrittleStarConfig, + env: BrittleStarJaxEnvWrapper, + run_dir: str, + run_name: str, + morph: MorphMode = MorphMode.CENTRALIZED, ): self.cfg = cfg self.ppo = cfg.ppo @@ -497,6 +501,8 @@ class PPOTrainer: self.key = jax.random.PRNGKey(self.experiment.seed) + self.adj = build_adjacency(cfg.morphology.segments_per_arm, morph) + self.sensor, self.feature_extractor, self.actor, self.critic = self._init_agent() self.sensor.apply = jax.jit(self.sensor.apply) self.feature_extractor.apply = jax.jit(self.feature_extractor.apply) From a1db544e764ad859565467ac6c153e8d24a07e81 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 10:43:48 +0200 Subject: [PATCH 06/96] feat: extract observations pipeline --- configs/main_config.yaml | 1 + configs/obs_bounds/default.yaml | 1 + .../configs/main_config.py | 8 +- .../configs/register_configs.py | 8 +- .../environment/env_config.py | 25 ++++++ .../environment/obs_processing.py | 83 +++++++++++++++++++ 6 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 configs/obs_bounds/default.yaml create mode 100644 src/brittle_star_project/environment/obs_processing.py diff --git a/configs/main_config.yaml b/configs/main_config.yaml index 745755a..b7cb620 100644 --- a/configs/main_config.yaml +++ b/configs/main_config.yaml @@ -11,6 +11,7 @@ defaults: - morphology: 5_arms_full - arena: default - environment: directed_locomotion + - obs_bounds: default - simulation: default - _self_ diff --git a/configs/obs_bounds/default.yaml b/configs/obs_bounds/default.yaml new file mode 100644 index 0000000..cd70b0b --- /dev/null +++ b/configs/obs_bounds/default.yaml @@ -0,0 +1 @@ +# Defaults provided by dataclass diff --git a/src/brittle_star_project/configs/main_config.py b/src/brittle_star_project/configs/main_config.py index 5a937a7..10fd22e 100644 --- a/src/brittle_star_project/configs/main_config.py +++ b/src/brittle_star_project/configs/main_config.py @@ -5,7 +5,12 @@ from brittle_star_project.configs.config_experiment import ExperimentConfig from brittle_star_project.configs.config_ppo import PPOConfig from brittle_star_project.configs.config_architecture import ArchitectureConfig from brittle_star_project.configs.config_simulation import SimulationSettings -from brittle_star_project.environment.env_config import MorphologyConfig, ArenaConfig, EnvConfig +from brittle_star_project.environment.env_config import ( + MorphologyConfig, + ArenaConfig, + EnvConfig, + ObservationBoundsConfig, +) @dataclass @@ -25,4 +30,5 @@ class BrittleStarConfig: morphology: MorphologyConfig = field(default_factory=MorphologyConfig) arena: ArenaConfig = field(default_factory=ArenaConfig) environment: EnvConfig = field(default_factory=EnvConfig) + obs_bounds: ObservationBoundsConfig = field(default_factory=ObservationBoundsConfig) simulation: SimulationSettings = field(default_factory=SimulationSettings) diff --git a/src/brittle_star_project/configs/register_configs.py b/src/brittle_star_project/configs/register_configs.py index b677b31..147da10 100644 --- a/src/brittle_star_project/configs/register_configs.py +++ b/src/brittle_star_project/configs/register_configs.py @@ -8,7 +8,12 @@ from brittle_star_project.configs.config_architecture import ( DecentralizedConfig, ) from brittle_star_project.configs.config_simulation import SimulationSettings -from brittle_star_project.environment.env_config import MorphologyConfig, ArenaConfig, EnvConfig +from brittle_star_project.environment.env_config import ( + MorphologyConfig, + ArenaConfig, + EnvConfig, + ObservationBoundsConfig, +) from brittle_star_project.configs.main_config import BrittleStarConfig @@ -37,4 +42,5 @@ def register_configs() -> None: cs.store(group="morphology", name="base_morphology", node=MorphologyConfig) cs.store(group="arena", name="base_arena", node=ArenaConfig) cs.store(group="environment", name="base_environment", node=EnvConfig) + cs.store(group="obs_bounds", name="base_obs_bounds", node=ObservationBoundsConfig) cs.store(group="simulation", name="base_simulation", node=SimulationSettings) diff --git a/src/brittle_star_project/environment/env_config.py b/src/brittle_star_project/environment/env_config.py index 7cb4c21..0af387e 100644 --- a/src/brittle_star_project/environment/env_config.py +++ b/src/brittle_star_project/environment/env_config.py @@ -60,3 +60,28 @@ class EnvConfig: # Light escape # Per docs in upstream env config: integer factors of 200. light_perlin_noise_scale: int = 0 + + +@dataclass +class ObservationBoundsConfig: + """Physical observation bounds for deterministic min-max normalization.""" + + # TODO Inspect empirically observed ranges and update these bounds as needed. + joint_position: list[float] = field(default_factory=lambda: [-3.14, 3.14]) + joint_velocity: list[float] = field(default_factory=lambda: [-20.0, 20.0]) + joint_actuator_force: list[float] = field(default_factory=lambda: [-5.0, 5.0]) + segment_contact: list[float] = field(default_factory=lambda: [0.0, 1.0]) + unit_xy_direction_to_target: list[float] = field(default_factory=lambda: [-1.0, 1.0]) + xy_distance_to_target: list[float] = field(default_factory=lambda: [0.0, 20.0]) + disk_z_tilt: list[float] = field(default_factory=lambda: [0.0, 3.141592653589793]) + + def to_bounds_dict(self) -> dict[str, tuple[float, float]]: + return { + "joint_position": tuple(self.joint_position), + "joint_velocity": tuple(self.joint_velocity), + "joint_actuator_force": tuple(self.joint_actuator_force), + "segment_contact": tuple(self.segment_contact), + "unit_xy_direction_to_target": tuple(self.unit_xy_direction_to_target), + "xy_distance_to_target": tuple(self.xy_distance_to_target), + "disk_z_tilt": tuple(self.disk_z_tilt), + } diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py new file mode 100644 index 0000000..0ef6e3d --- /dev/null +++ b/src/brittle_star_project/environment/obs_processing.py @@ -0,0 +1,83 @@ +import jax +import jax.numpy as jnp +from typing import Dict, Tuple, Optional + +_JOINT_SCALED_KEYS = frozenset( + { + "joint_position", + "joint_velocity", + "joint_actuator_force", + "actuator_force", + } +) + +_SEGMENT_SCALED_KEYS = frozenset( + { + "segment_contact", + } +) + + +def create_obs_processor( + bounds_dict: Dict[str, Tuple[float, float]], padding_masks: Optional[Dict] = None +): + def _add_derived_features(obs: dict) -> dict: + new_obs = dict(obs) + if "disk_rotation" in new_obs: + rot = new_obs["disk_rotation"] + new_obs["disk_z_tilt"] = jnp.sqrt(jnp.pow(rot[0], 2) + jnp.pow(rot[1], 2)) + return new_obs + + def _normalize_features(obs: dict) -> dict: + normalized = {} + for key, arr in obs.items(): + if key in bounds_dict: + low, high = bounds_dict[key] + if low == -1.0 and high == 1.0: + normalized[key] = jnp.clip(arr, -1.0, 1.0) + else: + arr_clipped = jnp.clip(arr, low, high) + normalized[key] = 2.0 * (arr_clipped - low) / (high - low) - 1.0 + else: + normalized[key] = arr + return normalized + + def _pad_features(obs: dict) -> dict: + padded = {} + for key, arr in obs.items(): + if key in _JOINT_SCALED_KEYS: + padded_arr = jnp.zeros(padding_masks["target_size_2x"], dtype=arr.dtype) + padded[key] = padded_arr.at[padding_masks["mask_2x"]].set(arr) + elif key in _SEGMENT_SCALED_KEYS: + padded_arr = jnp.zeros(padding_masks["target_size_1x"], dtype=arr.dtype) + padded[key] = padded_arr.at[padding_masks["mask_1x"]].set(arr) + else: + padded[key] = arr + return padded + + def _flatten_features(obs: dict) -> jnp.ndarray: + ordered_keys = [ + "disk_z_tilt", + "joint_actuator_force", + "joint_position", + "joint_velocity", + "segment_contact", + "unit_xy_direction_to_target", + "xy_distance_to_target", + ] + values = [] + for key in ordered_keys: + if key in obs: + arr = jnp.asarray(obs[key]).flatten() + if arr.size > 0: + values.append(arr) + return jnp.concatenate(values) + + def _process_single(obs_dict: dict) -> jnp.ndarray: + processed = _add_derived_features(obs_dict) + processed = _normalize_features(processed) + if padding_masks is not None: + processed = _pad_features(processed) + return _flatten_features(processed) + + return jax.jit(jax.vmap(_process_single)) From 0032496073059af2037a6e3d8ee88d7cf16a037c Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 10:44:55 +0200 Subject: [PATCH 07/96] docs: describe normalization --- docs/design/input_action_spaces.md | 34 +++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/docs/design/input_action_spaces.md b/docs/design/input_action_spaces.md index 8d24d37..143dce5 100644 --- a/docs/design/input_action_spaces.md +++ b/docs/design/input_action_spaces.md @@ -10,9 +10,12 @@ decentralized control architecture in mind, we divide these inputs into global a Global inputs, always broadcasted to all nodes: -- Vertical orientation/tilt: A single, simplified metric representing the tilt or vertical alignment of the agent's - central body/disk, derived from the environment's raw disk rotation 3D vector $[roll, pitch, yaw]$: - $$tilt = sqrt(roll^2 + pitch^2)$$. This represents the deviation from the global Z-axis. +- Vertical orientation/tilt: A single, simplified metric representing the tilt/vertical alignment of the agent's + central body/disk, a.k.a. the deviation from the global Z-axis. Its value is derived from the environment's raw disk + rotation 3D vector $[roll, pitch, yaw]$: + $$ + tilt = sqrt(roll^2 + pitch^2) + $$ - Goal vector: Instead of just a scalar distance, the goal is represented asa a vector (distance and ange/direction) to the target. @@ -29,6 +32,16 @@ The action space defines how the agent interacts with the environment. - Joint offsets: *absolute* target positions (offsets) for the joints, i.e. the exact angle the joint should move to. +## Normalization and Scaling + +Both the input (observation) and output (action) spaces are rescaled to the range **$[-1, 1]$**. + +For the input space, all raw physical values (angles, velocities, forces, distances) are normalized based on their +defined physical bounds. If a value exceeds these bounds during simulation, it is clipped to the $[-1, 1]$ range. + +For the output space, the neural network's tanh-activated outputs (which naturally fall in $[-1, 1]$) are linearly +mapped to the physical joint limits defined in the robot's morphology. + ## Rationale When designing the state space, we must ask: *Could a human operator perform this task given only these inputs?* @@ -59,6 +72,17 @@ When designing the state space, we must ask: *Could a human operator perform thi random walks or spiraling) to deduce the direction, drastically increasing the difficulty of the learning task. - Contact sensors: Segment contact detects external ground interaction and is biologically vital for timing gait transitions. +- **Zero-Centered Rescaling ($[-1, 1]$):** Using a zero-centered range is standard best practice for continuous control + tasks. It provides several mathematical and physical advantages: + - **Improved Gradient Flow:** Neural networks optimize faster when inputs are zero-centered. If all inputs were + positive (e.g., $[0, 1]$), the gradients during backpropagation would be forced to the same sign, causing + inefficient "zig-zag" weight updates. + - **Meaningful "Neutral" State:** In robotics, $0.0$ naturally represents a resting state (zero velocity, centered + position, no force). In a $[-1, 1]$ system, this physical rest maps to a neutral $0.0$ signal in the network. + - **Robustness to Amputation:** In this project, amputated limbs are padded with $0.0$. In a $[-1, 1]$ system, this + correctly communicates a "neutral/dead" signal. In a $[0, 1]$ system, $0.0$ would represent the absolute minimum + physical limit, causing the network to misinterpret missing limbs as being at their extreme limits. + Specifically, we do not include some available inputs: @@ -80,6 +104,10 @@ Alternative state and action formulations include: - Scalar Goal Distance: Giving the agent only the scalar distance to the target would force it to learn a localized searching behavior (e.g., spiraling or random walks) to determine the correct direction. While biologically plausible for simpler organisms following chemical gradients, it drastically increases the difficulty of the learning task. +- **$[0, 1]$ Rescaling:** While some domains (like computer vision) use $[0, 1]$ scaling, it is generally avoided in + robotics. Scaling to $[0, 1]$ would mean that a resting joint (velocity = 0) maps to an input of $0.5$. This + constant positive bias forces the network to waste capacity learning to ignore or subtract this baseline signal just + to stand still. Furthermore, it breaks the "dead signal" interpretation of zero-padding used for amputations. ## MuJoCo From 036edf8aab4e85b42d0b38c650d430ad94e6b79d Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 11:15:16 +0200 Subject: [PATCH 08/96] chore: observation pipeline in training --- .../environment/BrittleStarJaxEnvWrapper.py | 22 +++--- .../trainers/PPOTrainer.py | 79 ++++--------------- 2 files changed, 27 insertions(+), 74 deletions(-) diff --git a/src/brittle_star_project/environment/BrittleStarJaxEnvWrapper.py b/src/brittle_star_project/environment/BrittleStarJaxEnvWrapper.py index a5175a7..b514c11 100644 --- a/src/brittle_star_project/environment/BrittleStarJaxEnvWrapper.py +++ b/src/brittle_star_project/environment/BrittleStarJaxEnvWrapper.py @@ -5,7 +5,7 @@ from experiment_logger import get_logger from .env_config import EnvConfig, MorphologyConfig, ArenaConfig from .env_types import Backend from .factory import BrittleStarEnvFactory -from .padded_obs_wrapper import compute_padding_masks, pad_observations_batched +from .padded_obs_wrapper import compute_padding_masks class BrittleStarJaxEnvWrapper: @@ -48,6 +48,15 @@ class BrittleStarJaxEnvWrapper: def raw(self): return self._env + @property + def padding_masks(self) -> dict: + """Pre-computed boolean masks for amputated limb padding. + + Pass to create_obs_processor so the processor handles padding + after normalization in the correct pipeline order. + """ + return self._padding_masks + @property def single_action_space(self): return self._env.action_space @@ -61,10 +70,6 @@ class BrittleStarJaxEnvWrapper: self._action_rng, env_rng = jax.random.split(jax.random.PRNGKey(seed), 2) env_rngs = jnp.array(jax.random.split(env_rng, self._num_envs)) state = self._vectorized_reset(rng=env_rngs) - - state = state.replace( - observations=pad_observations_batched(state.observations, self._padding_masks) - ) return state def sample_actions(self): @@ -75,12 +80,7 @@ class BrittleStarJaxEnvWrapper: return self._vectorized_action_sample(rng=jnp.array(sub_rngs)) def step(self, state, action): - next_state = self._vectorized_step(state=state, action=action) - - next_state = next_state.replace( - observations=pad_observations_batched(next_state.observations, self._padding_masks) - ) - return next_state + return self._vectorized_step(state=state, action=action) def close(self): self._env.close() diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 7cdc1ff..a3e4eac 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -16,6 +16,7 @@ from experiment_logger import get_logger from brittle_star_project.configs.main_config import BrittleStarConfig from brittle_star_project.dataclasses import EpisodeStatistics from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleStarJaxEnvWrapper +from brittle_star_project.environment.obs_processing import create_obs_processor from brittle_star_project.MLPs.mlps import ( Actor, AgentParams, @@ -25,19 +26,6 @@ from brittle_star_project.MLPs.mlps import ( ) from brittle_star_project.ppo import PPO -# TODO: move to config -_ALLOWED_OBS_KEYS = { - "joint_position", - "joint_velocity", - "joint_actuator_force", - "actuator_force", - "disk_position", - "disk_rotation", - "disk_linear_velocity", - "disk_angular_velocity", - "unit_xy_direction_to_target", - "xy_distance_to_target", -} # TODO: clip scaled reward? @@ -65,27 +53,6 @@ def _linear_schedule(count, minibatch_count, update_epochs, num_iterations, lear return learning_rate * frac -@jax.jit -def _normalize_obs(obs, mean, var, eps=1e-8): - return jnp.clip((obs - mean) / jnp.sqrt(var + eps), -10.0, 10.0) - - -@jax.jit -def _convert_obs_dict_to_array(obs_dict: dict) -> jnp.ndarray: - """Convert the raw observation dict → flat array, filtering unwanted keys.""" - - def _filter_and_flatten(o: dict) -> jnp.ndarray: - values = [] - for key in sorted(o.keys()): - if key in _ALLOWED_OBS_KEYS: # TODO: NORMALIZATION or .. of observations?? - v = o[key] - if v.size > 0: - values.append(jnp.asarray(v).flatten()) - return jnp.concatenate(values) - - return jax.vmap(_filter_and_flatten)(obs_dict) - - def _get_action_and_value_noise( sensor: GenericDenseLayersWithActivation, feature_extractor: GenericDenseLayersWithActivation, @@ -168,7 +135,7 @@ def _reward_fn(env_state, next_env_state): return jnp.where(next_env_state.terminated, 50.0, clipped_env_reward - penalty) -def _step_env_wrapped(episode_stats, env_state, action, env_step_fn): +def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, obs_processor): next_env_state = env_step_fn(env_state, action) reward = _reward_fn(env_state, next_env_state) @@ -192,7 +159,7 @@ def _step_env_wrapped(episode_stats, env_state, action, env_step_fn): return ( episode_stats, next_env_state, - (_convert_obs_dict_to_array(next_env_state.observations), reward, done), + (obs_processor(next_env_state.observations), reward, done), ) @@ -303,6 +270,12 @@ class PPOTrainer: self.key = jax.random.PRNGKey(self.experiment.seed) + # Build the centralized observation processor: derive -> normalize -> pad -> flatten. + self.obs_processor = create_obs_processor( + bounds_dict=self.cfg.obs_bounds.to_bounds_dict(), + padding_masks=self.env.padding_masks, + ) + self.sensor, self.feature_extractor, self.actor, self.critic = self._init_agent() self.sensor.apply = jax.jit(self.sensor.apply) self.feature_extractor.apply = jax.jit(self.feature_extractor.apply) @@ -316,7 +289,11 @@ class PPOTrainer: partial( _rollout_jit, max_steps=self.ppo.num_steps, - step_env_fn=partial(_step_env_wrapped, env_step_fn=self.env.step), + step_env_fn=partial( + _step_env_wrapped, + env_step_fn=self.env.step, + obs_processor=self.obs_processor, + ), sensor=self.sensor, feature_extractor=self.feature_extractor, actor=self.actor, @@ -367,10 +344,7 @@ class PPOTrainer: ) dummy_reset = self.env.reset(seed=0) - sample_obs = _convert_obs_dict_to_array(dummy_reset.observations)[0] # take first env - self.obs_mean = jnp.zeros((len(sample_obs),)) - self.obs_var = jnp.ones((len(sample_obs),)) - self.obs_count = 1e-4 + sample_obs = self.obs_processor(dummy_reset.observations)[0] # take first env sensor_params = self.sensor.init(sensor_key, sample_obs) feature_extractor_params = self.feature_extractor.init(feature_extractor_key, sample_obs) actor_params = self.actor.init(actor_key, self.sensor.apply(sensor_params, sample_obs)) @@ -410,25 +384,6 @@ class PPOTrainer: returned_episode_lengths=jnp.zeros(self.ppo.num_envs, dtype=jnp.int32), ) - def _update_obs_stats(self, obs: jnp.ndarray): - batch_mean = jnp.mean(obs, axis=0) - batch_var = jnp.var(obs, axis=0) - batch_count = obs.shape[0] - - delta = batch_mean - self.obs_mean - total_count = self.obs_count + batch_count - - new_mean = self.obs_mean + delta * batch_count / total_count - - m_a = self.obs_var * self.obs_count - m_b = batch_var * batch_count - M2 = m_a + m_b + delta**2 * self.obs_count * batch_count / total_count - new_var = M2 / total_count - - self.obs_mean = new_mean - self.obs_var = new_var - self.obs_count = total_count - def _rollout(self, env_state, next_obs, next_done) -> tuple[Any, ...]: return self._rollout_jit( self.agent_state, @@ -594,7 +549,7 @@ class PPOTrainer: self.logger.log_non_interactive(f"Initial reset started: {time.ctime()}") env_state = self.env.reset(seed=self.experiment.seed) - next_obs = _convert_obs_dict_to_array(env_state.observations) + next_obs = self.obs_processor(env_state.observations) next_done = jnp.zeros(self.ppo.num_envs, dtype=jnp.bool_) self.logger.log_non_interactive(f"Initial reset completed: {time.ctime()}") @@ -609,8 +564,6 @@ class PPOTrainer: env_state, next_obs, next_done, training_measurements, storage = self._step( env_state, next_obs, next_done, iteration=iteration ) - self._update_obs_stats(next_obs) - next_obs = _normalize_obs(next_obs, self.obs_mean, self.obs_var) global_step += self.ppo.num_steps * self.ppo.num_envs self._log( From a3a1f3643f84210936cd539ccd619d1dab0f938b Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 11:40:28 +0200 Subject: [PATCH 09/96] chore: observation pipeline in simulate --- scripts/simulate.py | 92 +++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 58 deletions(-) diff --git a/scripts/simulate.py b/scripts/simulate.py index a9a51f4..0e6d01b 100644 --- a/scripts/simulate.py +++ b/scripts/simulate.py @@ -27,23 +27,9 @@ from omegaconf import DictConfig, OmegaConf, open_dict from brittle_star_project import Backend, BrittleStarEnv, BrittleStarEnvFactory from brittle_star_project.configs.main_config import BrittleStarConfig from brittle_star_project.configs.register_configs import register_configs -from brittle_star_project.environment.padded_obs_wrapper import ( - compute_padding_masks, - pad_observation, -) - -_ALLOWED_OBS_KEYS = { - "joint_position", - "joint_velocity", - "joint_actuator_force", - "actuator_force", - "disk_position", - "disk_rotation", - "disk_linear_velocity", - "disk_angular_velocity", - "unit_xy_direction_to_target", - "xy_distance_to_target", -} +from brittle_star_project.environment.padded_obs_wrapper import compute_padding_masks +from brittle_star_project.environment.obs_processing import create_obs_processor +from brittle_star_project.environment.env_config import ObservationBoundsConfig def _dense_layer_sizes_from_params(params: Any) -> list[int]: @@ -113,28 +99,6 @@ def _maybe_clip_action( return np.clip(action, low, high) -def _transform_obs_dict(obs_dict: dict[str, Any]) -> jnp.ndarray: - """Flatten the env's observation dict into a 1D vector. - - Matches training behavior: - - only includes keys in _ALLOWED_OBS_KEYS - - iterates keys in sorted order for stable layout - - skips empty arrays - """ - parts: list[jnp.ndarray] = [] - for key in sorted(obs_dict.keys()): - if key not in _ALLOWED_OBS_KEYS: - continue - arr = jnp.asarray(obs_dict[key]) - if arr.size == 0: - continue - parts.append(arr.reshape((-1,))) - - if not parts: - return jnp.zeros((0,), dtype=jnp.float32) - return jnp.concatenate(parts, axis=0) - - # A minimal policy class to load a CleanRL/Flax checkpoint and run inference. class CleanRLPPOPolicy: def __init__( @@ -143,6 +107,7 @@ class CleanRLPPOPolicy: sensor_params: Any, actor_params: Any, action_dim: int, + obs_processor: Any, ) -> None: from brittle_star_project.MLPs.mlps import Actor, GenericDenseLayersWithActivation @@ -155,12 +120,14 @@ class CleanRLPPOPolicy: "sensor_params": sensor_params, "actor_params": actor_params, } + self._obs_processor = obs_processor @staticmethod def load( path: Path, *, action_dim: int, + obs_processor: Any, ) -> "CleanRLPPOPolicy": def _get_index(container: Any, idx: int) -> Any: if isinstance(container, (list, tuple)): @@ -280,10 +247,12 @@ class CleanRLPPOPolicy: sensor_params=sensor_params, actor_params=actor_params, action_dim=action_dim, + obs_processor=obs_processor, ) def act(self, *, observations: dict[str, Any]) -> np.ndarray: - obs = _transform_obs_dict(observations) + batched_obs = jax.tree.map(lambda x: jnp.asarray(x)[None, ...], observations) + obs = self._obs_processor(batched_obs)[0] hidden = self._sensor_apply(self._params["sensor_params"], obs) mean, _log_std = self._actor_apply(self._params["actor_params"], hidden) @@ -312,7 +281,6 @@ def _rollout_one_episode_headless( max_steps: int, action_low: np.ndarray | None, action_high: np.ndarray | None, - padding_masks: dict[str, Any] | None, ) -> tuple[float, int, bool, float | None]: """Run one rollout up to max_steps. @@ -332,8 +300,6 @@ def _rollout_one_episode_headless( steps = 0 for _ in range(int(max_steps)): obs_dict = observations or {} - if padding_masks is not None: - obs_dict = pad_observation(obs_dict, padding_masks) action = policy.act(observations=obs_dict) action = _maybe_clip_action(action, action_low, action_high) @@ -369,7 +335,6 @@ def _run_one_episode_viewer( max_steps: int | None, action_low: np.ndarray | None, action_high: np.ndarray | None, - padding_masks: dict[str, Any] | None, ) -> None: import mujoco.viewer @@ -392,8 +357,6 @@ def _run_one_episode_viewer( step_start = time.time() obs_dict = observations or {} - if padding_masks is not None: - obs_dict = pad_observation(obs_dict, padding_masks) action = policy.act(observations=obs_dict) action = _maybe_clip_action(action, action_low, action_high) @@ -596,23 +559,29 @@ def main(dict_cfg: DictConfig) -> None: # Match training's padded observation layout for amputated morphologies. padding_masks = compute_padding_masks(config.morphology.segments_per_arm) - # Match training's action clipping behavior. - action_space = getattr(raw_env, "action_space", None) - action_low = ( - None if action_space is None else np.asarray(action_space.low, dtype=np.float32).ravel() - ) - action_high = ( - None if action_space is None else np.asarray(action_space.high, dtype=np.float32).ravel() + training_bounds = ObservationBoundsConfig().to_bounds_dict() + if trained_cfg_path and "obs_bounds" in trained_cfg: + try: + training_bounds = OmegaConf.to_object(trained_cfg.obs_bounds).to_bounds_dict() + except Exception: + pass + else: + training_bounds = config.obs_bounds.to_bounds_dict() + + obs_processor = create_obs_processor( + bounds_dict=training_bounds, + padding_masks=padding_masks, ) # ======= MODEL SETUP ======= nu = int(state0.mj_model.nu) - policy = CleanRLPPOPolicy.load(model_path, action_dim=nu) + policy = CleanRLPPOPolicy.load(model_path, action_dim=nu, obs_processor=obs_processor) # Helpful early failure when configs don't match the checkpoint. observations0 = _get_observations(state0) - obs0_dict = pad_observation(observations0 or {}, padding_masks) - env_obs_dim = int(_transform_obs_dict(obs0_dict).shape[0]) + obs0_dict = observations0 or {} + batched_obs0 = jax.tree.map(lambda x: jnp.asarray(x)[None, ...], obs0_dict) + env_obs_dim = int(obs_processor(batched_obs0).shape[1]) ckpt_obs_dim = _infer_checkpoint_obs_dim(policy) if ckpt_obs_dim is not None and ckpt_obs_dim != env_obs_dim: @@ -623,6 +592,15 @@ def main(dict_cfg: DictConfig) -> None: "that was used during training." ) + # Match training's action clipping behavior. + action_space = getattr(raw_env, "action_space", None) + action_low = ( + None if action_space is None else np.asarray(action_space.low, dtype=np.float32).ravel() + ) + action_high = ( + None if action_space is None else np.asarray(action_space.high, dtype=np.float32).ravel() + ) + # ======= SIMULATION ======= headless = bool(config.simulation.headless) max_steps = config.simulation.max_steps @@ -641,7 +619,6 @@ def main(dict_cfg: DictConfig) -> None: max_steps=max_steps_i, action_low=action_low, action_high=action_high, - padding_masks=padding_masks, ) final_dist_str = "n/a" if final_dist is None else f"{final_dist:.3f}" print( @@ -670,7 +647,6 @@ def main(dict_cfg: DictConfig) -> None: max_steps=max_steps_val, action_low=action_low, action_high=action_high, - padding_masks=padding_masks, ) env.close() From 8f2a5d25edd7ef36faddd4496f6b8ed76deb4a6f Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 13:17:24 +0200 Subject: [PATCH 10/96] feat(simulate): metadata config loading --- configs/simulation/default.yaml | 8 +- scripts/simulate.py | 557 ++++++------------ .../configs/config_simulation.py | 10 +- .../environment/__init__.py | 7 +- .../environment/padded_obs_wrapper.py | 84 +-- 5 files changed, 190 insertions(+), 476 deletions(-) diff --git a/configs/simulation/default.yaml b/configs/simulation/default.yaml index 84694e0..390cd46 100644 --- a/configs/simulation/default.yaml +++ b/configs/simulation/default.yaml @@ -9,7 +9,7 @@ headless: false # In headless mode this is required; in viewer mode null means "infinite". max_steps: null -# Optional: path to the Hydra config.yaml used during training. -# When set, scripts/simulate.py will use it to default morphology/arena/environment/architecture -# to match training (unless you explicitly override those keys via CLI). -trained_config_path: null +# Optional: override morphology for amputation experiments. +# Points to a morphology config YAML file (e.g. configs/morphology/3_arms.yaml). +# If null, the training morphology from the model's metadata is used. +morphology_override: null diff --git a/scripts/simulate.py b/scripts/simulate.py index 0e6d01b..bee6214 100644 --- a/scripts/simulate.py +++ b/scripts/simulate.py @@ -1,11 +1,10 @@ """Simulate a trained policy in the MuJoCo viewer. -Uses Hydra to load the same BrittleStarConfig that was used during training. -Override settings via CLI, e.g.: - python scripts/simulate.py morphology=3_arms - -To replay a run using the *exact* Hydra config used during training, pass: - python scripts/simulate.py simulation.trained_config_path=runs/.../.hydra/config.yaml \ +Automatically extracts the training configuration (morphology, environment, etc.) +from the sidecar metadata YAML file to ensure simulation perfectly matches training. +Override simulation settings via CLI, e.g.: + uv run scripts/simulate.py \ + simulation.morphology_override=config/morphology/3_arms.yaml \ simulation.model_path=runs/.../final_model.flax """ @@ -22,85 +21,24 @@ import jax import jax.numpy as jnp import numpy as np import yaml -from omegaconf import DictConfig, OmegaConf, open_dict +from omegaconf import DictConfig, OmegaConf from brittle_star_project import Backend, BrittleStarEnv, BrittleStarEnvFactory from brittle_star_project.configs.main_config import BrittleStarConfig from brittle_star_project.configs.register_configs import register_configs from brittle_star_project.environment.padded_obs_wrapper import compute_padding_masks from brittle_star_project.environment.obs_processing import create_obs_processor -from brittle_star_project.environment.env_config import ObservationBoundsConfig +from brittle_star_project.environment.env_config import ( + MorphologyConfig, + ArenaConfig, + EnvConfig, + ObservationBoundsConfig, +) -def _dense_layer_sizes_from_params(params: Any) -> list[int]: - """Infer GenericDenseLayersWithActivation.layer_sizes from a Flax params tree.""" +class PolicyAgent: + """Wraps a trained Flax actor for deterministic inference.""" - try: - dense_params = params["params"] - except Exception as exc: - raise ValueError("Unexpected sensor params structure (missing 'params')") from exc - - layer_sizes: list[int] = [] - idx = 0 - while True: - key = f"Dense_{idx}" - if key not in dense_params: - break - kernel = dense_params[key]["kernel"] - layer_sizes.append(int(np.asarray(kernel).shape[1])) - idx += 1 - - if not layer_sizes: - raise ValueError("Could not infer Dense_* layers from sensor params") - return layer_sizes - - -def _infer_action_dim_from_actor_params(params: Any) -> int | None: - """Best-effort infer action_dim from a Flax Actor params tree.""" - - try: - dense0 = params["params"]["Dense_0"] - bias = dense0.get("bias") - kernel = dense0.get("kernel") - except Exception: - return None - - if bias is not None: - try: - return int(np.asarray(bias).shape[0]) - except Exception: - return None - - if kernel is not None: - try: - return int(np.asarray(kernel).shape[1]) - except Exception: - return None - - return None - - -def _has_cli_override(overrides: list[str], key: str) -> bool: - prefixes = (f"{key}=", f"{key}.", f"+{key}=", f"+{key}.") - return any(str(o).startswith(prefixes) for o in overrides) - - -def _maybe_clip_action( - action: np.ndarray, - low: np.ndarray | None, - high: np.ndarray | None, -) -> np.ndarray: - if low is None or high is None: - return action - low = np.asarray(low, dtype=np.float32).ravel() - high = np.asarray(high, dtype=np.float32).ravel() - if low.shape != action.shape or high.shape != action.shape: - return action - return np.clip(action, low, high) - - -# A minimal policy class to load a CleanRL/Flax checkpoint and run inference. -class CleanRLPPOPolicy: def __init__( self, *, @@ -111,7 +49,28 @@ class CleanRLPPOPolicy: ) -> None: from brittle_star_project.MLPs.mlps import Actor, GenericDenseLayersWithActivation - layer_sizes = _dense_layer_sizes_from_params(sensor_params) + # Infer layer sizes from params + try: + dense_params = ( + sensor_params.get("params", {}) + if isinstance(sensor_params, dict) + else sensor_params["params"] + ) + except Exception: + dense_params = sensor_params + + layer_sizes = [] + idx = 0 + while True: + key = f"Dense_{idx}" + if key not in dense_params: + break + layer_sizes.append(int(np.asarray(dense_params[key]["kernel"]).shape[1])) + idx += 1 + + if not layer_sizes: + raise ValueError("Could not infer Dense_* layers from sensor params") + self._sensor = GenericDenseLayersWithActivation(layer_sizes=layer_sizes) self._actor = Actor(action_dim=action_dim) self._sensor_apply = jax.jit(self._sensor.apply) @@ -128,122 +87,31 @@ class CleanRLPPOPolicy: *, action_dim: int, obs_processor: Any, - ) -> "CleanRLPPOPolicy": - def _get_index(container: Any, idx: int) -> Any: - if isinstance(container, (list, tuple)): - return container[idx] - if isinstance(container, dict): - return container.get(idx, container.get(str(idx))) - raise KeyError(idx) - - def _looks_like_indexed_dict(container: Any) -> bool: - return ( - isinstance(container, dict) - and container - and all(str(k).isdigit() for k in container.keys()) - ) - - def _parse_checkpoint(restored_obj: Any) -> tuple[Any, Any, Any, Any, Any]: - """Extract checkpoint parts. - - Returns (config_dict, sensor_params, actor_params, critic_params, - feature_extractor_params). - - PPOTrainer saves: - flax.serialization.to_bytes([ - config_dict, - [sensor_params, actor_params, critic_params, feature_extractor_params], - ]) - - msgpack_restore() may restore lists as dicts keyed by string indices - ("0", "1", ...), so we accept both shapes. - """ - - cfg_part: Any | None = None - params_part: Any = restored_obj - - if isinstance(restored_obj, (list, tuple)) and len(restored_obj) >= 2: - cfg_part = restored_obj[0] - params_part = restored_obj[1] - elif _looks_like_indexed_dict(restored_obj) and ( - "0" in restored_obj or "1" in restored_obj - ): - cfg_part = restored_obj.get("0", restored_obj.get(0)) - params_part = restored_obj.get("1", restored_obj.get(1)) - - if _looks_like_indexed_dict(params_part): - sensor_params = _get_index(params_part, 0) - actor_params = _get_index(params_part, 1) - critic_params = _get_index(params_part, 2) - feature_extractor_params = _get_index(params_part, 3) - if sensor_params is None or actor_params is None: - raise ValueError("Missing required params in checkpoint") - return ( - cfg_part, - sensor_params, - actor_params, - critic_params, - feature_extractor_params, - ) - - if isinstance(params_part, (list, tuple)) and len(params_part) >= 2: - sensor_params = params_part[0] - actor_params = params_part[1] - critic_params = params_part[2] if len(params_part) >= 3 else None - feature_extractor_params = params_part[3] if len(params_part) >= 4 else None - return ( - cfg_part, - sensor_params, - actor_params, - critic_params, - feature_extractor_params, - ) - - # Accept a plain dict-shaped Flax params mapping commonly produced - # by saving `agent_state.params` directly. Typical keys are - # 'sensor_params' and 'actor_params', or sometimes nested under 'params'. - if isinstance(restored_obj, dict): - # Top-level params dict - params_sub = restored_obj.get("params", {}) - sensor_params = restored_obj.get("sensor_params") or params_sub.get("sensor_params") - actor_params = restored_obj.get("actor_params") or params_sub.get("actor_params") - critic_params = restored_obj.get("critic_params") or params_sub.get("critic_params") - feature_extractor_params = restored_obj.get( - "feature_extractor_params" - ) or params_sub.get("feature_extractor_params") - # Some checkpoints only save actor+sensor as top-level - if sensor_params is not None and actor_params is not None: - return ( - cfg_part, - sensor_params, - actor_params, - critic_params, - feature_extractor_params, - ) - - raise ValueError( - f"Unexpected checkpoint structure in {path}. " - "Expected [config_dict, [sensor_params, actor_params, critic_params, " - "feature_extractor_params]] or an equivalent dict-indexed variant." - ) - + ) -> "PolicyAgent": payload = path.read_bytes() restored = flax.serialization.msgpack_restore(payload) - _cfg_dict, sensor_params, actor_params, _critic_params, _feature_extractor_params = ( - _parse_checkpoint(restored) - ) - ckpt_action_dim = _infer_action_dim_from_actor_params(actor_params) - if ckpt_action_dim is not None and ckpt_action_dim != action_dim: - raise ValueError( - "Checkpoint/env mismatch: " - f"checkpoint expects action_dim={ckpt_action_dim}, " - f"env provides action_dim={action_dim}. " - "Use the same Hydra config (morphology/arena/environment) " - "that was used during training." - ) + sensor_params = None + actor_params = None - return CleanRLPPOPolicy( + # Extract params from restored checkpoint + if isinstance(restored, dict): + params_sub = restored.get("params", {}) + sensor_params = restored.get("sensor_params") or params_sub.get("sensor_params") + actor_params = restored.get("actor_params") or params_sub.get("actor_params") + elif isinstance(restored, (list, tuple)) and len(restored) >= 2: + params_part = restored[1] + if isinstance(params_part, dict): + sensor_params = params_part.get("0", params_part.get(0)) + actor_params = params_part.get("1", params_part.get(1)) + elif isinstance(params_part, (list, tuple)) and len(params_part) >= 2: + sensor_params = params_part[0] + actor_params = params_part[1] + + if sensor_params is None or actor_params is None: + raise ValueError(f"Could not extract sensor and actor params from checkpoint: {path}") + + return PolicyAgent( sensor_params=sensor_params, actor_params=actor_params, action_dim=action_dim, @@ -273,23 +141,30 @@ def _target_reached(*, state: Any) -> bool: return bool(getattr(state, "terminated", False) or getattr(state, "truncated", False)) -def _rollout_one_episode_headless( +def _maybe_clip_action( + action: np.ndarray, + low: np.ndarray | None, + high: np.ndarray | None, +) -> np.ndarray: + if low is None or high is None: + return action + low = np.asarray(low, dtype=np.float32).ravel() + high = np.asarray(high, dtype=np.float32).ravel() + if low.shape != action.shape or high.shape != action.shape: + return action + return np.clip(action, low, high) + + +def _rollout_headless( *, env: BrittleStarEnv, - policy: CleanRLPPOPolicy, + policy: PolicyAgent, seed: int, max_steps: int, action_low: np.ndarray | None, action_high: np.ndarray | None, + action_mask: np.ndarray | None = None, ) -> tuple[float, int, bool, float | None]: - """Run one rollout up to max_steps. - - Returns (return, length, reached_target, final_xy_dist). - - Note: In the MJC backend, the raw env reward can be 0.0; we compute a simple - progress reward based on xy_distance_to_target. - """ - state = env.reset(seed=seed) ep_return = 0.0 @@ -302,12 +177,10 @@ def _rollout_one_episode_headless( obs_dict = observations or {} action = policy.act(observations=obs_dict) + if action_mask is not None: + action = action[action_mask] action = _maybe_clip_action(action, action_low, action_high) - nu = int(state.mj_model.nu) - if nu > 0 and action.shape != (nu,): - raise ValueError(f"Policy returned action shape {action.shape}, expected ({nu},)") - state = env.step(state=state, action=action) steps += 1 @@ -325,23 +198,23 @@ def _rollout_one_episode_headless( return ep_return, steps, reached_target, final_dist -def _run_one_episode_viewer( +def _rollout_viewer( *, env: BrittleStarEnv, - policy: CleanRLPPOPolicy, + policy: PolicyAgent, seed: int, state: Any, control_dt: float, max_steps: int | None, action_low: np.ndarray | None, action_high: np.ndarray | None, + action_mask: np.ndarray | None = None, ) -> None: import mujoco.viewer model = state.mj_model data = state.mj_data - _ = int(seed) episode_return = 0.0 observations = _get_observations(state) prev_dist = _get_xy_distance_to_target(observations) @@ -359,11 +232,9 @@ def _run_one_episode_viewer( obs_dict = observations or {} action = policy.act(observations=obs_dict) + if action_mask is not None: + action = action[action_mask] action = _maybe_clip_action(action, action_low, action_high) - if model.nu > 0 and action.shape != (int(model.nu),): - raise ValueError( - f"Policy returned action shape {action.shape}, expected ({int(model.nu)},)" - ) # The passive viewer runs a GUI thread; protect MuJoCo state mutation. with viewer.lock(): @@ -398,199 +269,117 @@ def _run_one_episode_viewer( ) -def _infer_checkpoint_obs_dim(policy: CleanRLPPOPolicy) -> int | None: - """Best-effort read of the first Dense kernel input dim (obs dim).""" - - try: - kernel = policy._params["sensor_params"]["params"]["Dense_0"]["kernel"] - return int(getattr(kernel, "shape")[0]) - except Exception: - return None - - -def _load_trained_config(path: Path) -> DictConfig: - """Load a trained config YAML. - - Supports both: - - Hydra's run config (e.g. runs/.../.hydra/config.yaml) - - This project's logger metadata YAMLs, which may contain - ``!!python/object/apply:...`` tags for Enums. - - For safety, we *do not* execute Python constructors from YAML; we only - treat these tags as data and extract their scalar arguments. - """ - - if not path.exists(): - raise FileNotFoundError(f"trained_config_path does not exist: '{path}'.") - if not path.is_file(): - raise ValueError(f"trained_config_path must be a file, got: '{path}'.") - - try: - return OmegaConf.load(path) - except Exception as exc: - python_apply_prefix = "tag:yaml.org,2002:python/object/apply:" - - class _SafeLoaderWithPythonApply(yaml.SafeLoader): - pass - - def _construct_python_apply( - loader: yaml.SafeLoader, - _tag_suffix: str, - node: yaml.Node, - ) -> Any: - if isinstance(node, yaml.SequenceNode): - seq = loader.construct_sequence(node) - if len(seq) == 1: - return seq[0] - return seq - if isinstance(node, yaml.MappingNode): - return loader.construct_mapping(node) - return loader.construct_scalar(node) - - _SafeLoaderWithPythonApply.add_multi_constructor( - python_apply_prefix, _construct_python_apply +def _load_metadata_yaml(model_path: Path) -> dict: + """Discover and load the sidecar metadata YAML file.""" + metadata_path = model_path.with_name(model_path.stem + "_metadata.yaml") + if not metadata_path.exists(): + raise FileNotFoundError( + f"Could not find metadata YAML for {model_path.name}. Expected it at {metadata_path}" ) - - try: - data = yaml.load(path.read_text(encoding="utf-8"), Loader=_SafeLoaderWithPythonApply) - except Exception as yaml_exc: - raise ValueError( - "Failed to load trained_config_path as YAML. " - "If this is a Hydra run, pass the run's '.hydra/config.yaml' file. " - f"Got: '{path}'." - ) from yaml_exc - - if not isinstance(data, dict): - raise ValueError( - "trained_config_path must contain a YAML mapping (dict-like) at the root. " - f"Got type={type(data).__name__} from '{path}'." - ) from exc - - # Normalize known enum-like strings to their Enum *names* so OmegaConf's - # structured config merge behaves like the normal Hydra config. - from brittle_star_project.environment.env_types import Task - - env_cfg = data.get("environment") - if isinstance(env_cfg, dict) and isinstance(env_cfg.get("task"), str): - task_str = str(env_cfg["task"]) - try: - env_cfg["task"] = Task[task_str].name - except Exception: - try: - env_cfg["task"] = Task(task_str).name - except Exception: - pass - - return OmegaConf.create(data) + with open(metadata_path, "r") as f: + return yaml.safe_load(f) @hydra.main(config_path="../configs", config_name="main_config", version_base="1.3") def main(dict_cfg: DictConfig) -> None: - # Compose against the structured schema first, so missing keys are validated. - cfg = OmegaConf.merge(OmegaConf.structured(BrittleStarConfig), dict_cfg) + # 1. Hydra composes ONLY SimulationSettings + cfg = OmegaConf.to_object(OmegaConf.merge(OmegaConf.structured(BrittleStarConfig), dict_cfg)) + sim_cfg = cfg.simulation - # Optional: override env-defining sections (morphology/arena/environment/architecture) - # using the exact Hydra config that was used for training. - trained_cfg_path = cfg.simulation.trained_config_path - if trained_cfg_path: - overrides_raw = OmegaConf.select(cfg, "hydra.overrides.task") or [] - overrides = [str(o) for o in overrides_raw] - - trained_cfg_path_abs = Path(hydra.utils.to_absolute_path(trained_cfg_path)) - trained_cfg = _load_trained_config(trained_cfg_path_abs) - if "hydra" in trained_cfg: - with open_dict(trained_cfg): - del trained_cfg["hydra"] - - with open_dict(cfg): - for key in ("morphology", "arena", "environment", "architecture"): - if key in trained_cfg and not _has_cli_override(overrides, key): - base_node = OmegaConf.select(cfg, key) - override_node = OmegaConf.select(trained_cfg, key) - try: - cfg[key] = OmegaConf.merge(base_node, override_node) - except Exception as exc: - raise ValueError( - "Failed to merge trained config into the active Hydra config. " - f"Key={key!r}, trained_config_path='{trained_cfg_path_abs}'." - ) from exc - - # Convert DictConfig to structured dataclass. - config: BrittleStarConfig = OmegaConf.to_object(cfg) - - backend = Backend.MJC - seed = int(config.experiment.seed) - - if getattr(config.architecture, "name", None) != "centralized": - raise ValueError( - "simulate.py currently only supports architecture=centralized. " - f"Got architecture.name={getattr(config.architecture, 'name', None)!r}. " - "(Training supports decentralized, but simulation wiring for it isn't implemented.)" - ) - - model_path_str = config.simulation.model_path + model_path_str = sim_cfg.model_path if model_path_str is None: raise ValueError( "simulation.model_path must be set to a .flax checkpoint (e.g. final_model.flax)" ) - # Hydra chdir changes CWD; resolve relative paths relative to the invocation. model_path = Path(hydra.utils.to_absolute_path(model_path_str)) if model_path.suffix != ".flax": raise ValueError(f"Expected a '.flax' checkpoint, got '{model_path.name}'.") - # ======= ENVIRONMENT SETUP ======= + # 2. Discover + load sidecar metadata YAML + metadata = _load_metadata_yaml(model_path) + + # 3. Reconstruct typed configs from metadata + trained_morphology = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(MorphologyConfig), metadata.get("morphology", {})) + ) + trained_arena = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(ArenaConfig), metadata.get("arena", {})) + ) + + env_dict = metadata.get("environment", {}) + if isinstance(env_dict.get("task"), str): + from brittle_star_project.environment.env_types import Task + + try: + env_dict["task"] = Task[env_dict["task"]].name + except Exception: + try: + env_dict["task"] = Task(env_dict["task"]).name + except Exception: + pass + + trained_environment = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(EnvConfig), env_dict) + ) + trained_obs_bounds = OmegaConf.to_object( + OmegaConf.merge( + OmegaConf.structured(ObservationBoundsConfig), metadata.get("obs_bounds", {}) + ) + ) + + # 4. Determine environment morphology + if sim_cfg.morphology_override is not None: + override_path = Path(hydra.utils.to_absolute_path(sim_cfg.morphology_override)) + if not override_path.exists(): + raise FileNotFoundError(f"Could not find morphology override YAML at {override_path}") + with open(override_path, "r") as f: + override_dict = yaml.safe_load(f) + env_morphology = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(MorphologyConfig), override_dict) + ) + else: + env_morphology = trained_morphology + + # 5. Build obs_processor with TRAINING morphology padding masks always + padding_masks = compute_padding_masks( + segments_per_arm=env_morphology.segments_per_arm, + ) + obs_processor = create_obs_processor( + bounds_dict=trained_obs_bounds.to_bounds_dict(), + padding_masks=padding_masks, + ) + + # 6. Build environment + backend = Backend.MJC + seed = int(cfg.experiment.seed) + factory = BrittleStarEnvFactory() raw_env = factory.create_environment( backend, - config.morphology, - config.arena, - config.environment, + env_morphology, + trained_arena, + trained_environment, ) env = BrittleStarEnv( raw_env, backend=backend, - config=config.environment, - morphology_config=config.morphology, + config=trained_environment, + morphology_config=env_morphology, ) state0 = env.reset(seed=seed) - # Match training's padded observation layout for amputated morphologies. - padding_masks = compute_padding_masks(config.morphology.segments_per_arm) + # Calculate the action dimension the model was trained with + trained_action_dim = sum(trained_morphology.segments_per_arm) * 2 - training_bounds = ObservationBoundsConfig().to_bounds_dict() - if trained_cfg_path and "obs_bounds" in trained_cfg: - try: - training_bounds = OmegaConf.to_object(trained_cfg.obs_bounds).to_bounds_dict() - except Exception: - pass - else: - training_bounds = config.obs_bounds.to_bounds_dict() - - obs_processor = create_obs_processor( - bounds_dict=training_bounds, - padding_masks=padding_masks, + # 7. Load policy + policy = PolicyAgent.load( + model_path, action_dim=trained_action_dim, obs_processor=obs_processor ) - # ======= MODEL SETUP ======= - nu = int(state0.mj_model.nu) - policy = CleanRLPPOPolicy.load(model_path, action_dim=nu, obs_processor=obs_processor) - - # Helpful early failure when configs don't match the checkpoint. - observations0 = _get_observations(state0) - obs0_dict = observations0 or {} - batched_obs0 = jax.tree.map(lambda x: jnp.asarray(x)[None, ...], obs0_dict) - env_obs_dim = int(obs_processor(batched_obs0).shape[1]) - ckpt_obs_dim = _infer_checkpoint_obs_dim(policy) - - if ckpt_obs_dim is not None and ckpt_obs_dim != env_obs_dim: - raise ValueError( - "Checkpoint/env mismatch: " - f"checkpoint expects obs_dim={ckpt_obs_dim}, env provides obs_dim={env_obs_dim}. " - "Use the same Hydra config (morphology/arena/environment) " - "that was used during training." - ) + # Convert the JAX boolean mask to a numpy array for easy indexing + action_mask = np.asarray(padding_masks["mask_2x"]) # Match training's action clipping behavior. action_space = getattr(raw_env, "action_space", None) @@ -601,24 +390,26 @@ def main(dict_cfg: DictConfig) -> None: None if action_space is None else np.asarray(action_space.high, dtype=np.float32).ravel() ) - # ======= SIMULATION ======= - headless = bool(config.simulation.headless) - max_steps = config.simulation.max_steps + # 8. Run simulation + headless = bool(sim_cfg.headless) + max_steps = sim_cfg.max_steps if headless: if max_steps is None: raise ValueError("simulation.max_steps is required when simulation.headless=true") + max_steps_i = int(max_steps) if max_steps_i <= 0: raise ValueError("simulation.max_steps must be > 0") - ep_return, ep_len, reached_target, final_dist = _rollout_one_episode_headless( + ep_return, ep_len, reached_target, final_dist = _rollout_headless( env=env, policy=policy, seed=seed, max_steps=max_steps_i, action_low=action_low, action_high=action_high, + action_mask=action_mask, ) final_dist_str = "n/a" if final_dist is None else f"{final_dist:.3f}" print( @@ -627,18 +418,17 @@ def main(dict_cfg: DictConfig) -> None: f"target_reached={reached_target}, final_xy_dist={final_dist_str}" ) else: + max_steps_val = None if max_steps is not None: max_steps_i = int(max_steps) if max_steps_i <= 0: raise ValueError("simulation.max_steps must be > 0") - max_steps_val: int | None = max_steps_i - else: - max_steps_val = None + max_steps_val = max_steps_i model_dt = float(state0.mj_model.opt.timestep) - control_dt = model_dt * float(config.environment.num_physics_steps_per_control_step) + control_dt = model_dt * float(trained_environment.num_physics_steps_per_control_step) - _run_one_episode_viewer( + _rollout_viewer( env=env, policy=policy, seed=seed, @@ -647,6 +437,7 @@ def main(dict_cfg: DictConfig) -> None: max_steps=max_steps_val, action_low=action_low, action_high=action_high, + action_mask=action_mask, ) env.close() diff --git a/src/brittle_star_project/configs/config_simulation.py b/src/brittle_star_project/configs/config_simulation.py index 872ca20..a10682d 100644 --- a/src/brittle_star_project/configs/config_simulation.py +++ b/src/brittle_star_project/configs/config_simulation.py @@ -13,7 +13,9 @@ class SimulationSettings: # If None, viewer mode runs until window closed or target reached. max_steps: Optional[int] = None - # Optional: point to a Hydra config.yaml from a training run (e.g. runs/.../.hydra/config.yaml). - # When set, the simulation script can override - # morphology/arena/environment/architecture to match. - trained_config_path: Optional[str] = None + # Override morphology for amputation experiments. + # When set, the environment uses this morphology instead of the trained one. + # Points to a morphology config YAML file (e.g. configs/morphology/3_arms.yaml). + # Observations are padded from the override morphology UP TO the training + # morphology's shape via compute_padding_masks(override, reference=training). + morphology_override: Optional[str] = None diff --git a/src/brittle_star_project/environment/__init__.py b/src/brittle_star_project/environment/__init__.py index 78896cb..77d106c 100644 --- a/src/brittle_star_project/environment/__init__.py +++ b/src/brittle_star_project/environment/__init__.py @@ -1,7 +1,9 @@ from .env_config import ArenaConfig, EnvConfig, MorphologyConfig from .env_types import Backend, Task -from .env_wrapper import BrittleStarEnv, StepResult +from .env_wrapper import BrittleStarEnv from .factory import BrittleStarEnvFactory +from .obs_processing import create_obs_processor +from .padded_obs_wrapper import compute_padding_masks __all__ = [ "ArenaConfig", @@ -10,6 +12,7 @@ __all__ = [ "Backend", "Task", "BrittleStarEnv", - "StepResult", "BrittleStarEnvFactory", + "create_obs_processor", + "compute_padding_masks", ] diff --git a/src/brittle_star_project/environment/padded_obs_wrapper.py b/src/brittle_star_project/environment/padded_obs_wrapper.py index ae64de4..ea00713 100644 --- a/src/brittle_star_project/environment/padded_obs_wrapper.py +++ b/src/brittle_star_project/environment/padded_obs_wrapper.py @@ -1,35 +1,11 @@ -"""Observation padding wrapper for amputated brittle star morphologies. - -When using a centralized controller, the global observation vector must remain -a constant size regardless of how many segments are amputated. This wrapper pads -the observation dictionary values with zeros using spatial insertion so that the -flattened observation maintains the correct physical mapping to the neural network. -""" +"""Observation padding masks for amputated brittle star morphologies.""" from __future__ import annotations from typing import Any, Sequence -import jax import jax.numpy as jnp -# Observation keys whose size scales with the number of joints (2 per segment). -_JOINT_SCALED_KEYS = frozenset( - { - "joint_position", - "joint_velocity", - "joint_actuator_force", - "actuator_force", - } -) - -# Observation keys whose size scales with the number of segments (1 per segment). -_SEGMENT_SCALED_KEYS = frozenset( - { - "segment_contact", - } -) - def compute_padding_masks( segments_per_arm: Sequence[int], @@ -60,7 +36,6 @@ def compute_padding_masks( f"actual segments ({actual}) must be between 0 and reference ({ref})." ) # 1x scaling (e.g., contacts: 1 value per segment) - # 1x scaling (e.g., contacts: 1 value per segment) mask_1x.extend([True] * actual + [False] * (ref - actual)) # 2x scaling (e.g., joints: 2 values per segment) mask_2x.extend([True] * (actual * 2) + [False] * ((ref - actual) * 2)) @@ -71,60 +46,3 @@ def compute_padding_masks( "target_size_1x": sum(reference_segments_per_arm), "target_size_2x": sum(reference_segments_per_arm) * 2, } - - -def pad_observation( - obs: dict[str, Any], - masks: dict[str, Any], -) -> dict[str, Any]: - """Pad an observation dict using spatial insertion.""" - padded = {} - for key, value in obs.items(): - padded_dtype = _padding_dtype(value) - if key in _JOINT_SCALED_KEYS: - out = jnp.zeros(masks["target_size_2x"], dtype=padded_dtype) - padded[key] = out.at[masks["mask_2x"]].set(value) - elif key in _SEGMENT_SCALED_KEYS: - out = jnp.zeros(masks["target_size_1x"], dtype=padded_dtype) - padded[key] = out.at[masks["mask_1x"]].set(value) - else: - padded[key] = value - return padded - - -def pad_observations_batched( - obs: dict[str, Any], - masks: dict[str, Any], -) -> dict[str, Any]: - """Pad a batched observation dict (leading batch dimension) using spatial insertion.""" - padded = {} - for key, value in obs.items(): - batch_size = value.shape[0] - padded_dtype = _padding_dtype(value) - if key in _JOINT_SCALED_KEYS: - out = jnp.zeros((batch_size, masks["target_size_2x"]), dtype=padded_dtype) - padded[key] = out.at[:, masks["mask_2x"]].set(value) - elif key in _SEGMENT_SCALED_KEYS: - out = jnp.zeros((batch_size, masks["target_size_1x"]), dtype=padded_dtype) - padded[key] = out.at[:, masks["mask_1x"]].set(value) - else: - padded[key] = value - return padded - - -def _padding_dtype(value: Any) -> jnp.dtype: - """Choose a JAX-safe dtype for padding arrays. - - When JAX x64 is disabled, allocating float64 zeros emits a warning. We - preserve the original dtype whenever it is supported, and otherwise fall - back to float32 for padding buffers. - """ - - dtype = getattr(value, "dtype", None) - if dtype is None: - dtype = jnp.asarray(value).dtype - else: - dtype = jnp.dtype(dtype) - if dtype == jnp.float64 and not jax.config.read("jax_enable_x64"): - return jnp.float32 - return dtype From 9d1e2c9bfff74c291a4f5fd5b50d567c8f4ada6e Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 13:39:01 +0200 Subject: [PATCH 11/96] refactor: evaluation subpackage --- scripts/simulate.py | 320 ++---------------- src/brittle_star_project/__init__.py | 16 +- .../evaluation/__init__.py | 17 + .../evaluation/checkpoint.py | 105 ++++++ src/brittle_star_project/evaluation/policy.py | 89 +++++ .../evaluation/rollout.py | 163 +++++++++ src/brittle_star_project/render/__init__.py | 3 - src/brittle_star_project/render/renderer.py | 78 ----- 8 files changed, 409 insertions(+), 382 deletions(-) create mode 100644 src/brittle_star_project/evaluation/__init__.py create mode 100644 src/brittle_star_project/evaluation/checkpoint.py create mode 100644 src/brittle_star_project/evaluation/policy.py create mode 100644 src/brittle_star_project/evaluation/rollout.py delete mode 100644 src/brittle_star_project/render/__init__.py delete mode 100644 src/brittle_star_project/render/renderer.py diff --git a/scripts/simulate.py b/scripts/simulate.py index bee6214..7bb2800 100644 --- a/scripts/simulate.py +++ b/scripts/simulate.py @@ -4,280 +4,29 @@ Automatically extracts the training configuration (morphology, environment, etc. from the sidecar metadata YAML file to ensure simulation perfectly matches training. Override simulation settings via CLI, e.g.: uv run scripts/simulate.py \ - simulation.morphology_override=config/morphology/3_arms.yaml \ + simulation.morphology_override=configs/morphology/3_arms.yaml \ simulation.model_path=runs/.../final_model.flax """ from __future__ import annotations -import itertools -import time from pathlib import Path -from typing import Any -import flax import hydra -import jax -import jax.numpy as jnp import numpy as np -import yaml from omegaconf import DictConfig, OmegaConf +import yaml from brittle_star_project import Backend, BrittleStarEnv, BrittleStarEnvFactory from brittle_star_project.configs.main_config import BrittleStarConfig from brittle_star_project.configs.register_configs import register_configs from brittle_star_project.environment.padded_obs_wrapper import compute_padding_masks from brittle_star_project.environment.obs_processing import create_obs_processor -from brittle_star_project.environment.env_config import ( - MorphologyConfig, - ArenaConfig, - EnvConfig, - ObservationBoundsConfig, -) +from brittle_star_project.environment.env_config import MorphologyConfig - -class PolicyAgent: - """Wraps a trained Flax actor for deterministic inference.""" - - def __init__( - self, - *, - sensor_params: Any, - actor_params: Any, - action_dim: int, - obs_processor: Any, - ) -> None: - from brittle_star_project.MLPs.mlps import Actor, GenericDenseLayersWithActivation - - # Infer layer sizes from params - try: - dense_params = ( - sensor_params.get("params", {}) - if isinstance(sensor_params, dict) - else sensor_params["params"] - ) - except Exception: - dense_params = sensor_params - - layer_sizes = [] - idx = 0 - while True: - key = f"Dense_{idx}" - if key not in dense_params: - break - layer_sizes.append(int(np.asarray(dense_params[key]["kernel"]).shape[1])) - idx += 1 - - if not layer_sizes: - raise ValueError("Could not infer Dense_* layers from sensor params") - - self._sensor = GenericDenseLayersWithActivation(layer_sizes=layer_sizes) - self._actor = Actor(action_dim=action_dim) - self._sensor_apply = jax.jit(self._sensor.apply) - self._actor_apply = jax.jit(self._actor.apply) - self._params = { - "sensor_params": sensor_params, - "actor_params": actor_params, - } - self._obs_processor = obs_processor - - @staticmethod - def load( - path: Path, - *, - action_dim: int, - obs_processor: Any, - ) -> "PolicyAgent": - payload = path.read_bytes() - restored = flax.serialization.msgpack_restore(payload) - - sensor_params = None - actor_params = None - - # Extract params from restored checkpoint - if isinstance(restored, dict): - params_sub = restored.get("params", {}) - sensor_params = restored.get("sensor_params") or params_sub.get("sensor_params") - actor_params = restored.get("actor_params") or params_sub.get("actor_params") - elif isinstance(restored, (list, tuple)) and len(restored) >= 2: - params_part = restored[1] - if isinstance(params_part, dict): - sensor_params = params_part.get("0", params_part.get(0)) - actor_params = params_part.get("1", params_part.get(1)) - elif isinstance(params_part, (list, tuple)) and len(params_part) >= 2: - sensor_params = params_part[0] - actor_params = params_part[1] - - if sensor_params is None or actor_params is None: - raise ValueError(f"Could not extract sensor and actor params from checkpoint: {path}") - - return PolicyAgent( - sensor_params=sensor_params, - actor_params=actor_params, - action_dim=action_dim, - obs_processor=obs_processor, - ) - - def act(self, *, observations: dict[str, Any]) -> np.ndarray: - batched_obs = jax.tree.map(lambda x: jnp.asarray(x)[None, ...], observations) - obs = self._obs_processor(batched_obs)[0] - hidden = self._sensor_apply(self._params["sensor_params"], obs) - mean, _log_std = self._actor_apply(self._params["actor_params"], hidden) - - # Always evaluate with the actor mean. - # (Sampling adds exploration noise, which is useful for training but not for evaluation.) - return np.asarray(mean, dtype=np.float32).ravel() - - -def _get_observations(state: Any) -> dict[str, Any] | None: - return getattr(state, "observations", None) - - -def _get_xy_distance_to_target(observations: dict[str, Any]) -> float | None: - return float(np.asarray(observations["xy_distance_to_target"]).reshape(-1)[0]) - - -def _target_reached(*, state: Any) -> bool: - return bool(getattr(state, "terminated", False) or getattr(state, "truncated", False)) - - -def _maybe_clip_action( - action: np.ndarray, - low: np.ndarray | None, - high: np.ndarray | None, -) -> np.ndarray: - if low is None or high is None: - return action - low = np.asarray(low, dtype=np.float32).ravel() - high = np.asarray(high, dtype=np.float32).ravel() - if low.shape != action.shape or high.shape != action.shape: - return action - return np.clip(action, low, high) - - -def _rollout_headless( - *, - env: BrittleStarEnv, - policy: PolicyAgent, - seed: int, - max_steps: int, - action_low: np.ndarray | None, - action_high: np.ndarray | None, - action_mask: np.ndarray | None = None, -) -> tuple[float, int, bool, float | None]: - state = env.reset(seed=seed) - - ep_return = 0.0 - observations = _get_observations(state) - prev_dist = _get_xy_distance_to_target(observations) - reached_target = _target_reached(state=state) - - steps = 0 - for _ in range(int(max_steps)): - obs_dict = observations or {} - - action = policy.act(observations=obs_dict) - if action_mask is not None: - action = action[action_mask] - action = _maybe_clip_action(action, action_low, action_high) - - state = env.step(state=state, action=action) - steps += 1 - - observations = _get_observations(state) - cur_dist = _get_xy_distance_to_target(observations) - if prev_dist is not None and cur_dist is not None: - ep_return += prev_dist - cur_dist - prev_dist = cur_dist - - reached_target = _target_reached(state=state) - if reached_target: - break - - final_dist = _get_xy_distance_to_target(observations) - return ep_return, steps, reached_target, final_dist - - -def _rollout_viewer( - *, - env: BrittleStarEnv, - policy: PolicyAgent, - seed: int, - state: Any, - control_dt: float, - max_steps: int | None, - action_low: np.ndarray | None, - action_high: np.ndarray | None, - action_mask: np.ndarray | None = None, -) -> None: - import mujoco.viewer - - model = state.mj_model - data = state.mj_data - - episode_return = 0.0 - observations = _get_observations(state) - prev_dist = _get_xy_distance_to_target(observations) - reached_target = _target_reached(state=state) - - steps = 0 - # Use the viewer as a context manager to avoid GLX teardown races. - with mujoco.viewer.launch_passive(model, data) as viewer: - step_iter = range(int(max_steps)) if max_steps is not None else itertools.count() - for _step_idx in step_iter: - if not viewer.is_running(): - break - step_start = time.time() - - obs_dict = observations or {} - - action = policy.act(observations=obs_dict) - if action_mask is not None: - action = action[action_mask] - action = _maybe_clip_action(action, action_low, action_high) - - # The passive viewer runs a GUI thread; protect MuJoCo state mutation. - with viewer.lock(): - state = env.step(state=state, action=action) - - if not viewer.is_running(): - break - viewer.sync() - - steps += 1 - - observations = _get_observations(state) - cur_dist = _get_xy_distance_to_target(observations) - if prev_dist is not None and cur_dist is not None: - episode_return += prev_dist - cur_dist - prev_dist = cur_dist - - reached_target = _target_reached(state=state) - if reached_target: - break - - remaining = control_dt - (time.time() - step_start) - if remaining > 0: - time.sleep(remaining) - - dist = _get_xy_distance_to_target(observations) - dist_str = "n/a" if dist is None else f"{dist:.3f}" - print( - "episode done: " - f"return={episode_return:.6f}, len={steps}, " - f"target_reached={reached_target}, final_xy_dist={dist_str}" - ) - - -def _load_metadata_yaml(model_path: Path) -> dict: - """Discover and load the sidecar metadata YAML file.""" - metadata_path = model_path.with_name(model_path.stem + "_metadata.yaml") - if not metadata_path.exists(): - raise FileNotFoundError( - f"Could not find metadata YAML for {model_path.name}. Expected it at {metadata_path}" - ) - with open(metadata_path, "r") as f: - return yaml.safe_load(f) +from brittle_star_project.evaluation.checkpoint import load_metadata, metadata_to_configs +from brittle_star_project.evaluation.policy import PolicyAgent +from brittle_star_project.evaluation.rollout import rollout_headless, rollout_viewer @hydra.main(config_path="../configs", config_name="main_config", version_base="1.3") @@ -297,36 +46,10 @@ def main(dict_cfg: DictConfig) -> None: raise ValueError(f"Expected a '.flax' checkpoint, got '{model_path.name}'.") # 2. Discover + load sidecar metadata YAML - metadata = _load_metadata_yaml(model_path) + metadata = load_metadata(model_path) # 3. Reconstruct typed configs from metadata - trained_morphology = OmegaConf.to_object( - OmegaConf.merge(OmegaConf.structured(MorphologyConfig), metadata.get("morphology", {})) - ) - trained_arena = OmegaConf.to_object( - OmegaConf.merge(OmegaConf.structured(ArenaConfig), metadata.get("arena", {})) - ) - - env_dict = metadata.get("environment", {}) - if isinstance(env_dict.get("task"), str): - from brittle_star_project.environment.env_types import Task - - try: - env_dict["task"] = Task[env_dict["task"]].name - except Exception: - try: - env_dict["task"] = Task(env_dict["task"]).name - except Exception: - pass - - trained_environment = OmegaConf.to_object( - OmegaConf.merge(OmegaConf.structured(EnvConfig), env_dict) - ) - trained_obs_bounds = OmegaConf.to_object( - OmegaConf.merge( - OmegaConf.structured(ObservationBoundsConfig), metadata.get("obs_bounds", {}) - ) - ) + training = metadata_to_configs(metadata) # 4. Determine environment morphology if sim_cfg.morphology_override is not None: @@ -339,14 +62,15 @@ def main(dict_cfg: DictConfig) -> None: OmegaConf.merge(OmegaConf.structured(MorphologyConfig), override_dict) ) else: - env_morphology = trained_morphology + env_morphology = training.morphology # 5. Build obs_processor with TRAINING morphology padding masks always padding_masks = compute_padding_masks( segments_per_arm=env_morphology.segments_per_arm, + reference_segments_per_arm=training.morphology.segments_per_arm, ) obs_processor = create_obs_processor( - bounds_dict=trained_obs_bounds.to_bounds_dict(), + bounds_dict=training.obs_bounds.to_bounds_dict(), padding_masks=padding_masks, ) @@ -358,23 +82,23 @@ def main(dict_cfg: DictConfig) -> None: raw_env = factory.create_environment( backend, env_morphology, - trained_arena, - trained_environment, + training.arena, + training.environment, ) env = BrittleStarEnv( raw_env, backend=backend, - config=trained_environment, + config=training.environment, morphology_config=env_morphology, ) state0 = env.reset(seed=seed) # Calculate the action dimension the model was trained with - trained_action_dim = sum(trained_morphology.segments_per_arm) * 2 + trained_action_dim = sum(training.morphology.segments_per_arm) * 2 # 7. Load policy - policy = PolicyAgent.load( + policy = PolicyAgent.from_checkpoint( model_path, action_dim=trained_action_dim, obs_processor=obs_processor ) @@ -402,7 +126,7 @@ def main(dict_cfg: DictConfig) -> None: if max_steps_i <= 0: raise ValueError("simulation.max_steps must be > 0") - ep_return, ep_len, reached_target, final_dist = _rollout_headless( + result = rollout_headless( env=env, policy=policy, seed=seed, @@ -411,11 +135,11 @@ def main(dict_cfg: DictConfig) -> None: action_high=action_high, action_mask=action_mask, ) - final_dist_str = "n/a" if final_dist is None else f"{final_dist:.3f}" + final_dist_str = "n/a" if result.final_xy_dist is None else f"{result.final_xy_dist:.3f}" print( "episode done: " - f"return={ep_return:.6f}, len={ep_len}, " - f"target_reached={reached_target}, final_xy_dist={final_dist_str}" + f"return={result.return_:.6f}, len={result.length}, " + f"target_reached={result.reached_target}, final_xy_dist={final_dist_str}" ) else: max_steps_val = None @@ -426,9 +150,9 @@ def main(dict_cfg: DictConfig) -> None: max_steps_val = max_steps_i model_dt = float(state0.mj_model.opt.timestep) - control_dt = model_dt * float(trained_environment.num_physics_steps_per_control_step) + control_dt = model_dt * float(training.environment.num_physics_steps_per_control_step) - _rollout_viewer( + rollout_viewer( env=env, policy=policy, seed=seed, diff --git a/src/brittle_star_project/__init__.py b/src/brittle_star_project/__init__.py index 3902cbb..4eec766 100644 --- a/src/brittle_star_project/__init__.py +++ b/src/brittle_star_project/__init__.py @@ -2,7 +2,14 @@ from .environment.env_types import Backend, Task from .environment.env_config import ArenaConfig, EnvConfig, MorphologyConfig from .environment.factory import BrittleStarEnvFactory from .environment.env_wrapper import BrittleStarEnv -from .render import simulate_policy, SimulationConfig, ControlPolicy +from .evaluation import ( + PolicyAgent, + ControlPolicy, + load_metadata, + rollout_headless, + rollout_viewer, + EpisodeResult, +) __all__ = [ "ArenaConfig", @@ -12,7 +19,10 @@ __all__ = [ "EnvConfig", "MorphologyConfig", "Task", - "simulate_policy", - "SimulationConfig", + "PolicyAgent", "ControlPolicy", + "load_metadata", + "rollout_headless", + "rollout_viewer", + "EpisodeResult", ] diff --git a/src/brittle_star_project/evaluation/__init__.py b/src/brittle_star_project/evaluation/__init__.py new file mode 100644 index 0000000..73719e6 --- /dev/null +++ b/src/brittle_star_project/evaluation/__init__.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from .checkpoint import load_metadata, load_params, metadata_to_configs, TrainingConfig +from .policy import PolicyAgent, ControlPolicy +from .rollout import rollout_headless, rollout_viewer, EpisodeResult + +__all__ = [ + "load_metadata", + "load_params", + "metadata_to_configs", + "TrainingConfig", + "PolicyAgent", + "ControlPolicy", + "rollout_headless", + "rollout_viewer", + "EpisodeResult", +] diff --git a/src/brittle_star_project/evaluation/checkpoint.py b/src/brittle_star_project/evaluation/checkpoint.py new file mode 100644 index 0000000..ffbc27a --- /dev/null +++ b/src/brittle_star_project/evaluation/checkpoint.py @@ -0,0 +1,105 @@ +from __future__ import annotations + +import yaml +from dataclasses import dataclass +from pathlib import Path + +import flax +from omegaconf import OmegaConf + +from brittle_star_project.environment.env_config import ( + MorphologyConfig, + ArenaConfig, + EnvConfig, + ObservationBoundsConfig, +) + + +@dataclass +class TrainingConfig: + """Holds typed configurations extracted from a training run's metadata.""" + + morphology: MorphologyConfig + arena: ArenaConfig + environment: EnvConfig + obs_bounds: ObservationBoundsConfig + + +def load_params(path: Path) -> dict: + """Load model parameters from a .flax checkpoint file.""" + payload = path.read_bytes() + restored = flax.serialization.msgpack_restore(payload) + + sensor_params = None + actor_params = None + + # Extract params from restored checkpoint + if isinstance(restored, dict): + params_sub = restored.get("params", {}) + sensor_params = restored.get("sensor_params") or params_sub.get("sensor_params") + actor_params = restored.get("actor_params") or params_sub.get("actor_params") + elif isinstance(restored, (list, tuple)) and len(restored) >= 2: + params_part = restored[1] + if isinstance(params_part, dict): + sensor_params = params_part.get("0", params_part.get(0)) + actor_params = params_part.get("1", params_part.get(1)) + elif isinstance(params_part, (list, tuple)) and len(params_part) >= 2: + sensor_params = params_part[0] + actor_params = params_part[1] + + if sensor_params is None or actor_params is None: + raise ValueError(f"Could not extract sensor and actor params from checkpoint: {path}") + + return { + "sensor_params": sensor_params, + "actor_params": actor_params, + } + + +def load_metadata(model_path: Path) -> dict: + """Discover and load the sidecar metadata YAML file.""" + metadata_path = model_path.with_name(model_path.stem + "_metadata.yaml") + if not metadata_path.exists(): + raise FileNotFoundError( + f"Could not find metadata YAML for {model_path.name}. Expected it at {metadata_path}" + ) + with open(metadata_path, "r") as f: + return yaml.safe_load(f) + + +def metadata_to_configs(metadata: dict) -> TrainingConfig: + """Reconstruct typed configuration objects from a metadata dictionary.""" + trained_morphology = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(MorphologyConfig), metadata.get("morphology", {})) + ) + trained_arena = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(ArenaConfig), metadata.get("arena", {})) + ) + + env_dict = metadata.get("environment", {}) + if isinstance(env_dict.get("task"), str): + from brittle_star_project.environment.env_types import Task + + try: + env_dict["task"] = Task[env_dict["task"]].name + except Exception: + try: + env_dict["task"] = Task(env_dict["task"]).name + except Exception: + pass + + trained_environment = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(EnvConfig), env_dict) + ) + trained_obs_bounds = OmegaConf.to_object( + OmegaConf.merge( + OmegaConf.structured(ObservationBoundsConfig), metadata.get("obs_bounds", {}) + ) + ) + + return TrainingConfig( + morphology=trained_morphology, + arena=trained_arena, + environment=trained_environment, + obs_bounds=trained_obs_bounds, + ) diff --git a/src/brittle_star_project/evaluation/policy.py b/src/brittle_star_project/evaluation/policy.py new file mode 100644 index 0000000..5aa2d6e --- /dev/null +++ b/src/brittle_star_project/evaluation/policy.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +from pathlib import Path +from typing import Any, Protocol + +import jax +import jax.numpy as jnp +import numpy as np + +from brittle_star_project.evaluation.checkpoint import load_params + + +class ControlPolicy(Protocol): + """Protocol for any policy that can produce actions from observations.""" + + def act(self, *, observations: dict[str, Any]) -> np.ndarray: ... + + +class PolicyAgent: + """Wraps a trained Flax actor for deterministic inference.""" + + def __init__( + self, + *, + sensor_params: Any, + actor_params: Any, + action_dim: int, + obs_processor: Any, + ) -> None: + from brittle_star_project.MLPs.mlps import Actor, GenericDenseLayersWithActivation + + # Infer layer sizes from params + try: + dense_params = ( + sensor_params.get("params", {}) + if isinstance(sensor_params, dict) + else sensor_params["params"] + ) + except Exception: + dense_params = sensor_params + + layer_sizes = [] + idx = 0 + while True: + key = f"Dense_{idx}" + if key not in dense_params: + break + layer_sizes.append(int(np.asarray(dense_params[key]["kernel"]).shape[1])) + idx += 1 + + if not layer_sizes: + raise ValueError("Could not infer Dense_* layers from sensor params") + + self._sensor = GenericDenseLayersWithActivation(layer_sizes=layer_sizes) + self._actor = Actor(action_dim=action_dim) + self._sensor_apply = jax.jit(self._sensor.apply) + self._actor_apply = jax.jit(self._actor.apply) + self._params = { + "sensor_params": sensor_params, + "actor_params": actor_params, + } + self._obs_processor = obs_processor + + @classmethod + def from_checkpoint( + cls, + model_path: Path, + *, + action_dim: int, + obs_processor: Any, + ) -> "PolicyAgent": + """Load params from .flax and construct the agent.""" + params = load_params(model_path) + + return cls( + sensor_params=params["sensor_params"], + actor_params=params["actor_params"], + action_dim=action_dim, + obs_processor=obs_processor, + ) + + def act(self, *, observations: dict[str, Any]) -> np.ndarray: + """Return deterministic action (actor mean, no exploration noise).""" + batched_obs = jax.tree.map(lambda x: jnp.asarray(x)[None, ...], observations) + obs = self._obs_processor(batched_obs)[0] + hidden = self._sensor_apply(self._params["sensor_params"], obs) + mean, _log_std = self._actor_apply(self._params["actor_params"], hidden) + + return np.asarray(mean, dtype=np.float32).ravel() diff --git a/src/brittle_star_project/evaluation/rollout.py b/src/brittle_star_project/evaluation/rollout.py new file mode 100644 index 0000000..79c86ed --- /dev/null +++ b/src/brittle_star_project/evaluation/rollout.py @@ -0,0 +1,163 @@ +from __future__ import annotations + +import itertools +import time +from dataclasses import dataclass +from typing import Any + +import numpy as np + +from brittle_star_project import BrittleStarEnv +from brittle_star_project.evaluation.policy import ControlPolicy + + +@dataclass +class EpisodeResult: + return_: float + length: int + reached_target: bool + final_xy_dist: float | None + + +def _get_observations(state: Any) -> dict[str, Any] | None: + return getattr(state, "observations", None) + + +def _get_xy_distance_to_target(observations: dict[str, Any]) -> float | None: + return float(np.asarray(observations["xy_distance_to_target"]).reshape(-1)[0]) + + +def _target_reached(*, state: Any) -> bool: + return bool(getattr(state, "terminated", False) or getattr(state, "truncated", False)) + + +def _maybe_clip_action( + action: np.ndarray, + low: np.ndarray | None, + high: np.ndarray | None, +) -> np.ndarray: + if low is None or high is None: + return action + low = np.asarray(low, dtype=np.float32).ravel() + high = np.asarray(high, dtype=np.float32).ravel() + if low.shape != action.shape or high.shape != action.shape: + return action + return np.clip(action, low, high) + + +def rollout_headless( + *, + env: BrittleStarEnv, + policy: ControlPolicy, + seed: int, + max_steps: int, + action_low: np.ndarray | None, + action_high: np.ndarray | None, + action_mask: np.ndarray | None = None, +) -> EpisodeResult: + """Run an episode headlessly and return the result.""" + state = env.reset(seed=seed) + + ep_return = 0.0 + observations = _get_observations(state) + prev_dist = _get_xy_distance_to_target(observations) if observations else None + reached_target = _target_reached(state=state) + + steps = 0 + for _ in range(int(max_steps)): + obs_dict = observations or {} + + action = policy.act(observations=obs_dict) + if action_mask is not None: + action = action[action_mask] + action = _maybe_clip_action(action, action_low, action_high) + + state = env.step(state=state, action=action) + steps += 1 + + observations = _get_observations(state) + cur_dist = _get_xy_distance_to_target(observations) if observations else None + if prev_dist is not None and cur_dist is not None: + ep_return += prev_dist - cur_dist + prev_dist = cur_dist + + reached_target = _target_reached(state=state) + if reached_target: + break + + final_dist = _get_xy_distance_to_target(observations) if observations else None + return EpisodeResult( + return_=ep_return, + length=steps, + reached_target=reached_target, + final_xy_dist=final_dist, + ) + + +def rollout_viewer( + *, + env: BrittleStarEnv, + policy: ControlPolicy, + seed: int, + state: Any, + control_dt: float, + max_steps: int | None, + action_low: np.ndarray | None, + action_high: np.ndarray | None, + action_mask: np.ndarray | None = None, +) -> None: + """Run an episode using the interactive MuJoCo viewer.""" + import mujoco.viewer + + model = state.mj_model + data = state.mj_data + + episode_return = 0.0 + observations = _get_observations(state) + prev_dist = _get_xy_distance_to_target(observations) if observations else None + reached_target = _target_reached(state=state) + + steps = 0 + with mujoco.viewer.launch_passive(model, data) as viewer: + step_iter = range(int(max_steps)) if max_steps is not None else itertools.count() + for _step_idx in step_iter: + if not viewer.is_running(): + break + step_start = time.time() + + obs_dict = observations or {} + action = policy.act(observations=obs_dict) + if action_mask is not None: + action = action[action_mask] + action = _maybe_clip_action(action, action_low, action_high) + + with viewer.lock(): + state = env.step(state=state, action=action) + + if not viewer.is_running(): + break + viewer.sync() + + steps += 1 + + observations = _get_observations(state) + cur_dist = _get_xy_distance_to_target(observations) if observations else None + if prev_dist is not None and cur_dist is not None: + episode_return += prev_dist - cur_dist + prev_dist = cur_dist + + reached_target = _target_reached(state=state) + if reached_target: + break + + remaining = control_dt - (time.time() - step_start) + if remaining > 0: + time.sleep(remaining) + + dist = _get_xy_distance_to_target(observations) if observations else None + dist_str = "n/a" if dist is None else f"{dist:.3f}" + print( + "episode done: " + f"return={episode_return:.6f}, len={steps}, " + f"target_reached={reached_target}, final_xy_dist={dist_str}" + ) diff --git a/src/brittle_star_project/render/__init__.py b/src/brittle_star_project/render/__init__.py deleted file mode 100644 index 51e0aa1..0000000 --- a/src/brittle_star_project/render/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .renderer import simulate_policy, SimulationConfig, ControlPolicy - -__all__ = ["simulate_policy", "SimulationConfig", "ControlPolicy"] diff --git a/src/brittle_star_project/render/renderer.py b/src/brittle_star_project/render/renderer.py deleted file mode 100644 index 91e669c..0000000 --- a/src/brittle_star_project/render/renderer.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import annotations - -import time -from dataclasses import dataclass -from typing import Any, Protocol - -import numpy as np - - -@dataclass -class SimulationConfig: - realtime: bool = True - seed: int = 0 - - -class ControlPolicy(Protocol): - def act(self, *, obs: np.ndarray | None = None, t: float = 0.0) -> np.ndarray: ... - - -def _default_observations(data: Any) -> np.ndarray: - qpos = np.asarray(data.qpos, dtype=np.float32).ravel() - qvel = np.asarray(data.qvel, dtype=np.float32).ravel() - return np.concatenate([qpos, qvel], axis=0) - - -def simulate_policy( - policy: ControlPolicy, - config: SimulationConfig, - state: Any | None = None, -) -> None: - """Open MuJoCo's native viewer and step using actions from a policy. - - This path drives MuJoCo physics directly (mj_step) and uses the policy output - as `data.ctrl`. - """ - - import mujoco.viewer - - if state is None: - raise ValueError("A valid environment state must be provided.") - - model = state.mj_model - data = state.mj_data - - start = time.time() - with mujoco.viewer.launch_passive(model, data) as viewer: - while viewer.is_running(): - step_start = time.time() - - t = time.time() - start - - # Input vector for the policy - # TODO: custom input - obs = _default_observations(data) - - # Policy action - ctrl = policy.act(obs=obs, t=t) - - # Check if the policy output vector give an input for each actuator (nu) - # TODO: what if model trained on full morphology but we want to test on a damaged one? - # (nu mismatch) - if model.nu > 0: - ctrl = np.asarray(ctrl, dtype=np.float32).ravel() - if ctrl.shape != (model.nu,): - raise ValueError( - f"Policy returned ctrl shape {ctrl.shape}, expected ({model.nu},)" - ) - data.ctrl[:] = ctrl - - # Step the simulation and update the viewer - mujoco.mj_step(model, data) - viewer.sync() - - # If we're running in realtime mode, sleep to maintain real-time pacing. - if config.realtime: - remaining = model.opt.timestep - (time.time() - step_start) - if remaining > 0: - time.sleep(remaining) From d6146850fbae921d08694bbb80cf3a8b7ece3a4f Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 13:55:36 +0200 Subject: [PATCH 12/96] feat(simulate): capture video --- configs/simulation/default.yaml | 5 + pyproject.toml | 4 + scripts/simulate.py | 48 +++++- .../configs/config_simulation.py | 5 + .../evaluation/__init__.py | 4 + src/brittle_star_project/evaluation/video.py | 148 ++++++++++++++++++ uv.lock | 22 ++- 7 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 src/brittle_star_project/evaluation/video.py diff --git a/configs/simulation/default.yaml b/configs/simulation/default.yaml index 390cd46..b2ca27a 100644 --- a/configs/simulation/default.yaml +++ b/configs/simulation/default.yaml @@ -13,3 +13,8 @@ max_steps: null # Points to a morphology config YAML file (e.g. configs/morphology/3_arms.yaml). # If null, the training morphology from the model's metadata is used. morphology_override: null + +# Video recording (requires [evaluation] extra) +record_video: false +# When null, video is saved in a per-model evaluation folder alongside the model. +video_output_path: null diff --git a/pyproject.toml b/pyproject.toml index 607e704..df3c6a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,10 @@ cuda = [ analysis = [ "tensorboard", ] +evaluation = [ + "imageio>=2.35.0", + "imageio-ffmpeg>=0.5.1", +] [dependency-groups] dev = [ diff --git a/scripts/simulate.py b/scripts/simulate.py index 7bb2800..7f27509 100644 --- a/scripts/simulate.py +++ b/scripts/simulate.py @@ -27,6 +27,11 @@ from brittle_star_project.environment.env_config import MorphologyConfig from brittle_star_project.evaluation.checkpoint import load_metadata, metadata_to_configs from brittle_star_project.evaluation.policy import PolicyAgent from brittle_star_project.evaluation.rollout import rollout_headless, rollout_viewer +from brittle_star_project.evaluation.video import ( + record_episode, + create_evaluation_dir, + save_evaluation_metadata, +) @hydra.main(config_path="../configs", config_name="main_config", version_base="1.3") @@ -118,7 +123,48 @@ def main(dict_cfg: DictConfig) -> None: headless = bool(sim_cfg.headless) max_steps = sim_cfg.max_steps - if headless: + if sim_cfg.record_video: + if max_steps is None: + raise ValueError("simulation.max_steps is required when simulation.record_video=true") + + max_steps_i = int(max_steps) + if max_steps_i <= 0: + raise ValueError("simulation.max_steps must be > 0") + + if sim_cfg.video_output_path is None: + eval_dir = create_evaluation_dir(model_path) + output_path = eval_dir / "simulation.mp4" + else: + output_path = Path(hydra.utils.to_absolute_path(sim_cfg.video_output_path)) + eval_dir = output_path.parent + eval_dir.mkdir(parents=True, exist_ok=True) + + result = record_episode( + env=env, + policy=policy, + seed=seed, + max_steps=max_steps_i, + action_low=action_low, + action_high=action_high, + action_mask=action_mask, + output_path=output_path, + ) + + save_evaluation_metadata( + eval_dir=eval_dir, + morphology_override_path=sim_cfg.morphology_override, + seed=seed, + max_steps=max_steps_i, + result=result, + ) + final_dist_str = "n/a" if result.final_xy_dist is None else f"{result.final_xy_dist:.3f}" + print(f"Video saved to {output_path}") + print( + "episode done: " + f"return={result.return_:.6f}, len={result.length}, " + f"target_reached={result.reached_target}, final_xy_dist={final_dist_str}" + ) + elif headless: if max_steps is None: raise ValueError("simulation.max_steps is required when simulation.headless=true") diff --git a/src/brittle_star_project/configs/config_simulation.py b/src/brittle_star_project/configs/config_simulation.py index a10682d..0b93fd8 100644 --- a/src/brittle_star_project/configs/config_simulation.py +++ b/src/brittle_star_project/configs/config_simulation.py @@ -19,3 +19,8 @@ class SimulationSettings: # Observations are padded from the override morphology UP TO the training # morphology's shape via compute_padding_masks(override, reference=training). morphology_override: Optional[str] = None + + # Video recording (requires [evaluation] extra) + record_video: bool = False + # When None, video is saved in a per-model evaluation folder alongside the model. + video_output_path: Optional[str] = None diff --git a/src/brittle_star_project/evaluation/__init__.py b/src/brittle_star_project/evaluation/__init__.py index 73719e6..38a1c8b 100644 --- a/src/brittle_star_project/evaluation/__init__.py +++ b/src/brittle_star_project/evaluation/__init__.py @@ -3,6 +3,7 @@ from __future__ import annotations from .checkpoint import load_metadata, load_params, metadata_to_configs, TrainingConfig from .policy import PolicyAgent, ControlPolicy from .rollout import rollout_headless, rollout_viewer, EpisodeResult +from .video import record_episode, create_evaluation_dir, save_evaluation_metadata __all__ = [ "load_metadata", @@ -14,4 +15,7 @@ __all__ = [ "rollout_headless", "rollout_viewer", "EpisodeResult", + "record_episode", + "create_evaluation_dir", + "save_evaluation_metadata", ] diff --git a/src/brittle_star_project/evaluation/video.py b/src/brittle_star_project/evaluation/video.py new file mode 100644 index 0000000..726edcb --- /dev/null +++ b/src/brittle_star_project/evaluation/video.py @@ -0,0 +1,148 @@ +from __future__ import annotations + +import datetime +from pathlib import Path + +import numpy as np +import yaml + +from brittle_star_project import BrittleStarEnv +from brittle_star_project.evaluation.policy import ControlPolicy +from brittle_star_project.evaluation.rollout import ( + EpisodeResult, + _get_observations, + _get_xy_distance_to_target, + _target_reached, + _maybe_clip_action, +) + + +def create_evaluation_dir(model_path: Path) -> Path: + """Create a unique timestamped directory for saving evaluation results.""" + timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + eval_dir = model_path.parent / f"{model_path.stem}_evaluations" / f"eval_{timestamp}" + eval_dir.mkdir(parents=True, exist_ok=True) + return eval_dir + + +def save_evaluation_metadata( + eval_dir: Path, + *, + morphology_override_path: str | None, + seed: int, + max_steps: int | None, + result: EpisodeResult, +) -> None: + """Save metadata about the evaluation run.""" + metadata = { + "timestamp": datetime.datetime.now().isoformat(), + "morphology_override": morphology_override_path, + "seed": seed, + "max_steps": max_steps, + "result": { + "return": float(result.return_), + "length": int(result.length), + "reached_target": bool(result.reached_target), + "final_xy_dist": float(result.final_xy_dist) + if result.final_xy_dist is not None + else None, + }, + } + with open(eval_dir / "evaluation_metadata.yaml", "w") as f: + yaml.safe_dump(metadata, f, sort_keys=False) + + +def record_episode( + *, + env: BrittleStarEnv, + policy: ControlPolicy, + seed: int, + max_steps: int, + action_low: np.ndarray | None, + action_high: np.ndarray | None, + action_mask: np.ndarray | None = None, + output_path: Path, + fps: int = 60, + width: int = 640, + height: int = 480, +) -> EpisodeResult: + """Run an episode headlessly and record a video using MuJoCo's Renderer and imageio. + + Args: + env: The environment. + policy: The policy agent. + seed: Random seed. + max_steps: Maximum number of steps. + action_low: Minimum action values. + action_high: Maximum action values. + action_mask: Boolean mask for the actions. + output_path: Where to save the .mp4 file. + fps: Frames per second for the video. + width: Video width. + height: Video height. + """ + try: + import imageio + import mujoco + except ImportError as e: + raise ImportError( + "Video recording requires 'imageio' and 'mujoco'. " + "Please install the evaluation dependencies: `uv pip install .[evaluation]`" + ) from e + + state = env.reset(seed=seed) + model = state.mj_model + data = state.mj_data + + # Use the first camera defined in the environment config, or default to 0 + camera_id = env._config.camera_ids[0] if env._config.camera_ids else 0 + renderer = mujoco.Renderer(model, width=width, height=height) + + ep_return = 0.0 + observations = _get_observations(state) + prev_dist = _get_xy_distance_to_target(observations) if observations else None + reached_target = _target_reached(state=state) + + frames = [] + steps = 0 + + for _ in range(int(max_steps)): + # Capture frame + renderer.update_scene(data, camera=camera_id) + frames.append(renderer.render()) + + # Step environment + obs_dict = observations or {} + action = policy.act(observations=obs_dict) + if action_mask is not None: + action = action[action_mask] + action = _maybe_clip_action(action, action_low, action_high) + + state = env.step(state=state, action=action) + steps += 1 + + observations = _get_observations(state) + cur_dist = _get_xy_distance_to_target(observations) if observations else None + if prev_dist is not None and cur_dist is not None: + ep_return += prev_dist - cur_dist + prev_dist = cur_dist + + reached_target = _target_reached(state=state) + if reached_target: + break + + # Capture final frame + renderer.update_scene(data, camera=camera_id) + frames.append(renderer.render()) + renderer.close() + + # Save video + imageio.mimsave(str(output_path), frames, fps=fps) + + final_dist = _get_xy_distance_to_target(observations) if observations else None + return EpisodeResult( + return_=ep_return, + length=steps, + reached_target=reached_target, + final_xy_dist=final_dist, + ) diff --git a/uv.lock b/uv.lock index bca7772..86d6ed9 100644 --- a/uv.lock +++ b/uv.lock @@ -42,6 +42,10 @@ analysis = [ cuda = [ { name = "jax", extra = ["cuda13"] }, ] +evaluation = [ + { name = "imageio" }, + { name = "imageio-ffmpeg" }, +] [package.dev-dependencies] dev = [ @@ -58,6 +62,8 @@ requires-dist = [ { name = "flax", specifier = ">=0.12.2" }, { name = "gymnasium", specifier = ">=1.2.3" }, { name = "hydra-core", specifier = ">=1.3.2" }, + { name = "imageio", marker = "extra == 'evaluation'", specifier = ">=2.35.0" }, + { name = "imageio-ffmpeg", marker = "extra == 'evaluation'", specifier = ">=0.5.1" }, { name = "ipykernel", specifier = "==7.2.0" }, { name = "jax", specifier = "==0.9.0.1" }, { name = "jax", extras = ["cuda13"], marker = "extra == 'cuda'", specifier = "==0.9.0.1" }, @@ -75,7 +81,7 @@ requires-dist = [ { name = "wandb", specifier = "==0.24.2" }, { name = "warp-lang" }, ] -provides-extras = ["cuda", "analysis"] +provides-extras = ["cuda", "analysis", "evaluation"] [package.metadata.requires-dev] dev = [ @@ -795,6 +801,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/49/fa/391e437a34e55095173dca5f24070d89cbc233ff85bf1c29c93248c6588d/imageio-2.37.3-py3-none-any.whl", hash = "sha256:46f5bb8522cd421c0f5ae104d8268f569d856b29eb1a13b92829d1970f32c9f0", size = 317646, upload-time = "2026-03-09T11:31:10.771Z" }, ] +[[package]] +name = "imageio-ffmpeg" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/bd/c3343c721f2a1b0c9fc71c1aebf1966a3b7f08c2eea8ed5437a2865611d6/imageio_ffmpeg-0.6.0.tar.gz", hash = "sha256:e2556bed8e005564a9f925bb7afa4002d82770d6b08825078b7697ab88ba1755", size = 25210, upload-time = "2025-01-16T21:34:32.747Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/58/87ef68ac83f4c7690961bce288fd8e382bc5f1513860fc7f90a9c1c1c6bf/imageio_ffmpeg-0.6.0-py3-none-macosx_10_9_intel.macosx_10_9_x86_64.whl", hash = "sha256:9d2baaf867088508d4a3458e61eeb30e945c4ad8016025545f66c4b5aaef0a61", size = 24932969, upload-time = "2025-01-16T21:34:20.464Z" }, + { url = "https://files.pythonhosted.org/packages/40/5c/f3d8a657d362cc93b81aab8feda487317da5b5d31c0e1fdfd5e986e55d17/imageio_ffmpeg-0.6.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b1ae3173414b5fc5f538a726c4e48ea97edc0d2cdc11f103afee655c463fa742", size = 21113891, upload-time = "2025-01-16T21:34:00.277Z" }, + { url = "https://files.pythonhosted.org/packages/33/e7/1925bfbc563c39c1d2e82501d8372734a5c725e53ac3b31b4c2d081e895b/imageio_ffmpeg-0.6.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1d47bebd83d2c5fc770720d211855f208af8a596c82d17730aa51e815cdee6dc", size = 25632706, upload-time = "2025-01-16T21:33:53.475Z" }, + { url = "https://files.pythonhosted.org/packages/a0/2d/43c8522a2038e9d0e7dbdf3a61195ecc31ca576fb1527a528c877e87d973/imageio_ffmpeg-0.6.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c7e46fcec401dd990405049d2e2f475e2b397779df2519b544b8aab515195282", size = 29498237, upload-time = "2025-01-16T21:34:13.726Z" }, + { url = "https://files.pythonhosted.org/packages/a0/13/59da54728351883c3c1d9fca1710ab8eee82c7beba585df8f25ca925f08f/imageio_ffmpeg-0.6.0-py3-none-win32.whl", hash = "sha256:196faa79366b4a82f95c0f4053191d2013f4714a715780f0ad2a68ff37483cc2", size = 19652251, upload-time = "2025-01-16T21:34:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c6/fa760e12a2483469e2bf5058c5faff664acf66cadb4df2ad6205b016a73d/imageio_ffmpeg-0.6.0-py3-none-win_amd64.whl", hash = "sha256:02fa47c83703c37df6bfe4896aab339013f62bf02c5ebf2dce6da56af04ffc0a", size = 31246824, upload-time = "2025-01-16T21:34:28.6Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" From aabf1bc1862ca798c7daea50eff3e069834993b0 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 14:00:12 +0200 Subject: [PATCH 13/96] feat(simulate): configurable camera id --- configs/simulation/default.yaml | 2 ++ scripts/simulate.py | 1 + src/brittle_star_project/configs/config_simulation.py | 2 ++ src/brittle_star_project/evaluation/video.py | 4 ++-- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/configs/simulation/default.yaml b/configs/simulation/default.yaml index b2ca27a..e689c3b 100644 --- a/configs/simulation/default.yaml +++ b/configs/simulation/default.yaml @@ -18,3 +18,5 @@ morphology_override: null record_video: false # When null, video is saved in a per-model evaluation folder alongside the model. video_output_path: null +# Camera ID to use for video recording (1 is usually the close-up camera) +camera_id: 1 diff --git a/scripts/simulate.py b/scripts/simulate.py index 7f27509..f17d8ef 100644 --- a/scripts/simulate.py +++ b/scripts/simulate.py @@ -148,6 +148,7 @@ def main(dict_cfg: DictConfig) -> None: action_high=action_high, action_mask=action_mask, output_path=output_path, + camera_id=sim_cfg.camera_id, ) save_evaluation_metadata( diff --git a/src/brittle_star_project/configs/config_simulation.py b/src/brittle_star_project/configs/config_simulation.py index 0b93fd8..e15d94e 100644 --- a/src/brittle_star_project/configs/config_simulation.py +++ b/src/brittle_star_project/configs/config_simulation.py @@ -24,3 +24,5 @@ class SimulationSettings: record_video: bool = False # When None, video is saved in a per-model evaluation folder alongside the model. video_output_path: Optional[str] = None + # Camera ID to use for video recording (1 is usually the close-up camera) + camera_id: int = 1 diff --git a/src/brittle_star_project/evaluation/video.py b/src/brittle_star_project/evaluation/video.py index 726edcb..174326b 100644 --- a/src/brittle_star_project/evaluation/video.py +++ b/src/brittle_star_project/evaluation/video.py @@ -62,6 +62,7 @@ def record_episode( action_high: np.ndarray | None, action_mask: np.ndarray | None = None, output_path: Path, + camera_id: int = 1, fps: int = 60, width: int = 640, height: int = 480, @@ -77,6 +78,7 @@ def record_episode( action_high: Maximum action values. action_mask: Boolean mask for the actions. output_path: Where to save the .mp4 file. + camera_id: Camera index to use for rendering (1 is usually close-up). fps: Frames per second for the video. width: Video width. height: Video height. @@ -94,8 +96,6 @@ def record_episode( model = state.mj_model data = state.mj_data - # Use the first camera defined in the environment config, or default to 0 - camera_id = env._config.camera_ids[0] if env._config.camera_ids else 0 renderer = mujoco.Renderer(model, width=width, height=height) ep_return = 0.0 From a1b4df0921f59b92d61c1f72f624bb8c5ed3ed80 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 14:20:27 +0200 Subject: [PATCH 14/96] test(simulate): evaluation --- tests/test_evaluation.py | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tests/test_evaluation.py diff --git a/tests/test_evaluation.py b/tests/test_evaluation.py new file mode 100644 index 0000000..c8bffa9 --- /dev/null +++ b/tests/test_evaluation.py @@ -0,0 +1,77 @@ +import numpy as np + +from brittle_star_project.evaluation.checkpoint import metadata_to_configs, TrainingConfig +from brittle_star_project.evaluation.rollout import _maybe_clip_action +from brittle_star_project.environment.env_config import ( + MorphologyConfig, + ArenaConfig, + EnvConfig, + ObservationBoundsConfig, +) +from brittle_star_project.environment.env_types import Task + + +def test_metadata_to_configs(): + """Test that a raw metadata dictionary correctly instantiates the typed configs.""" + mock_metadata = { + "morphology": { + "segments_per_arm": [4, 0, 4, 0, 0], + "use_p_control": False, + }, + "arena": {"sand_ground_color": False, "size": [15.0, 10.0]}, + "environment": { + "task": "LIGHT_ESCAPE", + "simulation_time": 5000.0, + }, + "obs_bounds": {"joint_velocity": [-10.0, 10.0]}, + } + + config = metadata_to_configs(mock_metadata) + + assert isinstance(config, TrainingConfig) + + # Check MorphologyConfig + assert isinstance(config.morphology, MorphologyConfig) + assert config.morphology.segments_per_arm == [4, 0, 4, 0, 0] + assert config.morphology.use_p_control is False + assert config.morphology.use_torque_control is False # default + + # Check ArenaConfig + assert isinstance(config.arena, ArenaConfig) + assert config.arena.sand_ground_color is False + assert config.arena.size == [15.0, 10.0] + assert config.arena.wall_height == 1.5 # default + + # Check EnvConfig + assert isinstance(config.environment, EnvConfig) + assert config.environment.task == Task.LIGHT_ESCAPE + assert config.environment.simulation_time == 5000.0 + assert config.environment.time_scale == 2 # default + + # Check ObservationBoundsConfig + assert isinstance(config.obs_bounds, ObservationBoundsConfig) + assert config.obs_bounds.joint_velocity == [-10.0, 10.0] + assert config.obs_bounds.segment_contact == [0.0, 1.0] # default + + +def test_maybe_clip_action(): + """Test action clipping against boundaries.""" + # Test valid clipping + action = np.array([1.5, -2.5, 0.0]) + low = np.array([-1.0, -1.0, -1.0]) + high = np.array([1.0, 1.0, 1.0]) + + clipped = _maybe_clip_action(action, low, high) + np.testing.assert_array_equal(clipped, np.array([1.0, -1.0, 0.0])) + + # Test skipping when bounds are None + unclipped_1 = _maybe_clip_action(action, None, high) + np.testing.assert_array_equal(unclipped_1, action) + + unclipped_2 = _maybe_clip_action(action, low, None) + np.testing.assert_array_equal(unclipped_2, action) + + # Test skipping on shape mismatch + wrong_low = np.array([-1.0, -1.0]) # Shape mismatch + unclipped_3 = _maybe_clip_action(action, wrong_low, high) + np.testing.assert_array_equal(unclipped_3, action) From 5716b73eb9620b4092d6910bd003ac000fb4079a Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 16:25:05 +0200 Subject: [PATCH 15/96] docs: restructure API docs --- README.md | 44 ++++++++----------------------- docs/DEVELOPMENT.md | 21 +++------------ docs/README.md | 10 +++++-- docs/api/simulate.md | 14 ---------- docs/api/simulation.md | 39 +++++++++++++++++++++++++++ docs/api/tracking.md | 60 ++++++++++++++++++++++++++++++++++++++++++ docs/api/training.md | 49 ++++++++++++++++++++++++++++++++++ 7 files changed, 171 insertions(+), 66 deletions(-) delete mode 100644 docs/api/simulate.md create mode 100644 docs/api/simulation.md create mode 100644 docs/api/tracking.md create mode 100644 docs/api/training.md diff --git a/README.md b/README.md index dd85e12..572fd73 100644 --- a/README.md +++ b/README.md @@ -13,44 +13,22 @@ To set up the UV module, you can run the following command: uv sync --frozen ``` -### Configuration +## Usage -1. **Copy the default configuration:** +For detailed instructions on how to use the project, please refer to the **[API Documentation](docs/README.md)**. + +### Quick Start + +1. **Train a model:** ```bash - cp configs/default_ppo.yaml configs/my_experiment.yaml + uv run python scripts/train.py ppo.learning_rate=0.001 logging.track=true ``` -2. **Edit `configs/my_experiment.yaml`** to set your WandB credentials: - ```yaml - track: true # Enable WandB logging - wandb_entity: "your-wandb-username" # Replace with your username/team - wandb_project_name: "PPO-Modularity" - ``` +2. **Monitor progress:** + See [Tracking & Monitoring](docs/api/tracking.md). -3. **(Optional) Login to WandB:** - ```bash - uv run wandb login - ``` - -### Training - -example command: - -```bash -uv run python scripts/train.py -``` - -Or use a custom config file: - -```bash -uv run python scripts/train.py --config configs/my_experiment.yaml -``` - -Override specific parameters: - -```bash -uv run python scripts/train.py --learning-rate 0.001 --num-envs 32 --track -``` +3. **Simulate a trained model:** + See [Simulation & Evaluation](docs/api/simulation.md). ## HPC diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 5a01d26..3518b38 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -62,22 +62,9 @@ In the devcontainer, this will succeed on both CPU and GPU. A `GpuDevice` is exp ## Logging & Monitoring -This project uses a unified logging system through the `experiment_logger` package. For a full API reference, see the [package README](../src/experiment_logger/README.md). - -### Quick Setup - -1. **Authorization**: Export your API key in your terminal to enable WandB synchronization: - ```bash - export WANDB_API_KEY=your_copied_api_key_here - ``` -2. **Toggle Tracking**: Use the `--track` flag in `scripts/train.py` to enable online sync. -3. **Local Monitoring**: All runs are recorded in the `runs/` directory. View scalars with TensorBoard: - ```bash - tensorboard --logdir runs/ - ``` - -### Environment Awareness - -The logger automatically detects if it is running in an interactive terminal or a non-interactive environment (like an HPC Slurm job). It will automatically disable progress bars and switch to robust fallback modes (offline logging) to ensure your experiments never hang. +This project uses a unified logging system through the `experiment_logger` package. +- **Usage in Code**: To use the logger in your scripts, refer to the [package README](../src/experiment_logger/README.md) for the API reference. +- **WandB/TensorBoard Setup**: For information on how to configure tracking for experiments, see the [Tracking & Monitoring API Guide](./api/tracking.md). +The logger automatically detects if it is running in an interactive terminal or a non-interactive environment (like an HPC Slurm job), adjusting progress bars and fallback modes accordingly. diff --git a/docs/README.md b/docs/README.md index a4f4ea0..3c76684 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,6 +2,8 @@ ## Design & architecture ([`/design`](./design/)) +If you are interested in the "why did you do it like this?" + - [Actor/critic architecture](./design/actor-critic.md): Description of the actor-critic pipeline. - [Communication](./design/communication.md): Message propagation, Nerve-Net style. - [Controllers](./design/controllers.md): Macroscopig brain toplogy, centralized, arm-level, segment-level. @@ -11,5 +13,9 @@ ## API reference ([`/api`](./api/)) -- [Environment](./api/environment.md): MuJoCo environment interaction, state retrieval, and configuration. -- [Simulate](./api/simulate.md): Simulation rendering. +If you are interested in the "how do I use it?" + +- [Training](./api/training.md): How to configure and run experiments. +- [Tracking & Monitoring](./api/tracking.md): Setting up WandB and TensorBoard to monitor runs. +- [Simulation](./api/simulation.md): Visualizing and evaluating models. +- [Environment](./api/environment.md): MuJoCo environment interaction and configuration. diff --git a/docs/api/simulate.md b/docs/api/simulate.md deleted file mode 100644 index 9c4b21b..0000000 --- a/docs/api/simulate.md +++ /dev/null @@ -1,14 +0,0 @@ -# Training and Simulation for Brittle Star Models - -## Simulating a model - -In order to simulate and view the behavior of a trained model, you can use the `simulate.py` script. This script allows you to specify the path to a trained model and will launch a simulation using that model. This script has the following parameters: - -- `--model`: The path to the trained model artifact to simulate. -- `--model-type`: The type of model to simulate (e.g., `random`, ...) -- `--task`: The task to simulate (e.g., `directed_locomotion`, ...) -- `--seed`: The random seed for reproducibility. - -```bash -python simulate.py --model artifacts/my_model --model-type random --task directed_locomotion --seed 0 -``` \ No newline at end of file diff --git a/docs/api/simulation.md b/docs/api/simulation.md new file mode 100644 index 0000000..0a0e041 --- /dev/null +++ b/docs/api/simulation.md @@ -0,0 +1,39 @@ +# Simulation & Evaluation + +The simulation pipeline allows you to visualize trained models and evaluate their performance under various conditions. + +## Overview + +The simulation pipeline is metadata-driven. Training-specific configurations (morphology, arena, environment, etc.) are automatically loaded from the `_metadata.yaml` file associated with the model checkpoint. + +## Basic Simulation + +To simulate a model in the MuJoCo viewer: + +```bash +uv run scripts/simulate.py simulation.model_path=runs/your_run/final_model.flax +``` + +## Amputation & Morphology Overrides + +You can test trained models on different morphologies (e.g., amputating legs) by providing a morphology override. The observations will be automatically padded up to the training morphology's dimensions: + +```bash +uv run scripts/simulate.py \ + simulation.model_path=runs/your_run/final_model.flax \ + simulation.morphology_override=configs/morphology/3_arms.yaml +``` + +## Video Recording + +Recording videos requires the `[evaluation]` extra: + +```bash +uv run scripts/simulate.py \ + simulation.model_path=runs/your_run/final_model.flax \ + simulation.record_video=true \ + simulation.max_steps=1000 +``` + +Videos and evaluation metadata are stored in timestamped folders alongside the model: +`runs/your_run/final_model_evaluations/eval_/simulation.mp4` diff --git a/docs/api/tracking.md b/docs/api/tracking.md new file mode 100644 index 0000000..226992b --- /dev/null +++ b/docs/api/tracking.md @@ -0,0 +1,60 @@ +# Tracking & Monitoring + +This guide explains how to monitor your experiments using Weights & Biases (WandB) and TensorBoard. + +## Weights & Biases (WandB) + +WandB is used for online synchronization and visualization of training metrics. + +### Authorization + +Export your API key in your terminal to enable WandB synchronization: + +```bash +export WANDB_API_KEY=your_copied_api_key_here +``` + +Alternatively, you can log in using the CLI: + +```bash +uv run wandb login +``` + +### Enabling Tracking + +To enable online sync during a training run, set `logging.track=true` on the command line: + +```bash +uv run python scripts/train.py logging.track=true +``` + +You can also configure your project and entity: + +```bash +uv run python scripts/train.py \ + logging.track=true \ + logging.wandb_project_name="MyProject" \ + logging.wandb_entity="my-team" +``` + +These can also be set in your configuration YAML file under the `logging` key. + +## Local Monitoring with TensorBoard + +All runs are recorded locally in the `runs/` directory (or the directory specified in `experiment.base_run_dir`). You can view scalars and other metrics with TensorBoard: + +```bash +tensorboard --logdir runs/ +``` + +Access the interface at `http://localhost:6006`. + +### CLI Exploration Tool + +For quick diagnostics or to export data to CSV without launching the full TensorBoard UI, you can use the `explore_tensorboard.py` script: + +```bash +uv run python scripts/analysis/explore_tensorboard.py runs/your_run_name/ +``` + +See the detailed description in [`/scripts/analysis/README.md`](../../scripts/analysis/README.md). diff --git a/docs/api/training.md b/docs/api/training.md new file mode 100644 index 0000000..a9678bb --- /dev/null +++ b/docs/api/training.md @@ -0,0 +1,49 @@ +# Training Models + +This guide covers how to configure and run training experiments for the Brittle Star project using Hydra-based configurations. + +## Configuration + +The project uses a modular configuration system powered by [Hydra](https://hydra.cc/). Instead of passing many command-line flags, you select and override configuration groups. + +### Creating a Custom Experiment + +1. **Create a new experiment file:** + Create a file at `configs/experiment/my_experiment.yaml`. You can copy an existing one as a template: + ```bash + cp configs/experiment/base.yaml configs/experiment/my_experiment.yaml + ``` + +2. **Edit `configs/experiment/my_experiment.yaml`** to set your experiment parameters: + ```yaml + # @package _global_ + experiment: + exp_name: "my_custom_run" + seed: 42 + ``` + +## Training Execution + +To start a training run with the default settings defined in `configs/main_config.yaml`: + +```bash +uv run python scripts/train.py +``` + +### Using a Custom Experiment Configuration + +To run with your custom experiment file: + +```bash +uv run python scripts/train.py experiment=my_experiment +``` + +### Command-Line Overrides + +You can override any parameter directly from the command line using Hydra's dot notation. This is useful for quick tests: + +```bash +uv run python scripts/train.py ppo.learning_rate=0.001 ppo.num_envs=32 logging.track=true +``` + +For more details on tracking your experiments, see [Tracking & Monitoring](./tracking.md). From 33fbc4c96f6f564f2282f0aedde3a08c95153d42 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 16:42:46 +0200 Subject: [PATCH 16/96] feat: tool to construct XML --- scripts/analysis/dump_mjcf.py | 186 ++++++++++++++++++++++++++++++++ tests/test_morphology_render.py | 4 +- 2 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 scripts/analysis/dump_mjcf.py diff --git a/scripts/analysis/dump_mjcf.py b/scripts/analysis/dump_mjcf.py new file mode 100644 index 0000000..1f552d9 --- /dev/null +++ b/scripts/analysis/dump_mjcf.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 +""" +Dump MJCF XML for a brittle-star morphology using the project's Hydra configs. + +Usage examples: + + # Use a named morphology config from configs/morphology (Hydra style) + uv run python scripts/analysis/dump_mjcf.py morphology=3_arms + + # Use a morphology override YAML (same key as simulation.morphology_override) + uv run python scripts/analysis/dump_mjcf.py \ + simulation.morphology_override=configs/morphology/3_arms.yaml + +Output path: + Provide `dump_out=path/to/file.xml` on the command line, otherwise writes `morphology.xml` in + current directory. +""" + +from __future__ import annotations + +from pathlib import Path +import sys +import xml.etree.ElementTree as ET + +import hydra +from omegaconf import DictConfig, OmegaConf + +from brittle_star_project.configs.main_config import BrittleStarConfig +from brittle_star_project.configs.register_configs import register_configs +from brittle_star_project.environment.env_config import MorphologyConfig +from brittle_star_project.environment.factory import BrittleStarEnvFactory + + +def try_serialize(obj): + """Try multiple common accessors to obtain an XML string from the morphology object.""" + candidates = [ + "to_xml_string", + "to_xml", + "to_string", + "to_mjcf", + "to_mjcf_string", + "get_mjcf", + "get_mjcf_str", + "get_mjcf_assets", + "export_to_xml_with_assets", + "get_xml", + "xml", + "mjcf", + "mjcf_model", + "mjcf_body", + "model", + "root", + ] + + def normalize(out): + if out is None: + return None + # lxml element + try: + import lxml.etree as lxml_et + + if isinstance(out, lxml_et._Element): + return lxml_et.tostring(out, encoding="unicode") + except Exception: + pass + + if isinstance(out, ET.Element): + return ET.tostring(out, encoding="unicode") + + if isinstance(out, bytes): + try: + return out.decode() + except Exception: + return None + + if hasattr(out, "toxml") and callable(out.toxml): + try: + return out.toxml() + except Exception: + pass + + try: + s = str(out) + if s.lstrip().startswith("<"): + return s + return s + except Exception: + return None + + for name in candidates: + attr = getattr(obj, name, None) + if callable(attr): + try: + out = attr() + except Exception: + out = None + if out: + norm = normalize(out) + if norm: + return norm + elif attr is not None: + norm = normalize(attr) + if norm: + return norm + + if hasattr(obj, "mjcf"): + nested = getattr(obj, "mjcf") + if nested is not None: + return try_serialize(nested) + + return None + + +@hydra.main(config_path="../../configs", config_name="main_config", version_base="1.3") +def main(dict_cfg: DictConfig) -> None: + # Compose typed config like the rest of the project + cfg = OmegaConf.to_object(OmegaConf.merge(OmegaConf.structured(BrittleStarConfig), dict_cfg)) + + # Check for a simulation morphology override (points to a YAML file) + sim_override = None + try: + sim_override = dict_cfg.get("simulation", {}).get("morphology_override", None) + except Exception: + sim_override = getattr(getattr(cfg, "simulation", None), "morphology_override", None) + + if sim_override: + override_path = Path(hydra.utils.to_absolute_path(sim_override)) + if not override_path.exists(): + raise FileNotFoundError(f"Could not find morphology override YAML at {override_path}") + import yaml + + with open(override_path, "r") as f: + override_dict = yaml.safe_load(f) + env_morphology = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(MorphologyConfig), override_dict) + ) + else: + env_morphology = cfg.morphology + + # Ensure we have a MorphologyConfig instance + if isinstance(env_morphology, dict): + morph_cfg = MorphologyConfig(**env_morphology) + else: + morph_cfg = env_morphology + + # Build morphology via project factory (same as runtime) + morph = BrittleStarEnvFactory.create_morphology(morph_cfg) + + xml_text = try_serialize(morph) + if xml_text is None and hasattr(morph, "mjcf"): + xml_text = try_serialize(morph.mjcf) + + if xml_text is None: + raise RuntimeError( + "Failed to serialize morphology to MJCF/XML. Inspect the `morph` object interactively." + ) + + # Prefer explicit CLI override `dump_out=...` if provided, otherwise choose a sensible default. + dump_out = None + try: + dump_out = dict_cfg.get("dump_out", None) + except Exception: + dump_out = None + + if dump_out is None: + # If the user passed a morphology group on the CLI (e.g. morphology=3_arms), + # use a descriptive default path under `runs/morphologies/`. + morph_name = None + for a in sys.argv[1:]: + if a.startswith("morphology="): + morph_name = a.split("=", 1)[1] + break + + default_out = f"runs/morphologies/{morph_name}.xml" if morph_name else "morphology.xml" + out_path = Path(hydra.utils.to_absolute_path(default_out)) + else: + out_path = Path(hydra.utils.to_absolute_path(str(dump_out))) + + out_path.parent.mkdir(parents=True, exist_ok=True) + out_path.write_text(xml_text) + print(f"Wrote MJCF XML to {out_path}") + + +if __name__ == "__main__": + register_configs() + main() diff --git a/tests/test_morphology_render.py b/tests/test_morphology_render.py index 6b435cf..a80b5e6 100644 --- a/tests/test_morphology_render.py +++ b/tests/test_morphology_render.py @@ -14,7 +14,7 @@ from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleSta @pytest.mark.skipif(os.getenv("CI") == "true", reason="No OpenGL display in CI") def test_render_morphologies(): - base_dir = "runs/renders" + base_dir = "runs/morphologies" os.makedirs(base_dir, exist_ok=True) # --- 1. Full 5-Arm Morphology --- @@ -34,7 +34,7 @@ def test_render_morphologies(): renderer_full = mujoco.Renderer(model=model_full) renderer_full.update_scene(data_full, camera=1) pixels_full = renderer_full.render() - image_path = os.path.join(base_dir, "full_5_arm.png") + image_path = os.path.join(base_dir, "5_arm.png") Image.fromarray(pixels_full).save(image_path) print(f"Generated full morphology render: {image_path}") From 49f587403524e3474b2dcb4c491a1e4e12fe2386 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 17:27:08 +0200 Subject: [PATCH 17/96] chore: remove distance to target from model input --- docs/design/input_action_spaces.md | 7 +++++-- src/brittle_star_project/environment/env_config.py | 2 -- src/brittle_star_project/environment/obs_processing.py | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/design/input_action_spaces.md b/docs/design/input_action_spaces.md index 143dce5..50f142e 100644 --- a/docs/design/input_action_spaces.md +++ b/docs/design/input_action_spaces.md @@ -16,8 +16,7 @@ Global inputs, always broadcasted to all nodes: $$ tilt = sqrt(roll^2 + pitch^2) $$ -- Goal vector: Instead of just a scalar distance, the goal is represented asa a vector (distance and ange/direction) to - the target. +- Goal vector: Instead of just a scalar distance, the goal is represented as an angle/direction to the target. Local inputs, routed directly to specific nodes: @@ -70,6 +69,10 @@ When designing the state space, we must ask: *Could a human operator perform thi as a normalized unit vector bounds the values to the $[-1, 1]$ range, which stabilizes neural network training. Providing only a scalar "distance to the goal" would force the agent to learning localized searching behaviors (e.g. random walks or spiraling) to deduce the direction, drastically increasing the difficulty of the learning task. + + **NOTE:** We later dropped the "distance to vector", switching to only a direction as the input. Our reasoning is + the agent should always move towards the goal (it should not learn to stop at the goal), which allows for this + simplification that decreases the model input size. - Contact sensors: Segment contact detects external ground interaction and is biologically vital for timing gait transitions. - **Zero-Centered Rescaling ($[-1, 1]$):** Using a zero-centered range is standard best practice for continuous control diff --git a/src/brittle_star_project/environment/env_config.py b/src/brittle_star_project/environment/env_config.py index 0af387e..b9a621d 100644 --- a/src/brittle_star_project/environment/env_config.py +++ b/src/brittle_star_project/environment/env_config.py @@ -72,7 +72,6 @@ class ObservationBoundsConfig: joint_actuator_force: list[float] = field(default_factory=lambda: [-5.0, 5.0]) segment_contact: list[float] = field(default_factory=lambda: [0.0, 1.0]) unit_xy_direction_to_target: list[float] = field(default_factory=lambda: [-1.0, 1.0]) - xy_distance_to_target: list[float] = field(default_factory=lambda: [0.0, 20.0]) disk_z_tilt: list[float] = field(default_factory=lambda: [0.0, 3.141592653589793]) def to_bounds_dict(self) -> dict[str, tuple[float, float]]: @@ -82,6 +81,5 @@ class ObservationBoundsConfig: "joint_actuator_force": tuple(self.joint_actuator_force), "segment_contact": tuple(self.segment_contact), "unit_xy_direction_to_target": tuple(self.unit_xy_direction_to_target), - "xy_distance_to_target": tuple(self.xy_distance_to_target), "disk_z_tilt": tuple(self.disk_z_tilt), } diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 0ef6e3d..37a775f 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -63,7 +63,6 @@ def create_obs_processor( "joint_velocity", "segment_contact", "unit_xy_direction_to_target", - "xy_distance_to_target", ] values = [] for key in ordered_keys: From 2a34b84f83125c2503554ab9bbb83f3cfd16a9e4 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 17:38:02 +0200 Subject: [PATCH 18/96] chore: min/max of inputs --- scripts/extract_observation_bounds.py | 138 ++++++++++++++++++ .../environment/env_config.py | 13 +- 2 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 scripts/extract_observation_bounds.py diff --git a/scripts/extract_observation_bounds.py b/scripts/extract_observation_bounds.py new file mode 100644 index 0000000..374babc --- /dev/null +++ b/scripts/extract_observation_bounds.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 +"""Empirically extract observation bounds (focused on joint velocities). + +This script creates a MuJoCo environment using the project's factory and +randomly samples actions to discover observed maxima for selected +observation keys (joint_velocity, joint_position, joint_actuator_force). + +Usage: + python scripts/extract_observation_bounds.py \ + --morphology configs/morphology/3_arms.yaml --num-steps 5000 --seed 42 + +If `--morphology` is omitted the default `MorphologyConfig()` is used. +""" + +from __future__ import annotations + +import argparse +from pathlib import Path +import yaml +import numpy as np + +from brittle_star_project import BrittleStarEnvFactory, BrittleStarEnv, Backend +from brittle_star_project.environment.env_config import ( + MorphologyConfig, + ArenaConfig, + EnvConfig, +) + + +def load_morphology(path: str | None) -> MorphologyConfig: + if path is None: + return MorphologyConfig() + p = Path(path) + if not p.exists(): + raise FileNotFoundError(f"Morphology file not found: {p}") + with open(p, "r") as f: + data = yaml.safe_load(f) or {} + return MorphologyConfig(**data) + + +def _extract_observations(state): + # Under different backends the returned state may be a dict or an object + obs = getattr(state, "observations", None) + if obs is None and isinstance(state, dict): + obs = state.get("observations", state) + return obs + + +def find_empirical_bounds( + morph_cfg: MorphologyConfig, + arena_cfg: ArenaConfig, + env_cfg: EnvConfig, + num_steps: int = 5000, + seed: int = 42, +) -> None: + factory = BrittleStarEnvFactory() + raw_env = factory.create_environment(Backend.MJC, morph_cfg, arena_cfg, env_cfg) + env = BrittleStarEnv(raw_env, backend=Backend.MJC, config=env_cfg, morphology_config=morph_cfg) + + # Initial reset + state = env.reset(seed=seed) + + # Determine action bounds + action_space = getattr(raw_env, "action_space", None) + if action_space is None: + raise RuntimeError("Environment missing `action_space`; cannot sample actions.") + + action_low = np.asarray(action_space.low, dtype=np.float32) + action_high = np.asarray(action_space.high, dtype=np.float32) + action_shape = action_low.shape + + # Track maximum absolute observed values + tracked_keys = ["joint_velocity", "joint_position", "joint_actuator_force"] + max_observed = {k: 0.0 for k in tracked_keys} + + # Include observation at reset + obs0 = _extract_observations(state) + if isinstance(obs0, dict): + for k in tracked_keys: + if k in obs0: + max_observed[k] = max(max_observed[k], float(np.max(np.abs(np.asarray(obs0[k]))))) + + rng = np.random.RandomState(seed) + for i in range(num_steps): + u = rng.uniform(size=action_shape) + action = action_low + (action_high - action_low) * u + + # Provide a numpy RNG to the env step; wrapper will pass it if accepted. + step_out = env.step(state=state, action=action, rng=env.make_rng(seed + i + 1)) + + # Unpack next state from common return conventions + if hasattr(step_out, "state"): + next_state = step_out.state + elif isinstance(step_out, (tuple, list)) and len(step_out) >= 1: + next_state = step_out[0] + else: + next_state = step_out + + obs = _extract_observations(next_state) + if isinstance(obs, dict): + for k in tracked_keys: + if k in obs: + val = float(np.max(np.abs(np.asarray(obs[k])))) + if val > max_observed[k]: + max_observed[k] = val + + state = next_state + + # Print recommended bounds with a 20% safety margin + print("\n--- Recommended Observation Bounds (20% margin) ---") + for k, v in max_observed.items(): + if v == 0.0: + print(f"{k}: observed max 0.0 (increase sampling or inspect env)") + else: + safe = v * 1.2 + print(f"{k}: [-{safe:.6f}, {safe:.6f}] (observed max: {v:.6f})") + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument( + "--morphology", type=str, default=None, help="Path to morphology YAML (optional)" + ) + parser.add_argument( + "--num-steps", type=int, default=5000, help="Number of random steps to sample" + ) + parser.add_argument("--seed", type=int, default=42, help="RNG seed") + args = parser.parse_args() + + morph_cfg = load_morphology(args.morphology) + arena_cfg = ArenaConfig() + env_cfg = EnvConfig() + + find_empirical_bounds(morph_cfg, arena_cfg, env_cfg, num_steps=args.num_steps, seed=args.seed) + + +if __name__ == "__main__": + main() diff --git a/src/brittle_star_project/environment/env_config.py b/src/brittle_star_project/environment/env_config.py index b9a621d..f26b428 100644 --- a/src/brittle_star_project/environment/env_config.py +++ b/src/brittle_star_project/environment/env_config.py @@ -66,10 +66,15 @@ class EnvConfig: class ObservationBoundsConfig: """Physical observation bounds for deterministic min-max normalization.""" - # TODO Inspect empirically observed ranges and update these bounds as needed. - joint_position: list[float] = field(default_factory=lambda: [-3.14, 3.14]) - joint_velocity: list[float] = field(default_factory=lambda: [-20.0, 20.0]) - joint_actuator_force: list[float] = field(default_factory=lambda: [-5.0, 5.0]) + # Empirical testing based on the extract_observation_bounds.py script run for 1.000.000 steps + + # Based on max. ctrlrange (0.78539816339744828) in XML, but empirical testing went slightly over + joint_position: list[float] = field(default_factory=lambda: [-0.8, 0.8]) + # Empirical testing showed max. 3.22, adding buffer to be safe + joint_velocity: list[float] = field(default_factory=lambda: [-5.0, 5.0]) + # Based on max. forceRange in XML, verified with empirical testing + joint_actuator_force: list[float] = field(default_factory=lambda: [-3.75, 3.75]) + # Based on intuition and reasoning segment_contact: list[float] = field(default_factory=lambda: [0.0, 1.0]) unit_xy_direction_to_target: list[float] = field(default_factory=lambda: [-1.0, 1.0]) disk_z_tilt: list[float] = field(default_factory=lambda: [0.0, 3.141592653589793]) From ba8184b03423a0e2e4825224dd035d41b29235a5 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Tue, 28 Apr 2026 18:03:53 +0200 Subject: [PATCH 19/96] test: fix outdated imports etc. --- tests/test_network_shapes.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/tests/test_network_shapes.py b/tests/test_network_shapes.py index 32e9898..e1a7a1a 100644 --- a/tests/test_network_shapes.py +++ b/tests/test_network_shapes.py @@ -2,8 +2,8 @@ import jax import jax.numpy as jnp from brittle_star_project.environment.padded_obs_wrapper import ( compute_padding_masks, - pad_observations_batched, ) +from brittle_star_project.environment.obs_processing import create_obs_processor # We use Actor and OneDenseLayerMLP (as the critic) based on your mlps.py from brittle_star_project.MLPs.mlps import Actor, OneDenseLayerMLP @@ -20,21 +20,10 @@ def test_centralized_forward_pass_with_padding(): "segment_contact": jnp.zeros((batch_size, 14)), } - # 2. Pad Observation using the boolean scattering wrapper + # 2. Process and Pad Observation masks = compute_padding_masks(segments_per_arm=(4, 0, 4, 2, 4)) - padded_obs = pad_observations_batched(amputated_obs, masks) - - # Assertions to ensure padding sizes are correct (40 joints, 20 segments) - assert padded_obs["joint_position"].shape == (batch_size, 40), "Padding failed for joint keys" - assert padded_obs["segment_contact"].shape == (batch_size, 20), ( - "Padding failed for segment keys" - ) - - # 3. Concatenate for Centralized MLP (simulating the global state vector) - global_state = jnp.concatenate( - [padded_obs["joint_position"], padded_obs["joint_velocity"], padded_obs["segment_contact"]], - axis=-1, - ) + obs_processor = create_obs_processor(bounds_dict={}, padding_masks=masks) + global_state = obs_processor(amputated_obs) # 40 + 40 + 20 = 100 dimensions assert global_state.shape == (batch_size, 100), ( From db5d4c3dc2a226e87cbf9a6831f7406e629f27d0 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Tue, 28 Apr 2026 22:23:46 +0200 Subject: [PATCH 20/96] fix(PPOTrainer): fixed duplicate definition of conversion function, tracing error related to obs_mode, added adjacent matrix argument --- .../environment/__init__.py | 3 +- .../environment/env_config.py | 11 +++ .../trainers/PPOTrainer.py | 72 ++++++++++++++----- 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/src/brittle_star_project/environment/__init__.py b/src/brittle_star_project/environment/__init__.py index 78896cb..4395b1f 100644 --- a/src/brittle_star_project/environment/__init__.py +++ b/src/brittle_star_project/environment/__init__.py @@ -1,4 +1,4 @@ -from .env_config import ArenaConfig, EnvConfig, MorphologyConfig +from .env_config import ArenaConfig, EnvConfig, MorphologyConfig, MorphMode from .env_types import Backend, Task from .env_wrapper import BrittleStarEnv, StepResult from .factory import BrittleStarEnvFactory @@ -12,4 +12,5 @@ __all__ = [ "BrittleStarEnv", "StepResult", "BrittleStarEnvFactory", + "MorphMode", ] diff --git a/src/brittle_star_project/environment/env_config.py b/src/brittle_star_project/environment/env_config.py index 7cb4c21..8c2be31 100644 --- a/src/brittle_star_project/environment/env_config.py +++ b/src/brittle_star_project/environment/env_config.py @@ -1,10 +1,18 @@ from __future__ import annotations from dataclasses import dataclass, field +from enum import Enum from .env_types import Task +class MorphMode(Enum): + CENTRALIZED = 0 + FULLY_CONNECTED = 1 + RING = 2 + SEGMENT = 3 + + @dataclass class MorphologyConfig: """Brittle star morphology configuration. @@ -20,6 +28,7 @@ class MorphologyConfig: segments_per_arm: list[int] = field(default_factory=lambda: [4, 4, 4, 4, 4]) use_p_control: bool = True use_torque_control: bool = False + morph_mode: MorphMode = MorphMode.CENTRALIZED @property def num_arms(self) -> int: @@ -60,3 +69,5 @@ class EnvConfig: # Light escape # Per docs in upstream env config: integer factors of 200. light_perlin_noise_scale: int = 0 + + obs_mode: int = 0 # TODO: ???? diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index d431328..d340b50 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -24,15 +24,7 @@ from brittle_star_project.MLPs.mlps import ( Storage, ) from brittle_star_project.ppo import PPO -from enum import Enum - - -class MorphMode(Enum): - CENTRALIZED = 0 - FULLY_CONNECTED = 1 - RING = 2 - SEGMENT = 3 - +from brittle_star_project.environment import MorphMode # TODO: move to config _ALLOWED_OBS_KEYS = { @@ -138,7 +130,7 @@ def _normalize_obs(obs, mean, var, eps=1e-8): @jax.jit -def _convert_obs_dict_to_array(obs_dict, morph_mode, segments_per_arm): +def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm): num_segments = sum(segments_per_arm) num_arms = len(segments_per_arm) @@ -221,7 +213,7 @@ _SEGMENT_SCALED_KEYS = frozenset( ) -@jax.jit +@jax.jit(static_argnums=(1,)) def _convert_obs_dict_to_array(obs_dict, obs_mode, segments_per_arm): num_segments = sum(segments_per_arm) @@ -279,6 +271,7 @@ def _convert_obs_dict_to_array(obs_dict, obs_mode, segments_per_arm): return jax.vmap(_filter_and_flatten)(obs_dict) +# TODO: update to work with extra dimension + message passing def _get_action_and_value_noise( sensor: GenericDenseLayersWithActivation, feature_extractor: GenericDenseLayersWithActivation, @@ -289,6 +282,7 @@ def _get_action_and_value_noise( key: jax.random.PRNGKey, action_low, action_high, + adj_matrix: jnp.ndarray, ): hidden = sensor.apply(agent_state.params["sensor_params"], next_obs) hidden_critic = feature_extractor.apply( @@ -308,10 +302,12 @@ def _get_action_and_value_noise( return clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key +# TODO: update to work with extra dimension + message passing def _step_once( carry, _, env_step_fn, + adj_matrix, sensor: GenericDenseLayersWithActivation, feature_extractor: GenericDenseLayersWithActivation, actor: Actor, @@ -321,7 +317,16 @@ def _step_once( ): agent_state, episode_stats, obs, done, key, env_state = carry clipped_action, raw_action, logprob, value, mean, std, key = _get_action_and_value_noise( - sensor, feature_extractor, actor, critic, agent_state, obs, key, action_low, action_high + sensor, + feature_extractor, + actor, + critic, + agent_state, + obs, + key, + action_low, + action_high, + adj_matrix, ) episode_stats, env_state, (next_obs, reward, next_done) = env_step_fn( @@ -361,7 +366,8 @@ def _reward_fn(env_state, next_env_state): return jnp.where(next_env_state.terminated, 50.0, clipped_env_reward - penalty) -def _step_env_wrapped(episode_stats, env_state, action, env_step_fn): +# TODO: update to work with extra dimension + message passing +def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, obs_mode, segments_per_arm): next_env_state = env_step_fn(env_state, action) reward = _reward_fn(env_state, next_env_state) @@ -385,16 +391,22 @@ def _step_env_wrapped(episode_stats, env_state, action, env_step_fn): return ( episode_stats, next_env_state, - (_convert_obs_dict_to_array(next_env_state.observations), reward, done), + ( + _convert_obs_dict_to_array(next_env_state.observations, obs_mode, segments_per_arm), + reward, + done, + ), ) +# TODO: update to work with extra dimension + message passing def _rollout_jit( agent_state, episode_stats, env_state, next_obs, next_done, + adj_matrix, key, max_steps, step_env_fn, @@ -415,6 +427,7 @@ def _rollout_jit( env_step_fn=step_env_fn, action_low=action_low, action_high=action_high, + adj_matrix=adj_matrix, ), (agent_state, episode_stats, next_obs, next_done, key, env_state), (), @@ -442,6 +455,7 @@ def _compute_gae_jit( num_envs, feature_extractor, critic, + adj_matrix: jnp.ndarray, ): next_value = critic.apply( agent_state.params["critic_params"], @@ -484,7 +498,6 @@ class PPOTrainer: env: BrittleStarJaxEnvWrapper, run_dir: str, run_name: str, - morph: MorphMode = MorphMode.CENTRALIZED, ): self.cfg = cfg self.ppo = cfg.ppo @@ -501,6 +514,9 @@ class PPOTrainer: self.key = jax.random.PRNGKey(self.experiment.seed) + morph = cfg.morphology.morph_mode + + self.logger.info(f"[INIT]: Used morphology mode {morph}") self.adj = build_adjacency(cfg.morphology.segments_per_arm, morph) self.sensor, self.feature_extractor, self.actor, self.critic = self._init_agent() @@ -509,6 +525,9 @@ class PPOTrainer: self.actor.apply = jax.jit(self.actor.apply) self.critic.apply = jax.jit(self.critic.apply) + self.obs_mode = self.cfg.environment.obs_mode + self.segments_per_arm = jnp.asarray(self.cfg.morphology.segments_per_arm, dtype=jnp.int32) + action_low = jnp.asarray(self.env.single_action_space.low, dtype=jnp.float32) action_high = jnp.asarray(self.env.single_action_space.high, dtype=jnp.float32) @@ -516,13 +535,19 @@ class PPOTrainer: partial( _rollout_jit, max_steps=self.ppo.num_steps, - step_env_fn=partial(_step_env_wrapped, env_step_fn=self.env.step), + step_env_fn=partial( + _step_env_wrapped, + env_step_fn=self.env.step, + obs_mode=self.obs_mode, + segments_per_arm=self.segments_per_arm, + ), sensor=self.sensor, feature_extractor=self.feature_extractor, actor=self.actor, critic=self.critic, action_low=action_low, action_high=action_high, + adj_matrix=self.adj, ) ) self._compute_gae_jit = jax.jit( @@ -533,6 +558,7 @@ class PPOTrainer: gae_lambda=self.ppo.gae_lambda, feature_extractor=self.feature_extractor, critic=self.critic, + adj_matrix=self.adj, ) ) @@ -568,8 +594,12 @@ class PPOTrainer: dummy_reset = self.env.reset(seed=0) for k, v in dummy_reset.observations.items(): - print(k, v.shape) - sample_obs = _convert_obs_dict_to_array(dummy_reset.observations)[0] # take first env + self.logger.debug(k, v.shape) + sample_obs = _convert_obs_dict_to_array( + dummy_reset.observations, + self.obs_mode, + self.segments_per_arm, + )[0] # take first env self.obs_mean = jnp.zeros((len(sample_obs),)) self.obs_var = jnp.ones((len(sample_obs),)) self.obs_count = 1e-4 @@ -796,7 +826,11 @@ class PPOTrainer: self.logger.log_non_interactive(f"Initial reset started: {time.ctime()}") env_state = self.env.reset(seed=self.experiment.seed) - next_obs = _convert_obs_dict_to_array(env_state.observations) + next_obs = _convert_obs_dict_to_array( + env_state.observations, + self.obs_mode, + self.segments_per_arm, + ) next_done = jnp.zeros(self.ppo.num_envs, dtype=jnp.bool_) self.logger.log_non_interactive(f"Initial reset completed: {time.ctime()}") From bc3408b59a3ad9192697717ecc60afb6cdb8253c Mon Sep 17 00:00:00 2001 From: Cedric Date: Wed, 29 Apr 2026 08:14:13 +0000 Subject: [PATCH 21/96] feat: init agents array --- .../environment/env_config.py | 2 +- .../trainers/PPOTrainer.py | 132 +++++++----------- 2 files changed, 49 insertions(+), 85 deletions(-) diff --git a/src/brittle_star_project/environment/env_config.py b/src/brittle_star_project/environment/env_config.py index 8c2be31..6683e45 100644 --- a/src/brittle_star_project/environment/env_config.py +++ b/src/brittle_star_project/environment/env_config.py @@ -70,4 +70,4 @@ class EnvConfig: # Per docs in upstream env config: integer factors of 200. light_perlin_noise_scale: int = 0 - obs_mode: int = 0 # TODO: ???? + morph_mode: MorphMode = MorphMode.CENTRALIZED diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index d340b50..330b078 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -43,7 +43,7 @@ _ALLOWED_OBS_KEYS = { def build_adjacency(segments_per_arm, mode: MorphMode): - num_arms = len(segments_per_arm) + num_arms = sum(1 for s in segments_per_arm if s > 0) num_segments = sum(segments_per_arm) # FOR NOW SEMI HARDCODE: @@ -131,9 +131,8 @@ def _normalize_obs(obs, mean, var, eps=1e-8): @jax.jit def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm): - num_segments = sum(segments_per_arm) - num_arms = len(segments_per_arm) + num_arms = sum(1 for s in segments_per_arm if s > 0) def _filter_and_flatten(o): values = [] @@ -154,10 +153,12 @@ def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm # -------- SPLIT TO SEGMENTS -------- if key in _JOINT_SCALED_KEYS: if morph_mode == 3: + # special case: segment lvl and scale with joints, + # needs to split logic for center mlps and arms + # center: + # 3 joints per arm, each joint has 2 values B = v.shape[0] - - center_size = num_arms * 3 * 2 # 3 slots per arm, each slot has 2 values - + center_size = num_arms * 3 * 2 v_center = v[:, :center_size] v_center = v_center.reshape(B, num_arms, 3, 2) @@ -173,6 +174,7 @@ def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm v = v[..., None] # (env, segments, 1) else: + # global key, share with all if morph_mode == 3: # segment v = jnp.repeat(v[:, None, :], num_segments + num_arms, axis=1) @@ -197,7 +199,7 @@ def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm # Observation keys whose size scales with the number of joints (2 per segment). _JOINT_SCALED_KEYS = frozenset( - { + { # TODO CODE SMELL "joint_position", "joint_velocity", "joint_actuator_force", @@ -213,64 +215,6 @@ _SEGMENT_SCALED_KEYS = frozenset( ) -@jax.jit(static_argnums=(1,)) -def _convert_obs_dict_to_array(obs_dict, obs_mode, segments_per_arm): - - num_segments = sum(segments_per_arm) - num_arms = len(segments_per_arm) - - def _filter_and_flatten(o): - values = [] - - for key in sorted(o.keys()): - if key not in _ALLOWED_OBS_KEYS: - continue - - v = o[key] - if v.size == 0: - continue - - # -------- CENTRALIZED -------- - if obs_mode == 0: - values.append(v.reshape(v.shape[0], -1)) - continue - - # -------- SPLIT TO SEGMENTS -------- - if key in _JOINT_SCALED_KEYS: - v = v.reshape(v.shape[0], num_segments, 2) - - elif key in _SEGMENT_SCALED_KEYS: - v = v[..., None] # (env, segments, 1) - - else: - # global → broadcast - if obs_mode == 2: - v = jnp.repeat(v[:, None, :], num_segments, axis=1) - else: - v = jnp.repeat(v[:, None, :], num_arms, axis=1) - values.append(v) - continue - - # -------- SEGMENT MODE -------- - if obs_mode == 2: - values.append(v) - continue - - # -------- ARM MODE -------- - # reshape (segments → arms, seg_per_arm) - v = v.reshape(v.shape[0], num_arms, -1) - - values.append(v) - - # -------- CONCAT -------- - if obs_mode == 0: - return jnp.concatenate(values, axis=-1) - else: - return jnp.concatenate(values, axis=-1) - - return jax.vmap(_filter_and_flatten)(obs_dict) - - # TODO: update to work with extra dimension + message passing def _get_action_and_value_noise( sensor: GenericDenseLayersWithActivation, @@ -284,12 +228,12 @@ def _get_action_and_value_noise( action_high, adj_matrix: jnp.ndarray, ): - hidden = sensor.apply(agent_state.params["sensor_params"], next_obs) - hidden_critic = feature_extractor.apply( - agent_state.params["feature_extractor_params"], next_obs + hidden = apply_per_node(sensor, agent_state.params["sensor_params"], next_obs) + hidden_critic = apply_per_node( + feature_extractor, agent_state.params["feature_extractor_params"], next_obs ) - mean, log_std = actor.apply(agent_state.params["actor_params"], hidden) + mean, log_std = apply_per_node(actor, agent_state.params["actor_params"], hidden) log_std = jnp.clip(log_std, -5, 2) key, subkey = jax.random.split(key) noise = jax.random.normal(subkey, shape=mean.shape) @@ -367,7 +311,7 @@ def _reward_fn(env_state, next_env_state): # TODO: update to work with extra dimension + message passing -def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, obs_mode, segments_per_arm): +def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, morph_mode, segments_per_arm): next_env_state = env_step_fn(env_state, action) reward = _reward_fn(env_state, next_env_state) @@ -392,13 +336,20 @@ def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, obs_mode, s episode_stats, next_env_state, ( - _convert_obs_dict_to_array(next_env_state.observations, obs_mode, segments_per_arm), + _convert_obs_dict_to_array_morphology( + next_env_state.observations, morph_mode, segments_per_arm + ), reward, done, ), ) +def apply_per_node(net, params, x): + # x: (batch, nodes, feat) + return jax.vmap(lambda node_x: net.apply(params, node_x), in_axes=1, out_axes=1)(x) + + # TODO: update to work with extra dimension + message passing def _rollout_jit( agent_state, @@ -514,18 +465,16 @@ class PPOTrainer: self.key = jax.random.PRNGKey(self.experiment.seed) - morph = cfg.morphology.morph_mode + self.morph_mode = self.cfg.morphology.morph_mode - self.logger.info(f"[INIT]: Used morphology mode {morph}") - self.adj = build_adjacency(cfg.morphology.segments_per_arm, morph) + self.logger.info(f"[INIT]: Used morphology mode {self.morph_mode}") + self.adj = build_adjacency(cfg.morphology.segments_per_arm, self.morph_mode) self.sensor, self.feature_extractor, self.actor, self.critic = self._init_agent() self.sensor.apply = jax.jit(self.sensor.apply) self.feature_extractor.apply = jax.jit(self.feature_extractor.apply) self.actor.apply = jax.jit(self.actor.apply) self.critic.apply = jax.jit(self.critic.apply) - - self.obs_mode = self.cfg.environment.obs_mode self.segments_per_arm = jnp.asarray(self.cfg.morphology.segments_per_arm, dtype=jnp.int32) action_low = jnp.asarray(self.env.single_action_space.low, dtype=jnp.float32) @@ -538,7 +487,7 @@ class PPOTrainer: step_env_fn=partial( _step_env_wrapped, env_step_fn=self.env.step, - obs_mode=self.obs_mode, + morph_mode=self.morph_mode, segments_per_arm=self.segments_per_arm, ), sensor=self.sensor, @@ -578,12 +527,27 @@ class PPOTrainer: def _init_agent(self): self.logger.info("[AGENT]: Initializing agent...") + sensors = [] + actors = [] + message_passers = [] + needed_copies = 1 + if (self.morph_mode == MorphMode.FULLY_CONNECTED) or (self.morph_mode == MorphMode.RING): + needed_copies = sum(1 for s in self.segments_per_arm if s > 0) + else: + needed_copies = sum(self.segments_per_arm) + sum( + 1 for s in self.segments_per_arm if s > 0 + ) + + for _ in range(needed_copies): + actor = Actor(action_dim=self.env.single_action_space.shape[0]) + sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) + sensors.append(sensor) + actors.append(actor) + message_passers.append(OneDenseLayerMLP()) - sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) feature_extractor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) - actor = Actor(action_dim=self.env.single_action_space.shape[0]) critic = OneDenseLayerMLP() - return sensor, feature_extractor, actor, critic + return sensors, message_passers, actors, feature_extractor, critic def _init_agent_state(self) -> TrainState: self.logger.info("[AGENT STATE]: Initializing agent state...") @@ -595,9 +559,9 @@ class PPOTrainer: dummy_reset = self.env.reset(seed=0) for k, v in dummy_reset.observations.items(): self.logger.debug(k, v.shape) - sample_obs = _convert_obs_dict_to_array( + sample_obs = _convert_obs_dict_to_array_morphology( dummy_reset.observations, - self.obs_mode, + self.morph_mode, self.segments_per_arm, )[0] # take first env self.obs_mean = jnp.zeros((len(sample_obs),)) @@ -826,9 +790,9 @@ class PPOTrainer: self.logger.log_non_interactive(f"Initial reset started: {time.ctime()}") env_state = self.env.reset(seed=self.experiment.seed) - next_obs = _convert_obs_dict_to_array( + next_obs = _convert_obs_dict_to_array_morphology( env_state.observations, - self.obs_mode, + self.morph_mode, self.segments_per_arm, ) next_done = jnp.zeros(self.ppo.num_envs, dtype=jnp.bool_) From e85fc09ed698139bc1233b4b3f81a511c6bb7c70 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Wed, 29 Apr 2026 11:23:01 +0200 Subject: [PATCH 22/96] feat(PPOTrainer): vectorized init agent state, partially added message passer param to rollout, ... --- src/brittle_star_project/MLPs/mlps.py | 32 +++---- .../trainers/PPOTrainer.py | 87 ++++++++++++------- 2 files changed, 75 insertions(+), 44 deletions(-) diff --git a/src/brittle_star_project/MLPs/mlps.py b/src/brittle_star_project/MLPs/mlps.py index 5e2deb5..45a9359 100644 --- a/src/brittle_star_project/MLPs/mlps.py +++ b/src/brittle_star_project/MLPs/mlps.py @@ -6,6 +6,7 @@ import jax.numpy as jnp import jax.tree_util from typing import Sequence, Callable from flax.linen.initializers import constant, orthogonal +from flax.core import FrozenDict # semi generic so we can easily make a config for it in experiments @@ -40,27 +41,28 @@ class Actor(nn.Module): @jax.tree_util.register_dataclass @dataclass class AgentParams: - sensor_params: flax.core.FrozenDict - actor_params: flax.core.FrozenDict - critic_params: flax.core.FrozenDict - feature_extractor_params: flax.core.FrozenDict + sensor_params: FrozenDict | dict + actor_params: FrozenDict | dict + critic_params: FrozenDict | dict + feature_extractor_params: FrozenDict | dict + message_passer_params: FrozenDict | dict @jax.tree_util.register_dataclass @dataclass class Storage: - obs: jnp.array - actions: jnp.array - logprobs: jnp.array - dones: jnp.array - values: jnp.array - advantages: jnp.array - returns: jnp.array - rewards: jnp.array + obs: jnp.ndarray + actions: jnp.ndarray + logprobs: jnp.ndarray + dones: jnp.ndarray + values: jnp.ndarray + advantages: jnp.ndarray + returns: jnp.ndarray + rewards: jnp.ndarray - raw_actions: jnp.ndarray = None # before clipping - means: jnp.ndarray = None # policy mean - stds: jnp.ndarray = None # policy std + raw_actions: jnp.ndarray | None = None # before clipping + means: jnp.ndarray | None = None # policy mean + stds: jnp.ndarray | None = None # policy std def replace(self, **kwargs) -> "Storage": fs = fields(self) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 330b078..319712d 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -9,6 +9,7 @@ import jax import jax.numpy as jnp import numpy as np import optax +import flax.linen as nn from flax.training.train_state import TrainState from experiment_logger import get_logger @@ -217,10 +218,10 @@ _SEGMENT_SCALED_KEYS = frozenset( # TODO: update to work with extra dimension + message passing def _get_action_and_value_noise( - sensor: GenericDenseLayersWithActivation, - feature_extractor: GenericDenseLayersWithActivation, - actor: Actor, - critic: OneDenseLayerMLP, + sensor: nn.Module, + feature_extractor: nn.Module, + actor: nn.Module, + critic: nn.Module, agent_state: TrainState, next_obs: jnp.ndarray, key: jax.random.PRNGKey, @@ -252,10 +253,11 @@ def _step_once( _, env_step_fn, adj_matrix, - sensor: GenericDenseLayersWithActivation, - feature_extractor: GenericDenseLayersWithActivation, - actor: Actor, - critic: OneDenseLayerMLP, + sensor: nn.Module, + feature_extractor: nn.Module, + actor: nn.Module, + critic: nn.Module, + message_passer: nn.Module, action_low, action_high, ): @@ -361,10 +363,11 @@ def _rollout_jit( key, max_steps, step_env_fn, - sensor: GenericDenseLayersWithActivation, - feature_extractor: GenericDenseLayersWithActivation, - actor: Actor, - critic: OneDenseLayerMLP, + sensor: nn.Module, + feature_extractor: nn.Module, + actor: nn.Module, + critic: nn.Module, + message_passer: nn.Module, action_low, action_high, ): @@ -375,6 +378,7 @@ def _rollout_jit( feature_extractor=feature_extractor, actor=actor, critic=critic, + message_passer=message_passer, env_step_fn=step_env_fn, action_low=action_low, action_high=action_high, @@ -470,7 +474,15 @@ class PPOTrainer: self.logger.info(f"[INIT]: Used morphology mode {self.morph_mode}") self.adj = build_adjacency(cfg.morphology.segments_per_arm, self.morph_mode) - self.sensor, self.feature_extractor, self.actor, self.critic = self._init_agent() + ( + self.sensor, + self.message_passer, + self.actor, + self.feature_extractor, + self.critic, + self.needed_copies, + ) = self._init_agent() + self.sensor.apply = jax.jit(self.sensor.apply) self.feature_extractor.apply = jax.jit(self.feature_extractor.apply) self.actor.apply = jax.jit(self.actor.apply) @@ -494,6 +506,7 @@ class PPOTrainer: feature_extractor=self.feature_extractor, actor=self.actor, critic=self.critic, + message_passer=self.message_passer, action_low=action_low, action_high=action_high, adj_matrix=self.adj, @@ -527,10 +540,7 @@ class PPOTrainer: def _init_agent(self): self.logger.info("[AGENT]: Initializing agent...") - sensors = [] - actors = [] - message_passers = [] - needed_copies = 1 + if (self.morph_mode == MorphMode.FULLY_CONNECTED) or (self.morph_mode == MorphMode.RING): needed_copies = sum(1 for s in self.segments_per_arm if s > 0) else: @@ -538,22 +548,19 @@ class PPOTrainer: 1 for s in self.segments_per_arm if s > 0 ) - for _ in range(needed_copies): - actor = Actor(action_dim=self.env.single_action_space.shape[0]) - sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) - sensors.append(sensor) - actors.append(actor) - message_passers.append(OneDenseLayerMLP()) + actor = Actor(action_dim=self.env.single_action_space.shape[0]) + sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) + message_passer = OneDenseLayerMLP() feature_extractor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) critic = OneDenseLayerMLP() - return sensors, message_passers, actors, feature_extractor, critic + return sensor, message_passer, actor, feature_extractor, critic, needed_copies def _init_agent_state(self) -> TrainState: self.logger.info("[AGENT STATE]: Initializing agent state...") - self.key, sensor_key, actor_key, critic_key, feature_extractor_key = jax.random.split( - self.key, 5 + self.key, sensor_key, actor_key, critic_key, feature_extractor_key, message_passer_key = ( + jax.random.split(self.key, 6) ) dummy_reset = self.env.reset(seed=0) @@ -564,12 +571,28 @@ class PPOTrainer: self.morph_mode, self.segments_per_arm, )[0] # take first env + self.obs_mean = jnp.zeros((len(sample_obs),)) self.obs_var = jnp.ones((len(sample_obs),)) self.obs_count = 1e-4 - sensor_params = self.sensor.init(sensor_key, sample_obs) + + sensor_keys = jax.random.split(sensor_key, self.needed_copies) + actor_keys = jax.random.split(actor_key, self.needed_copies) + message_passer_keys = jax.random.split(message_passer_key, self.needed_copies) + + sensor_params = jax.vmap(lambda k: self.sensor.init(k, sample_obs))(sensor_keys) + + single_sensor_param = jax.tree.map(lambda x: x[0], sensor_params) + sensor_params_sample = self.sensor.apply(single_sensor_param, sample_obs) + actor_params = jax.vmap(lambda k: self.actor.init(k, sensor_params_sample))(actor_keys) + + message_passer_params = jax.vmap( + lambda k: self.message_passer.init( + k, self.sensor.apply(single_sensor_param, sample_obs) + ) + )(message_passer_keys) + feature_extractor_params = self.feature_extractor.init(feature_extractor_key, sample_obs) - actor_params = self.actor.init(actor_key, self.sensor.apply(sensor_params, sample_obs)) critic_params = self.critic.init( critic_key, self.feature_extractor.apply(feature_extractor_params, sample_obs) ) @@ -577,7 +600,13 @@ class PPOTrainer: return TrainState.create( apply_fn=None, params=asdict( - AgentParams(sensor_params, actor_params, critic_params, feature_extractor_params) + AgentParams( + sensor_params, + actor_params, + critic_params, + feature_extractor_params, + message_passer_params, + ) ), tx=optax.chain( optax.clip_by_global_norm(self.ppo.max_grad_norm), From f8eb43004fb4b7c662b4e4a0b8130392938620e2 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Thu, 30 Apr 2026 15:58:46 +0200 Subject: [PATCH 23/96] other: backup, finding bug in conversion from dict to array --- .../trainers/PPOTrainer.py | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 319712d..e6d1737 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -130,12 +130,12 @@ def _normalize_obs(obs, mean, var, eps=1e-8): return jnp.clip((obs - mean) / jnp.sqrt(var + eps), -10.0, 10.0) -@jax.jit -def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm): - num_segments = sum(segments_per_arm) - num_arms = sum(1 for s in segments_per_arm if s > 0) +def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm: jnp.ndarray): + num_segments = segments_per_arm.sum() + num_arms = jnp.where(segments_per_arm > 0, 1, 0).sum() - def _filter_and_flatten(o): + @jax.jit + def _filter_and_flatten(o) -> jnp.ndarray: values = [] for key in sorted(o.keys()): @@ -147,13 +147,13 @@ def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm continue # -------- CENTRALIZED -------- - if morph_mode == 0: + if morph_mode == MorphMode.CENTRALIZED: values.append(v.reshape(v.shape[0], -1)) continue # -------- SPLIT TO SEGMENTS -------- if key in _JOINT_SCALED_KEYS: - if morph_mode == 3: + if morph_mode == MorphMode.SEGMENT: # special case: segment lvl and scale with joints, # needs to split logic for center mlps and arms # center: @@ -185,7 +185,7 @@ def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm continue # -------- SEGMENT MODE -------- - if morph_mode == 3: + if morph_mode == MorphMode.SEGMENT: values.append(v) continue @@ -193,7 +193,7 @@ def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm v = v.reshape(v.shape[0], num_arms, -1) values.append(v) - return jnp.concatenate(values, axis=-1) + return jnp.concatenate(values, axis=0) return jax.vmap(_filter_and_flatten)(obs_dict) @@ -247,7 +247,7 @@ def _get_action_and_value_noise( return clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key -# TODO: update to work with extra dimension + message passing +# TODO: update to work vectorized (sensor, actor, message passer) + message passing def _step_once( carry, _, @@ -349,7 +349,7 @@ def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, morph_mode, def apply_per_node(net, params, x): # x: (batch, nodes, feat) - return jax.vmap(lambda node_x: net.apply(params, node_x), in_axes=1, out_axes=1)(x) + return jax.vmap(net.apply, in_axes=(0, 1), out_axes=1)(params, x) # TODO: update to work with extra dimension + message passing @@ -359,7 +359,6 @@ def _rollout_jit( env_state, next_obs, next_done, - adj_matrix, key, max_steps, step_env_fn, @@ -370,6 +369,7 @@ def _rollout_jit( message_passer: nn.Module, action_low, action_high, + adj_matrix, ): (agent_state, episode_stats, next_obs, next_done, key, env_state), storage = jax.lax.scan( partial( @@ -470,6 +470,7 @@ class PPOTrainer: self.key = jax.random.PRNGKey(self.experiment.seed) self.morph_mode = self.cfg.morphology.morph_mode + self.segments_per_arm = jnp.asarray(self.cfg.morphology.segments_per_arm, dtype=jnp.int32) self.logger.info(f"[INIT]: Used morphology mode {self.morph_mode}") self.adj = build_adjacency(cfg.morphology.segments_per_arm, self.morph_mode) @@ -487,7 +488,6 @@ class PPOTrainer: self.feature_extractor.apply = jax.jit(self.feature_extractor.apply) self.actor.apply = jax.jit(self.actor.apply) self.critic.apply = jax.jit(self.critic.apply) - self.segments_per_arm = jnp.asarray(self.cfg.morphology.segments_per_arm, dtype=jnp.int32) action_low = jnp.asarray(self.env.single_action_space.low, dtype=jnp.float32) action_high = jnp.asarray(self.env.single_action_space.high, dtype=jnp.float32) From 1530e7d21033c4afb524b925db8da1a3c91d51ba Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Thu, 30 Apr 2026 19:32:20 +0200 Subject: [PATCH 24/96] good luck cedric :saluting_face: --- .../trainers/PPOTrainer.py | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index e6d1737..e027a6a 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -136,66 +136,53 @@ def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm @jax.jit def _filter_and_flatten(o) -> jnp.ndarray: + # vmap feeds one env at a time — v has NO batch dim here + # shapes are e.g. (n_features,) or (n_nodes, feat) values = [] for key in sorted(o.keys()): if key not in _ALLOWED_OBS_KEYS: continue - v = o[key] if v.size == 0: continue # -------- CENTRALIZED -------- if morph_mode == MorphMode.CENTRALIZED: - values.append(v.reshape(v.shape[0], -1)) + values.append(v.reshape(1, -1)) # (1, feat) continue # -------- SPLIT TO SEGMENTS -------- if key in _JOINT_SCALED_KEYS: if morph_mode == MorphMode.SEGMENT: - # special case: segment lvl and scale with joints, - # needs to split logic for center mlps and arms - # center: - # 3 joints per arm, each joint has 2 values - B = v.shape[0] center_size = num_arms * 3 * 2 - v_center = v[:, :center_size] - v_center = v_center.reshape(B, num_arms, 3, 2) - - v_segs = v[:, center_size:] - v_segs = v_segs.reshape(B, -1, 2) - - v = jnp.concatenate([v_center.reshape(B, -1, 2), v_segs], axis=1) - values.append(v) + v_center = v[:center_size].reshape(num_arms, 3 * 2) # (arms, 6) + v_segs = v[center_size:].reshape(-1, 2) # (segs, 2) + values.append(jnp.concatenate([v_center, v_segs], axis=0)) # (arms+segs, ?) continue - v = v.reshape(v.shape[0], num_segments, 2) + v = v.reshape(num_arms, -1) # (n_arms, 2) elif key in _SEGMENT_SCALED_KEYS: - v = v[..., None] # (env, segments, 1) + v = v[:, None] # (segments, 1) else: - # global key, share with all - if morph_mode == 3: # segment - v = jnp.repeat(v[:, None, :], num_segments + num_arms, axis=1) - - else: # ring or fully connect - v = jnp.repeat(v[:, None, :], num_arms, axis=1) - values.append(v) - continue + # global key, broadcast to all nodes + n_nodes = (num_segments + num_arms) if morph_mode == MorphMode.SEGMENT else num_arms + v = jnp.repeat(v[None, :], n_nodes, axis=0) # (n_nodes, feat) # -------- SEGMENT MODE -------- if morph_mode == MorphMode.SEGMENT: - values.append(v) + values.append(v) # (n_nodes, feat) continue # -------- ARM MODE -------- - v = v.reshape(v.shape[0], num_arms, -1) - values.append(v) + v = v.reshape(num_arms, -1) + values.append(v) # (n_arms, feat) - return jnp.concatenate(values, axis=0) + return jnp.concatenate(values, axis=-1) # (n_nodes, total_feat) return jax.vmap(_filter_and_flatten)(obs_dict) + # output: (batch, n_nodes, total_feat) # Observation keys whose size scales with the number of joints (2 per segment). @@ -541,12 +528,15 @@ class PPOTrainer: def _init_agent(self): self.logger.info("[AGENT]: Initializing agent...") - if (self.morph_mode == MorphMode.FULLY_CONNECTED) or (self.morph_mode == MorphMode.RING): - needed_copies = sum(1 for s in self.segments_per_arm if s > 0) - else: - needed_copies = sum(self.segments_per_arm) + sum( - 1 for s in self.segments_per_arm if s > 0 - ) + match self.morph_mode: + case MorphMode.CENTRALIZED: + needed_copies = 1 + case MorphMode.FULLY_CONNECTED | MorphMode.RING: + needed_copies = jnp.where(self.segments_per_arm > 0, 1, 0).sum() + case MorphMode.SEGMENT: + needed_copies = ( + self.segments_per_arm.sum() + jnp.where(self.segments_per_arm > 0, 1, 0).sum() + ) actor = Actor(action_dim=self.env.single_action_space.shape[0]) sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) @@ -580,6 +570,7 @@ class PPOTrainer: actor_keys = jax.random.split(actor_key, self.needed_copies) message_passer_keys = jax.random.split(message_passer_key, self.needed_copies) + # (needed_copies, 175) sensor_params = jax.vmap(lambda k: self.sensor.init(k, sample_obs))(sensor_keys) single_sensor_param = jax.tree.map(lambda x: x[0], sensor_params) From be78fb15bd6e111a2f2d7ef91bac122aa06e0647 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 30 Apr 2026 20:19:42 +0200 Subject: [PATCH 25/96] feat: allow model metadata cli override --- configs/simulation/default.yaml | 4 ++ scripts/simulate.py | 6 ++- .../configs/config_simulation.py | 4 ++ .../evaluation/checkpoint.py | 12 +++--- tests/test_evaluation.py | 39 ++++++++++++++++++- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/configs/simulation/default.yaml b/configs/simulation/default.yaml index e689c3b..61599a4 100644 --- a/configs/simulation/default.yaml +++ b/configs/simulation/default.yaml @@ -20,3 +20,7 @@ record_video: false video_output_path: null # Camera ID to use for video recording (1 is usually the close-up camera) camera_id: 1 + +# Optional override for the metadata YAML file path. +# If null, the script looks for `_metadata.yaml` alongside the model_path. +metadata_path: null diff --git a/scripts/simulate.py b/scripts/simulate.py index f17d8ef..a2b121e 100644 --- a/scripts/simulate.py +++ b/scripts/simulate.py @@ -51,7 +51,11 @@ def main(dict_cfg: DictConfig) -> None: raise ValueError(f"Expected a '.flax' checkpoint, got '{model_path.name}'.") # 2. Discover + load sidecar metadata YAML - metadata = load_metadata(model_path) + metadata_override = None + if sim_cfg.metadata_path is not None: + metadata_override = Path(hydra.utils.to_absolute_path(sim_cfg.metadata_path)) + + metadata = load_metadata(model_path, metadata_override) # 3. Reconstruct typed configs from metadata training = metadata_to_configs(metadata) diff --git a/src/brittle_star_project/configs/config_simulation.py b/src/brittle_star_project/configs/config_simulation.py index e15d94e..9fd1507 100644 --- a/src/brittle_star_project/configs/config_simulation.py +++ b/src/brittle_star_project/configs/config_simulation.py @@ -26,3 +26,7 @@ class SimulationSettings: video_output_path: Optional[str] = None # Camera ID to use for video recording (1 is usually the close-up camera) camera_id: int = 1 + + # Optional override for the sidecar metadata YAML file. + # If None, it defaults to the model_path with a `_metadata.yaml` suffix. + metadata_path: Optional[str] = None diff --git a/src/brittle_star_project/evaluation/checkpoint.py b/src/brittle_star_project/evaluation/checkpoint.py index ffbc27a..d10046b 100644 --- a/src/brittle_star_project/evaluation/checkpoint.py +++ b/src/brittle_star_project/evaluation/checkpoint.py @@ -56,13 +56,15 @@ def load_params(path: Path) -> dict: } -def load_metadata(model_path: Path) -> dict: +def load_metadata(model_path: Path, metadata_override_path: Path | None = None) -> dict: """Discover and load the sidecar metadata YAML file.""" - metadata_path = model_path.with_name(model_path.stem + "_metadata.yaml") + if metadata_override_path is not None: + metadata_path = metadata_override_path + else: + metadata_path = model_path.with_name(model_path.stem + "_metadata.yaml") + if not metadata_path.exists(): - raise FileNotFoundError( - f"Could not find metadata YAML for {model_path.name}. Expected it at {metadata_path}" - ) + raise FileNotFoundError(f"Could not find metadata YAML at {metadata_path}") with open(metadata_path, "r") as f: return yaml.safe_load(f) diff --git a/tests/test_evaluation.py b/tests/test_evaluation.py index c8bffa9..bbb03f8 100644 --- a/tests/test_evaluation.py +++ b/tests/test_evaluation.py @@ -1,6 +1,13 @@ import numpy as np +import pytest +import yaml +from pathlib import Path -from brittle_star_project.evaluation.checkpoint import metadata_to_configs, TrainingConfig +from brittle_star_project.evaluation.checkpoint import ( + metadata_to_configs, + TrainingConfig, + load_metadata, +) from brittle_star_project.evaluation.rollout import _maybe_clip_action from brittle_star_project.environment.env_config import ( MorphologyConfig, @@ -75,3 +82,33 @@ def test_maybe_clip_action(): wrong_low = np.array([-1.0, -1.0]) # Shape mismatch unclipped_3 = _maybe_clip_action(action, wrong_low, high) np.testing.assert_array_equal(unclipped_3, action) + + +def test_load_metadata_with_override(tmp_path: Path): + """Test that metadata can be loaded from both default and override paths.""" + # 1. Setup + model_path = tmp_path / "model.flax" + model_path.write_bytes(b"dummy") + + default_metadata_path = tmp_path / "model_metadata.yaml" + default_content = {"version": "default", "seed": 42} + with open(default_metadata_path, "w") as f: + yaml.dump(default_content, f) + + override_path = tmp_path / "custom_metadata.yaml" + override_content = {"version": "override", "seed": 1337} + with open(override_path, "w") as f: + yaml.dump(override_content, f) + + # 2. Test default behavior + loaded_default = load_metadata(model_path) + assert loaded_default == default_content + + # 3. Test override behavior + loaded_override = load_metadata(model_path, metadata_override_path=override_path) + assert loaded_override == override_content + + # 4. Test Error Case + non_existent = tmp_path / "missing.yaml" + with pytest.raises(FileNotFoundError, match="Could not find metadata YAML at"): + load_metadata(model_path, metadata_override_path=non_existent) From 86a53ee9f7b2ecea8122451ba96cda0d27c367c9 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 30 Apr 2026 21:10:17 +0200 Subject: [PATCH 26/96] fix: robot direction to target --- docs/design/input_action_spaces.md | 28 +++---- .../environment/env_config.py | 10 +-- .../environment/obs_processing.py | 11 ++- tests/test_target_direction.py | 78 +++++++++++++++++++ 4 files changed, 107 insertions(+), 20 deletions(-) create mode 100644 tests/test_target_direction.py diff --git a/docs/design/input_action_spaces.md b/docs/design/input_action_spaces.md index 50f142e..ddb7a55 100644 --- a/docs/design/input_action_spaces.md +++ b/docs/design/input_action_spaces.md @@ -16,7 +16,8 @@ Global inputs, always broadcasted to all nodes: $$ tilt = sqrt(roll^2 + pitch^2) $$ -- Goal vector: Instead of just a scalar distance, the goal is represented as an angle/direction to the target. +- Goal vector: A 2D unit vector representing the *egocentric* direction to the target. A value of $[1.0, 0.0]$ + indicates that the target is directly in front of the agent (angle 0). Local inputs, routed directly to specific nodes: @@ -73,20 +74,21 @@ When designing the state space, we must ask: *Could a human operator perform thi **NOTE:** We later dropped the "distance to vector", switching to only a direction as the input. Our reasoning is the agent should always move towards the goal (it should not learn to stop at the goal), which allows for this simplification that decreases the model input size. + + The environment provides a raw `unit_xy_direction_to_target` (global), which we transform into a calculated + `robot_direction_to_target` (egocentric) before passing it to the MLPs. This vector consists of the X and Y + direction, where a value of $[1.0, 0.0]$ (mapping to an angle of $0$) means the robot is facing directly towards the + target. - Contact sensors: Segment contact detects external ground interaction and is biologically vital for timing gait transitions. -- **Zero-Centered Rescaling ($[-1, 1]$):** Using a zero-centered range is standard best practice for continuous control +- Zero-Centered Rescaling ($[-1, 1]$): Using a zero-centered range is standard best practice for continuous control tasks. It provides several mathematical and physical advantages: - - **Improved Gradient Flow:** Neural networks optimize faster when inputs are zero-centered. If all inputs were - positive (e.g., $[0, 1]$), the gradients during backpropagation would be forced to the same sign, causing - inefficient "zig-zag" weight updates. - - **Meaningful "Neutral" State:** In robotics, $0.0$ naturally represents a resting state (zero velocity, centered + - Improved Gradient Flow: Neural networks optimize faster when inputs are zero-centered. If all inputs were positive + (e.g., $[0, 1]$), the gradients during backpropagation would be forced to the same sign, causing inefficient + "zig-zag" weight updates. + - Meaningful Neutral State: In robotics, $0.0$ naturally represents a resting state (zero velocity, centered position, no force). In a $[-1, 1]$ system, this physical rest maps to a neutral $0.0$ signal in the network. - - **Robustness to Amputation:** In this project, amputated limbs are padded with $0.0$. In a $[-1, 1]$ system, this - correctly communicates a "neutral/dead" signal. In a $[0, 1]$ system, $0.0$ would represent the absolute minimum - physical limit, causing the network to misinterpret missing limbs as being at their extreme limits. - - + This also correctly communicaties a "neutral/dead" signal for amputated limbs that are padded with $0.0$ values. Specifically, we do not include some available inputs: @@ -120,8 +122,7 @@ This is what the filtered input vectors look like in MuJoCo, with $J$ joints and - `joint_velocity`: shape=(J,), dtype=float64 - `joint_actuator_force`: shape=(J,), dtype=float64 - `segment_contact`: shape=(S,), dtype=float64 -- `unit_xy_direction_to_target`: shape=(2,), dtype=float64 -- `xy_distance_to_target`: shape=(1,), dtype=float64 +- `robot_direction_to_target`: shape=(2,), dtype=float64, egocentric - `disk_z_tilt`: shape=(1,), dtype=float64, derived from `disk_rotation` This brings the entire input space down to $3J + S + 4$ float64's, compared to $4J + S + 15$ float64's for the @@ -159,6 +160,5 @@ disk_angular_velocity: shape=(3,), dtype=float64, size=3 tendon_position: shape=(0,), dtype=float64, size=0 tendon_velocity: shape=(0,), dtype=float64, size=0 segment_contact: shape=(6,), dtype=float64, size=6 -unit_xy_direction_to_target: shape=(2,), dtype=float64, size=2 xy_distance_to_target: shape=(1,), dtype=float64, size=1 ``` diff --git a/src/brittle_star_project/environment/env_config.py b/src/brittle_star_project/environment/env_config.py index f26b428..22b8967 100644 --- a/src/brittle_star_project/environment/env_config.py +++ b/src/brittle_star_project/environment/env_config.py @@ -70,21 +70,21 @@ class ObservationBoundsConfig: # Based on max. ctrlrange (0.78539816339744828) in XML, but empirical testing went slightly over joint_position: list[float] = field(default_factory=lambda: [-0.8, 0.8]) - # Empirical testing showed max. 3.22, adding buffer to be safe + # Empirical testing showed max. 3.22, adding buffer to be safe. Consider higher values "fast". joint_velocity: list[float] = field(default_factory=lambda: [-5.0, 5.0]) # Based on max. forceRange in XML, verified with empirical testing joint_actuator_force: list[float] = field(default_factory=lambda: [-3.75, 3.75]) # Based on intuition and reasoning segment_contact: list[float] = field(default_factory=lambda: [0.0, 1.0]) - unit_xy_direction_to_target: list[float] = field(default_factory=lambda: [-1.0, 1.0]) + robot_direction_to_target: list[float] = field(default_factory=lambda: [-1.0, 1.0]) disk_z_tilt: list[float] = field(default_factory=lambda: [0.0, 3.141592653589793]) def to_bounds_dict(self) -> dict[str, tuple[float, float]]: return { + "disk_z_tilt": tuple(self.disk_z_tilt), + "joint_actuator_force": tuple(self.joint_actuator_force), "joint_position": tuple(self.joint_position), "joint_velocity": tuple(self.joint_velocity), - "joint_actuator_force": tuple(self.joint_actuator_force), + "robot_direction_to_target": tuple(self.robot_direction_to_target), "segment_contact": tuple(self.segment_contact), - "unit_xy_direction_to_target": tuple(self.unit_xy_direction_to_target), - "disk_z_tilt": tuple(self.disk_z_tilt), } diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 37a775f..b18ee8c 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -26,6 +26,15 @@ def create_obs_processor( if "disk_rotation" in new_obs: rot = new_obs["disk_rotation"] new_obs["disk_z_tilt"] = jnp.sqrt(jnp.pow(rot[0], 2) + jnp.pow(rot[1], 2)) + + if "unit_xy_direction_to_target" in new_obs: + yaw = rot[2] + unit_x, unit_y = new_obs["unit_xy_direction_to_target"] + cos_yaw, sin_yaw = jnp.cos(yaw), jnp.sin(yaw) + new_x = unit_x * cos_yaw + unit_y * sin_yaw + new_y = -unit_x * sin_yaw + unit_y * cos_yaw + new_obs["robot_direction_to_target"] = jnp.stack([new_x, new_y]) + return new_obs def _normalize_features(obs: dict) -> dict: @@ -61,8 +70,8 @@ def create_obs_processor( "joint_actuator_force", "joint_position", "joint_velocity", + "robot_direction_to_target", "segment_contact", - "unit_xy_direction_to_target", ] values = [] for key in ordered_keys: diff --git a/tests/test_target_direction.py b/tests/test_target_direction.py new file mode 100644 index 0000000..a81cdf1 --- /dev/null +++ b/tests/test_target_direction.py @@ -0,0 +1,78 @@ +import jax.numpy as jnp + +from brittle_star_project.configs.main_config import BrittleStarConfig +from brittle_star_project.environment.env_types import Backend +from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleStarJaxEnvWrapper +from brittle_star_project.environment.obs_processing import create_obs_processor + + +def test_raw_environment_returns_allocentric_direction(): + """ + Verifies that the raw environment returns a GLOBAL (allocentric) + direction to the target. If the robot rotates in place, + the global vector to the target should remain identical. + """ + env = BrittleStarJaxEnvWrapper.default(num_envs=1, backend=Backend.MJX) + env_state = env.reset(seed=42) + raw_obs_1 = env_state.observations["unit_xy_direction_to_target"] + + ninety_deg_z_quat = jnp.array([0.7071068, 0.0, 0.0, 0.7071068]) + new_qpos = env_state.mjx_data.qpos.at[..., 3:7].set(ninety_deg_z_quat) + new_data = env_state.mjx_data.replace(qpos=new_qpos) + rotated_env_state = env_state.replace(mjx_data=new_data) + + zero_action = jnp.zeros(env.single_action_space.shape) + if len(raw_obs_1.shape) > 1: + zero_action = jnp.expand_dims(zero_action, 0) + final_env_state = env.step(rotated_env_state, zero_action) + raw_obs_2 = final_env_state.observations["unit_xy_direction_to_target"] + + # If the vector is allocentric, it should not change when the robot spins. + assert jnp.sum(jnp.abs(raw_obs_1 - raw_obs_2)) < 1e-4, ( + f"The raw environment observation changed when the robot rotated! " + f"This means it is already egocentric. " + f"Obs 1: {raw_obs_1}, Obs 2: {raw_obs_2}" + ) + + +def test_processor_converts_to_egocentric_direction(): + """ + Verifies that the obs_processor correctly applies a 2D inverse rotation + matrix to convert the global target vector into a local (egocentric) vector. + """ + cfg = BrittleStarConfig() + env = BrittleStarJaxEnvWrapper.default(num_envs=1, backend=Backend.MJX) + + obs_processor = create_obs_processor( + bounds_dict=cfg.obs_bounds.to_bounds_dict(), padding_masks=env.padding_masks + ) + + env_state = env.reset(seed=42) + + # --- Scenario 1 --- + # Robot is rotated 90 degrees Left (facing global Y) + # Target is straight ahead on the global X axis [1.0, 0.0] + # Because the robot is facing Y, the target on X is to its RIGHT [0.0, -1.0] locally. + dummy_obs_1 = dict(env_state.observations) + dummy_obs_1["disk_rotation"] = jnp.array([[0.0, 0.0, jnp.pi / 2.0]]) + dummy_obs_1["unit_xy_direction_to_target"] = jnp.array([[1.0, 0.0]]) + processed_1 = obs_processor(dummy_obs_1) + + # --- Scenario 2 (used to find the array indices) --- + # We change ONLY the target vector so we can isolate it in the final array + dummy_obs_2 = dict(env_state.observations) + dummy_obs_2["disk_rotation"] = jnp.array([[0.0, 0.0, jnp.pi / 2.0]]) + dummy_obs_2["unit_xy_direction_to_target"] = jnp.array([[0.0, 1.0]]) + processed_2 = obs_processor(dummy_obs_2) + + # Find the indices of the elements that changed + diff_array = jnp.abs(processed_1[0] - processed_2[0]) + changed_indices = jnp.where(diff_array > 1e-4)[0] + + local_target = processed_1[0, changed_indices] + expected_local_target = jnp.array([0.0, -1.0]) + + assert jnp.sum(jnp.abs(local_target - expected_local_target)) < 1e-4, ( + f"The obs_processor did not correctly rotate the vector to egocentric. " + f"Expected {expected_local_target}, but got {local_target}." + ) From 304a8e9c4336224e5b50d15b61967524ba525ce7 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 30 Apr 2026 22:18:07 +0200 Subject: [PATCH 27/96] refactor: clean tools --- scripts/analysis/dump_mjcf.py | 186 ------------------ scripts/tools/dump_mjcf.py | 141 +++++++++++++ .../{ => tools}/extract_observation_bounds.py | 0 3 files changed, 141 insertions(+), 186 deletions(-) delete mode 100644 scripts/analysis/dump_mjcf.py create mode 100644 scripts/tools/dump_mjcf.py rename scripts/{ => tools}/extract_observation_bounds.py (100%) diff --git a/scripts/analysis/dump_mjcf.py b/scripts/analysis/dump_mjcf.py deleted file mode 100644 index 1f552d9..0000000 --- a/scripts/analysis/dump_mjcf.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python3 -""" -Dump MJCF XML for a brittle-star morphology using the project's Hydra configs. - -Usage examples: - - # Use a named morphology config from configs/morphology (Hydra style) - uv run python scripts/analysis/dump_mjcf.py morphology=3_arms - - # Use a morphology override YAML (same key as simulation.morphology_override) - uv run python scripts/analysis/dump_mjcf.py \ - simulation.morphology_override=configs/morphology/3_arms.yaml - -Output path: - Provide `dump_out=path/to/file.xml` on the command line, otherwise writes `morphology.xml` in - current directory. -""" - -from __future__ import annotations - -from pathlib import Path -import sys -import xml.etree.ElementTree as ET - -import hydra -from omegaconf import DictConfig, OmegaConf - -from brittle_star_project.configs.main_config import BrittleStarConfig -from brittle_star_project.configs.register_configs import register_configs -from brittle_star_project.environment.env_config import MorphologyConfig -from brittle_star_project.environment.factory import BrittleStarEnvFactory - - -def try_serialize(obj): - """Try multiple common accessors to obtain an XML string from the morphology object.""" - candidates = [ - "to_xml_string", - "to_xml", - "to_string", - "to_mjcf", - "to_mjcf_string", - "get_mjcf", - "get_mjcf_str", - "get_mjcf_assets", - "export_to_xml_with_assets", - "get_xml", - "xml", - "mjcf", - "mjcf_model", - "mjcf_body", - "model", - "root", - ] - - def normalize(out): - if out is None: - return None - # lxml element - try: - import lxml.etree as lxml_et - - if isinstance(out, lxml_et._Element): - return lxml_et.tostring(out, encoding="unicode") - except Exception: - pass - - if isinstance(out, ET.Element): - return ET.tostring(out, encoding="unicode") - - if isinstance(out, bytes): - try: - return out.decode() - except Exception: - return None - - if hasattr(out, "toxml") and callable(out.toxml): - try: - return out.toxml() - except Exception: - pass - - try: - s = str(out) - if s.lstrip().startswith("<"): - return s - return s - except Exception: - return None - - for name in candidates: - attr = getattr(obj, name, None) - if callable(attr): - try: - out = attr() - except Exception: - out = None - if out: - norm = normalize(out) - if norm: - return norm - elif attr is not None: - norm = normalize(attr) - if norm: - return norm - - if hasattr(obj, "mjcf"): - nested = getattr(obj, "mjcf") - if nested is not None: - return try_serialize(nested) - - return None - - -@hydra.main(config_path="../../configs", config_name="main_config", version_base="1.3") -def main(dict_cfg: DictConfig) -> None: - # Compose typed config like the rest of the project - cfg = OmegaConf.to_object(OmegaConf.merge(OmegaConf.structured(BrittleStarConfig), dict_cfg)) - - # Check for a simulation morphology override (points to a YAML file) - sim_override = None - try: - sim_override = dict_cfg.get("simulation", {}).get("morphology_override", None) - except Exception: - sim_override = getattr(getattr(cfg, "simulation", None), "morphology_override", None) - - if sim_override: - override_path = Path(hydra.utils.to_absolute_path(sim_override)) - if not override_path.exists(): - raise FileNotFoundError(f"Could not find morphology override YAML at {override_path}") - import yaml - - with open(override_path, "r") as f: - override_dict = yaml.safe_load(f) - env_morphology = OmegaConf.to_object( - OmegaConf.merge(OmegaConf.structured(MorphologyConfig), override_dict) - ) - else: - env_morphology = cfg.morphology - - # Ensure we have a MorphologyConfig instance - if isinstance(env_morphology, dict): - morph_cfg = MorphologyConfig(**env_morphology) - else: - morph_cfg = env_morphology - - # Build morphology via project factory (same as runtime) - morph = BrittleStarEnvFactory.create_morphology(morph_cfg) - - xml_text = try_serialize(morph) - if xml_text is None and hasattr(morph, "mjcf"): - xml_text = try_serialize(morph.mjcf) - - if xml_text is None: - raise RuntimeError( - "Failed to serialize morphology to MJCF/XML. Inspect the `morph` object interactively." - ) - - # Prefer explicit CLI override `dump_out=...` if provided, otherwise choose a sensible default. - dump_out = None - try: - dump_out = dict_cfg.get("dump_out", None) - except Exception: - dump_out = None - - if dump_out is None: - # If the user passed a morphology group on the CLI (e.g. morphology=3_arms), - # use a descriptive default path under `runs/morphologies/`. - morph_name = None - for a in sys.argv[1:]: - if a.startswith("morphology="): - morph_name = a.split("=", 1)[1] - break - - default_out = f"runs/morphologies/{morph_name}.xml" if morph_name else "morphology.xml" - out_path = Path(hydra.utils.to_absolute_path(default_out)) - else: - out_path = Path(hydra.utils.to_absolute_path(str(dump_out))) - - out_path.parent.mkdir(parents=True, exist_ok=True) - out_path.write_text(xml_text) - print(f"Wrote MJCF XML to {out_path}") - - -if __name__ == "__main__": - register_configs() - main() diff --git a/scripts/tools/dump_mjcf.py b/scripts/tools/dump_mjcf.py new file mode 100644 index 0000000..ae582c7 --- /dev/null +++ b/scripts/tools/dump_mjcf.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 +""" +Dump MJCF XML for a brittle-star morphology using the project's Hydra configs. + +Usage examples: + + # Use a named morphology config from configs/morphology (Hydra style) + uv run python scripts/analysis/dump_mjcf.py morphology=3_arms + + # Use a morphology override YAML (same key as simulation.morphology_override) + uv run python scripts/analysis/dump_mjcf.py \ + simulation.morphology_override=configs/morphology/3_arms.yaml + +Output path: + Provide `dump_out=path/to/file.xml` on the command line, otherwise writes `morphology.xml` in + current directory or `runs/morphologies/.xml`. +""" + +from __future__ import annotations + +import dataclasses +import logging +import sys +from pathlib import Path +from typing import Any, Optional + +import hydra +import yaml +from omegaconf import DictConfig, OmegaConf + +from brittle_star_project.configs.register_configs import register_configs +from brittle_star_project.environment.env_config import MorphologyConfig +from brittle_star_project.environment.factory import BrittleStarEnvFactory + +logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") +logger = logging.getLogger(__name__) + + +def extract_xml_string(obj: Any) -> Optional[str]: + """ + Attempts to serialize the morphology object to an XML string by checking + common dm_control and internal API methods. + """ + serialization_methods = [ + "to_xml_string", + "to_xml", + "to_string", + "to_mjcf", + "to_mjcf_string", + "get_mjcf", + "get_mjcf_str", + "export_to_xml_string", + ] + + # If the object itself has an 'mjcf' attribute, try to serialize that instead + target_obj = getattr(obj, "mjcf", obj) + + for method_name in serialization_methods: + method = getattr(target_obj, method_name, None) + if callable(method): + try: + xml_data = method() + # Safely handle both string and byte responses + if isinstance(xml_data, str): + return xml_data + elif isinstance(xml_data, bytes): + return xml_data.decode("utf-8") + except Exception as e: + logger.debug(f"Method {method_name}() failed during serialization: {e}") + + return None + + +def resolve_output_path(cfg: DictConfig) -> Path: + """Determines the appropriate output path for the MJCF XML.""" + dump_out = cfg.get("dump_out", None) + if dump_out is not None: + return Path(hydra.utils.to_absolute_path(str(dump_out))) + + morph_name = "morphology" + for arg in sys.argv[1:]: + if arg.startswith("morphology="): + morph_name = arg.split("=", 1)[1] + break + + default_out = ( + f"runs/morphologies/{morph_name}.xml" if morph_name != "morphology" else "morphology.xml" + ) + return Path(hydra.utils.to_absolute_path(default_out)) + + +@hydra.main(config_path="../../configs", config_name="main_config", version_base="1.3") +def main(cfg: DictConfig) -> None: + """Main entry point to construct the morphology and dump its XML.""" + logger.info("Initializing morphology construction...") + + # Extract morphology config safely using dict `.get()` to avoid OmegaConf AttributeErrors + simulation_cfg = cfg.get("simulation", cfg) + override_path = simulation_cfg.get("morphology_override", None) + + if override_path: + logger.info(f"Using morphology override: {override_path}") + with open(hydra.utils.to_absolute_path(override_path), "r") as f: + data = yaml.safe_load(f) or {} + morph_cfg = MorphologyConfig(**data) + else: + # Fallback to default simulation morphology, or an empty base config + morph_node = simulation_cfg.get("morphology", cfg.get("morphology", None)) + + if morph_node is not None: + # Convert OmegaConf node to dict and instantiate MorphologyConfig. + # This ensures any missing keys gracefully fall back to the dataclass defaults. + morph_dict = OmegaConf.to_container(morph_node, resolve=True) + if isinstance(morph_dict, dict): + # Filter to avoid unexpected kwargs if the dataclass is strictly defined + if dataclasses.is_dataclass(MorphologyConfig): + valid_keys = {f.name for f in dataclasses.fields(MorphologyConfig)} + morph_dict = {k: v for k, v in morph_dict.items() if k in valid_keys} + morph_cfg = MorphologyConfig(**morph_dict) + else: + morph_cfg = MorphologyConfig() + else: + morph_cfg = MorphologyConfig() + + morphology = BrittleStarEnvFactory.create_morphology(morph_cfg) + + xml_text = extract_xml_string(morphology) + if not xml_text: + raise RuntimeError("Failed to serialize morphology to MJCF/XML. ") + + out_path = resolve_output_path(cfg) + out_path.parent.mkdir(parents=True, exist_ok=True) + with out_path.open("w", encoding="utf-8") as f: + f.write(xml_text) + + logger.info(f"Successfully exported MJCF XML to: {out_path}") + + +if __name__ == "__main__": + register_configs() + main() diff --git a/scripts/extract_observation_bounds.py b/scripts/tools/extract_observation_bounds.py similarity index 100% rename from scripts/extract_observation_bounds.py rename to scripts/tools/extract_observation_bounds.py From 22c43f05b1a2388fcc13cabc5f1de65b5f62a329 Mon Sep 17 00:00:00 2001 From: JibrilExe Date: Fri, 1 May 2026 10:40:02 +0200 Subject: [PATCH 28/96] fix: critic init now fixed? --- scripts/hpc/train.pbs | 2 +- src/brittle_star_project/ppo.py | 10 ++--- .../trainers/PPOTrainer.py | 45 ++++++++++++++----- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/scripts/hpc/train.pbs b/scripts/hpc/train.pbs index 0f95b18..a0e79cc 100644 --- a/scripts/hpc/train.pbs +++ b/scripts/hpc/train.pbs @@ -66,7 +66,7 @@ fi # Run training using Hydra overrides python scripts/train.py \ hydra.run.dir="$SCRATCH_RUNDIR" \ - ppo=stable \ + ppo=smoke_test \ logging=hpc echo ">>> Staging out results to $DATA_RUNDIR..." diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index 1ea37a8..0b1cd95 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -8,7 +8,7 @@ import jax.numpy as jnp # Chose to use a class as it seemed the easiest way to integrate the CleanRL code style # with our need to seperate concerns class PPO: - def __init__(self, args, sensor, actor, critic, feature_extractor, message_passer=None): + def __init__(self, args, sensor_apply, actor_apply, critic_apply, feature_extractor_apply, message_passer=None): self.args = args if not message_passer: @@ -18,10 +18,10 @@ class PPO: partial( ppo_loss, args=args, - sensor_apply=sensor.apply, - actor_apply=actor.apply, - critic_apply=critic.apply, - feature_extractor_apply=feature_extractor.apply, + sensor_apply=sensor_apply, + actor_apply=actor_apply, + critic_apply=critic_apply, + feature_extractor_apply=feature_extractor_apply, message_passer=message_passer, ), has_aux=True, diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index e027a6a..502dd6d 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -217,7 +217,7 @@ def _get_action_and_value_noise( adj_matrix: jnp.ndarray, ): hidden = apply_per_node(sensor, agent_state.params["sensor_params"], next_obs) - hidden_critic = apply_per_node( + hidden_critic = apply_shared( feature_extractor, agent_state.params["feature_extractor_params"], next_obs ) @@ -226,11 +226,17 @@ def _get_action_and_value_noise( key, subkey = jax.random.split(key) noise = jax.random.normal(subkey, shape=mean.shape) std = jnp.exp(log_std) + raw_action = mean + noise * std clipped_action = _clip_action(raw_action, action_low, action_high) - logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum(-1) - value = critic.apply(agent_state.params["critic_params"], hidden_critic) + + logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum(-1) + value = apply_shared(critic, agent_state.params["critic_params"], hidden_critic) + + raw_action = raw_action.reshape(-1) + raw_action = raw_action.reshape(raw_action.shape[0], -1) # concat the per agent, keep the envs dim + clipped_action = _clip_action(raw_action, action_low, action_high) return clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key @@ -333,11 +339,22 @@ def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, morph_mode, ), ) - def apply_per_node(net, params, x): + # params: (nodes, ...) # x: (batch, nodes, feat) - return jax.vmap(net.apply, in_axes=(0, 1), out_axes=1)(params, x) + def apply_single_node(p, x_node): + # x_node: (batch, feat) + return jax.vmap(lambda xi: net.apply(p, xi))(x_node) + + return jax.vmap(apply_single_node, in_axes=(0, 1), out_axes=1)(params, x) + +def apply_shared(net, params, x): + # x: (batch, nodes, feat) + # If the critic expects a single vector per environment: + batch_size = x.shape[0] + x_flattened = x.reshape(batch_size, -1) + return jax.vmap(lambda xi: net.apply(params, xi))(x_flattened) # TODO: update to work with extra dimension + message passing def _rollout_jit( @@ -399,9 +416,9 @@ def _compute_gae_jit( critic, adj_matrix: jnp.ndarray, ): - next_value = critic.apply( + next_value = apply_shared(critic, agent_state.params["critic_params"], - feature_extractor.apply(agent_state.params["feature_extractor_params"], next_obs), + apply_shared(feature_extractor,agent_state.params["feature_extractor_params"], next_obs), ).squeeze(-1) advantages = jnp.zeros((num_envs,)) @@ -511,7 +528,12 @@ class PPOTrainer: ) ) - self._ppo = PPO(self.ppo, self.sensor, self.actor, self.critic, self.feature_extractor) + apply_sensor = lambda p, x: apply_per_node(self.sensor, p, x) + apply_actor = lambda p, x: apply_per_node(self.actor, p, x) + apply_critic = lambda p, x: apply_shared(self.critic, p, x) + apply_feature = lambda p, x: apply_shared(self.feature_extractor, p, x) + + self._ppo = PPO(self.ppo, apply_sensor, apply_actor, apply_critic, apply_feature) self.agent_state = self._init_agent_state() @@ -583,9 +605,12 @@ class PPOTrainer: ) )(message_passer_keys) - feature_extractor_params = self.feature_extractor.init(feature_extractor_key, sample_obs) + flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic + feature_extractor_params = self.feature_extractor.init(feature_extractor_key, flat_obs) + critic_params = self.critic.init( - critic_key, self.feature_extractor.apply(feature_extractor_params, sample_obs) + critic_key, + self.feature_extractor.apply(feature_extractor_params, flat_obs) ) return TrainState.create( From e867dbab498ec62002c1a4e3bdeb306611c903b5 Mon Sep 17 00:00:00 2001 From: JibrilExe Date: Fri, 1 May 2026 10:43:27 +0200 Subject: [PATCH 29/96] fix: dubble reshape bad --- src/brittle_star_project/trainers/PPOTrainer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 502dd6d..4a71b69 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -234,7 +234,6 @@ def _get_action_and_value_noise( logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum(-1) value = apply_shared(critic, agent_state.params["critic_params"], hidden_critic) - raw_action = raw_action.reshape(-1) raw_action = raw_action.reshape(raw_action.shape[0], -1) # concat the per agent, keep the envs dim clipped_action = _clip_action(raw_action, action_low, action_high) return clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key From 951f6827232a7f1339c17933cb06cdeba3b20c78 Mon Sep 17 00:00:00 2001 From: JibrilExe Date: Fri, 1 May 2026 11:36:25 +0200 Subject: [PATCH 30/96] fix: latest attempt at fexing exploding mem leak --- src/brittle_star_project/ppo.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index 0b1cd95..1768efc 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -63,14 +63,13 @@ class PPO: pg_loss, v_loss, entropy_loss, - approx_kl, - grads, + approx_kl ) agent_state, metrics = jax.lax.scan(update_minibatch, agent_state, shuffled_storage) return (agent_state, key), metrics - (agent_state, key), (loss, pg_loss, v_loss, entropy_loss, approx_kl, grads) = jax.lax.scan( + (agent_state, key), (loss, pg_loss, v_loss, entropy_loss, approx_kl) = jax.lax.scan( update_epoch, (agent_state, key), (), length=args.update_epochs ) return agent_state, loss, pg_loss, v_loss, entropy_loss, approx_kl, key @@ -102,8 +101,10 @@ def get_action_and_value( log_std = jnp.clip(log_std, -5, 2) std = jnp.exp(log_std) - logprob = -0.5 * (((action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum(-1) - entropy = (0.5 + 0.5 * jnp.log(2 * jnp.pi) + log_std).sum(-1) + logprob = -0.5 * (((action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)) + # Sum over BOTH the action dimensions (-1) AND the node dimension (-2) (sums per arm logprob) + logprob = logprob.sum(axis=(-2, -1)) + entropy = (0.5 + 0.5 * jnp.log(2 * jnp.pi) + log_std).sum(axis=(-2, -1)) value = critic_apply(params["critic_params"], hidden_critic).squeeze(-1) return logprob, entropy, value From bceb7fe4cf9de4c788b7c9681e980e737e3a7ec4 Mon Sep 17 00:00:00 2001 From: JibrilExe Date: Fri, 1 May 2026 11:52:57 +0200 Subject: [PATCH 31/96] logging: now we can see shapes in ppo update --- src/brittle_star_project/ppo.py | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index 1768efc..6eb5221 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -3,8 +3,9 @@ from functools import partial import flax import jax import jax.numpy as jnp +from experiment_logger import get_logger - +logger = get_logger() # Chose to use a class as it seemed the easiest way to integrate the CleanRL code style # with our need to seperate concerns class PPO: @@ -31,6 +32,12 @@ class PPO: # or this function will need to recompile @partial(jax.jit, static_argnums=0) def update_ppo(self, agent_state, storage, key): + logger.info(f"[PPO] storage.obs shape: {getattr(storage, 'obs', None).shape}") + logger.info(f"[PPO] storage.actions shape: {storage.actions.shape}") + logger.info(f"[PPO] storage.logprobs shape: {storage.logprobs.shape}") + logger.info(f"[PPO] storage.advantages shape: {storage.advantages.shape}") + logger.info(f"[PPO] storage.returns shape: {storage.returns.shape}") + args = self.args ppo_loss_grad_fn = self.ppo_loss_grad_fn @@ -49,6 +56,11 @@ class PPO: shuffled_storage = jax.tree.map(convert_data, flatten_storage) def update_minibatch(agent_state, minibatch): + logger.info(f"[PPO] minibatch.obs: {minibatch.obs.shape}") + logger.info(f"[PPO] minibatch.actions: {minibatch.actions.shape}") + logger.info(f"[PPO] minibatch.logprobs: {minibatch.logprobs.shape}") + logger.info(f"[PPO] minibatch.advantages: {minibatch.advantages.shape}") + logger.info(f"[PPO] minibatch.returns: {minibatch.returns.shape}") (loss, (pg_loss, v_loss, entropy_loss, approx_kl)), grads = ppo_loss_grad_fn( agent_state.params, minibatch.obs, @@ -97,16 +109,26 @@ def get_action_and_value( hidden_sensor = sensor_apply(params["sensor_params"], x) hidden_critic = feature_extractor_apply(params["feature_extractor_params"], x) hidden_sensor = message_passer(hidden_sensor) + + logger.info(f"[SHAPE] hidden_sensor: {hidden_sensor.shape}") + logger.info(f"[SHAPE] hidden_critic: {hidden_critic.shape}") + mean, log_std = actor_apply(params["actor_params"], hidden_sensor) + + logger.info(f"[SHAPE] mean: {mean.shape}") + logger.info(f"[SHAPE] log_std: {log_std.shape}") + logger.info(f"[SHAPE] action: {action.shape}") + log_std = jnp.clip(log_std, -5, 2) std = jnp.exp(log_std) logprob = -0.5 * (((action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)) - # Sum over BOTH the action dimensions (-1) AND the node dimension (-2) (sums per arm logprob) - logprob = logprob.sum(axis=(-2, -1)) + logger.info(f"[SHAPE] logprob pre-sum: {logprob.shape}") + logprob = logprob.sum(axis=(-2, -1)) + logger.info(f"[SHAPE] logprob final: {logprob.shape}") entropy = (0.5 + 0.5 * jnp.log(2 * jnp.pi) + log_std).sum(axis=(-2, -1)) value = critic_apply(params["critic_params"], hidden_critic).squeeze(-1) - + logger.info(f"[SHAPE] value: {value.shape}") return logprob, entropy, value From 9f7c73b009c162aeec53200e454d2722bca483f7 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Fri, 1 May 2026 18:15:09 +0200 Subject: [PATCH 32/96] other: backup of current progress --- configs/ppo/smoke_test.yaml | 6 +- scripts/train.py | 2 + .../dataclasses/EpisodeStatistics.py | 8 +- src/brittle_star_project/ppo.py | 74 +++++++++++-------- .../trainers/PPOTrainer.py | 60 +++++++++------ src/brittle_star_project/utils/__init__.py | 3 + src/brittle_star_project/utils/logged_jit.py | 17 +++++ 7 files changed, 109 insertions(+), 61 deletions(-) create mode 100644 src/brittle_star_project/utils/__init__.py create mode 100644 src/brittle_star_project/utils/logged_jit.py diff --git a/configs/ppo/smoke_test.yaml b/configs/ppo/smoke_test.yaml index 40e4c07..4b7bb84 100644 --- a/configs/ppo/smoke_test.yaml +++ b/configs/ppo/smoke_test.yaml @@ -2,9 +2,9 @@ # Lower timestep count for quick iterations/testing. learning_rate: 0.0005 -total_timesteps: 65536 -num_envs: 512 -num_steps: 128 +total_timesteps: 1024 +num_envs: 32 +num_steps: 32 anneal_lr: true gamma: 0.99 gae_lambda: 0.95 diff --git a/scripts/train.py b/scripts/train.py index c367000..8e61bd0 100644 --- a/scripts/train.py +++ b/scripts/train.py @@ -8,6 +8,7 @@ from brittle_star_project.configs.register_configs import register_configs from brittle_star_project.trainers.PPOTrainer import PPOTrainer from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleStarJaxEnvWrapper from experiment_logger import init_logger, get_logger +import logging def make_env(cfg: BrittleStarConfig) -> BrittleStarJaxEnvWrapper: @@ -41,6 +42,7 @@ def main(dict_cfg: DictConfig): base_dir=os.path.dirname(run_dir), ) logger = get_logger() + logger.set_level(logging.DEBUG) logger.info(f"Hydra-initialized run: {run_name}") logger.info(f"Output directory: {run_dir}") diff --git a/src/brittle_star_project/dataclasses/EpisodeStatistics.py b/src/brittle_star_project/dataclasses/EpisodeStatistics.py index 0b2832f..ff2982e 100644 --- a/src/brittle_star_project/dataclasses/EpisodeStatistics.py +++ b/src/brittle_star_project/dataclasses/EpisodeStatistics.py @@ -4,7 +4,7 @@ import jax.numpy as jnp @flax.struct.dataclass class EpisodeStatistics: - episode_returns: jnp.array - episode_lengths: jnp.array - returned_episode_returns: jnp.array - returned_episode_lengths: jnp.array + episode_returns: jnp.ndarray + episode_lengths: jnp.ndarray + returned_episode_returns: jnp.ndarray + returned_episode_lengths: jnp.ndarray diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index 6eb5221..87e1dfe 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -1,15 +1,27 @@ from functools import partial -import flax import jax import jax.numpy as jnp +from jax import debug +from flax.core import FrozenDict from experiment_logger import get_logger +from brittle_star_project.utils import logged_jit logger = get_logger() + + # Chose to use a class as it seemed the easiest way to integrate the CleanRL code style # with our need to seperate concerns class PPO: - def __init__(self, args, sensor_apply, actor_apply, critic_apply, feature_extractor_apply, message_passer=None): + def __init__( + self, + args, + sensor_apply, + actor_apply, + critic_apply, + feature_extractor_apply, + message_passer=None, + ): self.args = args if not message_passer: @@ -30,13 +42,13 @@ class PPO: # This PPO class should be initialized only once, # or this function will need to recompile - @partial(jax.jit, static_argnums=0) + @partial(logged_jit, static_argnums=0) def update_ppo(self, agent_state, storage, key): - logger.info(f"[PPO] storage.obs shape: {getattr(storage, 'obs', None).shape}") - logger.info(f"[PPO] storage.actions shape: {storage.actions.shape}") - logger.info(f"[PPO] storage.logprobs shape: {storage.logprobs.shape}") - logger.info(f"[PPO] storage.advantages shape: {storage.advantages.shape}") - logger.info(f"[PPO] storage.returns shape: {storage.returns.shape}") + debug.callback(logger.debug, f"[PPO] storage.obs shape: {storage.obs.shape}") + debug.callback(logger.debug, f"[PPO] storage.actions shape: {storage.actions.shape}") + debug.callback(logger.debug, f"[PPO] storage.logprobs shape: {storage.logprobs.shape}") + debug.callback(logger.debug, f"[PPO] storage.advantages shape: {storage.advantages.shape}") + debug.callback(logger.debug, f"[PPO] storage.returns shape: {storage.returns.shape}") args = self.args ppo_loss_grad_fn = self.ppo_loss_grad_fn @@ -56,11 +68,16 @@ class PPO: shuffled_storage = jax.tree.map(convert_data, flatten_storage) def update_minibatch(agent_state, minibatch): - logger.info(f"[PPO] minibatch.obs: {minibatch.obs.shape}") - logger.info(f"[PPO] minibatch.actions: {minibatch.actions.shape}") - logger.info(f"[PPO] minibatch.logprobs: {minibatch.logprobs.shape}") - logger.info(f"[PPO] minibatch.advantages: {minibatch.advantages.shape}") - logger.info(f"[PPO] minibatch.returns: {minibatch.returns.shape}") + debug.callback(logger.debug, f"[PPO] minibatch.obs: {minibatch.obs.shape}") + debug.callback(logger.debug, f"[PPO] minibatch.actions: {minibatch.actions.shape}") + debug.callback( + logger.debug, f"[PPO] minibatch.logprobs: {minibatch.logprobs.shape}" + ) + debug.callback( + logger.debug, f"[PPO] minibatch.advantages: {minibatch.advantages.shape}" + ) + debug.callback(logger.debug, f"[PPO] minibatch.returns: {minibatch.returns.shape}") + (loss, (pg_loss, v_loss, entropy_loss, approx_kl)), grads = ppo_loss_grad_fn( agent_state.params, minibatch.obs, @@ -70,13 +87,7 @@ class PPO: minibatch.returns, ) agent_state = agent_state.apply_gradients(grads=grads) - return agent_state, ( - loss, - pg_loss, - v_loss, - entropy_loss, - approx_kl - ) + return agent_state, (loss, pg_loss, v_loss, entropy_loss, approx_kl) agent_state, metrics = jax.lax.scan(update_minibatch, agent_state, shuffled_storage) return (agent_state, key), metrics @@ -95,14 +106,14 @@ that are now not in the same scope """ -@partial(jax.jit, static_argnums=(0, 1, 2, 3, 4)) +@partial(logged_jit, static_argnums=(0, 1, 2, 3, 4)) def get_action_and_value( sensor_apply, actor_apply, message_passer, critic_apply, feature_extractor_apply, - params: flax.core.FrozenDict, + params: FrozenDict, x: jnp.ndarray, action: jnp.ndarray, ): @@ -110,25 +121,28 @@ def get_action_and_value( hidden_critic = feature_extractor_apply(params["feature_extractor_params"], x) hidden_sensor = message_passer(hidden_sensor) - logger.info(f"[SHAPE] hidden_sensor: {hidden_sensor.shape}") - logger.info(f"[SHAPE] hidden_critic: {hidden_critic.shape}") + debug.callback(logger.debug, f"[SHAPE] hidden_sensor: {hidden_sensor.shape}") + debug.callback(logger.debug, f"[SHAPE] hidden_critic: {hidden_critic.shape}") mean, log_std = actor_apply(params["actor_params"], hidden_sensor) - logger.info(f"[SHAPE] mean: {mean.shape}") - logger.info(f"[SHAPE] log_std: {log_std.shape}") - logger.info(f"[SHAPE] action: {action.shape}") + debug.callback(logger.debug, f"[SHAPE] mean: {mean.shape}") + debug.callback(logger.debug, f"[SHAPE] log_std: {log_std.shape}") + debug.callback(logger.debug, f"[SHAPE] action: {action.shape}") log_std = jnp.clip(log_std, -5, 2) std = jnp.exp(log_std) logprob = -0.5 * (((action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)) - logger.info(f"[SHAPE] logprob pre-sum: {logprob.shape}") + debug.callback(logger.debug, f"[SHAPE] logprob pre-sum: {logprob.shape}") + logprob = logprob.sum(axis=(-2, -1)) - logger.info(f"[SHAPE] logprob final: {logprob.shape}") + debug.callback(logger.debug, f"[SHAPE] logprob final: {logprob.shape}") + entropy = (0.5 + 0.5 * jnp.log(2 * jnp.pi) + log_std).sum(axis=(-2, -1)) value = critic_apply(params["critic_params"], hidden_critic).squeeze(-1) - logger.info(f"[SHAPE] value: {value.shape}") + debug.callback(logger.debug, f"[SHAPE] value: {value.shape}") + return logprob, entropy, value diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 4a71b69..fe0eb02 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -26,6 +26,7 @@ from brittle_star_project.MLPs.mlps import ( ) from brittle_star_project.ppo import PPO from brittle_star_project.environment import MorphMode +from brittle_star_project.utils import logged_jit # TODO: move to config _ALLOWED_OBS_KEYS = { @@ -108,7 +109,7 @@ def build_adjacency(segments_per_arm, mode: MorphMode): return adj -@jax.jit +@logged_jit def _clip_action(action: jnp.ndarray, low: jnp.ndarray, high: jnp.ndarray) -> jnp.ndarray: return jnp.clip(action, low, high) @@ -119,13 +120,13 @@ def _compute_explained_variance(values: jnp.ndarray, returns: jnp.ndarray) -> fl return float(explained_var) -@jax.jit +@logged_jit def _linear_schedule(count, minibatch_count, update_epochs, num_iterations, learning_rate): frac = 1.0 - (count // (minibatch_count * update_epochs)) / num_iterations return learning_rate * frac -@jax.jit +@logged_jit def _normalize_obs(obs, mean, var, eps=1e-8): return jnp.clip((obs - mean) / jnp.sqrt(var + eps), -10.0, 10.0) @@ -134,7 +135,7 @@ def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm num_segments = segments_per_arm.sum() num_arms = jnp.where(segments_per_arm > 0, 1, 0).sum() - @jax.jit + @logged_jit def _filter_and_flatten(o) -> jnp.ndarray: # vmap feeds one env at a time — v has NO batch dim here # shapes are e.g. (n_features,) or (n_nodes, feat) @@ -230,11 +231,12 @@ def _get_action_and_value_noise( raw_action = mean + noise * std clipped_action = _clip_action(raw_action, action_low, action_high) - logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum(-1) value = apply_shared(critic, agent_state.params["critic_params"], hidden_critic) - - raw_action = raw_action.reshape(raw_action.shape[0], -1) # concat the per agent, keep the envs dim + + raw_action = raw_action.reshape( + raw_action.shape[0], -1 + ) # concat the per agent, keep the envs dim clipped_action = _clip_action(raw_action, action_low, action_high) return clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key @@ -338,6 +340,7 @@ def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, morph_mode, ), ) + def apply_per_node(net, params, x): # params: (nodes, ...) # x: (batch, nodes, feat) @@ -348,6 +351,7 @@ def apply_per_node(net, params, x): return jax.vmap(apply_single_node, in_axes=(0, 1), out_axes=1)(params, x) + def apply_shared(net, params, x): # x: (batch, nodes, feat) # If the critic expects a single vector per environment: @@ -355,6 +359,7 @@ def apply_shared(net, params, x): x_flattened = x.reshape(batch_size, -1) return jax.vmap(lambda xi: net.apply(params, xi))(x_flattened) + # TODO: update to work with extra dimension + message passing def _rollout_jit( agent_state, @@ -415,9 +420,10 @@ def _compute_gae_jit( critic, adj_matrix: jnp.ndarray, ): - next_value = apply_shared(critic, + next_value = apply_shared( + critic, agent_state.params["critic_params"], - apply_shared(feature_extractor,agent_state.params["feature_extractor_params"], next_obs), + apply_shared(feature_extractor, agent_state.params["feature_extractor_params"], next_obs), ).squeeze(-1) advantages = jnp.zeros((num_envs,)) @@ -487,15 +493,15 @@ class PPOTrainer: self.needed_copies, ) = self._init_agent() - self.sensor.apply = jax.jit(self.sensor.apply) - self.feature_extractor.apply = jax.jit(self.feature_extractor.apply) - self.actor.apply = jax.jit(self.actor.apply) - self.critic.apply = jax.jit(self.critic.apply) + self.sensor.apply = logged_jit(self.sensor.apply) + self.feature_extractor.apply = logged_jit(self.feature_extractor.apply) + self.actor.apply = logged_jit(self.actor.apply) + self.critic.apply = logged_jit(self.critic.apply) action_low = jnp.asarray(self.env.single_action_space.low, dtype=jnp.float32) action_high = jnp.asarray(self.env.single_action_space.high, dtype=jnp.float32) - self._rollout_jit = jax.jit( + self._rollout_jit = logged_jit( partial( _rollout_jit, max_steps=self.ppo.num_steps, @@ -515,7 +521,7 @@ class PPOTrainer: adj_matrix=self.adj, ) ) - self._compute_gae_jit = jax.jit( + self._compute_gae_jit = logged_jit( partial( _compute_gae_jit, num_envs=self.ppo.num_envs, @@ -527,10 +533,17 @@ class PPOTrainer: ) ) - apply_sensor = lambda p, x: apply_per_node(self.sensor, p, x) - apply_actor = lambda p, x: apply_per_node(self.actor, p, x) - apply_critic = lambda p, x: apply_shared(self.critic, p, x) - apply_feature = lambda p, x: apply_shared(self.feature_extractor, p, x) + def apply_sensor(p, x): + return apply_per_node(self.sensor, p, x) + + def apply_actor(p, x): + return apply_per_node(self.actor, p, x) + + def apply_critic(p, x): + return apply_shared(self.critic, p, x) + + def apply_feature(p, x): + return apply_shared(self.feature_extractor, p, x) self._ppo = PPO(self.ppo, apply_sensor, apply_actor, apply_critic, apply_feature) @@ -553,11 +566,11 @@ class PPOTrainer: case MorphMode.CENTRALIZED: needed_copies = 1 case MorphMode.FULLY_CONNECTED | MorphMode.RING: - needed_copies = jnp.where(self.segments_per_arm > 0, 1, 0).sum() + needed_copies = jnp.where(self.segments_per_arm > 0, 1, 0).sum().item() case MorphMode.SEGMENT: needed_copies = ( self.segments_per_arm.sum() + jnp.where(self.segments_per_arm > 0, 1, 0).sum() - ) + ).item() actor = Actor(action_dim=self.env.single_action_space.shape[0]) sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) @@ -604,12 +617,11 @@ class PPOTrainer: ) )(message_passer_keys) - flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic + flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic feature_extractor_params = self.feature_extractor.init(feature_extractor_key, flat_obs) critic_params = self.critic.init( - critic_key, - self.feature_extractor.apply(feature_extractor_params, flat_obs) + critic_key, self.feature_extractor.apply(feature_extractor_params, flat_obs) ) return TrainState.create( diff --git a/src/brittle_star_project/utils/__init__.py b/src/brittle_star_project/utils/__init__.py new file mode 100644 index 0000000..ed72e5a --- /dev/null +++ b/src/brittle_star_project/utils/__init__.py @@ -0,0 +1,3 @@ +from .logged_jit import logged_jit + +__all__ = ["logged_jit"] diff --git a/src/brittle_star_project/utils/logged_jit.py b/src/brittle_star_project/utils/logged_jit.py new file mode 100644 index 0000000..3d29ba6 --- /dev/null +++ b/src/brittle_star_project/utils/logged_jit.py @@ -0,0 +1,17 @@ +import jax +from experiment_logger import get_logger + + +def logged_jit(fn, **jit_kwargs): + logger = get_logger() + name = getattr(fn, "__name__", getattr(fn, "__qualname__", repr(fn))) + + def decorator(func): + def traced_func(*args, **kwargs): + logger.debug(f"[JIT] Compiling {name}...") + return func(*args, **kwargs) + + jitted = jax.jit(traced_func, **jit_kwargs) + return jitted + + return decorator(fn) From f77766ba084cfc57b792752f67b48310fa6bcf22 Mon Sep 17 00:00:00 2001 From: JibrilExe Date: Sat, 2 May 2026 09:38:22 +0200 Subject: [PATCH 33/96] fix:logging shapes --- src/brittle_star_project/ppo.py | 36 +++++++------- .../trainers/PPOTrainer.py | 48 +++++++++++++++---- 2 files changed, 58 insertions(+), 26 deletions(-) diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index 6eb5221..38dc18b 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -32,11 +32,11 @@ class PPO: # or this function will need to recompile @partial(jax.jit, static_argnums=0) def update_ppo(self, agent_state, storage, key): - logger.info(f"[PPO] storage.obs shape: {getattr(storage, 'obs', None).shape}") - logger.info(f"[PPO] storage.actions shape: {storage.actions.shape}") - logger.info(f"[PPO] storage.logprobs shape: {storage.logprobs.shape}") - logger.info(f"[PPO] storage.advantages shape: {storage.advantages.shape}") - logger.info(f"[PPO] storage.returns shape: {storage.returns.shape}") + logger.info(f"[update_ppo] storage.obs shape: {getattr(storage, 'obs', None).shape}") + logger.info(f"[update_ppo] storage.actions shape: {storage.actions.shape}") + logger.info(f"[update_ppo] storage.logprobs shape: {storage.logprobs.shape}") + logger.info(f"[update_ppo] storage.advantages shape: {storage.advantages.shape}") + logger.info(f"[update_ppo] storage.returns shape: {storage.returns.shape}") args = self.args ppo_loss_grad_fn = self.ppo_loss_grad_fn @@ -56,11 +56,11 @@ class PPO: shuffled_storage = jax.tree.map(convert_data, flatten_storage) def update_minibatch(agent_state, minibatch): - logger.info(f"[PPO] minibatch.obs: {minibatch.obs.shape}") - logger.info(f"[PPO] minibatch.actions: {minibatch.actions.shape}") - logger.info(f"[PPO] minibatch.logprobs: {minibatch.logprobs.shape}") - logger.info(f"[PPO] minibatch.advantages: {minibatch.advantages.shape}") - logger.info(f"[PPO] minibatch.returns: {minibatch.returns.shape}") + logger.info(f"[update_ppo] minibatch.obs: {minibatch.obs.shape}") + logger.info(f"[update_ppo] minibatch.actions: {minibatch.actions.shape}") + logger.info(f"[update_ppo] minibatch.logprobs: {minibatch.logprobs.shape}") + logger.info(f"[update_ppo] minibatch.advantages: {minibatch.advantages.shape}") + logger.info(f"[update_ppo] minibatch.returns: {minibatch.returns.shape}") (loss, (pg_loss, v_loss, entropy_loss, approx_kl)), grads = ppo_loss_grad_fn( agent_state.params, minibatch.obs, @@ -110,25 +110,25 @@ def get_action_and_value( hidden_critic = feature_extractor_apply(params["feature_extractor_params"], x) hidden_sensor = message_passer(hidden_sensor) - logger.info(f"[SHAPE] hidden_sensor: {hidden_sensor.shape}") - logger.info(f"[SHAPE] hidden_critic: {hidden_critic.shape}") + logger.info(f"[get_action_and_value] hidden_sensor: {hidden_sensor.shape}") + logger.info(f"[get_action_and_value] hidden_critic: {hidden_critic.shape}") mean, log_std = actor_apply(params["actor_params"], hidden_sensor) - logger.info(f"[SHAPE] mean: {mean.shape}") - logger.info(f"[SHAPE] log_std: {log_std.shape}") - logger.info(f"[SHAPE] action: {action.shape}") + logger.info(f"[get_action_and_value] mean: {mean.shape}") + logger.info(f"[get_action_and_value] log_std: {log_std.shape}") + logger.info(f"[get_action_and_value] action: {action.shape}") log_std = jnp.clip(log_std, -5, 2) std = jnp.exp(log_std) logprob = -0.5 * (((action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)) - logger.info(f"[SHAPE] logprob pre-sum: {logprob.shape}") + logger.info(f"[get_action_and_value] logprob pre-sum: {logprob.shape}") logprob = logprob.sum(axis=(-2, -1)) - logger.info(f"[SHAPE] logprob final: {logprob.shape}") + logger.info(f"[get_action_and_value] logprob final: {logprob.shape}") entropy = (0.5 + 0.5 * jnp.log(2 * jnp.pi) + log_std).sum(axis=(-2, -1)) value = critic_apply(params["critic_params"], hidden_critic).squeeze(-1) - logger.info(f"[SHAPE] value: {value.shape}") + logger.info(f"[get_action_and_value] value: {value.shape}") return logprob, entropy, value diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 4a71b69..4684c17 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -27,6 +27,7 @@ from brittle_star_project.MLPs.mlps import ( from brittle_star_project.ppo import PPO from brittle_star_project.environment import MorphMode +logger11 = get_logger() # TODO: move to config _ALLOWED_OBS_KEYS = { "joint_position", @@ -266,7 +267,23 @@ def _step_once( action_high, adj_matrix, ) + logger11.info(f"[_step_once] raw_action: {raw_action.shape}") + logger11.info(f"[_step_once] clipped_action: {clipped_action.shape}") + # Supporting signals (often where mismatch originates) + logger11.info(f"[_step_once] logprob: {logprob.shape}") + logger11.info(f"[_step_once] value: {value.shape}") + logger11.info(f"[_step_once] mean: {mean.shape}") + logger11.info(f"[_step_once] std: {std.shape}") + + # ---- ENV STEP ---- + episode_stats, env_state, (next_obs, reward, next_done) = env_step_fn( + episode_stats, env_state, clipped_action + ) + + logger11.info(f"[_step_once] next_obs: {next_obs.shape}") + logger11.info(f"[_step_once] reward: {reward.shape}") + logger11.info(f"[_step_once] next_done: {next_done.shape}") episode_stats, env_state, (next_obs, reward, next_done) = env_step_fn( episode_stats, env_state, clipped_action ) @@ -582,10 +599,12 @@ class PPOTrainer: self.morph_mode, self.segments_per_arm, )[0] # take first env - + self.logger.info(f"[_init_agent_state] sample_obs: {sample_obs.shape}") self.obs_mean = jnp.zeros((len(sample_obs),)) self.obs_var = jnp.ones((len(sample_obs),)) self.obs_count = 1e-4 + self.logger.info(f"[_init_agent_state] obs_mean: {self.obs_mean.shape}") + self.logger.info(f"[_init_agent_state] obs_var: {self.obs_var.shape}") sensor_keys = jax.random.split(sensor_key, self.needed_copies) actor_keys = jax.random.split(actor_key, self.needed_copies) @@ -593,24 +612,35 @@ class PPOTrainer: # (needed_copies, 175) sensor_params = jax.vmap(lambda k: self.sensor.init(k, sample_obs))(sensor_keys) + self.logger.info(f"[_init_agent_state] sensor_params: {jax.tree.map(lambda x: x.shape, sensor_params)}") single_sensor_param = jax.tree.map(lambda x: x[0], sensor_params) + self.logger.info(f"[_init_agent_state] single_sensor_param: {jax.tree.map(lambda x: x.shape, single_sensor_param)}") + sensor_params_sample = self.sensor.apply(single_sensor_param, sample_obs) + self.logger.info(f"[_init_agent_state] sensor_params_sample: {sensor_params_sample.shape}") + actor_params = jax.vmap(lambda k: self.actor.init(k, sensor_params_sample))(actor_keys) + self.logger.info(f"[_init_agent_state] actor_params: {jax.tree.map(lambda x: x.shape, actor_params)}") message_passer_params = jax.vmap( lambda k: self.message_passer.init( k, self.sensor.apply(single_sensor_param, sample_obs) ) )(message_passer_keys) + self.logger.info(f"[_init_agent_state] message_passer_params: {jax.tree.map(lambda x: x.shape, message_passer_params)}") + + flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic + self.logger.info(f"[_init_agent_state] flat_obs: {flat_obs.shape}") - flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic feature_extractor_params = self.feature_extractor.init(feature_extractor_key, flat_obs) + self.logger.info(f"[_init_agent_state] feature_extractor_params: {jax.tree.map(lambda x: x.shape, feature_extractor_params)}") - critic_params = self.critic.init( - critic_key, - self.feature_extractor.apply(feature_extractor_params, flat_obs) - ) + critic_input = self.feature_extractor.apply(feature_extractor_params, flat_obs) + self.logger.info(f"[_init_agent_state] critic_input: {critic_input.shape}") + + critic_params = self.critic.init(critic_key, critic_input) + self.logger.info(f"[_init_agent_state] critic_params: {jax.tree.map(lambda x: x.shape, critic_params)}") return TrainState.create( apply_fn=None, @@ -743,7 +773,7 @@ class PPOTrainer: def _step(self, env_state, next_obs, next_done, iteration: int) -> tuple: if iteration == 1: self.logger.log_non_interactive(f"Starting first rollout (JIT): {time.ctime()}") - + self.logger.info(f"[_step] next_obs (in): {next_obs.shape}") ( self.agent_state, self.episode_stats, @@ -753,7 +783,7 @@ class PPOTrainer: self.key, next_env_state, ) = self._rollout(env_state, next_obs, next_done) - + self.logger.info(f"[_step] next_obs (post-rollout): {next_obs.shape}") if iteration == 1: self.logger.log_non_interactive(f"First rollout completed: {time.ctime()}") @@ -839,6 +869,7 @@ class PPOTrainer: self.morph_mode, self.segments_per_arm, ) + self.logger.info(f"[train] next_obs: {next_obs.shape}") next_done = jnp.zeros(self.ppo.num_envs, dtype=jnp.bool_) self.logger.log_non_interactive(f"Initial reset completed: {time.ctime()}") @@ -853,6 +884,7 @@ class PPOTrainer: env_state, next_obs, next_done, training_measurements, storage = self._step( env_state, next_obs, next_done, iteration=iteration ) + self.logger.info(f"[train] next_obs (post-step): {next_obs.shape}") self._update_obs_stats(next_obs) next_obs = _normalize_obs(next_obs, self.obs_mean, self.obs_var) From 2b46b3f5d20f1908f35b9b9ce50d6053b42bd4cd Mon Sep 17 00:00:00 2001 From: JibrilExe Date: Sat, 2 May 2026 11:08:48 +0200 Subject: [PATCH 34/96] fix: only flatten actions for environ --- .../trainers/PPOTrainer.py | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 4684c17..e7aaaa1 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -229,15 +229,14 @@ def _get_action_and_value_noise( std = jnp.exp(log_std) raw_action = mean + noise * std - clipped_action = _clip_action(raw_action, action_low, action_high) + flat_action = raw_action.reshape(raw_action.shape[0], -1) # concat the per agent, keep the envs dim + flat_clipped_action = _clip_action(flat_action, action_low, action_high) - logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum(-1) + logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum(axis=(-2, -1)) value = apply_shared(critic, agent_state.params["critic_params"], hidden_critic) - raw_action = raw_action.reshape(raw_action.shape[0], -1) # concat the per agent, keep the envs dim - clipped_action = _clip_action(raw_action, action_low, action_high) - return clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key + return flat_clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key # TODO: update to work vectorized (sensor, actor, message passer) + message passing @@ -255,7 +254,7 @@ def _step_once( action_high, ): agent_state, episode_stats, obs, done, key, env_state = carry - clipped_action, raw_action, logprob, value, mean, std, key = _get_action_and_value_noise( + flat_clipped_action, raw_action, logprob, value, mean, std, key = _get_action_and_value_noise( sensor, feature_extractor, actor, @@ -268,7 +267,7 @@ def _step_once( adj_matrix, ) logger11.info(f"[_step_once] raw_action: {raw_action.shape}") - logger11.info(f"[_step_once] clipped_action: {clipped_action.shape}") + logger11.info(f"[_step_once] clipped_action: {flat_clipped_action.shape}") # Supporting signals (often where mismatch originates) logger11.info(f"[_step_once] logprob: {logprob.shape}") @@ -278,15 +277,12 @@ def _step_once( # ---- ENV STEP ---- episode_stats, env_state, (next_obs, reward, next_done) = env_step_fn( - episode_stats, env_state, clipped_action + episode_stats, env_state, flat_clipped_action ) logger11.info(f"[_step_once] next_obs: {next_obs.shape}") logger11.info(f"[_step_once] reward: {reward.shape}") logger11.info(f"[_step_once] next_done: {next_done.shape}") - episode_stats, env_state, (next_obs, reward, next_done) = env_step_fn( - episode_stats, env_state, clipped_action - ) storage = Storage( obs=obs, @@ -788,7 +784,7 @@ class PPOTrainer: self.logger.log_non_interactive(f"First rollout completed: {time.ctime()}") storage = self._compute_gae(storage, next_obs, next_done) - + self.logger.info(f"[_step] storage.obs (post-gae): {storage.obs.shape}") if iteration == 1: self.logger.log_non_interactive(f"Starting first PPO update (JIT): {time.ctime()}") From 6114e36e277a39e23328f38122646e48a48a3ff4 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Sat, 2 May 2026 21:50:42 +0200 Subject: [PATCH 35/96] feat(PPOTrainer): decentralized message passing babyyyy --- configs/architecture/decentralized.yaml | 2 +- configs/environment/dir_loc_further.yaml | 2 + configs/experiment/long_2arm.yaml | 6 + configs/ppo/chickendinnerwinner.yaml | 16 +++ src/brittle_star_project/MLPs/mlps.py | 23 +++- .../trainers/PPOTrainer.py | 107 ++++++++++++------ 6 files changed, 122 insertions(+), 34 deletions(-) create mode 100644 configs/environment/dir_loc_further.yaml create mode 100644 configs/experiment/long_2arm.yaml create mode 100644 configs/ppo/chickendinnerwinner.yaml diff --git a/configs/architecture/decentralized.yaml b/configs/architecture/decentralized.yaml index 4b9fffb..9e3ae53 100644 --- a/configs/architecture/decentralized.yaml +++ b/configs/architecture/decentralized.yaml @@ -26,7 +26,7 @@ critic: activation: "tanh" # Synchronous message-passing rounds per control step -message_passing_steps: 1 +message_passing_steps: 4 # Connectivity topology (e.g., ring, fully_connected) topology_type: "ring" diff --git a/configs/environment/dir_loc_further.yaml b/configs/environment/dir_loc_further.yaml new file mode 100644 index 0000000..236f0c5 --- /dev/null +++ b/configs/environment/dir_loc_further.yaml @@ -0,0 +1,2 @@ +simulation_time: 50000.0 +target_distance: 3.0 \ No newline at end of file diff --git a/configs/experiment/long_2arm.yaml b/configs/experiment/long_2arm.yaml new file mode 100644 index 0000000..ae4f4b0 --- /dev/null +++ b/configs/experiment/long_2arm.yaml @@ -0,0 +1,6 @@ +# Testing chicken dinner 4 but further distance. + +exp_name: "long2arm" +seed: 123 +torch_deterministic: true +cuda: true \ No newline at end of file diff --git a/configs/ppo/chickendinnerwinner.yaml b/configs/ppo/chickendinnerwinner.yaml new file mode 100644 index 0000000..cf5e3d6 --- /dev/null +++ b/configs/ppo/chickendinnerwinner.yaml @@ -0,0 +1,16 @@ +anneal_lr: true +clip_coef: 0.2 +clip_vloss: true +ent_coef: 0.001 +gae_lambda: 0.95 +gamma: 0.99 +learning_rate: 0.0001 +max_grad_norm: 0.5 +norm_adv: true +num_envs: 32 +num_minibatches: 32 +num_steps: 64 +target_kl: 0.02 +total_timesteps: 12288000 +update_epochs: 4 +vf_coef: 1.0 \ No newline at end of file diff --git a/src/brittle_star_project/MLPs/mlps.py b/src/brittle_star_project/MLPs/mlps.py index 45a9359..cf488c1 100644 --- a/src/brittle_star_project/MLPs/mlps.py +++ b/src/brittle_star_project/MLPs/mlps.py @@ -1,6 +1,5 @@ from dataclasses import dataclass, fields, field -import flax import flax.linen as nn import jax.numpy as jnp import jax.tree_util @@ -38,6 +37,28 @@ class Actor(nn.Module): return mean, log_std +class MessagePasser(nn.Module): + hidden_dim: int + num_propagation_steps: int + + @nn.compact + def __call__(self, x: jnp.ndarray, adj_matrix: jnp.ndarray): + for _ in range(self.num_propagation_steps): + messages = nn.Dense(self.hidden_dim)(x) + messages = nn.tanh(messages) + + agg = adj_matrix # if mean is wanted: adj_matrix / (adj.sum(axis=-1, keepdims=True) + 1e-8) + aggregated = agg @ messages + + x_concat = jnp.concatenate([x, aggregated], axis=-1) + + gate = nn.sigmoid(nn.Dense(self.hidden_dim)(x_concat)) + candidate = nn.tanh(nn.Dense(self.hidden_dim)(x_concat)) + x = gate * x + (1 - gate) * candidate + + return x + + @jax.tree_util.register_dataclass @dataclass class AgentParams: diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 146c184..fef6f1c 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -3,7 +3,7 @@ import random import time from dataclasses import asdict, dataclass from functools import partial -from typing import Any +from typing import Any, Optional import jax import jax.numpy as jnp @@ -21,6 +21,7 @@ from brittle_star_project.MLPs.mlps import ( Actor, AgentParams, GenericDenseLayersWithActivation, + MessagePasser, OneDenseLayerMLP, Storage, ) @@ -211,14 +212,20 @@ def _get_action_and_value_noise( feature_extractor: nn.Module, actor: nn.Module, critic: nn.Module, + message_passer: Optional[nn.Module], agent_state: TrainState, next_obs: jnp.ndarray, - key: jax.random.PRNGKey, + key, action_low, action_high, adj_matrix: jnp.ndarray, ): + def apply_message_passing(h): + return message_passer.apply(agent_state.params["message_passer_params"], h, adj_matrix) + hidden = apply_per_node(sensor, agent_state.params["sensor_params"], next_obs) + hidden = jax.vmap(apply_message_passing)(hidden) + hidden_critic = apply_shared( feature_extractor, agent_state.params["feature_extractor_params"], next_obs ) @@ -230,12 +237,16 @@ def _get_action_and_value_noise( std = jnp.exp(log_std) raw_action = mean + noise * std - flat_action = raw_action.reshape(raw_action.shape[0], -1) # concat the per agent, keep the envs dim + flat_action = raw_action.reshape( + raw_action.shape[0], -1 + ) # concat the per agent, keep the envs dim (batch, agent * action) flat_clipped_action = _clip_action(flat_action, action_low, action_high) - logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum(axis=(-2, -1)) + logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum( + axis=(-2, -1) + ) value = apply_shared(critic, agent_state.params["critic_params"], hidden_critic) - + return flat_clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key @@ -249,7 +260,7 @@ def _step_once( feature_extractor: nn.Module, actor: nn.Module, critic: nn.Module, - message_passer: nn.Module, + message_passer: Optional[nn.Module], action_low, action_high, ): @@ -259,6 +270,7 @@ def _step_once( feature_extractor, actor, critic, + message_passer, agent_state, obs, key, @@ -266,23 +278,23 @@ def _step_once( action_high, adj_matrix, ) - logger11.info(f"[_step_once] raw_action: {raw_action.shape}") - logger11.info(f"[_step_once] clipped_action: {flat_clipped_action.shape}") + logger11.debug(f"[_step_once] raw_action: {raw_action.shape}") + logger11.debug(f"[_step_once] clipped_action: {flat_clipped_action.shape}") # Supporting signals (often where mismatch originates) - logger11.info(f"[_step_once] logprob: {logprob.shape}") - logger11.info(f"[_step_once] value: {value.shape}") - logger11.info(f"[_step_once] mean: {mean.shape}") - logger11.info(f"[_step_once] std: {std.shape}") + logger11.debug(f"[_step_once] logprob: {logprob.shape}") + logger11.debug(f"[_step_once] value: {value.shape}") + logger11.debug(f"[_step_once] mean: {mean.shape}") + logger11.debug(f"[_step_once] std: {std.shape}") # ---- ENV STEP ---- episode_stats, env_state, (next_obs, reward, next_done) = env_step_fn( episode_stats, env_state, flat_clipped_action ) - logger11.info(f"[_step_once] next_obs: {next_obs.shape}") - logger11.info(f"[_step_once] reward: {reward.shape}") - logger11.info(f"[_step_once] next_done: {next_done.shape}") + logger11.debug(f"[_step_once] next_obs: {next_obs.shape}") + logger11.debug(f"[_step_once] reward: {reward.shape}") + logger11.debug(f"[_step_once] next_done: {next_done.shape}") storage = Storage( obs=obs, @@ -317,7 +329,7 @@ def _reward_fn(env_state, next_env_state): return jnp.where(next_env_state.terminated, 50.0, clipped_env_reward - penalty) -# TODO: update to work with extra dimension + message passing +# TODO: message passing def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, morph_mode, segments_per_arm): next_env_state = env_step_fn(env_state, action) @@ -385,7 +397,7 @@ def _rollout_jit( feature_extractor: nn.Module, actor: nn.Module, critic: nn.Module, - message_passer: nn.Module, + message_passer: Optional[nn.Module], action_low, action_high, adj_matrix, @@ -429,7 +441,6 @@ def _compute_gae_jit( num_envs, feature_extractor, critic, - adj_matrix: jnp.ndarray, ): next_value = apply_shared( critic, @@ -540,7 +551,6 @@ class PPOTrainer: gae_lambda=self.ppo.gae_lambda, feature_extractor=self.feature_extractor, critic=self.critic, - adj_matrix=self.adj, ) ) @@ -556,6 +566,9 @@ class PPOTrainer: def apply_feature(p, x): return apply_shared(self.feature_extractor, p, x) + def apply_message_passer(p, x): + return apply_shared(self.message_passer, p, x) + self._ppo = PPO(self.ppo, apply_sensor, apply_actor, apply_critic, apply_feature) self.agent_state = self._init_agent_state() @@ -585,7 +598,14 @@ class PPOTrainer: actor = Actor(action_dim=self.env.single_action_space.shape[0]) sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) - message_passer = OneDenseLayerMLP() + message_passer: Optional[nn.Module] = ( + MessagePasser( + hidden_dim=300, + num_propagation_steps=self.cfg.architecture.message_passing_steps or 4, + ) + if self.morph_mode != MorphMode.CENTRALIZED + else None + ) feature_extractor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) critic = OneDenseLayerMLP() @@ -615,39 +635,62 @@ class PPOTrainer: sensor_keys = jax.random.split(sensor_key, self.needed_copies) actor_keys = jax.random.split(actor_key, self.needed_copies) - message_passer_keys = jax.random.split(message_passer_key, self.needed_copies) + + # note: assumed only 1 message passer needed for now + # message_passer_keys = jax.random.split(message_passer_key, self.needed_copies) + message_passer_keys = jnp.asarray([message_passer_key], dtype=jnp.uint32) # (needed_copies, 175) sensor_params = jax.vmap(lambda k: self.sensor.init(k, sample_obs))(sensor_keys) - self.logger.info(f"[_init_agent_state] sensor_params: {jax.tree.map(lambda x: x.shape, sensor_params)}") + self.logger.info( + f"[_init_agent_state] sensor_params: {jax.tree.map(lambda x: x.shape, sensor_params)}" + ) single_sensor_param = jax.tree.map(lambda x: x[0], sensor_params) - self.logger.info(f"[_init_agent_state] single_sensor_param: {jax.tree.map(lambda x: x.shape, single_sensor_param)}") + self.logger.info( + f"[_init_agent_state] single_sensor_param: { + jax.tree.map(lambda x: x.shape, single_sensor_param) + }" + ) sensor_params_sample = self.sensor.apply(single_sensor_param, sample_obs) self.logger.info(f"[_init_agent_state] sensor_params_sample: {sensor_params_sample.shape}") actor_params = jax.vmap(lambda k: self.actor.init(k, sensor_params_sample))(actor_keys) - self.logger.info(f"[_init_agent_state] actor_params: {jax.tree.map(lambda x: x.shape, actor_params)}") + self.logger.info( + f"[_init_agent_state] actor_params: {jax.tree.map(lambda x: x.shape, actor_params)}" + ) - message_passer_params = jax.vmap( - lambda k: self.message_passer.init( - k, self.sensor.apply(single_sensor_param, sample_obs) - ) - )(message_passer_keys) - self.logger.info(f"[_init_agent_state] message_passer_params: {jax.tree.map(lambda x: x.shape, message_passer_params)}") + message_passer_params = {} + if self.morph_mode != MorphMode.CENTRALIZED: + message_passer_params = jax.vmap( + lambda k: self.message_passer.init( + k, self.sensor.apply(single_sensor_param, sample_obs) + ) + )(message_passer_keys) + self.logger.info( + f"[_init_agent_state] message_passer_params: { + jax.tree.map(lambda x: x.shape, message_passer_params) + }" + ) flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic self.logger.info(f"[_init_agent_state] flat_obs: {flat_obs.shape}") feature_extractor_params = self.feature_extractor.init(feature_extractor_key, flat_obs) - self.logger.info(f"[_init_agent_state] feature_extractor_params: {jax.tree.map(lambda x: x.shape, feature_extractor_params)}") + self.logger.info( + f"[_init_agent_state] feature_extractor_params: { + jax.tree.map(lambda x: x.shape, feature_extractor_params) + }" + ) critic_input = self.feature_extractor.apply(feature_extractor_params, flat_obs) self.logger.info(f"[_init_agent_state] critic_input: {critic_input.shape}") critic_params = self.critic.init(critic_key, critic_input) - self.logger.info(f"[_init_agent_state] critic_params: {jax.tree.map(lambda x: x.shape, critic_params)}") + self.logger.info( + f"[_init_agent_state] critic_params: {jax.tree.map(lambda x: x.shape, critic_params)}" + ) return TrainState.create( apply_fn=None, From 027b13b30f43dc9656f396d18214731d3d2338b1 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Sat, 2 May 2026 23:15:55 +0200 Subject: [PATCH 36/96] feat(message passing): used config value for message passing repetitions --- configs/architecture/decentralized.yaml | 2 +- configs/morphology/2_arms_decentralized.yaml | 6 ++++++ scripts/train.py | 2 +- src/brittle_star_project/trainers/PPOTrainer.py | 7 ++++++- 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 configs/morphology/2_arms_decentralized.yaml diff --git a/configs/architecture/decentralized.yaml b/configs/architecture/decentralized.yaml index 9e3ae53..70b0fb2 100644 --- a/configs/architecture/decentralized.yaml +++ b/configs/architecture/decentralized.yaml @@ -29,4 +29,4 @@ critic: message_passing_steps: 4 # Connectivity topology (e.g., ring, fully_connected) -topology_type: "ring" +topology_type: "fully_connected" diff --git a/configs/morphology/2_arms_decentralized.yaml b/configs/morphology/2_arms_decentralized.yaml new file mode 100644 index 0000000..9fe3160 --- /dev/null +++ b/configs/morphology/2_arms_decentralized.yaml @@ -0,0 +1,6 @@ +# 2 Arms Morphology Configuration + +segments_per_arm: [4, 0, 4, 0, 0] +use_p_control: true +use_torque_control: false +morph_mode: FULLY_CONNECTED \ No newline at end of file diff --git a/scripts/train.py b/scripts/train.py index 8e61bd0..f82d6bc 100644 --- a/scripts/train.py +++ b/scripts/train.py @@ -42,7 +42,7 @@ def main(dict_cfg: DictConfig): base_dir=os.path.dirname(run_dir), ) logger = get_logger() - logger.set_level(logging.DEBUG) + logger.set_level(logging.INFO) logger.info(f"Hydra-initialized run: {run_name}") logger.info(f"Output directory: {run_dir}") diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index fef6f1c..72c4734 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -221,10 +221,15 @@ def _get_action_and_value_noise( adj_matrix: jnp.ndarray, ): def apply_message_passing(h): + assert message_passer is not None, ( + "message passing shouldn't be performed if morphology mode is Centralized" + ) + return message_passer.apply(agent_state.params["message_passer_params"], h, adj_matrix) hidden = apply_per_node(sensor, agent_state.params["sensor_params"], next_obs) - hidden = jax.vmap(apply_message_passing)(hidden) + if message_passer is not None: + hidden = jax.vmap(apply_message_passing)(hidden) hidden_critic = apply_shared( feature_extractor, agent_state.params["feature_extractor_params"], next_obs From 3cb3c765cc6d3a06996ffa4a1150d9cdfa1d4581 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Sat, 2 May 2026 23:27:31 +0200 Subject: [PATCH 37/96] feat(message passing): fixed tracing bug, todo: dense layer input dimension incorrect --- src/brittle_star_project/trainers/PPOTrainer.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 72c4734..a297a07 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -134,8 +134,8 @@ def _normalize_obs(obs, mean, var, eps=1e-8): def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm: jnp.ndarray): - num_segments = segments_per_arm.sum() - num_arms = jnp.where(segments_per_arm > 0, 1, 0).sum() + num_segments = int(segments_per_arm.sum()) + num_arms = int(jnp.where(segments_per_arm > 0, 1, 0).sum()) @logged_jit def _filter_and_flatten(o) -> jnp.ndarray: @@ -668,9 +668,11 @@ class PPOTrainer: message_passer_params = {} if self.morph_mode != MorphMode.CENTRALIZED: + assert self.message_passer is not None, "MessagePasser is None" + message_passer_params = jax.vmap( lambda k: self.message_passer.init( - k, self.sensor.apply(single_sensor_param, sample_obs) + k, self.sensor.apply(single_sensor_param, sample_obs), self.adj ) )(message_passer_keys) self.logger.info( From bb14507fc7206f103404bf65671499ed0215d1da Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Sat, 2 May 2026 23:34:52 +0200 Subject: [PATCH 38/96] fix(message passing): forgot vmapping over params :thumbs_up: --- src/brittle_star_project/trainers/PPOTrainer.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index a297a07..7e11b29 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -220,16 +220,18 @@ def _get_action_and_value_noise( action_high, adj_matrix: jnp.ndarray, ): - def apply_message_passing(h): + def apply_message_passing(p, h): assert message_passer is not None, ( "message passing shouldn't be performed if morphology mode is Centralized" ) - return message_passer.apply(agent_state.params["message_passer_params"], h, adj_matrix) + return jax.vmap(lambda x: message_passer.apply(p, x, adj_matrix))(h) hidden = apply_per_node(sensor, agent_state.params["sensor_params"], next_obs) if message_passer is not None: - hidden = jax.vmap(apply_message_passing)(hidden) + hidden = jax.vmap(apply_message_passing)( + agent_state.params["message_passer_params"], hidden + ) hidden_critic = apply_shared( feature_extractor, agent_state.params["feature_extractor_params"], next_obs @@ -334,7 +336,6 @@ def _reward_fn(env_state, next_env_state): return jnp.where(next_env_state.terminated, 50.0, clipped_env_reward - penalty) -# TODO: message passing def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, morph_mode, segments_per_arm): next_env_state = env_step_fn(env_state, action) From 90c2c3d1f0e6d3d3633757744a2392f39b99c521 Mon Sep 17 00:00:00 2001 From: Jona Reynaert Date: Sun, 3 May 2026 15:53:26 +0200 Subject: [PATCH 39/96] feat: added flags for checkpoint evaluation --- configs/logging/default.yaml | 3 +++ src/experiment_logger/config_logger.py | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/configs/logging/default.yaml b/configs/logging/default.yaml index 1ecf7fd..af9bc6d 100644 --- a/configs/logging/default.yaml +++ b/configs/logging/default.yaml @@ -11,3 +11,6 @@ checkpoint_frequency: 100 upload_final_model: false upload_checkpoints: false hf_entity: "" +evaluate_checkpoints: false +eval_max_steps: 5000 +eval_seed: 0 \ No newline at end of file diff --git a/src/experiment_logger/config_logger.py b/src/experiment_logger/config_logger.py index c34c162..d158e84 100644 --- a/src/experiment_logger/config_logger.py +++ b/src/experiment_logger/config_logger.py @@ -18,6 +18,13 @@ class LoggingConfig: upload_final_model: bool = False upload_checkpoints: bool = False + # Checkpoint evaluation (synchronous, in-process) + # When enabled, each saved checkpoint is evaluated headlessly and the results + # are appended to a CSV in the run's metrics/ folder. + evaluate_checkpoints: bool = False + eval_max_steps: int = 5000 + eval_seed: int = 0 + hf_entity: str = "" def __post_init__(self): @@ -31,3 +38,20 @@ class LoggingConfig: "Configuration Error: 'upload_checkpoints' is True, but it requires " "both 'track' and 'save_checkpoints' to also be True." ) + + if self.evaluate_checkpoints: + if not self.save_checkpoints: + raise ValueError( + "Configuration Error: 'evaluate_checkpoints' is True, but it requires " + "'save_checkpoints' to also be True." + ) + if self.checkpoint_frequency <= 0: + raise ValueError( + "Configuration Error: 'evaluate_checkpoints' is True, but it requires " + "'checkpoint_frequency' to be > 0." + ) + if self.eval_max_steps <= 0: + raise ValueError( + "Configuration Error: 'eval_max_steps' must be > 0 when " + "'evaluate_checkpoints' is enabled." + ) From a3d6b32eaa78442f3f39a1f1c2330122a0dff58e Mon Sep 17 00:00:00 2001 From: Jona Reynaert Date: Sun, 3 May 2026 15:53:47 +0200 Subject: [PATCH 40/96] feat: implemented checkpoint evaluation --- .../trainers/PPOTrainer.py | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index a3e4eac..725f29b 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -1,8 +1,10 @@ import datetime import random import time +import csv from dataclasses import asdict, dataclass from functools import partial +from pathlib import Path from typing import Any import jax @@ -26,6 +28,10 @@ from brittle_star_project.MLPs.mlps import ( ) from brittle_star_project.ppo import PPO +from brittle_star_project import Backend, BrittleStarEnv, BrittleStarEnvFactory +from brittle_star_project.evaluation.policy import PolicyAgent +from brittle_star_project.evaluation.rollout import rollout_headless + # TODO: clip scaled reward? @@ -538,6 +544,144 @@ class PPOTrainer: params=self.agent_state.params, step=iteration, metadata=asdict(self.cfg) ) + def _maybe_sync_csv_to_wandb(self, csv_path: Path) -> None: + if not self.logging_cfg.track: + return + try: + import wandb + + if wandb.run is None: + return + + # "Simple sync" behavior: wandb will copy this file into the run. + wandb.save(str(csv_path), base_path=str(csv_path.parent)) + except Exception as e: + self.logger.warning(f"[EVAL]: Failed to sync CSV to wandb: {e}") + + def _append_checkpoint_eval_row( + self, + *, + iteration: int, + reached_target: bool, + steps_to_target: int, + max_steps: int, + seed: int, + ) -> Path: + metrics_dir = Path(self.run_dir) / "metrics" + metrics_dir.mkdir(parents=True, exist_ok=True) + csv_path = metrics_dir / "checkpoint_evaluation.csv" + + file_exists = csv_path.exists() + with open(csv_path, "a", newline="") as f: + writer = csv.DictWriter( + f, + fieldnames=[ + "iteration", + "steps_to_target", + "reached_target", + "max_steps", + "seed", + ], + ) + if not file_exists: + writer.writeheader() + writer.writerow( + { + "iteration": int(iteration), + "steps_to_target": int(steps_to_target), + "reached_target": bool(reached_target), + "max_steps": int(max_steps), + "seed": int(seed), + } + ) + + return csv_path + + def _evaluate_checkpoint(self, iteration: int) -> None: + if not self.logging_cfg.evaluate_checkpoints: + return + + checkpoint_path = Path(self.run_dir) / "checkpoints" / f"checkpoint_step_{iteration}.flax" + if not checkpoint_path.exists(): + self.logger.warning( + f"[EVAL]: Checkpoint not found at {checkpoint_path} (skipping evaluation)" + ) + return + + max_steps = int(self.logging_cfg.eval_max_steps) + seed = int(self.logging_cfg.eval_seed) + + # Run evaluation best-effort; never fail training because evaluation failed. + env = None + try: + backend = Backend.MJC + + factory = BrittleStarEnvFactory() + raw_env = factory.create_environment( + backend, + self.cfg.morphology, + self.cfg.arena, + self.cfg.environment, + ) + env = BrittleStarEnv( + raw_env, + backend=backend, + config=self.cfg.environment, + morphology_config=self.cfg.morphology, + ) + + action_space = getattr(raw_env, "action_space", None) + action_dim = ( + int(np.asarray(action_space.shape).reshape(-1)[0]) + if action_space is not None and hasattr(action_space, "shape") + else sum(self.cfg.morphology.segments_per_arm) * 2 + ) + + action_low = ( + None + if action_space is None + else np.asarray(action_space.low, dtype=np.float32).ravel() + ) + action_high = ( + None + if action_space is None + else np.asarray(action_space.high, dtype=np.float32).ravel() + ) + + policy = PolicyAgent.from_checkpoint( + checkpoint_path, + action_dim=action_dim, + obs_processor=self.obs_processor, + ) + + result = rollout_headless( + env=env, + policy=policy, + seed=seed, + max_steps=max_steps, + action_low=action_low, + action_high=action_high, + action_mask=None, + ) + + steps_to_target = int(result.length) if result.reached_target else int(max_steps) + csv_path = self._append_checkpoint_eval_row( + iteration=iteration, + reached_target=bool(result.reached_target), + steps_to_target=steps_to_target, + max_steps=max_steps, + seed=seed, + ) + self._maybe_sync_csv_to_wandb(csv_path) + except Exception as e: + self.logger.warning(f"[EVAL]: Checkpoint evaluation failed: {e}") + finally: + try: + if env is not None: + env.close() + except Exception: + pass + def train(self): """ Train the PPO agent for a specified number of iterations. @@ -591,6 +735,7 @@ class PPOTrainer: if self.logging_cfg.save_checkpoints and self.logging_cfg.checkpoint_frequency > 0: if iteration % self.logging_cfg.checkpoint_frequency == 0: self._save_checkpoint(iteration) + self._evaluate_checkpoint(iteration) if getattr(self.cfg.experiment, "debug_sanity", False): self.logger.info("\n[SANITY CHECK] Successfully completed 1 epoch") From 0b845dd7a9a2783565943564a76625f2355ada67 Mon Sep 17 00:00:00 2001 From: Jona Reynaert Date: Sun, 3 May 2026 18:26:24 +0200 Subject: [PATCH 41/96] fix: improved speed of checkpoint eval --- src/brittle_star_project/evaluation/policy.py | 22 +++ .../trainers/PPOTrainer.py | 179 ++++++++++-------- 2 files changed, 120 insertions(+), 81 deletions(-) diff --git a/src/brittle_star_project/evaluation/policy.py b/src/brittle_star_project/evaluation/policy.py index 5aa2d6e..75b6a22 100644 --- a/src/brittle_star_project/evaluation/policy.py +++ b/src/brittle_star_project/evaluation/policy.py @@ -61,6 +61,28 @@ class PolicyAgent: } self._obs_processor = obs_processor + @classmethod + def from_params( + cls, + *, + sensor_params: Any, + actor_params: Any, + action_dim: int, + obs_processor: Any, + ) -> "PolicyAgent": + """Construct a PolicyAgent directly from in-memory parameters.""" + return cls( + sensor_params=sensor_params, + actor_params=actor_params, + action_dim=action_dim, + obs_processor=obs_processor, + ) + + def set_params(self, *, sensor_params: Any, actor_params: Any) -> None: + """Update parameters for evaluation without rebuilding the model.""" + self._params["sensor_params"] = sensor_params + self._params["actor_params"] = actor_params + @classmethod def from_checkpoint( cls, diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 725f29b..54653a1 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -28,9 +28,7 @@ from brittle_star_project.MLPs.mlps import ( ) from brittle_star_project.ppo import PPO -from brittle_star_project import Backend, BrittleStarEnv, BrittleStarEnvFactory -from brittle_star_project.evaluation.policy import PolicyAgent -from brittle_star_project.evaluation.rollout import rollout_headless +from brittle_star_project.environment.env_types import Backend # TODO: clip scaled reward? @@ -290,6 +288,8 @@ class PPOTrainer: action_low = jnp.asarray(self.env.single_action_space.low, dtype=jnp.float32) action_high = jnp.asarray(self.env.single_action_space.high, dtype=jnp.float32) + self._action_low = action_low + self._action_high = action_high self._rollout_jit = jax.jit( partial( @@ -326,6 +326,60 @@ class PPOTrainer: self.episode_stats = self._init_episode_stats() self._init_random() + # Lazily created MJX/JAX evaluation rollout (compiled on first use) + self._eval_rollout_mjx_fn = None + + def _get_or_create_eval_rollout_mjx_fn(self): + if self._eval_rollout_mjx_fn is not None: + return self._eval_rollout_mjx_fn + + # Use the same backend as training (typically MJX). + if getattr(self.env, "backend", None) != Backend.MJX: + self.logger.warning( + f"[EVAL]: Training env backend is {self.env.backend}; " + "MJX evaluation may be unavailable/slow." + ) + + # We vmap over a single environment (batch size 1) for simplicity. + reset_1 = jax.vmap(self.env.raw.reset) + step_1 = jax.vmap(self.env.raw.step) + + action_low = self._action_low + action_high = self._action_high + obs_processor = self.obs_processor + sensor_apply = self.sensor.apply + actor_apply = self.actor.apply + + def _eval_rollout(params, seed: int, max_steps: int): + rng = jax.random.PRNGKey(seed) + rngs = jnp.asarray(jax.random.split(rng, 1)) + state = reset_1(rng=rngs) + + t0 = jnp.asarray(0, dtype=jnp.int32) + done0 = jnp.squeeze(state.terminated | state.truncated) + + def cond(carry): + t, _state, done = carry + return jnp.logical_and(t < max_steps, jnp.logical_not(done)) + + def body(carry): + t, state, _done = carry + + obs = obs_processor(state.observations) + hidden = sensor_apply(params["sensor_params"], obs) + mean, _log_std = actor_apply(params["actor_params"], hidden) + + action = jnp.clip(mean, action_low, action_high) + next_state = step_1(state=state, action=action) + + done_next = jnp.squeeze(next_state.terminated | next_state.truncated) + return (t + 1, next_state, done_next) + + t, _state, done = jax.lax.while_loop(cond, body, (t0, state, done0)) + return t, done + + self._eval_rollout_mjx_fn = jax.jit(_eval_rollout) + return self._eval_rollout_mjx_fn def _init_random(self): self.logger.info(f"[RANDOM]: Setting random seed to {self.experiment.seed}") @@ -564,24 +618,51 @@ class PPOTrainer: iteration: int, reached_target: bool, steps_to_target: int, - max_steps: int, - seed: int, ) -> Path: metrics_dir = Path(self.run_dir) / "metrics" metrics_dir.mkdir(parents=True, exist_ok=True) csv_path = metrics_dir / "checkpoint_evaluation.csv" + fieldnames = [ + "iteration", + "steps_to_target", + "reached_target", + ] + + # If a previous version created this CSV with a different header, migrate it. + if csv_path.exists(): + try: + with open(csv_path, "r", newline="") as f: + reader = csv.reader(f) + header = next(reader, None) + + if header is not None and list(header) != fieldnames: + migrated_rows: list[dict[str, Any]] = [] + with open(csv_path, "r", newline="") as f: + dict_reader = csv.DictReader(f) + for row in dict_reader: + migrated_rows.append( + { + "iteration": row.get("iteration"), + "steps_to_target": row.get("steps_to_target"), + "reached_target": row.get("reached_target"), + } + ) + + with open(csv_path, "w", newline="") as f: + writer = csv.DictWriter(f, fieldnames=fieldnames) + writer.writeheader() + for row in migrated_rows: + writer.writerow(row) + except Exception: + # Best-effort only; do not fail training on migration issues. + pass + file_exists = csv_path.exists() with open(csv_path, "a", newline="") as f: writer = csv.DictWriter( f, - fieldnames=[ - "iteration", - "steps_to_target", - "reached_target", - "max_steps", - "seed", - ], + fieldnames=fieldnames, ) if not file_exists: writer.writeheader() @@ -590,8 +671,6 @@ class PPOTrainer: "iteration": int(iteration), "steps_to_target": int(steps_to_target), "reached_target": bool(reached_target), - "max_steps": int(max_steps), - "seed": int(seed), } ) @@ -601,86 +680,24 @@ class PPOTrainer: if not self.logging_cfg.evaluate_checkpoints: return - checkpoint_path = Path(self.run_dir) / "checkpoints" / f"checkpoint_step_{iteration}.flax" - if not checkpoint_path.exists(): - self.logger.warning( - f"[EVAL]: Checkpoint not found at {checkpoint_path} (skipping evaluation)" - ) - return - max_steps = int(self.logging_cfg.eval_max_steps) seed = int(self.logging_cfg.eval_seed) # Run evaluation best-effort; never fail training because evaluation failed. - env = None try: - backend = Backend.MJC + eval_fn = self._get_or_create_eval_rollout_mjx_fn() + steps, reached = eval_fn(self.agent_state.params, seed, max_steps) + steps_to_target = int(steps) + reached_target = bool(reached) - factory = BrittleStarEnvFactory() - raw_env = factory.create_environment( - backend, - self.cfg.morphology, - self.cfg.arena, - self.cfg.environment, - ) - env = BrittleStarEnv( - raw_env, - backend=backend, - config=self.cfg.environment, - morphology_config=self.cfg.morphology, - ) - - action_space = getattr(raw_env, "action_space", None) - action_dim = ( - int(np.asarray(action_space.shape).reshape(-1)[0]) - if action_space is not None and hasattr(action_space, "shape") - else sum(self.cfg.morphology.segments_per_arm) * 2 - ) - - action_low = ( - None - if action_space is None - else np.asarray(action_space.low, dtype=np.float32).ravel() - ) - action_high = ( - None - if action_space is None - else np.asarray(action_space.high, dtype=np.float32).ravel() - ) - - policy = PolicyAgent.from_checkpoint( - checkpoint_path, - action_dim=action_dim, - obs_processor=self.obs_processor, - ) - - result = rollout_headless( - env=env, - policy=policy, - seed=seed, - max_steps=max_steps, - action_low=action_low, - action_high=action_high, - action_mask=None, - ) - - steps_to_target = int(result.length) if result.reached_target else int(max_steps) csv_path = self._append_checkpoint_eval_row( iteration=iteration, - reached_target=bool(result.reached_target), + reached_target=reached_target, steps_to_target=steps_to_target, - max_steps=max_steps, - seed=seed, ) self._maybe_sync_csv_to_wandb(csv_path) except Exception as e: self.logger.warning(f"[EVAL]: Checkpoint evaluation failed: {e}") - finally: - try: - if env is not None: - env.close() - except Exception: - pass def train(self): """ From f66e073f186186c93aa73b3814ed8587fe4f775d Mon Sep 17 00:00:00 2001 From: Jona Reynaert Date: Sun, 3 May 2026 23:56:27 +0200 Subject: [PATCH 42/96] feat: reset training envs when goal is reached --- .../trainers/PPOTrainer.py | 123 +++++++++++++++--- 1 file changed, 108 insertions(+), 15 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index a3e4eac..6f5a301 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -86,6 +86,7 @@ def _step_once( carry, _, env_step_fn, + num_envs: int, sensor: GenericDenseLayersWithActivation, feature_extractor: GenericDenseLayersWithActivation, actor: Actor, @@ -93,15 +94,24 @@ def _step_once( action_low, action_high, ): - agent_state, episode_stats, obs, done, key, env_state = carry + agent_state, episode_stats, obs, done, key, env_state, terminated_any, truncated_any = carry clipped_action, raw_action, logprob, value, mean, std, key = _get_action_and_value_noise( sensor, feature_extractor, actor, critic, agent_state, obs, key, action_low, action_high ) - episode_stats, env_state, (next_obs, reward, next_done) = env_step_fn( - episode_stats, env_state, clipped_action + key, reset_key = jax.random.split(key) + reset_rngs = jax.random.split(reset_key, num_envs) + + episode_stats, env_state, (next_obs, reward, next_done, terminated, truncated) = env_step_fn( + episode_stats, + env_state, + clipped_action, + reset_rngs, ) + terminated_any = terminated_any | terminated + truncated_any = truncated_any | truncated + storage = Storage( obs=obs, actions=raw_action, @@ -115,7 +125,16 @@ def _step_once( returns=jnp.zeros_like(reward), advantages=jnp.zeros_like(reward), ) - return (agent_state, episode_stats, next_obs, next_done, key, env_state), storage + return ( + agent_state, + episode_stats, + next_obs, + next_done, + key, + env_state, + terminated_any, + truncated_any, + ), storage def _reward_fn(env_state, next_env_state): @@ -135,12 +154,20 @@ def _reward_fn(env_state, next_env_state): return jnp.where(next_env_state.terminated, 50.0, clipped_env_reward - penalty) -def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, obs_processor): - next_env_state = env_step_fn(env_state, action) +def _step_env_wrapped( + episode_stats, + env_state, + action, + reset_rngs, + env_step_fn, + reset_single_fn, + obs_processor, +): + next_env_state_pre_reset = env_step_fn(env_state, action) - reward = _reward_fn(env_state, next_env_state) - terminated = next_env_state.terminated - truncated = next_env_state.truncated + reward = _reward_fn(env_state, next_env_state_pre_reset) + terminated = next_env_state_pre_reset.terminated + truncated = next_env_state_pre_reset.truncated done = terminated | truncated new_episode_return = episode_stats.episode_returns + reward @@ -156,10 +183,39 @@ def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, obs_process done, new_episode_length, episode_stats.returned_episode_lengths ), ) + + def _maybe_reset(state_i, rng_i, do_reset_i): + def _do(_): + reset_state = reset_single_fn(rng=rng_i) + + def _cast_leaf(new_leaf, like_leaf): + if like_leaf is None or new_leaf is None: + return new_leaf + + # Use jnp.asarray(...) to robustly get dtype for both JAX arrays and Python scalars. + like_dtype = jnp.asarray(like_leaf).dtype + + # Avoid unnecessary work when already matching. + if hasattr(new_leaf, "dtype") and new_leaf.dtype == like_dtype: + return new_leaf + + return jnp.asarray(new_leaf, dtype=like_dtype) + + # `lax.cond` requires both branches to return identical PyTree types/dtypes. + return jax.tree_util.tree_map(_cast_leaf, reset_state, state_i) + + def _dont(_): + return state_i + + return jax.lax.cond(do_reset_i, _do, _dont, operand=None) + + # Auto-reset done envs so rollouts continue with fresh episode initial states. + next_env_state = jax.vmap(_maybe_reset)(next_env_state_pre_reset, reset_rngs, done) + return ( episode_stats, next_env_state, - (obs_processor(next_env_state.observations), reward, done), + (obs_processor(next_env_state.observations), reward, done, terminated, truncated), ) @@ -172,6 +228,7 @@ def _rollout_jit( key, max_steps, step_env_fn, + num_envs: int, sensor: GenericDenseLayersWithActivation, feature_extractor: GenericDenseLayersWithActivation, actor: Actor, @@ -179,7 +236,19 @@ def _rollout_jit( action_low, action_high, ): - (agent_state, episode_stats, next_obs, next_done, key, env_state), storage = jax.lax.scan( + terminated_any0 = jnp.zeros((num_envs,), dtype=jnp.bool_) + truncated_any0 = jnp.zeros((num_envs,), dtype=jnp.bool_) + + ( + agent_state, + episode_stats, + next_obs, + next_done, + key, + env_state, + terminated_any, + truncated_any, + ), storage = jax.lax.scan( partial( _step_once, sensor=sensor, @@ -187,14 +256,34 @@ def _rollout_jit( actor=actor, critic=critic, env_step_fn=step_env_fn, + num_envs=num_envs, action_low=action_low, action_high=action_high, ), - (agent_state, episode_stats, next_obs, next_done, key, env_state), + ( + agent_state, + episode_stats, + next_obs, + next_done, + key, + env_state, + terminated_any0, + truncated_any0, + ), (), max_steps, ) - return agent_state, episode_stats, next_obs, next_done, storage, key, env_state + return ( + agent_state, + episode_stats, + next_obs, + next_done, + storage, + key, + env_state, + terminated_any, + truncated_any, + ) def _compute_gae_once(carry, inp, gamma, gae_lambda): @@ -292,8 +381,10 @@ class PPOTrainer: step_env_fn=partial( _step_env_wrapped, env_step_fn=self.env.step, + reset_single_fn=self.env.raw.reset, obs_processor=self.obs_processor, ), + num_envs=self.ppo.num_envs, sensor=self.sensor, feature_extractor=self.feature_extractor, actor=self.actor, @@ -467,6 +558,8 @@ class PPOTrainer: storage, self.key, next_env_state, + terminated_any, + truncated_any, ) = self._rollout(env_state, next_obs, next_done) if iteration == 1: @@ -490,8 +583,8 @@ class PPOTrainer: explained_var = _compute_explained_variance(storage.values, storage.returns) - terminated = next_env_state.terminated - truncated = next_env_state.truncated + terminated = terminated_any + truncated = truncated_any episode_lengths = self.episode_stats.returned_episode_lengths num_terminated = int(jnp.sum(terminated).item()) From 0a00a978e8e4e9f99dd2dd5e0df67c3c2a003c40 Mon Sep 17 00:00:00 2001 From: Jona Reynaert Date: Mon, 4 May 2026 00:00:05 +0200 Subject: [PATCH 43/96] fix: formatted file --- .../trainers/PPOTrainer.py | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 6f5a301..9f22ae3 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -240,15 +240,18 @@ def _rollout_jit( truncated_any0 = jnp.zeros((num_envs,), dtype=jnp.bool_) ( - agent_state, - episode_stats, - next_obs, - next_done, - key, - env_state, - terminated_any, - truncated_any, - ), storage = jax.lax.scan( + ( + agent_state, + episode_stats, + next_obs, + next_done, + key, + env_state, + terminated_any, + truncated_any, + ), + storage, + ) = jax.lax.scan( partial( _step_once, sensor=sensor, From a43f3c0172993cb578a376695929034da0892a25 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Mon, 4 May 2026 19:36:59 +0200 Subject: [PATCH 44/96] fix(ppo training): fixed shape error while clipping action --- scripts/train.py | 2 +- src/brittle_star_project/MLPs/mlps.py | 1 + .../trainers/PPOTrainer.py | 105 ++++++++++-------- 3 files changed, 58 insertions(+), 50 deletions(-) diff --git a/scripts/train.py b/scripts/train.py index f82d6bc..8e61bd0 100644 --- a/scripts/train.py +++ b/scripts/train.py @@ -42,7 +42,7 @@ def main(dict_cfg: DictConfig): base_dir=os.path.dirname(run_dir), ) logger = get_logger() - logger.set_level(logging.INFO) + logger.set_level(logging.DEBUG) logger.info(f"Hydra-initialized run: {run_name}") logger.info(f"Output directory: {run_dir}") diff --git a/src/brittle_star_project/MLPs/mlps.py b/src/brittle_star_project/MLPs/mlps.py index cf488c1..27d81c9 100644 --- a/src/brittle_star_project/MLPs/mlps.py +++ b/src/brittle_star_project/MLPs/mlps.py @@ -44,6 +44,7 @@ class MessagePasser(nn.Module): @nn.compact def __call__(self, x: jnp.ndarray, adj_matrix: jnp.ndarray): for _ in range(self.num_propagation_steps): + # (n_nodes, feat) messages = nn.Dense(self.hidden_dim)(x) messages = nn.tanh(messages) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 7e11b29..30e45f3 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -220,18 +220,16 @@ def _get_action_and_value_noise( action_high, adj_matrix: jnp.ndarray, ): - def apply_message_passing(p, h): - assert message_passer is not None, ( - "message passing shouldn't be performed if morphology mode is Centralized" - ) - - return jax.vmap(lambda x: message_passer.apply(p, x, adj_matrix))(h) - + # (B, n_nodes, feat) hidden = apply_per_node(sensor, agent_state.params["sensor_params"], next_obs) + get_logger().debug(f"[_get_action_and_value_noise] hidden (before): {hidden.shape}") + if message_passer is not None: - hidden = jax.vmap(apply_message_passing)( - agent_state.params["message_passer_params"], hidden - ) + params = agent_state.params["message_passer_params"] + # (n_nodes, feat) --> let each node talk with its neighbours ==> vmap over B dimension + hidden = jax.vmap(lambda x: message_passer.apply(params, x, adj_matrix))(hidden) + + get_logger().debug(f"[_get_action_and_value_noise] hidden (after): {hidden.shape}") hidden_critic = apply_shared( feature_extractor, agent_state.params["feature_extractor_params"], next_obs @@ -244,10 +242,11 @@ def _get_action_and_value_noise( std = jnp.exp(log_std) raw_action = mean + noise * std - flat_action = raw_action.reshape( - raw_action.shape[0], -1 + clipped_action = _clip_action(raw_action, action_low, action_high) + + flat_clipped_action = clipped_action.reshape( + clipped_action.shape[0], -1 ) # concat the per agent, keep the envs dim (batch, agent * action) - flat_clipped_action = _clip_action(flat_action, action_low, action_high) logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum( axis=(-2, -1) @@ -632,73 +631,81 @@ class PPOTrainer: self.morph_mode, self.segments_per_arm, )[0] # take first env - self.logger.info(f"[_init_agent_state] sample_obs: {sample_obs.shape}") + + self.logger.debug(f"[_init_agent_state] sample_obs: {sample_obs.shape}") self.obs_mean = jnp.zeros((len(sample_obs),)) self.obs_var = jnp.ones((len(sample_obs),)) self.obs_count = 1e-4 - self.logger.info(f"[_init_agent_state] obs_mean: {self.obs_mean.shape}") - self.logger.info(f"[_init_agent_state] obs_var: {self.obs_var.shape}") + self.logger.debug(f"[_init_agent_state] obs_mean: {self.obs_mean.shape}") + self.logger.debug(f"[_init_agent_state] obs_var: {self.obs_var.shape}") + self.logger.debug(f"[_init_agent_state]: Needed copies: {self.needed_copies}") sensor_keys = jax.random.split(sensor_key, self.needed_copies) actor_keys = jax.random.split(actor_key, self.needed_copies) # note: assumed only 1 message passer needed for now # message_passer_keys = jax.random.split(message_passer_key, self.needed_copies) - message_passer_keys = jnp.asarray([message_passer_key], dtype=jnp.uint32) # (needed_copies, 175) sensor_params = jax.vmap(lambda k: self.sensor.init(k, sample_obs))(sensor_keys) - self.logger.info( - f"[_init_agent_state] sensor_params: {jax.tree.map(lambda x: x.shape, sensor_params)}" - ) + # self.logger.debug( + # f"[_init_agent_state] sensor_params: {jax.tree.map(lambda x: x.shape, sensor_params)}" + # ) single_sensor_param = jax.tree.map(lambda x: x[0], sensor_params) - self.logger.info( - f"[_init_agent_state] single_sensor_param: { - jax.tree.map(lambda x: x.shape, single_sensor_param) - }" - ) + # self.logger.debug( + # f"[_init_agent_state] single_sensor_param: { + # jax.tree.map(lambda x: x.shape, single_sensor_param) + # }" + # ) sensor_params_sample = self.sensor.apply(single_sensor_param, sample_obs) - self.logger.info(f"[_init_agent_state] sensor_params_sample: {sensor_params_sample.shape}") + self.logger.debug( + f"[_init_agent_state] sensor_params_sample shape: {sensor_params_sample.shape}" + ) actor_params = jax.vmap(lambda k: self.actor.init(k, sensor_params_sample))(actor_keys) - self.logger.info( - f"[_init_agent_state] actor_params: {jax.tree.map(lambda x: x.shape, actor_params)}" - ) + # self.logger.debug( + # f"[_init_agent_state] actor_params: {jax.tree.map(lambda x: x.shape, actor_params)}" + # ) message_passer_params = {} if self.morph_mode != MorphMode.CENTRALIZED: assert self.message_passer is not None, "MessagePasser is None" - message_passer_params = jax.vmap( - lambda k: self.message_passer.init( - k, self.sensor.apply(single_sensor_param, sample_obs), self.adj - ) - )(message_passer_keys) - self.logger.info( - f"[_init_agent_state] message_passer_params: { - jax.tree.map(lambda x: x.shape, message_passer_params) - }" - ) + # message_passer_params = jax.vmap( + # lambda k: self.message_passer.init( + # k, self.sensor.apply(single_sensor_param, sample_obs), self.adj + # ) + # )(message_passer_keys) + message_passer_params = self.message_passer.init( + message_passer_key, + self.sensor.apply(single_sensor_param, sample_obs), + self.adj, + ) + # self.logger.debug( + # f"[_init_agent_state] message_passer_params: { + # jax.tree.map(lambda x: x.shape, message_passer_params) + # }" + # ) flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic - self.logger.info(f"[_init_agent_state] flat_obs: {flat_obs.shape}") + self.logger.debug(f"[_init_agent_state] flat_obs: {flat_obs.shape}") feature_extractor_params = self.feature_extractor.init(feature_extractor_key, flat_obs) - self.logger.info( - f"[_init_agent_state] feature_extractor_params: { - jax.tree.map(lambda x: x.shape, feature_extractor_params) - }" - ) + # self.logger.debug( + # f"[_init_agent_state] feature_extractor_params: { + # jax.tree.map(lambda x: x.shape, feature_extractor_params) + # }" + # ) critic_input = self.feature_extractor.apply(feature_extractor_params, flat_obs) - self.logger.info(f"[_init_agent_state] critic_input: {critic_input.shape}") + self.logger.debug(f"[_init_agent_state] critic_input: {critic_input.shape}") critic_params = self.critic.init(critic_key, critic_input) - self.logger.info( - f"[_init_agent_state] critic_params: {jax.tree.map(lambda x: x.shape, critic_params)}" - ) + # self.logger.debug( + # f"[_init_agent_state] critic_params: {jax.tree.map(lambda x: x.shape, critic_params)}" + # ) return TrainState.create( apply_fn=None, From dd2612e2ec1a9c82cb1bac668c3e4276cc836984 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Mon, 4 May 2026 21:26:34 +0200 Subject: [PATCH 45/96] fix(ppo training): more shape-related bug fixes + moved computation of #arms and segments outside of jit compiled function --- .../trainers/PPOTrainer.py | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 30e45f3..cfe548a 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -133,10 +133,7 @@ def _normalize_obs(obs, mean, var, eps=1e-8): return jnp.clip((obs - mean) / jnp.sqrt(var + eps), -10.0, 10.0) -def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, segments_per_arm: jnp.ndarray): - num_segments = int(segments_per_arm.sum()) - num_arms = int(jnp.where(segments_per_arm > 0, 1, 0).sum()) - +def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, num_segments: int, num_arms: int): @logged_jit def _filter_and_flatten(o) -> jnp.ndarray: # vmap feeds one env at a time — v has NO batch dim here @@ -222,15 +219,12 @@ def _get_action_and_value_noise( ): # (B, n_nodes, feat) hidden = apply_per_node(sensor, agent_state.params["sensor_params"], next_obs) - get_logger().debug(f"[_get_action_and_value_noise] hidden (before): {hidden.shape}") if message_passer is not None: params = agent_state.params["message_passer_params"] # (n_nodes, feat) --> let each node talk with its neighbours ==> vmap over B dimension hidden = jax.vmap(lambda x: message_passer.apply(params, x, adj_matrix))(hidden) - get_logger().debug(f"[_get_action_and_value_noise] hidden (after): {hidden.shape}") - hidden_critic = apply_shared( feature_extractor, agent_state.params["feature_extractor_params"], next_obs ) @@ -242,11 +236,10 @@ def _get_action_and_value_noise( std = jnp.exp(log_std) raw_action = mean + noise * std - clipped_action = _clip_action(raw_action, action_low, action_high) - - flat_clipped_action = clipped_action.reshape( - clipped_action.shape[0], -1 + flat_action = raw_action.reshape( + raw_action.shape[0], -1 ) # concat the per agent, keep the envs dim (batch, agent * action) + flat_clipped_action = _clip_action(flat_action, action_low, action_high) logprob = -0.5 * (((raw_action - mean) / std) ** 2 + 2 * log_std + jnp.log(2 * jnp.pi)).sum( axis=(-2, -1) @@ -335,7 +328,9 @@ def _reward_fn(env_state, next_env_state): return jnp.where(next_env_state.terminated, 50.0, clipped_env_reward - penalty) -def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, morph_mode, segments_per_arm): +def _step_env_wrapped( + episode_stats, env_state, action, env_step_fn, morph_mode, num_segments: int, num_arms: int +): next_env_state = env_step_fn(env_state, action) reward = _reward_fn(env_state, next_env_state) @@ -361,7 +356,7 @@ def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, morph_mode, next_env_state, ( _convert_obs_dict_to_array_morphology( - next_env_state.observations, morph_mode, segments_per_arm + next_env_state.observations, morph_mode, num_segments, num_arms ), reward, done, @@ -508,6 +503,9 @@ class PPOTrainer: self.morph_mode = self.cfg.morphology.morph_mode self.segments_per_arm = jnp.asarray(self.cfg.morphology.segments_per_arm, dtype=jnp.int32) + self.num_segments = self.segments_per_arm.sum().item() + self.num_arms = jnp.where(self.segments_per_arm > 0, 1, 0).sum().item() + self.logger.info(f"[INIT]: Used morphology mode {self.morph_mode}") self.adj = build_adjacency(cfg.morphology.segments_per_arm, self.morph_mode) @@ -536,7 +534,8 @@ class PPOTrainer: _step_env_wrapped, env_step_fn=self.env.step, morph_mode=self.morph_mode, - segments_per_arm=self.segments_per_arm, + num_segments=self.num_segments, + num_arms=self.num_arms, ), sensor=self.sensor, feature_extractor=self.feature_extractor, @@ -601,7 +600,7 @@ class PPOTrainer: self.segments_per_arm.sum() + jnp.where(self.segments_per_arm > 0, 1, 0).sum() ).item() - actor = Actor(action_dim=self.env.single_action_space.shape[0]) + actor = Actor(action_dim=self.env.single_action_space.shape[0] // needed_copies) sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) message_passer: Optional[nn.Module] = ( MessagePasser( @@ -629,12 +628,13 @@ class PPOTrainer: sample_obs = _convert_obs_dict_to_array_morphology( dummy_reset.observations, self.morph_mode, - self.segments_per_arm, + self.num_segments, + self.num_arms, )[0] # take first env self.logger.debug(f"[_init_agent_state] sample_obs: {sample_obs.shape}") - self.obs_mean = jnp.zeros((len(sample_obs),)) - self.obs_var = jnp.ones((len(sample_obs),)) + self.obs_mean = jnp.zeros((sample_obs.shape[-1],)) + self.obs_var = jnp.ones((sample_obs.shape[-1],)) self.obs_count = 1e-4 self.logger.debug(f"[_init_agent_state] obs_mean: {self.obs_mean.shape}") self.logger.debug(f"[_init_agent_state] obs_var: {self.obs_var.shape}") @@ -746,10 +746,13 @@ class PPOTrainer: ) def _update_obs_stats(self, obs: jnp.ndarray): - batch_mean = jnp.mean(obs, axis=0) - batch_var = jnp.var(obs, axis=0) + batch_mean = jnp.mean(obs, axis=(0, 1)) + batch_var = jnp.var(obs, axis=(0, 1)) batch_count = obs.shape[0] + self.logger.debug(f"Batch mean shape: {batch_mean.shape}") + self.logger.debug(f"obs_mean shape: {self.obs_mean.shape}") + delta = batch_mean - self.obs_mean total_count = self.obs_count + batch_count @@ -932,7 +935,8 @@ class PPOTrainer: next_obs = _convert_obs_dict_to_array_morphology( env_state.observations, self.morph_mode, - self.segments_per_arm, + self.num_segments, + self.num_arms, ) self.logger.info(f"[train] next_obs: {next_obs.shape}") next_done = jnp.zeros(self.ppo.num_envs, dtype=jnp.bool_) From 791dcf231c98268c91aaa90db32a45bafb3f91bf Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Mon, 4 May 2026 21:29:27 +0200 Subject: [PATCH 46/96] other(ppo training loop): code cleanup + enabled debug logging of model parameters --- scripts/train.py | 2 +- .../trainers/PPOTrainer.py | 58 ++++++++----------- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/scripts/train.py b/scripts/train.py index 8e61bd0..f82d6bc 100644 --- a/scripts/train.py +++ b/scripts/train.py @@ -42,7 +42,7 @@ def main(dict_cfg: DictConfig): base_dir=os.path.dirname(run_dir), ) logger = get_logger() - logger.set_level(logging.DEBUG) + logger.set_level(logging.INFO) logger.info(f"Hydra-initialized run: {run_name}") logger.info(f"Output directory: {run_dir}") diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index cfe548a..81aa361 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -643,21 +643,18 @@ class PPOTrainer: sensor_keys = jax.random.split(sensor_key, self.needed_copies) actor_keys = jax.random.split(actor_key, self.needed_copies) - # note: assumed only 1 message passer needed for now - # message_passer_keys = jax.random.split(message_passer_key, self.needed_copies) - - # (needed_copies, 175) + # (needed_copies, X) sensor_params = jax.vmap(lambda k: self.sensor.init(k, sample_obs))(sensor_keys) - # self.logger.debug( - # f"[_init_agent_state] sensor_params: {jax.tree.map(lambda x: x.shape, sensor_params)}" - # ) + self.logger.debug( + f"[_init_agent_state] sensor_params: {jax.tree.map(lambda x: x.shape, sensor_params)}" + ) single_sensor_param = jax.tree.map(lambda x: x[0], sensor_params) - # self.logger.debug( - # f"[_init_agent_state] single_sensor_param: { - # jax.tree.map(lambda x: x.shape, single_sensor_param) - # }" - # ) + self.logger.debug( + f"[_init_agent_state] single_sensor_param: { + jax.tree.map(lambda x: x.shape, single_sensor_param) + }" + ) sensor_params_sample = self.sensor.apply(single_sensor_param, sample_obs) self.logger.debug( @@ -665,47 +662,42 @@ class PPOTrainer: ) actor_params = jax.vmap(lambda k: self.actor.init(k, sensor_params_sample))(actor_keys) - # self.logger.debug( - # f"[_init_agent_state] actor_params: {jax.tree.map(lambda x: x.shape, actor_params)}" - # ) + self.logger.debug( + f"[_init_agent_state] actor_params: {jax.tree.map(lambda x: x.shape, actor_params)}" + ) message_passer_params = {} if self.morph_mode != MorphMode.CENTRALIZED: assert self.message_passer is not None, "MessagePasser is None" - # message_passer_params = jax.vmap( - # lambda k: self.message_passer.init( - # k, self.sensor.apply(single_sensor_param, sample_obs), self.adj - # ) - # )(message_passer_keys) message_passer_params = self.message_passer.init( message_passer_key, self.sensor.apply(single_sensor_param, sample_obs), self.adj, ) - # self.logger.debug( - # f"[_init_agent_state] message_passer_params: { - # jax.tree.map(lambda x: x.shape, message_passer_params) - # }" - # ) + self.logger.debug( + f"[_init_agent_state] message_passer_params: { + jax.tree.map(lambda x: x.shape, message_passer_params) + }" + ) flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic self.logger.debug(f"[_init_agent_state] flat_obs: {flat_obs.shape}") feature_extractor_params = self.feature_extractor.init(feature_extractor_key, flat_obs) - # self.logger.debug( - # f"[_init_agent_state] feature_extractor_params: { - # jax.tree.map(lambda x: x.shape, feature_extractor_params) - # }" - # ) + self.logger.debug( + f"[_init_agent_state] feature_extractor_params: { + jax.tree.map(lambda x: x.shape, feature_extractor_params) + }" + ) critic_input = self.feature_extractor.apply(feature_extractor_params, flat_obs) self.logger.debug(f"[_init_agent_state] critic_input: {critic_input.shape}") critic_params = self.critic.init(critic_key, critic_input) - # self.logger.debug( - # f"[_init_agent_state] critic_params: {jax.tree.map(lambda x: x.shape, critic_params)}" - # ) + self.logger.debug( + f"[_init_agent_state] critic_params: {jax.tree.map(lambda x: x.shape, critic_params)}" + ) return TrainState.create( apply_fn=None, From 43de6a967002f5dd82d11425daa854e824bd3a64 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Mon, 4 May 2026 22:23:58 +0200 Subject: [PATCH 47/96] merge: merged dev into branch --- src/brittle_star_project/MLPs/mlps.py | 3 +- .../environment/obs_processing.py | 65 ++++++- .../trainers/PPOTrainer.py | 164 ++---------------- 3 files changed, 79 insertions(+), 153 deletions(-) diff --git a/src/brittle_star_project/MLPs/mlps.py b/src/brittle_star_project/MLPs/mlps.py index 27d81c9..cc8c226 100644 --- a/src/brittle_star_project/MLPs/mlps.py +++ b/src/brittle_star_project/MLPs/mlps.py @@ -48,7 +48,8 @@ class MessagePasser(nn.Module): messages = nn.Dense(self.hidden_dim)(x) messages = nn.tanh(messages) - agg = adj_matrix # if mean is wanted: adj_matrix / (adj.sum(axis=-1, keepdims=True) + 1e-8) + # note: if mean is wanted: adj_matrix / (adj.sum(axis=-1, keepdims=True) + 1e-8) + agg = adj_matrix aggregated = agg @ messages x_concat = jnp.concatenate([x, aggregated], axis=-1) diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index b18ee8c..6b7cbe8 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -2,6 +2,9 @@ import jax import jax.numpy as jnp from typing import Dict, Tuple, Optional +from brittle_star_project.environment.env_config import MorphMode +from experiment_logger import get_logger + _JOINT_SCALED_KEYS = frozenset( { "joint_position", @@ -19,7 +22,11 @@ _SEGMENT_SCALED_KEYS = frozenset( def create_obs_processor( - bounds_dict: Dict[str, Tuple[float, float]], padding_masks: Optional[Dict] = None + bounds_dict: Dict[str, Tuple[float, float]], + num_segments: int, + num_arms: int, + padding_masks: Optional[Dict] = None, + morph_mode: MorphMode = MorphMode.CENTRALIZED, ): def _add_derived_features(obs: dict) -> dict: new_obs = dict(obs) @@ -52,6 +59,8 @@ def create_obs_processor( return normalized def _pad_features(obs: dict) -> dict: + assert padding_masks is not None + padded = {} for key, arr in obs.items(): if key in _JOINT_SCALED_KEYS: @@ -73,13 +82,55 @@ def create_obs_processor( "robot_direction_to_target", "segment_contact", ] + values = [] - for key in ordered_keys: - if key in obs: - arr = jnp.asarray(obs[key]).flatten() - if arr.size > 0: - values.append(arr) - return jnp.concatenate(values) + + for key in sorted(obs.keys()): + if key not in ordered_keys: + continue + v = obs[key] + + # skip empty arrays and scalars + if v.size == 0: + continue + + # reshape scalars + if v.ndim == 0: + v = v.reshape(1) + + # -------- CENTRALIZED -------- + if morph_mode == MorphMode.CENTRALIZED: + values.append(v.reshape(1, -1)) # (1, feat) + continue + + # -------- SPLIT TO SEGMENTS -------- + if key in _JOINT_SCALED_KEYS: + if morph_mode == MorphMode.SEGMENT: + center_size = num_arms * 3 * 2 + v_center = v[:center_size].reshape(num_arms, 3 * 2) # (arms, 6) + v_segs = v[center_size:].reshape(-1, 2) # (segs, 2) + values.append(jnp.concatenate([v_center, v_segs], axis=0)) # (arms+segs, ?) + continue + v = v.reshape(num_arms, -1) # (n_arms, 2) + + elif key in _SEGMENT_SCALED_KEYS: + v = v[:, None] # (segments, 1) + + else: + # global key, broadcast to all nodes + n_nodes = (num_segments + num_arms) if morph_mode == MorphMode.SEGMENT else num_arms + v = jnp.repeat(v[None, :], n_nodes, axis=0) # (n_nodes, feat) + + # -------- SEGMENT MODE -------- + if morph_mode == MorphMode.SEGMENT: + values.append(v) # (n_nodes, feat) + continue + + # -------- ARM MODE -------- + v = v.reshape(num_arms, -1) + values.append(v) # (n_arms, feat) + + return jnp.concatenate(values, axis=-1) def _process_single(obs_dict: dict) -> jnp.ndarray: processed = _add_derived_features(obs_dict) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 569f276..a0af8b7 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -32,18 +32,7 @@ from brittle_star_project.utils import logged_jit logger11 = get_logger() # TODO: move to config -_ALLOWED_OBS_KEYS = { - "joint_position", - "joint_velocity", - "joint_actuator_force", - "actuator_force", - "disk_position", - "disk_rotation", - "disk_linear_velocity", - "disk_angular_velocity", - "unit_xy_direction_to_target", - "xy_distance_to_target", -} + # TODO: clip scaled reward? @@ -129,81 +118,6 @@ def _linear_schedule(count, minibatch_count, update_epochs, num_iterations, lear return learning_rate * frac -@logged_jit -def _normalize_obs(obs, mean, var, eps=1e-8): - return jnp.clip((obs - mean) / jnp.sqrt(var + eps), -10.0, 10.0) - -# TODO: update to work with new obs_processor -def _convert_obs_dict_to_array_morphology(obs_dict, morph_mode, num_segments: int, num_arms: int): - @logged_jit - def _filter_and_flatten(o) -> jnp.ndarray: - # vmap feeds one env at a time — v has NO batch dim here - # shapes are e.g. (n_features,) or (n_nodes, feat) - values = [] - - for key in sorted(o.keys()): - if key not in _ALLOWED_OBS_KEYS: - continue - v = o[key] - if v.size == 0: - continue - - # -------- CENTRALIZED -------- - if morph_mode == MorphMode.CENTRALIZED: - values.append(v.reshape(1, -1)) # (1, feat) - continue - - # -------- SPLIT TO SEGMENTS -------- - if key in _JOINT_SCALED_KEYS: - if morph_mode == MorphMode.SEGMENT: - center_size = num_arms * 3 * 2 - v_center = v[:center_size].reshape(num_arms, 3 * 2) # (arms, 6) - v_segs = v[center_size:].reshape(-1, 2) # (segs, 2) - values.append(jnp.concatenate([v_center, v_segs], axis=0)) # (arms+segs, ?) - continue - v = v.reshape(num_arms, -1) # (n_arms, 2) - - elif key in _SEGMENT_SCALED_KEYS: - v = v[:, None] # (segments, 1) - - else: - # global key, broadcast to all nodes - n_nodes = (num_segments + num_arms) if morph_mode == MorphMode.SEGMENT else num_arms - v = jnp.repeat(v[None, :], n_nodes, axis=0) # (n_nodes, feat) - - # -------- SEGMENT MODE -------- - if morph_mode == MorphMode.SEGMENT: - values.append(v) # (n_nodes, feat) - continue - - # -------- ARM MODE -------- - v = v.reshape(num_arms, -1) - values.append(v) # (n_arms, feat) - - return jnp.concatenate(values, axis=-1) # (n_nodes, total_feat) - - return jax.vmap(_filter_and_flatten)(obs_dict) - # output: (batch, n_nodes, total_feat) - - -# Observation keys whose size scales with the number of joints (2 per segment). -_JOINT_SCALED_KEYS = frozenset( - { # TODO CODE SMELL - "joint_position", - "joint_velocity", - "joint_actuator_force", - "actuator_force", - } -) - -# Observation keys whose size scales with the number of segments (1 per segment). -_SEGMENT_SCALED_KEYS = frozenset( - { - "segment_contact", - } -) - - def _get_action_and_value_noise( sensor: nn.Module, feature_extractor: nn.Module, @@ -249,7 +163,6 @@ def _get_action_and_value_noise( return flat_clipped_action, raw_action, logprob, value.squeeze(-1), mean, std, key -# TODO: update to work vectorized (sensor, actor, message passer) + message passing def _step_once( carry, _, @@ -328,9 +241,7 @@ def _reward_fn(env_state, next_env_state): return jnp.where(next_env_state.terminated, 50.0, clipped_env_reward - penalty) -def _step_env_wrapped( - episode_stats, env_state, action, env_step_fn, morph_mode, num_segments: int, num_arms: int, # TODO: obs_processor -): +def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, obs_processor): next_env_state = env_step_fn(env_state, action) reward = _reward_fn(env_state, next_env_state) @@ -355,13 +266,10 @@ def _step_env_wrapped( episode_stats, next_env_state, ( - _convert_obs_dict_to_array_morphology( - next_env_state.observations, morph_mode, num_segments, num_arms - ), + obs_processor(next_env_state.observations), reward, done, ), - # TODO (obs_processor(next_env_state.observations), reward, done), ) @@ -502,7 +410,7 @@ class PPOTrainer: self.key = jax.random.PRNGKey(self.experiment.seed) self.morph_mode = self.cfg.morphology.morph_mode - + self.segments_per_arm = jnp.asarray(self.cfg.morphology.segments_per_arm, dtype=jnp.int32) self.num_segments = self.segments_per_arm.sum().item() self.num_arms = jnp.where(self.segments_per_arm > 0, 1, 0).sum().item() @@ -527,6 +435,9 @@ class PPOTrainer: # Build the centralized observation processor: derive -> normalize -> pad -> flatten. self.obs_processor = create_obs_processor( bounds_dict=self.cfg.obs_bounds.to_bounds_dict(), + num_segments=self.num_segments, + num_arms=self.num_arms, + morph_mode=self.morph_mode, padding_masks=self.env.padding_masks, ) @@ -540,10 +451,7 @@ class PPOTrainer: step_env_fn=partial( _step_env_wrapped, env_step_fn=self.env.step, - morph_mode=self.morph_mode, - num_segments=self.num_segments, - num_arms=self.num_arms, - # TODO: obs_processor=self.obs_processor, + obs_processor=self.obs_processor, ), sensor=self.sensor, feature_extractor=self.feature_extractor, @@ -605,6 +513,7 @@ class PPOTrainer: self.segments_per_arm.sum() + jnp.where(self.segments_per_arm > 0, 1, 0).sum() ).item() + # scale actor output with size of model --> more models ==> less actions needed per model actor = Actor(action_dim=self.env.single_action_space.shape[0] // needed_copies) sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) message_passer: Optional[nn.Module] = ( @@ -628,15 +537,11 @@ class PPOTrainer: ) dummy_reset = self.env.reset(seed=0) - + for k, v in dummy_reset.observations.items(): self.logger.debug(k, v.shape) - sample_obs = _convert_obs_dict_to_array_morphology( - dummy_reset.observations, - self.morph_mode, - self.num_segments, - self.num_arms, - )[0] # take first env + + sample_obs = self.obs_processor(dummy_reset.observations)[0] # take first env self.logger.debug(f"[_init_agent_state] sample_obs: {sample_obs.shape}") self.obs_mean = jnp.zeros((sample_obs.shape[-1],)) @@ -703,7 +608,6 @@ class PPOTrainer: critic_params = self.critic.init(critic_key, critic_input) self.logger.debug( f"[_init_agent_state] critic_params: {jax.tree.map(lambda x: x.shape, critic_params)}" - # TODO: sample_obs = self.obs_processor(dummy_reset.observations)[0] # take first env ) return TrainState.create( @@ -744,28 +648,6 @@ class PPOTrainer: returned_episode_lengths=jnp.zeros(self.ppo.num_envs, dtype=jnp.int32), ) - def _update_obs_stats(self, obs: jnp.ndarray): - batch_mean = jnp.mean(obs, axis=(0, 1)) - batch_var = jnp.var(obs, axis=(0, 1)) - batch_count = obs.shape[0] - - self.logger.debug(f"Batch mean shape: {batch_mean.shape}") - self.logger.debug(f"obs_mean shape: {self.obs_mean.shape}") - - delta = batch_mean - self.obs_mean - total_count = self.obs_count + batch_count - - new_mean = self.obs_mean + delta * batch_count / total_count - - m_a = self.obs_var * self.obs_count - m_b = batch_var * batch_count - M2 = m_a + m_b + delta**2 * self.obs_count * batch_count / total_count - new_var = M2 / total_count - - self.obs_mean = new_mean - self.obs_var = new_var - self.obs_count = total_count - def _rollout(self, env_state, next_obs, next_done) -> tuple[Any, ...]: return self._rollout_jit( self.agent_state, @@ -840,7 +722,7 @@ class PPOTrainer: def _step(self, env_state, next_obs, next_done, iteration: int) -> tuple: if iteration == 1: self.logger.log_non_interactive(f"Starting first rollout (JIT): {time.ctime()}") - self.logger.info(f"[_step] next_obs (in): {next_obs.shape}") + self.logger.debug(f"[_step] next_obs (in): {next_obs.shape}") ( self.agent_state, self.episode_stats, @@ -850,12 +732,12 @@ class PPOTrainer: self.key, next_env_state, ) = self._rollout(env_state, next_obs, next_done) - self.logger.info(f"[_step] next_obs (post-rollout): {next_obs.shape}") + self.logger.debug(f"[_step] next_obs (post-rollout): {next_obs.shape}") if iteration == 1: self.logger.log_non_interactive(f"First rollout completed: {time.ctime()}") storage = self._compute_gae(storage, next_obs, next_done) - self.logger.info(f"[_step] storage.obs (post-gae): {storage.obs.shape}") + self.logger.debug(f"[_step] storage.obs (post-gae): {storage.obs.shape}") if iteration == 1: self.logger.log_non_interactive(f"Starting first PPO update (JIT): {time.ctime()}") @@ -931,15 +813,10 @@ class PPOTrainer: self.logger.log_non_interactive(f"Initial reset started: {time.ctime()}") env_state = self.env.reset(seed=self.experiment.seed) - - next_obs = _convert_obs_dict_to_array_morphology( - env_state.observations, - self.morph_mode, - self.num_segments, - self.num_arms, - ) - self.logger.info(f"[train] next_obs: {next_obs.shape}") - # TODO: next_obs = self.obs_processor(env_state.observations) + + next_obs = self.obs_processor(env_state.observations) + self.logger.debug(f"[train] next_obs: {next_obs.shape}") + next_done = jnp.zeros(self.ppo.num_envs, dtype=jnp.bool_) self.logger.log_non_interactive(f"Initial reset completed: {time.ctime()}") @@ -954,9 +831,6 @@ class PPOTrainer: env_state, next_obs, next_done, training_measurements, storage = self._step( env_state, next_obs, next_done, iteration=iteration ) - self.logger.debug(f"[train] next_obs (post-step): {next_obs.shape}") - self._update_obs_stats(next_obs) - next_obs = _normalize_obs(next_obs, self.obs_mean, self.obs_var) global_step += self.ppo.num_steps * self.ppo.num_envs self._log( From 2ac21e2014eebc0361e1067e493ace9d0e317366 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Mon, 4 May 2026 22:38:45 +0200 Subject: [PATCH 48/96] fix: linting + format --- .../environment/env_config.py | 2 +- .../environment/obs_processing.py | 1 - src/brittle_star_project/messager.py | 26 ------- .../trainers/PPOTrainer.py | 71 +------------------ tests/test_adjacency.py | 4 +- 5 files changed, 5 insertions(+), 99 deletions(-) delete mode 100644 src/brittle_star_project/messager.py diff --git a/src/brittle_star_project/environment/env_config.py b/src/brittle_star_project/environment/env_config.py index adf0736..33e8bdf 100644 --- a/src/brittle_star_project/environment/env_config.py +++ b/src/brittle_star_project/environment/env_config.py @@ -70,7 +70,7 @@ class EnvConfig: # Per docs in upstream env config: integer factors of 200. light_perlin_noise_scale: int = 0 - + @dataclass class ObservationBoundsConfig: """Physical observation bounds for deterministic min-max normalization.""" diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 6b7cbe8..14b48f2 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -3,7 +3,6 @@ import jax.numpy as jnp from typing import Dict, Tuple, Optional from brittle_star_project.environment.env_config import MorphMode -from experiment_logger import get_logger _JOINT_SCALED_KEYS = frozenset( { diff --git a/src/brittle_star_project/messager.py b/src/brittle_star_project/messager.py deleted file mode 100644 index 7178527..0000000 --- a/src/brittle_star_project/messager.py +++ /dev/null @@ -1,26 +0,0 @@ -import jax -import jax.numpy as jnp - - -def message_passer(params, hidden, adjacency): - # take current hidden state per env, per agent, needs to communicate according to adjacency - # adjacency can be assumed to be the same per env? or mix it too idk - # rest is simple, use adjacency to make which hidden states we can combine - # repeat X times with the new combined vectors - # return result.. - # use jax lax scan stuff or vmap for speed - def per_env(h): - # compute messages per agent - def compute_messages(h_i, h_all): - # broadcast h_i with all neighbors - h_i_rep = jnp.repeat(h_i[None, :], h_all.shape[0], axis=0) - msg_input = jnp.concatenate([h_i_rep, h_all], axis=-1) - messages = messager_apply(params, msg_input) - return messages - - msgs = jax.vmap(compute_messages, in_axes=(0, None))(h, h) - msgs = msgs * adjacency[..., None] # mask neighbors - agg = msgs.sum(axis=1) - return agg - - return jax.vmap(per_env)(hidden) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index a0af8b7..29c5d19 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -18,87 +18,20 @@ from brittle_star_project.configs.main_config import BrittleStarConfig from brittle_star_project.dataclasses import EpisodeStatistics from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleStarJaxEnvWrapper from brittle_star_project.environment.obs_processing import create_obs_processor -from brittle_star_project.MLPs.mlps import ( +from brittle_star_project.MLPs import ( Actor, AgentParams, GenericDenseLayersWithActivation, MessagePasser, OneDenseLayerMLP, Storage, + build_adjacency, ) from brittle_star_project.ppo import PPO from brittle_star_project.environment import MorphMode from brittle_star_project.utils import logged_jit logger11 = get_logger() -# TODO: move to config - -# TODO: clip scaled reward? - - -def build_adjacency(segments_per_arm, mode: MorphMode): - num_arms = sum(1 for s in segments_per_arm if s > 0) - num_segments = sum(segments_per_arm) - - # FOR NOW SEMI HARDCODE: - # CENTRALIZED: 1 agent, no stress, adja = 1,1 = [[1]] - # FULLY CONNECTED: 5 agents: adj = alle 1 - # CENTRAL DISK:#arms= 5 agents, only neighbor as adjacent so diagonal kinda.. - # ARM = #segments agents: diago kinda, but extra, center ring too, put center mlps first or.. - - if mode == MorphMode.CENTRALIZED: - return jnp.ones((1, 1)) - - if mode == MorphMode.FULLY_CONNECTED: - adj = jnp.ones((num_arms, num_arms)) # everybody adjacent everybody - return adj - - if mode == MorphMode.RING: # ring - adj = jnp.zeros((num_arms, num_arms)) - for i in range(num_arms): - adj = adj.at[i, i].set(1) # self - adj = adj.at[i, (i - 1) % num_arms].set(1) - adj = adj.at[i, (i + 1) % num_arms].set(1) # left and right.. - return adj - - if mode == MorphMode.SEGMENT: - num_nodes = num_arms + num_segments - adj = jnp.zeros((num_nodes, num_nodes)) - - # first ring - for i in range(num_arms): - # self - adj = adj.at[i, i].set(1) - - # ring neighbors - adj = adj.at[i, (i - 1) % num_arms].set(1) - adj = adj.at[i, (i + 1) % num_arms].set(1) - - # then segment chains - idx = 0 - for arm_idx, seg_count in enumerate(segments_per_arm): - for i in range(seg_count): - seg_node = num_arms + idx + i - - adj = adj.at[seg_node, seg_node].set(1) - if i > 0: - adj = adj.at[seg_node, seg_node - 1].set(1) - if i < seg_count - 1: - adj = adj.at[seg_node, seg_node + 1].set(1) - - idx += seg_count - - idx = 0 - for arm_idx, seg_count in enumerate(segments_per_arm): - first_seg = num_arms + idx # first segment of this arm - - # connect ring node first segment - adj = adj.at[arm_idx, first_seg].set(1) - adj = adj.at[first_seg, arm_idx].set(1) - - idx += seg_count - - return adj @logged_jit diff --git a/tests/test_adjacency.py b/tests/test_adjacency.py index 5e8a129..e6a1333 100644 --- a/tests/test_adjacency.py +++ b/tests/test_adjacency.py @@ -1,8 +1,8 @@ import jax.numpy as jnp -import pytest import numpy as np -from brittle_star_project.trainers.PPOTrainer import build_adjacency, MorphMode +from brittle_star_project.MLPs import build_adjacency +from brittle_star_project.environment.env_config import MorphMode def assert_symmetric(adj): From b244761db1783619331f2e732069196da6f52c51 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Mon, 4 May 2026 22:39:33 +0200 Subject: [PATCH 49/96] cleanup(MLPs): moved build adjacency to own file, made MLPs a full python package --- src/brittle_star_project/MLPs/__init__.py | 19 ++++++ .../MLPs/adjancency_builder.py | 67 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/brittle_star_project/MLPs/__init__.py create mode 100644 src/brittle_star_project/MLPs/adjancency_builder.py diff --git a/src/brittle_star_project/MLPs/__init__.py b/src/brittle_star_project/MLPs/__init__.py new file mode 100644 index 0000000..8f9c7f7 --- /dev/null +++ b/src/brittle_star_project/MLPs/__init__.py @@ -0,0 +1,19 @@ +from .mlps import ( + GenericDenseLayersWithActivation, + OneDenseLayerMLP, + Actor, + MessagePasser, + AgentParams, + Storage, +) +from .adjancency_builder import build_adjacency + +__all__ = [ + "GenericDenseLayersWithActivation", + "OneDenseLayerMLP", + "Actor", + "MessagePasser", + "AgentParams", + "Storage", + "build_adjacency", +] diff --git a/src/brittle_star_project/MLPs/adjancency_builder.py b/src/brittle_star_project/MLPs/adjancency_builder.py new file mode 100644 index 0000000..878a02c --- /dev/null +++ b/src/brittle_star_project/MLPs/adjancency_builder.py @@ -0,0 +1,67 @@ +from brittle_star_project.environment.env_config import MorphMode +import jax.numpy as jnp + + +def build_adjacency(segments_per_arm, mode: MorphMode): + num_arms = sum(1 for s in segments_per_arm if s > 0) + num_segments = sum(segments_per_arm) + + # FOR NOW SEMI HARDCODE: + # CENTRALIZED: 1 agent, no stress, adja = 1,1 = [[1]] + # FULLY CONNECTED: 5 agents: adj = alle 1 + # CENTRAL DISK:#arms= 5 agents, only neighbor as adjacent so diagonal kinda.. + # ARM = #segments agents: diago kinda, but extra, center ring too, put center mlps first or.. + + if mode == MorphMode.CENTRALIZED: + return jnp.ones((1, 1)) + + if mode == MorphMode.FULLY_CONNECTED: + adj = jnp.ones((num_arms, num_arms)) # everybody adjacent everybody + return adj + + if mode == MorphMode.RING: # ring + adj = jnp.zeros((num_arms, num_arms)) + for i in range(num_arms): + adj = adj.at[i, i].set(1) # self + adj = adj.at[i, (i - 1) % num_arms].set(1) + adj = adj.at[i, (i + 1) % num_arms].set(1) # left and right.. + return adj + + if mode == MorphMode.SEGMENT: + num_nodes = num_arms + num_segments + adj = jnp.zeros((num_nodes, num_nodes)) + + # first ring + for i in range(num_arms): + # self + adj = adj.at[i, i].set(1) + + # ring neighbors + adj = adj.at[i, (i - 1) % num_arms].set(1) + adj = adj.at[i, (i + 1) % num_arms].set(1) + + # then segment chains + idx = 0 + for arm_idx, seg_count in enumerate(segments_per_arm): + for i in range(seg_count): + seg_node = num_arms + idx + i + + adj = adj.at[seg_node, seg_node].set(1) + if i > 0: + adj = adj.at[seg_node, seg_node - 1].set(1) + if i < seg_count - 1: + adj = adj.at[seg_node, seg_node + 1].set(1) + + idx += seg_count + + idx = 0 + for arm_idx, seg_count in enumerate(segments_per_arm): + first_seg = num_arms + idx # first segment of this arm + + # connect ring node first segment + adj = adj.at[arm_idx, first_seg].set(1) + adj = adj.at[first_seg, arm_idx].set(1) + + idx += seg_count + + return adj From 3ad1ad8e394c1ce170affb0cb1661ea9b7a99289 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Tue, 5 May 2026 11:49:32 +0200 Subject: [PATCH 50/96] fix(testing): target direction updated to work with dim >= 2 --- .../environment/obs_processing.py | 1 + tests/test_network_shapes.py | 13 ++++++++++-- tests/test_target_direction.py | 21 ++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 14b48f2..73c2e94 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -105,6 +105,7 @@ def create_obs_processor( # -------- SPLIT TO SEGMENTS -------- if key in _JOINT_SCALED_KEYS: if morph_mode == MorphMode.SEGMENT: + # TODO: remove magic constants center_size = num_arms * 3 * 2 v_center = v[:center_size].reshape(num_arms, 3 * 2) # (arms, 6) v_segs = v[center_size:].reshape(-1, 2) # (segs, 2) diff --git a/tests/test_network_shapes.py b/tests/test_network_shapes.py index e1a7a1a..aad79fc 100644 --- a/tests/test_network_shapes.py +++ b/tests/test_network_shapes.py @@ -20,9 +20,18 @@ def test_centralized_forward_pass_with_padding(): "segment_contact": jnp.zeros((batch_size, 14)), } + segments_per_arm = jnp.array((4, 0, 4, 2, 4)) + num_segments = segments_per_arm.sum().item() + num_arms = jnp.where(segments_per_arm > 0, 1, 0).sum().item() + # 2. Process and Pad Observation - masks = compute_padding_masks(segments_per_arm=(4, 0, 4, 2, 4)) - obs_processor = create_obs_processor(bounds_dict={}, padding_masks=masks) + masks = compute_padding_masks(segments_per_arm=list(segments_per_arm)) + obs_processor = create_obs_processor( + bounds_dict={}, + num_segments=num_segments, + num_arms=num_arms, + padding_masks=masks, + ) global_state = obs_processor(amputated_obs) # 40 + 40 + 20 = 100 dimensions diff --git a/tests/test_target_direction.py b/tests/test_target_direction.py index a81cdf1..825c50c 100644 --- a/tests/test_target_direction.py +++ b/tests/test_target_direction.py @@ -1,6 +1,7 @@ import jax.numpy as jnp from brittle_star_project.configs.main_config import BrittleStarConfig +from brittle_star_project.environment.env_config import MorphMode from brittle_star_project.environment.env_types import Backend from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleStarJaxEnvWrapper from brittle_star_project.environment.obs_processing import create_obs_processor @@ -43,8 +44,16 @@ def test_processor_converts_to_egocentric_direction(): cfg = BrittleStarConfig() env = BrittleStarJaxEnvWrapper.default(num_envs=1, backend=Backend.MJX) + segments_per_arm = jnp.array((4, 4, 4, 4, 4)) + num_segments = segments_per_arm.sum().item() + num_arms = jnp.where(segments_per_arm > 0, 1, 0).sum().item() + obs_processor = create_obs_processor( - bounds_dict=cfg.obs_bounds.to_bounds_dict(), padding_masks=env.padding_masks + bounds_dict=cfg.obs_bounds.to_bounds_dict(), + num_segments=num_segments, + num_arms=num_arms, + padding_masks=env.padding_masks, + morph_mode=MorphMode.CENTRALIZED, ) env_state = env.reset(seed=42) @@ -66,13 +75,19 @@ def test_processor_converts_to_egocentric_direction(): processed_2 = obs_processor(dummy_obs_2) # Find the indices of the elements that changed - diff_array = jnp.abs(processed_1[0] - processed_2[0]) + diff_array = jnp.abs(processed_1[0, 0] - processed_2[0, 0]) changed_indices = jnp.where(diff_array > 1e-4)[0] - local_target = processed_1[0, changed_indices] + # (143,) + local_target = processed_1[0, 0, changed_indices] + + # (2,) expected_local_target = jnp.array([0.0, -1.0]) assert jnp.sum(jnp.abs(local_target - expected_local_target)) < 1e-4, ( f"The obs_processor did not correctly rotate the vector to egocentric. " f"Expected {expected_local_target}, but got {local_target}." ) + + +test_processor_converts_to_egocentric_direction() From 079480324d1c9c4cfccabea560b30d81a8c90e26 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Tue, 5 May 2026 12:11:37 +0200 Subject: [PATCH 51/96] fix(testing): forward pass test updated to new abstraction --- src/brittle_star_project/environment/obs_processing.py | 10 +++++++--- .../environment/padded_obs_wrapper.py | 6 ++++++ tests/test_network_shapes.py | 10 +++++++--- tests/test_target_direction.py | 3 --- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 73c2e94..87ebe10 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -105,9 +105,13 @@ def create_obs_processor( # -------- SPLIT TO SEGMENTS -------- if key in _JOINT_SCALED_KEYS: if morph_mode == MorphMode.SEGMENT: - # TODO: remove magic constants - center_size = num_arms * 3 * 2 - v_center = v[:center_size].reshape(num_arms, 3 * 2) # (arms, 6) + joint_count = 3 + axis_per_joint = 2 + + center_size = num_arms * joint_count * axis_per_joint + v_center = v[:center_size].reshape( + num_arms, joint_count * axis_per_joint + ) # (arms, 6) v_segs = v[center_size:].reshape(-1, 2) # (segs, 2) values.append(jnp.concatenate([v_center, v_segs], axis=0)) # (arms+segs, ?) continue diff --git a/src/brittle_star_project/environment/padded_obs_wrapper.py b/src/brittle_star_project/environment/padded_obs_wrapper.py index ea00713..3216dfe 100644 --- a/src/brittle_star_project/environment/padded_obs_wrapper.py +++ b/src/brittle_star_project/environment/padded_obs_wrapper.py @@ -30,6 +30,12 @@ def compute_padding_masks( mask_2x = [] for arm_idx, (actual, ref) in enumerate(zip(segments_per_arm, reference_segments_per_arm)): + if not isinstance(actual, int): + actual = actual.item() + + if not isinstance(ref, int): + ref = ref.item() + if not (0 <= actual <= ref): raise ValueError( f"Invalid amputation at arm {arm_idx}: " diff --git a/tests/test_network_shapes.py b/tests/test_network_shapes.py index aad79fc..1183377 100644 --- a/tests/test_network_shapes.py +++ b/tests/test_network_shapes.py @@ -1,5 +1,6 @@ import jax import jax.numpy as jnp +from brittle_star_project.environment.env_config import MorphMode from brittle_star_project.environment.padded_obs_wrapper import ( compute_padding_masks, ) @@ -31,11 +32,12 @@ def test_centralized_forward_pass_with_padding(): num_segments=num_segments, num_arms=num_arms, padding_masks=masks, + morph_mode=MorphMode.CENTRALIZED, ) global_state = obs_processor(amputated_obs) # 40 + 40 + 20 = 100 dimensions - assert global_state.shape == (batch_size, 100), ( + assert global_state.shape == (batch_size, 1, 100), ( f"Expected global state shape (2, 100), got {global_state.shape}" ) @@ -54,9 +56,11 @@ def test_centralized_forward_pass_with_padding(): action_mean, action_log_std = actor.apply(actor_params, global_state) value = critic.apply(critic_params, global_state) - assert action_mean.shape == (batch_size, 40), f"Actor mean shape mismatch: {action_mean.shape}" + assert action_mean.shape == (batch_size, 1, 40), ( + f"Actor mean shape mismatch: {action_mean.shape}" + ) assert action_log_std.shape == (40,), f"Actor log_std shape mismatch: {action_log_std.shape}" - assert value.shape == (batch_size, 1) or value.shape == (batch_size,), ( + assert value.shape == (batch_size, 1, 1) or value.shape == (batch_size,), ( f"Critic value shape mismatch: {value.shape}" ) diff --git a/tests/test_target_direction.py b/tests/test_target_direction.py index 825c50c..64a6361 100644 --- a/tests/test_target_direction.py +++ b/tests/test_target_direction.py @@ -88,6 +88,3 @@ def test_processor_converts_to_egocentric_direction(): f"The obs_processor did not correctly rotate the vector to egocentric. " f"Expected {expected_local_target}, but got {local_target}." ) - - -test_processor_converts_to_egocentric_direction() From af68a0064c23908a9c7a0600ae43d7260e966fab Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Tue, 5 May 2026 18:22:52 +0200 Subject: [PATCH 52/96] fix(ppo): added message_passer to ppo --- src/brittle_star_project/MLPs/mlps.py | 5 ++- .../environment/obs_processing.py | 40 +++++++------------ src/brittle_star_project/ppo.py | 2 +- .../trainers/PPOTrainer.py | 18 ++++----- 4 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/brittle_star_project/MLPs/mlps.py b/src/brittle_star_project/MLPs/mlps.py index cc8c226..2c5989f 100644 --- a/src/brittle_star_project/MLPs/mlps.py +++ b/src/brittle_star_project/MLPs/mlps.py @@ -40,16 +40,17 @@ class Actor(nn.Module): class MessagePasser(nn.Module): hidden_dim: int num_propagation_steps: int + adj_matrix: jnp.ndarray @nn.compact - def __call__(self, x: jnp.ndarray, adj_matrix: jnp.ndarray): + def __call__(self, x: jnp.ndarray): for _ in range(self.num_propagation_steps): # (n_nodes, feat) messages = nn.Dense(self.hidden_dim)(x) messages = nn.tanh(messages) # note: if mean is wanted: adj_matrix / (adj.sum(axis=-1, keepdims=True) + 1e-8) - agg = adj_matrix + agg = self.adj_matrix aggregated = agg @ messages x_concat = jnp.concatenate([x, aggregated], axis=-1) diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 87ebe10..5733177 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -72,6 +72,10 @@ def create_obs_processor( padded[key] = arr return padded + # TODO + def _split_to_agents() -> dict: + return {} + def _flatten_features(obs: dict) -> jnp.ndarray: ordered_keys = [ "disk_z_tilt", @@ -93,7 +97,7 @@ def create_obs_processor( if v.size == 0: continue - # reshape scalars + # reshape scalars to 1D array if v.ndim == 0: v = v.reshape(1) @@ -102,19 +106,8 @@ def create_obs_processor( values.append(v.reshape(1, -1)) # (1, feat) continue - # -------- SPLIT TO SEGMENTS -------- + # -------- SCALE WITH SEGMENTS -------- if key in _JOINT_SCALED_KEYS: - if morph_mode == MorphMode.SEGMENT: - joint_count = 3 - axis_per_joint = 2 - - center_size = num_arms * joint_count * axis_per_joint - v_center = v[:center_size].reshape( - num_arms, joint_count * axis_per_joint - ) # (arms, 6) - v_segs = v[center_size:].reshape(-1, 2) # (segs, 2) - values.append(jnp.concatenate([v_center, v_segs], axis=0)) # (arms+segs, ?) - continue v = v.reshape(num_arms, -1) # (n_arms, 2) elif key in _SEGMENT_SCALED_KEYS: @@ -122,25 +115,20 @@ def create_obs_processor( else: # global key, broadcast to all nodes - n_nodes = (num_segments + num_arms) if morph_mode == MorphMode.SEGMENT else num_arms - v = jnp.repeat(v[None, :], n_nodes, axis=0) # (n_nodes, feat) + v = jnp.repeat(v[None, :], num_arms, axis=0) # (num_arms, feat) - # -------- SEGMENT MODE -------- - if morph_mode == MorphMode.SEGMENT: - values.append(v) # (n_nodes, feat) - continue - - # -------- ARM MODE -------- + # RING + FULLY CONNECTED v = v.reshape(num_arms, -1) values.append(v) # (n_arms, feat) - return jnp.concatenate(values, axis=-1) + return jnp.concatenate(values, axis=-1) # (agent, feat) def _process_single(obs_dict: dict) -> jnp.ndarray: - processed = _add_derived_features(obs_dict) - processed = _normalize_features(processed) + processed = _add_derived_features(obs_dict) # key |--> (feat-count, feat-lengths, ) + processed = _normalize_features(processed) # key |--> (feat-count, feat-lengths, ) + # TODO: split to agents # key |--> (agents, feat-count, feat-lengths) if padding_masks is not None: - processed = _pad_features(processed) - return _flatten_features(processed) + processed = _pad_features(processed) # key |--> (agents, feat-count, feat-lengths') + return _flatten_features(processed) # (agents, feat) return jax.jit(jax.vmap(_process_single)) diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index 87e1dfe..635e7b8 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -119,7 +119,7 @@ def get_action_and_value( ): hidden_sensor = sensor_apply(params["sensor_params"], x) hidden_critic = feature_extractor_apply(params["feature_extractor_params"], x) - hidden_sensor = message_passer(hidden_sensor) + hidden_sensor = message_passer(params["message_passer_params"], hidden_sensor) debug.callback(logger.debug, f"[SHAPE] hidden_sensor: {hidden_sensor.shape}") debug.callback(logger.debug, f"[SHAPE] hidden_critic: {hidden_critic.shape}") diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 29c5d19..43de64b 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -62,7 +62,6 @@ def _get_action_and_value_noise( key, action_low, action_high, - adj_matrix: jnp.ndarray, ): # (B, n_nodes, feat) hidden = apply_per_node(sensor, agent_state.params["sensor_params"], next_obs) @@ -70,7 +69,7 @@ def _get_action_and_value_noise( if message_passer is not None: params = agent_state.params["message_passer_params"] # (n_nodes, feat) --> let each node talk with its neighbours ==> vmap over B dimension - hidden = jax.vmap(lambda x: message_passer.apply(params, x, adj_matrix))(hidden) + hidden = jax.vmap(lambda x: message_passer.apply(params, x))(hidden) hidden_critic = apply_shared( feature_extractor, agent_state.params["feature_extractor_params"], next_obs @@ -100,7 +99,6 @@ def _step_once( carry, _, env_step_fn, - adj_matrix, sensor: nn.Module, feature_extractor: nn.Module, actor: nn.Module, @@ -121,7 +119,6 @@ def _step_once( key, action_low, action_high, - adj_matrix, ) logger11.debug(f"[_step_once] raw_action: {raw_action.shape}") logger11.debug(f"[_step_once] clipped_action: {flat_clipped_action.shape}") @@ -242,7 +239,6 @@ def _rollout_jit( message_passer: Optional[nn.Module], action_low, action_high, - adj_matrix, ): (agent_state, episode_stats, next_obs, next_done, key, env_state), storage = jax.lax.scan( partial( @@ -255,7 +251,6 @@ def _rollout_jit( env_step_fn=step_env_fn, action_low=action_low, action_high=action_high, - adj_matrix=adj_matrix, ), (agent_state, episode_stats, next_obs, next_done, key, env_state), (), @@ -393,7 +388,6 @@ class PPOTrainer: message_passer=self.message_passer, action_low=action_low, action_high=action_high, - adj_matrix=self.adj, ) ) self._compute_gae_jit = logged_jit( @@ -419,7 +413,13 @@ class PPOTrainer: def apply_feature(p, x): return apply_shared(self.feature_extractor, p, x) - self._ppo = PPO(self.ppo, apply_sensor, apply_actor, apply_critic, apply_feature) + def apply_message_passer(p, x): + assert self.message_passer is not None + return jax.vmap(lambda x_in: self.message_passer.apply(p, x_in))(x) + + self._ppo = PPO( + self.ppo, apply_sensor, apply_actor, apply_critic, apply_feature, apply_message_passer + ) self.agent_state = self._init_agent_state() @@ -453,6 +453,7 @@ class PPOTrainer: MessagePasser( hidden_dim=300, num_propagation_steps=self.cfg.architecture.message_passing_steps or 4, + adj_matrix=self.adj, ) if self.morph_mode != MorphMode.CENTRALIZED else None @@ -517,7 +518,6 @@ class PPOTrainer: message_passer_params = self.message_passer.init( message_passer_key, self.sensor.apply(single_sensor_param, sample_obs), - self.adj, ) self.logger.debug( f"[_init_agent_state] message_passer_params: { From 5e7fd27b61a9927ae2c824c81c736404f4277294 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Wed, 6 May 2026 19:26:32 +0200 Subject: [PATCH 53/96] backup --- .../environment/obs_processing.py | 89 +++++++++++++------ .../trainers/PPOTrainer.py | 2 +- tests/test_network_shapes.py | 3 +- tests/test_target_direction.py | 3 +- 4 files changed, 63 insertions(+), 34 deletions(-) diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 5733177..96dd4ab 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -22,11 +22,23 @@ _SEGMENT_SCALED_KEYS = frozenset( def create_obs_processor( bounds_dict: Dict[str, Tuple[float, float]], - num_segments: int, num_arms: int, + needed_copies: int, padding_masks: Optional[Dict] = None, morph_mode: MorphMode = MorphMode.CENTRALIZED, ): + # made a set to allow O(1) search + ordered_keys = frozenset( + [ + "disk_z_tilt", + "joint_actuator_force", + "joint_position", + "joint_velocity", + "robot_direction_to_target", + "segment_contact", + ] + ) + def _add_derived_features(obs: dict) -> dict: new_obs = dict(obs) if "disk_rotation" in new_obs: @@ -57,49 +69,61 @@ def create_obs_processor( normalized[key] = arr return normalized - def _pad_features(obs: dict) -> dict: + # ndarray (agents, features) + def _pad_features(obs: dict, agent_count: int) -> dict: assert padding_masks is not None padded = {} + + # arr shape = (agent_count, ...) TODO for key, arr in obs.items(): if key in _JOINT_SCALED_KEYS: - padded_arr = jnp.zeros(padding_masks["target_size_2x"], dtype=arr.dtype) - padded[key] = padded_arr.at[padding_masks["mask_2x"]].set(arr) + padded_arr = jnp.zeros( + (agent_count, padding_masks["target_size_2x"]), dtype=arr.dtype + ) + padded[key] = padded_arr.at[:, padding_masks["mask_2x"]].set(arr) elif key in _SEGMENT_SCALED_KEYS: - padded_arr = jnp.zeros(padding_masks["target_size_1x"], dtype=arr.dtype) - padded[key] = padded_arr.at[padding_masks["mask_1x"]].set(arr) + padded_arr = jnp.zeros( + (agent_count, padding_masks["target_size_1x"]), dtype=arr.dtype + ) + padded[key] = padded_arr.at[:, padding_masks["mask_1x"]].set(arr) else: padded[key] = arr return padded - # TODO - def _split_to_agents() -> dict: - return {} + def _split_to_agents(obs: dict, agent_count: int) -> dict: + """ + Each observation type is now updated to (agent_count, feature_shape), + thus duplicating the observation for each agent + """ + output = {} + + for key, arr in obs.items(): + if key not in ordered_keys or arr.size == 0: + continue + + if arr.ndim == 0: + arr = arr.reshape(1) + + output[key] = jnp.repeat(arr[None, :], agent_count, axis=0) + + return output + + # TODO: update def _flatten_features(obs: dict) -> jnp.ndarray: - ordered_keys = [ - "disk_z_tilt", - "joint_actuator_force", - "joint_position", - "joint_velocity", - "robot_direction_to_target", - "segment_contact", - ] + """ + Collapse all observations into a single array + """ values = [] for key in sorted(obs.keys()): if key not in ordered_keys: continue - v = obs[key] - # skip empty arrays and scalars - if v.size == 0: - continue - - # reshape scalars to 1D array - if v.ndim == 0: - v = v.reshape(1) + # empty arrays handled in split_to_agents + v = obs[key] # (agent_count, feat) # -------- CENTRALIZED -------- if morph_mode == MorphMode.CENTRALIZED: @@ -124,11 +148,18 @@ def create_obs_processor( return jnp.concatenate(values, axis=-1) # (agent, feat) def _process_single(obs_dict: dict) -> jnp.ndarray: - processed = _add_derived_features(obs_dict) # key |--> (feat-count, feat-lengths, ) - processed = _normalize_features(processed) # key |--> (feat-count, feat-lengths, ) - # TODO: split to agents # key |--> (agents, feat-count, feat-lengths) + processed = _add_derived_features(obs_dict) # key |--> (feat-count,) + processed = _normalize_features(processed) # key |--> (feat-count,) + # TODO: split to agents + processed = _split_to_agents(processed, needed_copies) # key |--> (agents, feat-count) if padding_masks is not None: - processed = _pad_features(processed) # key |--> (agents, feat-count, feat-lengths') + processed = _pad_features( + processed, agent_count=needed_copies + ) # key |--> (agents, feat-count') + for k, v in processed.items(): + print(k, v.shape) + + exit(1) return _flatten_features(processed) # (agents, feat) return jax.jit(jax.vmap(_process_single)) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 43de64b..05761f5 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -363,7 +363,7 @@ class PPOTrainer: # Build the centralized observation processor: derive -> normalize -> pad -> flatten. self.obs_processor = create_obs_processor( bounds_dict=self.cfg.obs_bounds.to_bounds_dict(), - num_segments=self.num_segments, + needed_copies=self.needed_copies, num_arms=self.num_arms, morph_mode=self.morph_mode, padding_masks=self.env.padding_masks, diff --git a/tests/test_network_shapes.py b/tests/test_network_shapes.py index 1183377..3cf4c14 100644 --- a/tests/test_network_shapes.py +++ b/tests/test_network_shapes.py @@ -22,14 +22,13 @@ def test_centralized_forward_pass_with_padding(): } segments_per_arm = jnp.array((4, 0, 4, 2, 4)) - num_segments = segments_per_arm.sum().item() num_arms = jnp.where(segments_per_arm > 0, 1, 0).sum().item() # 2. Process and Pad Observation masks = compute_padding_masks(segments_per_arm=list(segments_per_arm)) obs_processor = create_obs_processor( bounds_dict={}, - num_segments=num_segments, + needed_copies=1, num_arms=num_arms, padding_masks=masks, morph_mode=MorphMode.CENTRALIZED, diff --git a/tests/test_target_direction.py b/tests/test_target_direction.py index 64a6361..f931c8a 100644 --- a/tests/test_target_direction.py +++ b/tests/test_target_direction.py @@ -45,12 +45,11 @@ def test_processor_converts_to_egocentric_direction(): env = BrittleStarJaxEnvWrapper.default(num_envs=1, backend=Backend.MJX) segments_per_arm = jnp.array((4, 4, 4, 4, 4)) - num_segments = segments_per_arm.sum().item() num_arms = jnp.where(segments_per_arm > 0, 1, 0).sum().item() obs_processor = create_obs_processor( bounds_dict=cfg.obs_bounds.to_bounds_dict(), - num_segments=num_segments, + needed_copies=1, num_arms=num_arms, padding_masks=env.padding_masks, morph_mode=MorphMode.CENTRALIZED, From 9c20c28b2ad120b1debe0ed4a385e29c4b91314f Mon Sep 17 00:00:00 2001 From: Cedric Date: Wed, 6 May 2026 18:52:19 +0000 Subject: [PATCH 54/96] feat: split n flat n pad decentered --- scripts/simulate.py | 1 + .../environment/obs_processing.py | 134 +++++++++++------- .../trainers/PPOTrainer.py | 1 + tests/test_network_shapes.py | 1 + tests/test_target_direction.py | 1 + 5 files changed, 88 insertions(+), 50 deletions(-) diff --git a/scripts/simulate.py b/scripts/simulate.py index a2b121e..11b4a90 100644 --- a/scripts/simulate.py +++ b/scripts/simulate.py @@ -81,6 +81,7 @@ def main(dict_cfg: DictConfig) -> None: obs_processor = create_obs_processor( bounds_dict=training.obs_bounds.to_bounds_dict(), padding_masks=padding_masks, + segments_per_arm=env_morphology.segments_per_arm, ) # 6. Build environment diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 96dd4ab..8b124fd 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -4,6 +4,10 @@ from typing import Dict, Tuple, Optional from brittle_star_project.environment.env_config import MorphMode +from experiment_logger import get_logger + +logger11 = get_logger() + _JOINT_SCALED_KEYS = frozenset( { "joint_position", @@ -20,12 +24,35 @@ _SEGMENT_SCALED_KEYS = frozenset( ) +def _build_joint_indices(segments_per_arm): + indices = [] + start = 0 + for segs in segments_per_arm: + # 2 joints per segment + count = segs * 2 + idx = jnp.arange(start, start + count) + indices.append(idx) + start += count + return indices + + +def _build_segment_indices(segments_per_arm): + indices = [] + start = 0 + for segs in segments_per_arm: + idx = jnp.arange(start, start + segs) + indices.append(idx) + start += segs + return indices + + def create_obs_processor( bounds_dict: Dict[str, Tuple[float, float]], num_arms: int, needed_copies: int, padding_masks: Optional[Dict] = None, morph_mode: MorphMode = MorphMode.CENTRALIZED, + segments_per_arm=[4, 4, 4, 4, 4], ): # made a set to allow O(1) search ordered_keys = frozenset( @@ -38,6 +65,8 @@ def create_obs_processor( "segment_contact", ] ) + segment_indices = _build_segment_indices(segments_per_arm) + joint_indices = _build_joint_indices(segments_per_arm) def _add_derived_features(obs: dict) -> dict: new_obs = dict(obs) @@ -69,96 +98,101 @@ def create_obs_processor( normalized[key] = arr return normalized - # ndarray (agents, features) def _pad_features(obs: dict, agent_count: int) -> dict: assert padding_masks is not None padded = {} - # arr shape = (agent_count, ...) TODO for key, arr in obs.items(): if key in _JOINT_SCALED_KEYS: - padded_arr = jnp.zeros( - (agent_count, padding_masks["target_size_2x"]), dtype=arr.dtype - ) - padded[key] = padded_arr.at[:, padding_masks["mask_2x"]].set(arr) + target_size = padding_masks["target_size_2x"] + out = jnp.zeros((agent_count, target_size), dtype=arr.dtype) + # place structured values at front, rest stays 0 + out = out.at[:, : arr.shape[1]].set(arr) + padded[key] = out + elif key in _SEGMENT_SCALED_KEYS: - padded_arr = jnp.zeros( - (agent_count, padding_masks["target_size_1x"]), dtype=arr.dtype - ) - padded[key] = padded_arr.at[:, padding_masks["mask_1x"]].set(arr) + target_size = padding_masks["target_size_1x"] + out = jnp.zeros((agent_count, target_size), dtype=arr.dtype) + out = out.at[:, : arr.shape[1]].set(arr) + padded[key] = out else: padded[key] = arr return padded - def _split_to_agents(obs: dict, agent_count: int) -> dict: - """ - Each observation type is now updated to (agent_count, feature_shape), - thus duplicating the observation for each agent - """ - + def _split_to_agents(obs: dict, morph_mode, segments_per_arm) -> dict: output = {} + num_arms = len(segments_per_arm) for key, arr in obs.items(): if key not in ordered_keys or arr.size == 0: continue + logger11.info(f"[INPUT] {key}: {arr.shape}") + if arr.ndim == 0: arr = arr.reshape(1) - output[key] = jnp.repeat(arr[None, :], agent_count, axis=0) + if morph_mode == MorphMode.CENTRALIZED: + out = arr.reshape(1, -1) + output[key] = out + continue + + if key in _SEGMENT_SCALED_KEYS: + per_agent = [jnp.take(arr, idx, axis=0) for idx in segment_indices] + out = jnp.stack(per_agent) + + elif key in _JOINT_SCALED_KEYS: + per_agent = [jnp.take(arr, idx, axis=0) for idx in joint_indices] + out = jnp.stack(per_agent) + + else: + out = jnp.repeat(arr[None, :], num_arms, axis=0) + + logger11.info(f"[OUTPUT] {key}: {out.shape}") + output[key] = out return output - # TODO: update def _flatten_features(obs: dict) -> jnp.ndarray: """ - Collapse all observations into a single array - """ + Input: + key -> (num_arms, feat_per_key) + Output: + (num_arms, total_features) + """ values = [] - for key in sorted(obs.keys()): - if key not in ordered_keys: + for key in ordered_keys: + if key not in obs: continue - # empty arrays handled in split_to_agents - v = obs[key] # (agent_count, feat) + arr = jnp.asarray(obs[key]) # (num_arms, feat) - # -------- CENTRALIZED -------- - if morph_mode == MorphMode.CENTRALIZED: - values.append(v.reshape(1, -1)) # (1, feat) + if arr.size == 0: continue - # -------- SCALE WITH SEGMENTS -------- - if key in _JOINT_SCALED_KEYS: - v = v.reshape(num_arms, -1) # (n_arms, 2) + if arr.ndim == 1: + arr = arr[:, None] - elif key in _SEGMENT_SCALED_KEYS: - v = v[:, None] # (segments, 1) + arr = arr.reshape(arr.shape[0], -1) - else: - # global key, broadcast to all nodes - v = jnp.repeat(v[None, :], num_arms, axis=0) # (num_arms, feat) + values.append(arr) - # RING + FULLY CONNECTED - v = v.reshape(num_arms, -1) - values.append(v) # (n_arms, feat) - - return jnp.concatenate(values, axis=-1) # (agent, feat) + return jnp.concatenate(values, axis=-1) # (num_arms, total_feat) def _process_single(obs_dict: dict) -> jnp.ndarray: - processed = _add_derived_features(obs_dict) # key |--> (feat-count,) - processed = _normalize_features(processed) # key |--> (feat-count,) - # TODO: split to agents - processed = _split_to_agents(processed, needed_copies) # key |--> (agents, feat-count) + processed = _add_derived_features(obs_dict) + processed = _normalize_features(processed) + # morph_mode = MorphMode.FULLY_CONNECTED + processed = _split_to_agents(processed, morph_mode, segments_per_arm) + # needed_copies = 5 if padding_masks is not None: - processed = _pad_features( - processed, agent_count=needed_copies - ) # key |--> (agents, feat-count') - for k, v in processed.items(): - print(k, v.shape) - + processed = _pad_features(processed, agent_count=needed_copies) + flat = _flatten_features(processed) # (num_arms, total_feat) + logger11.info(f"[FLATTENED FINAL] shape: {flat.shape}") + logger11.info(f"[PER AGENT] example row 0 shape: {flat[0].shape}") exit(1) return _flatten_features(processed) # (agents, feat) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 05761f5..5610fc9 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -367,6 +367,7 @@ class PPOTrainer: num_arms=self.num_arms, morph_mode=self.morph_mode, padding_masks=self.env.padding_masks, + segments_per_arm=self.segments_per_arm, ) action_low = jnp.asarray(self.env.single_action_space.low, dtype=jnp.float32) diff --git a/tests/test_network_shapes.py b/tests/test_network_shapes.py index 3cf4c14..3054510 100644 --- a/tests/test_network_shapes.py +++ b/tests/test_network_shapes.py @@ -32,6 +32,7 @@ def test_centralized_forward_pass_with_padding(): num_arms=num_arms, padding_masks=masks, morph_mode=MorphMode.CENTRALIZED, + segments_per_arm=segments_per_arm, ) global_state = obs_processor(amputated_obs) diff --git a/tests/test_target_direction.py b/tests/test_target_direction.py index f931c8a..8317fb2 100644 --- a/tests/test_target_direction.py +++ b/tests/test_target_direction.py @@ -53,6 +53,7 @@ def test_processor_converts_to_egocentric_direction(): num_arms=num_arms, padding_masks=env.padding_masks, morph_mode=MorphMode.CENTRALIZED, + segments_per_arm=segments_per_arm, ) env_state = env.reset(seed=42) From 9b626c0a6bb5cc9cec580e6729693b8e8ef64494 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Wed, 6 May 2026 23:35:18 +0200 Subject: [PATCH 55/96] feat: convergence plots --- scripts/analysis/analyze_convergence.py | 296 ++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 scripts/analysis/analyze_convergence.py diff --git a/scripts/analysis/analyze_convergence.py b/scripts/analysis/analyze_convergence.py new file mode 100644 index 0000000..c58a34b --- /dev/null +++ b/scripts/analysis/analyze_convergence.py @@ -0,0 +1,296 @@ +""" +Convergence Analysis Script for Poster Visualizations + +This script analyzes evaluation metrics from multiple training runs to determine +the convergence point of different reinforcement learning architectures. + +Workflow: +1. Loads evaluation data from the CSV files defined in FILE_MAPPING. +2. Calculates a rolling average of the reward and velocity to smooth noise. +3. Determines the convergence timestep for each metric (first time 95% of peak is reached). +4. Generates a grouped bar chart comparing convergence speed and line plots of the raw curves. + +Usage: + uv run python scripts/analysis/analyze_convergence.py + +Note: For these metrics to be valid, the evaluation CSVs must be generated with +exploration noise strictly disabled (e.g., taking the mean of the action distribution). +""" + +import logging +import os + +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +from enum import Enum + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(levelname)s] %(name)s: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", +) +logger = logging.getLogger(__name__) + +# --- Globals & Configuration --- +USING_DUMMY_DATA = False +SMOOTHING_WINDOW = 3 +CONVERGENCE_THRESHOLD = 0.95 + + +class Columns(str, Enum): + # ... (rest of the file remains same, just need to update plotting functions and obtain_data) + """Column names expected in every evaluation CSV.""" + + ARCH = "architecture" + TIMESTEPS = "total_trained_timesteps" + REWARD = "accumulated_reward" + VELOCITY = "velocity" + + +# Maps architecture display names to the path of their evaluation CSV. +# Update these paths once real evaluation data is available. +FILE_MAPPING: dict[str, str] = { + "centralized 2 arms": "runs/dummy/dummy_centralized_2_arms.csv", + "centralized 5 arms": "runs/dummy/dummy_centralized_5_arms.csv", + "decentralized fully connected": "runs/dummy/dummy_decentralized_fully_connected.csv", + "decentralized ring-level": "runs/dummy/dummy_decentralized_ring-level.csv", + "decentralized segment-level": "runs/dummy/dummy_decentralized_segment-level.csv", +} + +# Architecture profiles for dummy data generation: (max_reward, max_velocity, sigmoid_speed) +_DUMMY_PROFILES: dict[str, tuple[float, float, float]] = { + "centralized 2 arms": (300, 0.8, 1.2), + "centralized 5 arms": (450, 1.1, 1.0), + "decentralized fully connected": (500, 1.3, 0.7), + "decentralized ring-level": (480, 1.2, 0.8), + "decentralized segment-level": (520, 1.4, 0.6), +} + + +def generate_dummy_csvs(file_mapping: dict[str, str]): + """ + Generates one dummy CSV per architecture in FILE_MAPPING at their expected locations. + Skips any architecture without a defined profile. + """ + checkpoints = list(range(100, 1100, 100)) + timesteps = [cp * 10_000 for cp in checkpoints] + + for arch, path in file_mapping.items(): + if arch not in _DUMMY_PROFILES: + logger.warning(f"No dummy profile for '{arch}'. Skipping.") + continue + + m_reward, m_vel, speed = _DUMMY_PROFILES[arch] + + rows = [] + for i, ts in enumerate(timesteps): + progress = 1 / (1 + np.exp(-speed * (i - 4))) + rows.append( + { + Columns.TIMESTEPS: ts, + Columns.REWARD: m_reward * progress + np.random.normal(0, 5), + Columns.VELOCITY: m_vel * progress + np.random.normal(0, 0.02), + } + ) + + # Create parent directories if they don't exist + os.makedirs(os.path.dirname(path), exist_ok=True) + + pd.DataFrame(rows).to_csv(path, index=False) + logger.info(f"Generated dummy CSV at expected path: {path}") + + +def load_metrics(file_mapping: dict[str, str]) -> pd.DataFrame: + """ + Loads one CSV per architecture, injects the architecture name as a column, + and returns the combined DataFrame with only the required columns. + """ + required = [Columns.TIMESTEPS, Columns.REWARD, Columns.VELOCITY] + dfs = [] + + for arch_name, filepath in file_mapping.items(): + if not os.path.exists(filepath): + logger.warning(f"File not found: '{filepath}'. Skipping.") + continue + + df = pd.read_csv(filepath) + + missing = [c for c in required if c not in df.columns] + if missing: + logger.warning(f"Missing columns {missing} in '{filepath}'. Skipping.") + continue + + df = df[required].copy() + df[Columns.ARCH] = arch_name + dfs.append(df) + + return pd.concat(dfs, ignore_index=True) if dfs else pd.DataFrame() + + +def _convergence_timestep(series: pd.Series, timesteps: pd.Series) -> float: + """Returns the first timestep where the smoothed series reaches 95% of its peak.""" + smoothed = series.rolling(window=SMOOTHING_WINDOW, min_periods=1).mean() + threshold = smoothed.max() * CONVERGENCE_THRESHOLD + return timesteps[smoothed >= threshold].iloc[0] + + +def analyze_convergence(df: pd.DataFrame) -> pd.DataFrame: + """ + For each architecture, determines the convergence timestep based on both + reward and velocity, returning one summary row per architecture. + """ + results = [] + + for arch in df[Columns.ARCH].unique(): + arch_data = df[df[Columns.ARCH] == arch].sort_values(Columns.TIMESTEPS) + + results.append( + { + "Architecture": arch, + "Reward_Convergence_Timestep": _convergence_timestep( + arch_data[Columns.REWARD], arch_data[Columns.TIMESTEPS] + ), + "Velocity_Convergence_Timestep": _convergence_timestep( + arch_data[Columns.VELOCITY], arch_data[Columns.TIMESTEPS] + ), + } + ) + + return pd.DataFrame(results) + + +def _add_bar_labels(bars, max_val: float): + """Annotates each bar with its value in white bold text, positioned inside.""" + for bar in bars: + width = bar.get_width() + label = f"{width / 1e6:.1f}M" if width >= 1e6 else f"{width:,.0f}" + plt.text( + width - (max_val * 0.02), + bar.get_y() + bar.get_height() / 2, + label, + ha="right", + va="center", + fontsize=11, + color="white", + fontweight="bold", + ) + + +def plot_grouped_convergence_chart(results_df: pd.DataFrame, output_filename: str): + """ + Saves a grouped horizontal bar chart comparing Reward and Velocity convergence timesteps + across all architectures. + """ + sorted_df = results_df.sort_values("Reward_Convergence_Timestep", ascending=True) + architectures = sorted_df["Architecture"].tolist() + y_pos = np.arange(len(architectures)) + bar_height = 0.35 + max_val = sorted_df[ + ["Reward_Convergence_Timestep", "Velocity_Convergence_Timestep"] + ].values.max() + + _, ax = plt.subplots(figsize=(12, 8)) + + bars_reward = ax.barh( + y_pos + bar_height / 2, + sorted_df["Reward_Convergence_Timestep"], + height=bar_height, + label="Reward Convergence", + color="#1f77b4", + ) + bars_velocity = ax.barh( + y_pos - bar_height / 2, + sorted_df["Velocity_Convergence_Timestep"], + height=bar_height, + label="Velocity Convergence", + color="#ff7f0e", + ) + + title_suffix = " (DUMMY DATA)" if USING_DUMMY_DATA else "" + ax.set_title(f"Comparison of Training Convergence Timesteps{title_suffix}", fontsize=20, pad=20) + ax.set_xlabel("Timesteps to Convergence (95% of peak)", fontsize=16) + ax.set_ylabel("Architecture", fontsize=16) + ax.set_yticks(y_pos) + ax.set_yticklabels(architectures, fontsize=14) + ax.tick_params(axis="x", labelsize=14) + ax.legend(fontsize=12, loc="lower right") + ax.set_xlim(left=0) + ax.spines["top"].set_visible(False) + ax.spines["right"].set_visible(False) + + _add_bar_labels(bars_reward, max_val) + _add_bar_labels(bars_velocity, max_val) + + plt.tight_layout() + plt.savefig(output_filename, format="png", dpi=300, bbox_inches="tight") + plt.close() + + +def plot_metric_curves(df: pd.DataFrame, metric_col: str, title: str, output_filename: str): + """ + Saves a line plot of the given metric over training timesteps for every architecture. + """ + _, ax = plt.subplots(figsize=(12, 7)) + + for arch in df[Columns.ARCH].unique(): + arch_data = df[df[Columns.ARCH] == arch].sort_values(Columns.TIMESTEPS) + ax.plot( + arch_data[Columns.TIMESTEPS], + arch_data[metric_col], + label=arch, + marker="o", + markersize=4, + alpha=0.8, + ) + + title_suffix = " (DUMMY DATA)" if USING_DUMMY_DATA else "" + ax.set_title(f"{title}{title_suffix}", fontsize=18, pad=20) + ax.set_xlabel("Training Timesteps", fontsize=14) + ax.set_ylabel(metric_col.replace("_", " ").title(), fontsize=14) + ax.legend(bbox_to_anchor=(1.05, 1), loc="upper left", fontsize=10) + ax.grid(True, linestyle="--", alpha=0.6) + ax.set_xlim(left=0) + ax.set_ylim(bottom=0) + + plt.tight_layout() + plt.savefig(output_filename, format="png", dpi=300, bbox_inches="tight") + plt.close() + + +def plot_results(df: pd.DataFrame, results: pd.DataFrame): + """Generates and saves all analysis plots.""" + plot_grouped_convergence_chart(results, output_filename="convergence_comparison.png") + plot_metric_curves( + df, Columns.REWARD, "Training Progress: Accumulated Reward", "progress_reward_curves.png" + ) + plot_metric_curves( + df, Columns.VELOCITY, "Training Progress: Velocity", "progress_velocity_curves.png" + ) + + +def obtain_data() -> pd.DataFrame: + """Resolves the file mapping, falling back to generated dummy CSVs if needed.""" + global USING_DUMMY_DATA + if not any(os.path.exists(p) for p in FILE_MAPPING.values()): + logger.info("No real evaluation files found. Generating dummy CSVs at expected locations.") + generate_dummy_csvs(FILE_MAPPING) + USING_DUMMY_DATA = True + + return load_metrics(FILE_MAPPING) + + +def run_analysis(): + """Orchestrates data loading, convergence analysis, and plot generation.""" + df = obtain_data() + if df.empty: + logger.error("No data found to analyze.") + return + + results = analyze_convergence(df) + plot_results(df, results) + logger.info("Analysis complete. Plots saved to disk.") + + +if __name__ == "__main__": + run_analysis() From 4068ccef5d7a16e11b07e80fcbcd40f5b01dedac Mon Sep 17 00:00:00 2001 From: Cedric Date: Wed, 6 May 2026 21:51:39 +0000 Subject: [PATCH 56/96] fix: split pad dada --- .../environment/obs_processing.py | 88 ++++++++++++------- .../trainers/PPOTrainer.py | 19 +++- 2 files changed, 75 insertions(+), 32 deletions(-) diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 8b124fd..a57f00b 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -24,25 +24,27 @@ _SEGMENT_SCALED_KEYS = frozenset( ) -def _build_joint_indices(segments_per_arm): +def _build_joint_indices(segments_per_arm, indices_mlp): indices = [] start = 0 - for segs in segments_per_arm: + for i, segs in enumerate(segments_per_arm): # 2 joints per segment - count = segs * 2 - idx = jnp.arange(start, start + count) - indices.append(idx) - start += count + if i in indices_mlp: + count = segs * 2 + idx = jnp.arange(start, start + count) + indices.append(idx) + start += count return indices -def _build_segment_indices(segments_per_arm): +def _build_segment_indices(segments_per_arm, indices_mlp): indices = [] start = 0 - for segs in segments_per_arm: - idx = jnp.arange(start, start + segs) - indices.append(idx) - start += segs + for i, segs in enumerate(segments_per_arm): + if i in indices_mlp: + idx = jnp.arange(start, start + segs) + indices.append(idx) + start += segs return indices @@ -53,6 +55,7 @@ def create_obs_processor( padding_masks: Optional[Dict] = None, morph_mode: MorphMode = MorphMode.CENTRALIZED, segments_per_arm=[4, 4, 4, 4, 4], + agent_indices=[0, 1, 2, 3, 4], ): # made a set to allow O(1) search ordered_keys = frozenset( @@ -65,8 +68,8 @@ def create_obs_processor( "segment_contact", ] ) - segment_indices = _build_segment_indices(segments_per_arm) - joint_indices = _build_joint_indices(segments_per_arm) + segment_indices = _build_segment_indices(segments_per_arm, agent_indices) + joint_indices = _build_joint_indices(segments_per_arm, agent_indices) def _add_derived_features(obs: dict) -> dict: new_obs = dict(obs) @@ -120,34 +123,64 @@ def create_obs_processor( padded[key] = arr return padded - def _split_to_agents(obs: dict, morph_mode, segments_per_arm) -> dict: - output = {} - num_arms = len(segments_per_arm) + def _split_to_agents(obs: dict, morph_mode) -> dict: + total = 0 + for k, v in obs.items(): + if hasattr(v, "shape"): + size = v.size + logger11.info(f"[RAW] {k}: shape={v.shape}, size={size}") + total += size + else: + logger11.info(f"[RAW] {k}: non-array") + logger11.info(f"[RAW TOTAL FEATURES]: {total}") + output = {} + num_agents = needed_copies # IMPORTANT: number of MLPs for key, arr in obs.items(): if key not in ordered_keys or arr.size == 0: continue - logger11.info(f"[INPUT] {key}: {arr.shape}") - if arr.ndim == 0: arr = arr.reshape(1) - + # -------- CENTRALIZED -------- if morph_mode == MorphMode.CENTRALIZED: - out = arr.reshape(1, -1) - output[key] = out + output[key] = arr.reshape(1, -1) continue + # -------- SEGMENTS -------- if key in _SEGMENT_SCALED_KEYS: - per_agent = [jnp.take(arr, idx, axis=0) for idx in segment_indices] + per_agent = [] + + for i, agent_id in enumerate(agent_indices): + idx = segment_indices[i] + taken = jnp.take(arr, idx, axis=0) # (segs, ...) + logger11.info(f"WHY {taken.shape}") + # pad to 4 + pad_len = 4 - taken.shape[0] + padded = jnp.pad(taken, [(0, pad_len)] + [(0, 0)] * (taken.ndim - 1)) + + per_agent.append(padded.reshape(-1)) + out = jnp.stack(per_agent) + # -------- JOINTS -------- elif key in _JOINT_SCALED_KEYS: - per_agent = [jnp.take(arr, idx, axis=0) for idx in joint_indices] + per_agent = [] + + for i, agent_id in enumerate(agent_indices): + idx = joint_indices[i] + taken = jnp.take(arr, idx, axis=0) # (joint_n, ...) + # pad to 8 + pad_len = 8 - taken.shape[0] + + padded = jnp.pad(taken, [(0, pad_len)] + [(0, 0)] * (taken.ndim - 1)) + per_agent.append(padded.reshape(-1)) + out = jnp.stack(per_agent) + # -------- GLOBAL -------- else: - out = jnp.repeat(arr[None, :], num_arms, axis=0) + out = jnp.repeat(arr[None, :], num_agents, axis=0) logger11.info(f"[OUTPUT] {key}: {out.shape}") output[key] = out @@ -185,15 +218,10 @@ def create_obs_processor( def _process_single(obs_dict: dict) -> jnp.ndarray: processed = _add_derived_features(obs_dict) processed = _normalize_features(processed) - # morph_mode = MorphMode.FULLY_CONNECTED - processed = _split_to_agents(processed, morph_mode, segments_per_arm) - # needed_copies = 5 - if padding_masks is not None: - processed = _pad_features(processed, agent_count=needed_copies) + processed = _split_to_agents(processed, morph_mode) flat = _flatten_features(processed) # (num_arms, total_feat) logger11.info(f"[FLATTENED FINAL] shape: {flat.shape}") logger11.info(f"[PER AGENT] example row 0 shape: {flat[0].shape}") - exit(1) return _flatten_features(processed) # (agents, feat) return jax.jit(jax.vmap(_process_single)) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 5610fc9..18f30b7 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -353,6 +353,7 @@ class PPOTrainer: self.feature_extractor, self.critic, self.needed_copies, + self.agent_indices, ) = self._init_agent() self.sensor.apply = logged_jit(self.sensor.apply) @@ -368,6 +369,7 @@ class PPOTrainer: morph_mode=self.morph_mode, padding_masks=self.env.padding_masks, segments_per_arm=self.segments_per_arm, + agent_indices=self.agent_indices, ) action_low = jnp.asarray(self.env.single_action_space.low, dtype=jnp.float32) @@ -436,13 +438,18 @@ class PPOTrainer: def _init_agent(self): self.logger.info("[AGENT]: Initializing agent...") - + agent_indices = [0, 1, 2, 3, 4] match self.morph_mode: case MorphMode.CENTRALIZED: needed_copies = 1 case MorphMode.FULLY_CONNECTED | MorphMode.RING: + agent_mask = self.segments_per_arm > 0 + agent_indices = jnp.where(agent_mask)[0] needed_copies = jnp.where(self.segments_per_arm > 0, 1, 0).sum().item() case MorphMode.SEGMENT: + agent_mask = self.segments_per_arm > 0 + agent_indices = jnp.where(agent_mask)[0] + needed_copies = jnp.where(self.segments_per_arm > 0, 1, 0).sum().item() needed_copies = ( self.segments_per_arm.sum() + jnp.where(self.segments_per_arm > 0, 1, 0).sum() ).item() @@ -462,7 +469,15 @@ class PPOTrainer: feature_extractor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) critic = OneDenseLayerMLP() - return sensor, message_passer, actor, feature_extractor, critic, needed_copies + return ( + sensor, + message_passer, + actor, + feature_extractor, + critic, + needed_copies, + agent_indices, + ) def _init_agent_state(self) -> TrainState: self.logger.info("[AGENT STATE]: Initializing agent state...") From 23fcee211075262617249bf3a22bef54ab03d841 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Thu, 7 May 2026 08:42:35 +0200 Subject: [PATCH 57/96] fix(ppo training): forgot extra change from dev --- src/brittle_star_project/trainers/PPOTrainer.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 917beef..9cbcf7c 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -129,18 +129,21 @@ def _step_once( logger11.debug(f"[_step_once] value: {value.shape}") logger11.debug(f"[_step_once] mean: {mean.shape}") logger11.debug(f"[_step_once] std: {std.shape}") - + key, reset_key = jax.random.split(key) reset_rngs = jax.random.split(reset_key, num_envs) # ---- ENV STEP ---- key, reset_key = jax.random.split(key) reset_rngs = jax.random.split(reset_key, num_envs) - - episode_stats, env_state, (next_obs, reward, next_done) = env_step_fn( - episode_stats, env_state, flat_clipped_action, reset_rngs, + + episode_stats, env_state, (next_obs, reward, next_done, terminated, truncated) = env_step_fn( + episode_stats, + env_state, + flat_clipped_action, + reset_rngs, ) - + terminated_any = terminated_any | terminated truncated_any = truncated_any | truncated From 67c459ca94d230f2f9ce4fdfbe2dd76975cbff6f Mon Sep 17 00:00:00 2001 From: Jona Reynaert Date: Thu, 7 May 2026 12:03:53 +0200 Subject: [PATCH 58/96] fix: changed checkpoint evaluation csv fields --- .../trainers/PPOTrainer.py | 85 +++++++++++++++---- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 54653a1..9629e60 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -355,15 +355,18 @@ class PPOTrainer: rngs = jnp.asarray(jax.random.split(rng, 1)) state = reset_1(rng=rngs) + initial_xy_dist = jnp.squeeze(state.observations["xy_distance_to_target"]) + t0 = jnp.asarray(0, dtype=jnp.int32) done0 = jnp.squeeze(state.terminated | state.truncated) + return0 = jnp.asarray(0.0, dtype=jnp.float32) def cond(carry): - t, _state, done = carry + t, _state, done, _return_ = carry return jnp.logical_and(t < max_steps, jnp.logical_not(done)) def body(carry): - t, state, _done = carry + t, state, _done, return_ = carry obs = obs_processor(state.observations) hidden = sensor_apply(params["sensor_params"], obs) @@ -372,11 +375,22 @@ class PPOTrainer: action = jnp.clip(mean, action_low, action_high) next_state = step_1(state=state, action=action) - done_next = jnp.squeeze(next_state.terminated | next_state.truncated) - return (t + 1, next_state, done_next) + # Match training's shaped reward as closely as possible. + shaped_reward = _reward_fn(state, next_state) + return_ = return_ + jnp.squeeze(shaped_reward) - t, _state, done = jax.lax.while_loop(cond, body, (t0, state, done0)) - return t, done + done_next = jnp.squeeze(next_state.terminated | next_state.truncated) + return (t + 1, next_state, done_next, return_) + + t, final_state, _done, return_ = jax.lax.while_loop( + cond, body, (t0, state, done0, return0) + ) + + reached_target = jnp.squeeze(final_state.terminated) + final_xy_dist_raw = jnp.squeeze(final_state.observations["xy_distance_to_target"]) + final_xy_dist = jnp.where(reached_target, 0.0, final_xy_dist_raw) + + return t, reached_target, return_, final_xy_dist, initial_xy_dist self._eval_rollout_mjx_fn = jax.jit(_eval_rollout) return self._eval_rollout_mjx_fn @@ -616,16 +630,24 @@ class PPOTrainer: self, *, iteration: int, + trained_timesteps: int, + eval_steps: int, + eval_return: float, + final_xy_dist: float, + initial_xy_dist: float, reached_target: bool, - steps_to_target: int, ) -> Path: metrics_dir = Path(self.run_dir) / "metrics" metrics_dir.mkdir(parents=True, exist_ok=True) csv_path = metrics_dir / "checkpoint_evaluation.csv" fieldnames = [ - "iteration", - "steps_to_target", + "checkpoint", + "trained_timesteps", + "eval_steps", + "eval_return", + "final_xy_dist", + "initial_xy_dist", "reached_target", ] @@ -641,10 +663,17 @@ class PPOTrainer: with open(csv_path, "r", newline="") as f: dict_reader = csv.DictReader(f) for row in dict_reader: + # Support older schemas best-effort. + checkpoint = row.get("checkpoint", row.get("iteration")) + steps = row.get("eval_steps", row.get("steps_to_target")) migrated_rows.append( { - "iteration": row.get("iteration"), - "steps_to_target": row.get("steps_to_target"), + "checkpoint": checkpoint, + "trained_timesteps": row.get("trained_timesteps"), + "eval_steps": steps, + "eval_return": row.get("eval_return"), + "final_xy_dist": row.get("final_xy_dist"), + "initial_xy_dist": row.get("initial_xy_dist"), "reached_target": row.get("reached_target"), } ) @@ -668,15 +697,19 @@ class PPOTrainer: writer.writeheader() writer.writerow( { - "iteration": int(iteration), - "steps_to_target": int(steps_to_target), + "checkpoint": int(iteration), + "trained_timesteps": int(trained_timesteps), + "eval_steps": int(eval_steps), + "eval_return": float(eval_return), + "final_xy_dist": float(final_xy_dist), + "initial_xy_dist": float(initial_xy_dist), "reached_target": bool(reached_target), } ) return csv_path - def _evaluate_checkpoint(self, iteration: int) -> None: + def _evaluate_checkpoint(self, iteration: int, *, trained_timesteps: int) -> None: if not self.logging_cfg.evaluate_checkpoints: return @@ -686,14 +719,30 @@ class PPOTrainer: # Run evaluation best-effort; never fail training because evaluation failed. try: eval_fn = self._get_or_create_eval_rollout_mjx_fn() - steps, reached = eval_fn(self.agent_state.params, seed, max_steps) - steps_to_target = int(steps) + ( + steps, + reached, + eval_return, + final_xy_dist, + initial_xy_dist, + ) = eval_fn(self.agent_state.params, seed, max_steps) + + eval_steps = int(steps) reached_target = bool(reached) + # Keep numeric conversions explicit (JAX scalars -> Python scalars). + eval_return_f = float(eval_return) + final_xy_dist_f = float(final_xy_dist) + initial_xy_dist_f = float(initial_xy_dist) + csv_path = self._append_checkpoint_eval_row( iteration=iteration, + trained_timesteps=int(trained_timesteps), + eval_steps=eval_steps, + eval_return=eval_return_f, + final_xy_dist=final_xy_dist_f, + initial_xy_dist=initial_xy_dist_f, reached_target=reached_target, - steps_to_target=steps_to_target, ) self._maybe_sync_csv_to_wandb(csv_path) except Exception as e: @@ -752,7 +801,7 @@ class PPOTrainer: if self.logging_cfg.save_checkpoints and self.logging_cfg.checkpoint_frequency > 0: if iteration % self.logging_cfg.checkpoint_frequency == 0: self._save_checkpoint(iteration) - self._evaluate_checkpoint(iteration) + self._evaluate_checkpoint(iteration, trained_timesteps=global_step) if getattr(self.cfg.experiment, "debug_sanity", False): self.logger.info("\n[SANITY CHECK] Successfully completed 1 epoch") From b91908bf7a9fd73a94c31a7e03f345356fa8bce1 Mon Sep 17 00:00:00 2001 From: Jona Reynaert Date: Thu, 7 May 2026 13:45:03 +0200 Subject: [PATCH 59/96] feat: abstracted checkpoint eval configs --- configs/evaluation/default.yaml | 8 ++++++ configs/logging/default.yaml | 5 +--- configs/main_config.yaml | 1 + .../configs/config_evaluation.py | 24 ++++++++++++++++++ .../configs/main_config.py | 2 ++ .../configs/register_configs.py | 2 ++ .../trainers/PPOTrainer.py | 18 ++++++++++--- src/experiment_logger/config_logger.py | 25 ++----------------- 8 files changed, 55 insertions(+), 30 deletions(-) create mode 100644 configs/evaluation/default.yaml create mode 100644 src/brittle_star_project/configs/config_evaluation.py diff --git a/configs/evaluation/default.yaml b/configs/evaluation/default.yaml new file mode 100644 index 0000000..ac49e46 --- /dev/null +++ b/configs/evaluation/default.yaml @@ -0,0 +1,8 @@ +# Default Evaluation Configuration +# Settings used for checkpoint evaluation during training. + +evaluate_checkpoints: false +# Max number of control steps during evaluation rollout. +eval_max_steps: 5000 +# Seed for deterministic evaluation reset. +eval_seed: 0 diff --git a/configs/logging/default.yaml b/configs/logging/default.yaml index af9bc6d..2f7de8c 100644 --- a/configs/logging/default.yaml +++ b/configs/logging/default.yaml @@ -10,7 +10,4 @@ save_checkpoints: true checkpoint_frequency: 100 upload_final_model: false upload_checkpoints: false -hf_entity: "" -evaluate_checkpoints: false -eval_max_steps: 5000 -eval_seed: 0 \ No newline at end of file +hf_entity: "" \ No newline at end of file diff --git a/configs/main_config.yaml b/configs/main_config.yaml index b7cb620..44451f4 100644 --- a/configs/main_config.yaml +++ b/configs/main_config.yaml @@ -6,6 +6,7 @@ defaults: - brittle_star_config - experiment: base - logging: default + - evaluation: default - ppo: default - architecture: centralized - morphology: 5_arms_full diff --git a/src/brittle_star_project/configs/config_evaluation.py b/src/brittle_star_project/configs/config_evaluation.py new file mode 100644 index 0000000..4eeadbc --- /dev/null +++ b/src/brittle_star_project/configs/config_evaluation.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass +class EvaluationConfig: + """Evaluation settings. + + Currently used for synchronous checkpoint evaluation during training. + """ + + # When enabled, each saved checkpoint is evaluated headlessly and the results + # are appended to a CSV in the run's metrics/ folder. + evaluate_checkpoints: bool = False + eval_max_steps: int = 5000 + eval_seed: int = 0 + + def __post_init__(self) -> None: + if self.evaluate_checkpoints and self.eval_max_steps <= 0: + raise ValueError( + "Configuration Error: 'eval_max_steps' must be > 0 when " + "'evaluate_checkpoints' is enabled." + ) diff --git a/src/brittle_star_project/configs/main_config.py b/src/brittle_star_project/configs/main_config.py index 10fd22e..7caa1aa 100644 --- a/src/brittle_star_project/configs/main_config.py +++ b/src/brittle_star_project/configs/main_config.py @@ -2,6 +2,7 @@ from dataclasses import dataclass, field from experiment_logger.config_logger import LoggingConfig from brittle_star_project.configs.config_experiment import ExperimentConfig +from brittle_star_project.configs.config_evaluation import EvaluationConfig from brittle_star_project.configs.config_ppo import PPOConfig from brittle_star_project.configs.config_architecture import ArchitectureConfig from brittle_star_project.configs.config_simulation import SimulationSettings @@ -23,6 +24,7 @@ class BrittleStarConfig: experiment: ExperimentConfig = field(default_factory=ExperimentConfig) logging: LoggingConfig = field(default_factory=LoggingConfig) + evaluation: EvaluationConfig = field(default_factory=EvaluationConfig) ppo: PPOConfig = field(default_factory=PPOConfig) # This field is polymorphic; defaults to the base class to allow subclasses # (CentralizedConfig, DecentralizedConfig) to be merged in via Hydra. diff --git a/src/brittle_star_project/configs/register_configs.py b/src/brittle_star_project/configs/register_configs.py index 147da10..9522212 100644 --- a/src/brittle_star_project/configs/register_configs.py +++ b/src/brittle_star_project/configs/register_configs.py @@ -2,6 +2,7 @@ from hydra.core.config_store import ConfigStore from experiment_logger.config_logger import LoggingConfig from brittle_star_project.configs.config_experiment import ExperimentConfig +from brittle_star_project.configs.config_evaluation import EvaluationConfig from brittle_star_project.configs.config_ppo import PPOConfig from brittle_star_project.configs.config_architecture import ( CentralizedConfig, @@ -32,6 +33,7 @@ def register_configs() -> None: # Sub-config groups — each group corresponds to a configs/ subdirectory. cs.store(group="experiment", name="base_experiment", node=ExperimentConfig) cs.store(group="logging", name="base_logging", node=LoggingConfig) + cs.store(group="evaluation", name="base_evaluation", node=EvaluationConfig) cs.store(group="ppo", name="base_ppo", node=PPOConfig) # Architecture variants — swap via CLI: architecture=decentralized diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 9629e60..5ae20ec 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -263,6 +263,7 @@ class PPOTrainer: self.ppo = cfg.ppo self.experiment = cfg.experiment self.logging_cfg = cfg.logging + self.evaluation_cfg = cfg.evaluation self.env = env self.run_dir = run_dir self.run_name = run_name @@ -710,11 +711,22 @@ class PPOTrainer: return csv_path def _evaluate_checkpoint(self, iteration: int, *, trained_timesteps: int) -> None: - if not self.logging_cfg.evaluate_checkpoints: + if not self.evaluation_cfg.evaluate_checkpoints: return - max_steps = int(self.logging_cfg.eval_max_steps) - seed = int(self.logging_cfg.eval_seed) + max_steps = int(self.evaluation_cfg.eval_max_steps) + seed = int(self.evaluation_cfg.eval_seed) + + if max_steps <= 0: + self.logger.warning("[EVAL]: eval_max_steps must be > 0; skipping evaluation") + return + + if not self.logging_cfg.save_checkpoints or self.logging_cfg.checkpoint_frequency <= 0: + self.logger.warning( + "[EVAL]: evaluate_checkpoints is enabled but checkpoint saving is disabled; " + "skipping evaluation" + ) + return # Run evaluation best-effort; never fail training because evaluation failed. try: diff --git a/src/experiment_logger/config_logger.py b/src/experiment_logger/config_logger.py index d158e84..fd77a28 100644 --- a/src/experiment_logger/config_logger.py +++ b/src/experiment_logger/config_logger.py @@ -18,13 +18,6 @@ class LoggingConfig: upload_final_model: bool = False upload_checkpoints: bool = False - # Checkpoint evaluation (synchronous, in-process) - # When enabled, each saved checkpoint is evaluated headlessly and the results - # are appended to a CSV in the run's metrics/ folder. - evaluate_checkpoints: bool = False - eval_max_steps: int = 5000 - eval_seed: int = 0 - hf_entity: str = "" def __post_init__(self): @@ -39,19 +32,5 @@ class LoggingConfig: "both 'track' and 'save_checkpoints' to also be True." ) - if self.evaluate_checkpoints: - if not self.save_checkpoints: - raise ValueError( - "Configuration Error: 'evaluate_checkpoints' is True, but it requires " - "'save_checkpoints' to also be True." - ) - if self.checkpoint_frequency <= 0: - raise ValueError( - "Configuration Error: 'evaluate_checkpoints' is True, but it requires " - "'checkpoint_frequency' to be > 0." - ) - if self.eval_max_steps <= 0: - raise ValueError( - "Configuration Error: 'eval_max_steps' must be > 0 when " - "'evaluate_checkpoints' is enabled." - ) + # NOTE: Checkpoint evaluation settings live under the project's + # `evaluation` config group (see brittle_star_project.configs). From 7f5b730cdfb8314e046c657c8f8ce64645ea6c46 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Thu, 7 May 2026 13:52:57 +0200 Subject: [PATCH 60/96] fix(ppo trainer): added check if message passing is None --- configs/morphology/5_arms_full_fullconnected.yaml | 7 +++++++ src/brittle_star_project/ppo.py | 3 ++- src/brittle_star_project/trainers/PPOTrainer.py | 7 ++++++- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 configs/morphology/5_arms_full_fullconnected.yaml diff --git a/configs/morphology/5_arms_full_fullconnected.yaml b/configs/morphology/5_arms_full_fullconnected.yaml new file mode 100644 index 0000000..ab08e59 --- /dev/null +++ b/configs/morphology/5_arms_full_fullconnected.yaml @@ -0,0 +1,7 @@ +# 5 Arms Full Morphology Configuration +# Baseline 5-arm brittle star. + +segments_per_arm: [4, 4, 4, 4, 4] +use_p_control: true +use_torque_control: false +morph_mode: FULLY_CONNECTED diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index 635e7b8..79fea1c 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -119,7 +119,8 @@ def get_action_and_value( ): hidden_sensor = sensor_apply(params["sensor_params"], x) hidden_critic = feature_extractor_apply(params["feature_extractor_params"], x) - hidden_sensor = message_passer(params["message_passer_params"], hidden_sensor) + if message_passer is not None: + hidden_sensor = message_passer(params["message_passer_params"], hidden_sensor) debug.callback(logger.debug, f"[SHAPE] hidden_sensor: {hidden_sensor.shape}") debug.callback(logger.debug, f"[SHAPE] hidden_critic: {hidden_critic.shape}") diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 9cbcf7c..f7c6489 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -514,7 +514,12 @@ class PPOTrainer: return jax.vmap(lambda x_in: self.message_passer.apply(p, x_in))(x) self._ppo = PPO( - self.ppo, apply_sensor, apply_actor, apply_critic, apply_feature, apply_message_passer + self.ppo, + apply_sensor, + apply_actor, + apply_critic, + apply_feature, + apply_message_passer if self.message_passer is not None else None, ) self.agent_state = self._init_agent_state() From 7026125bbaea73c0a62f6a3db72c482851a8f1ba Mon Sep 17 00:00:00 2001 From: RobinMeersman <77965843+RobinMeersman@users.noreply.github.com> Date: Thu, 7 May 2026 13:56:28 +0200 Subject: [PATCH 61/96] Update scripts/hpc/train.pbs Co-authored-by: Tibo De Peuter --- scripts/hpc/train.pbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/hpc/train.pbs b/scripts/hpc/train.pbs index a0e79cc..0f95b18 100644 --- a/scripts/hpc/train.pbs +++ b/scripts/hpc/train.pbs @@ -66,7 +66,7 @@ fi # Run training using Hydra overrides python scripts/train.py \ hydra.run.dir="$SCRATCH_RUNDIR" \ - ppo=smoke_test \ + ppo=stable \ logging=hpc echo ">>> Staging out results to $DATA_RUNDIR..." From 4c5122e7793c49b80db510f73ecc58ee85e61f8a Mon Sep 17 00:00:00 2001 From: RobinMeersman <77965843+RobinMeersman@users.noreply.github.com> Date: Thu, 7 May 2026 13:57:19 +0200 Subject: [PATCH 62/96] Update tests/test_adjacency.py Co-authored-by: Tibo De Peuter --- tests/test_adjacency.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/test_adjacency.py b/tests/test_adjacency.py index e6a1333..27c8b43 100644 --- a/tests/test_adjacency.py +++ b/tests/test_adjacency.py @@ -30,9 +30,13 @@ def test_ring(): assert_symmetric(adj) # each node should connect to itself + 2 neighbors - for i in range(5): - assert adj[i, i] == 1 - assert jnp.sum(adj[i]) == 3 + for node in range(5): + assert adj[node, node] == 1 + assert jnp.sum(adj[node]) == 3 + neighbor1 = (node - 1) % 5 + neighbor2 = (node + 1) % 5 + assert adj[neighbor1, node] == 1 + assert adj[node, neighbor2] == 1 # Symmetrical def test_segment_structure(): From 517c3134ca0eb68478b20d3e6765907f2476d8b5 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Thu, 7 May 2026 14:00:39 +0200 Subject: [PATCH 63/96] fix: rewrote info logger calls to debug calls for debug related logs --- .../environment/obs_processing.py | 16 ++++++++-------- src/brittle_star_project/ppo.py | 2 ++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index a57f00b..41afe57 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -128,18 +128,18 @@ def create_obs_processor( for k, v in obs.items(): if hasattr(v, "shape"): size = v.size - logger11.info(f"[RAW] {k}: shape={v.shape}, size={size}") + logger11.debug(f"[RAW] {k}: shape={v.shape}, size={size}") total += size else: - logger11.info(f"[RAW] {k}: non-array") + logger11.debug(f"[RAW] {k}: non-array") - logger11.info(f"[RAW TOTAL FEATURES]: {total}") + logger11.debug(f"[RAW TOTAL FEATURES]: {total}") output = {} num_agents = needed_copies # IMPORTANT: number of MLPs for key, arr in obs.items(): if key not in ordered_keys or arr.size == 0: continue - logger11.info(f"[INPUT] {key}: {arr.shape}") + logger11.debug(f"[INPUT] {key}: {arr.shape}") if arr.ndim == 0: arr = arr.reshape(1) # -------- CENTRALIZED -------- @@ -154,7 +154,7 @@ def create_obs_processor( for i, agent_id in enumerate(agent_indices): idx = segment_indices[i] taken = jnp.take(arr, idx, axis=0) # (segs, ...) - logger11.info(f"WHY {taken.shape}") + logger11.debug(f"WHY {taken.shape}") # pad to 4 pad_len = 4 - taken.shape[0] padded = jnp.pad(taken, [(0, pad_len)] + [(0, 0)] * (taken.ndim - 1)) @@ -182,7 +182,7 @@ def create_obs_processor( else: out = jnp.repeat(arr[None, :], num_agents, axis=0) - logger11.info(f"[OUTPUT] {key}: {out.shape}") + logger11.debug(f"[OUTPUT] {key}: {out.shape}") output[key] = out return output @@ -220,8 +220,8 @@ def create_obs_processor( processed = _normalize_features(processed) processed = _split_to_agents(processed, morph_mode) flat = _flatten_features(processed) # (num_arms, total_feat) - logger11.info(f"[FLATTENED FINAL] shape: {flat.shape}") - logger11.info(f"[PER AGENT] example row 0 shape: {flat[0].shape}") + logger11.debug(f"[FLATTENED FINAL] shape: {flat.shape}") + logger11.debug(f"[PER AGENT] example row 0 shape: {flat[0].shape}") return _flatten_features(processed) # (agents, feat) return jax.jit(jax.vmap(_process_single)) diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index 79fea1c..fffc26b 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -119,6 +119,8 @@ def get_action_and_value( ): hidden_sensor = sensor_apply(params["sensor_params"], x) hidden_critic = feature_extractor_apply(params["feature_extractor_params"], x) + + # only apply message passing in decentralized context if message_passer is not None: hidden_sensor = message_passer(params["message_passer_params"], hidden_sensor) From 4e3cd0c6738b0efd128c70d170287965cb58aa71 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Thu, 7 May 2026 14:07:19 +0200 Subject: [PATCH 64/96] fix(ppo): identity function now takes 2 params, like message_passer --- src/brittle_star_project/ppo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/brittle_star_project/ppo.py b/src/brittle_star_project/ppo.py index fffc26b..fb27ccd 100644 --- a/src/brittle_star_project/ppo.py +++ b/src/brittle_star_project/ppo.py @@ -190,7 +190,7 @@ def ppo_loss( return loss, (pg_loss, v_loss, entropy_loss, jax.lax.stop_gradient(approx_kl)) -def identity(hidden): +def identity(_, hidden): """ Used for seamless jax integration, avoids having branching inside jitted function, From 6956c5e853560417667d3abcef8f6655a169d505 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 7 May 2026 19:08:18 +0200 Subject: [PATCH 65/96] refactor: cleanups while reviewing --- .../environment/obs_processing.py | 64 +++++++++---------- .../trainers/PPOTrainer.py | 35 +++++----- 2 files changed, 49 insertions(+), 50 deletions(-) diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 41afe57..216b008 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -6,8 +6,6 @@ from brittle_star_project.environment.env_config import MorphMode from experiment_logger import get_logger -logger11 = get_logger() - _JOINT_SCALED_KEYS = frozenset( { "joint_position", @@ -57,6 +55,8 @@ def create_obs_processor( segments_per_arm=[4, 4, 4, 4, 4], agent_indices=[0, 1, 2, 3, 4], ): + logger = get_logger() + # made a set to allow O(1) search ordered_keys = frozenset( [ @@ -87,6 +87,13 @@ def create_obs_processor( return new_obs + def _prune_features(obs: dict) -> dict: + pruned = {} + for key, arr in obs.items(): + if key in ordered_keys: + pruned[key] = arr + return pruned + def _normalize_features(obs: dict) -> dict: normalized = {} for key, arr in obs.items(): @@ -124,37 +131,29 @@ def create_obs_processor( return padded def _split_to_agents(obs: dict, morph_mode) -> dict: - total = 0 - for k, v in obs.items(): - if hasattr(v, "shape"): - size = v.size - logger11.debug(f"[RAW] {k}: shape={v.shape}, size={size}") - total += size - else: - logger11.debug(f"[RAW] {k}: non-array") - - logger11.debug(f"[RAW TOTAL FEATURES]: {total}") - output = {} + key_to_agents = {} num_agents = needed_copies # IMPORTANT: number of MLPs + for key, arr in obs.items(): - if key not in ordered_keys or arr.size == 0: + # TODO Should this still be here? + if arr.size == 0: continue - logger11.debug(f"[INPUT] {key}: {arr.shape}") + + logger.debug(f"[INPUT] {key}: {arr.shape}") + if arr.ndim == 0: arr = arr.reshape(1) - # -------- CENTRALIZED -------- + if morph_mode == MorphMode.CENTRALIZED: - output[key] = arr.reshape(1, -1) + key_to_agents[key] = arr.reshape(1, -1) continue - # -------- SEGMENTS -------- if key in _SEGMENT_SCALED_KEYS: per_agent = [] - for i, agent_id in enumerate(agent_indices): - idx = segment_indices[i] - taken = jnp.take(arr, idx, axis=0) # (segs, ...) - logger11.debug(f"WHY {taken.shape}") + for agent_id in agent_indices: + taken = jnp.take(arr, agent_id, axis=0) # (segs, ...) + logger.debug(f"WHY {taken.shape}") # pad to 4 pad_len = 4 - taken.shape[0] padded = jnp.pad(taken, [(0, pad_len)] + [(0, 0)] * (taken.ndim - 1)) @@ -163,13 +162,11 @@ def create_obs_processor( out = jnp.stack(per_agent) - # -------- JOINTS -------- elif key in _JOINT_SCALED_KEYS: per_agent = [] - for i, agent_id in enumerate(agent_indices): - idx = joint_indices[i] - taken = jnp.take(arr, idx, axis=0) # (joint_n, ...) + for agent_id in agent_indices: + taken = jnp.take(arr, agent_id, axis=0) # (joint_n, ...) # pad to 8 pad_len = 8 - taken.shape[0] @@ -182,10 +179,10 @@ def create_obs_processor( else: out = jnp.repeat(arr[None, :], num_agents, axis=0) - logger11.debug(f"[OUTPUT] {key}: {out.shape}") - output[key] = out + logger.debug(f"[OUTPUT] {key}: {out.shape}") + key_to_agents[key] = out - return output + return key_to_agents def _flatten_features(obs: dict) -> jnp.ndarray: """ @@ -217,11 +214,14 @@ def create_obs_processor( def _process_single(obs_dict: dict) -> jnp.ndarray: processed = _add_derived_features(obs_dict) + processed = _prune_features(processed) processed = _normalize_features(processed) processed = _split_to_agents(processed, morph_mode) flat = _flatten_features(processed) # (num_arms, total_feat) - logger11.debug(f"[FLATTENED FINAL] shape: {flat.shape}") - logger11.debug(f"[PER AGENT] example row 0 shape: {flat[0].shape}") - return _flatten_features(processed) # (agents, feat) + + logger.debug(f"[FLATTENED FINAL] shape: {flat.shape}") + logger.debug(f"[PER AGENT] example row 0 shape: {flat[0].shape}") + + return flat # (agents, feat) return jax.jit(jax.vmap(_process_single)) diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index f7c6489..f82ba83 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -31,8 +31,6 @@ from brittle_star_project.ppo import PPO from brittle_star_project.environment import MorphMode from brittle_star_project.utils import logged_jit -logger11 = get_logger() - @logged_jit def _clip_action(action: jnp.ndarray, low: jnp.ndarray, high: jnp.ndarray) -> jnp.ndarray: @@ -121,14 +119,16 @@ def _step_once( action_low, action_high, ) - logger11.debug(f"[_step_once] raw_action: {raw_action.shape}") - logger11.debug(f"[_step_once] clipped_action: {flat_clipped_action.shape}") + logger = get_logger() + + logger.debug(f"[_step_once] raw_action: {raw_action.shape}") + logger.debug(f"[_step_once] clipped_action: {flat_clipped_action.shape}") # Supporting signals (often where mismatch originates) - logger11.debug(f"[_step_once] logprob: {logprob.shape}") - logger11.debug(f"[_step_once] value: {value.shape}") - logger11.debug(f"[_step_once] mean: {mean.shape}") - logger11.debug(f"[_step_once] std: {std.shape}") + logger.debug(f"[_step_once] logprob: {logprob.shape}") + logger.debug(f"[_step_once] value: {value.shape}") + logger.debug(f"[_step_once] mean: {mean.shape}") + logger.debug(f"[_step_once] std: {std.shape}") key, reset_key = jax.random.split(key) reset_rngs = jax.random.split(reset_key, num_envs) @@ -147,9 +147,9 @@ def _step_once( terminated_any = terminated_any | terminated truncated_any = truncated_any | truncated - logger11.debug(f"[_step_once] next_obs: {next_obs.shape}") - logger11.debug(f"[_step_once] reward: {reward.shape}") - logger11.debug(f"[_step_once] next_done: {next_done.shape}") + logger.debug(f"[_step_once] next_obs: {next_obs.shape}") + logger.debug(f"[_step_once] reward: {reward.shape}") + logger.debug(f"[_step_once] next_done: {next_done.shape}") storage = Storage( obs=obs, @@ -547,7 +547,6 @@ class PPOTrainer: case MorphMode.SEGMENT: agent_mask = self.segments_per_arm > 0 agent_indices = jnp.where(agent_mask)[0] - needed_copies = jnp.where(self.segments_per_arm > 0, 1, 0).sum().item() needed_copies = ( self.segments_per_arm.sum() + jnp.where(self.segments_per_arm > 0, 1, 0).sum() ).item() @@ -627,17 +626,17 @@ class PPOTrainer: message_passer_params = {} if self.morph_mode != MorphMode.CENTRALIZED: - assert self.message_passer is not None, "MessagePasser is None" + assert self.message_passer is not None, "decentralized modes require a message passer" message_passer_params = self.message_passer.init( message_passer_key, self.sensor.apply(single_sensor_param, sample_obs), ) - self.logger.debug( - f"[_init_agent_state] message_passer_params: { - jax.tree.map(lambda x: x.shape, message_passer_params) - }" - ) + self.logger.debug( + f"[_init_agent_state] message_passer_params: { + jax.tree.map(lambda x: x.shape, message_passer_params) + }" + ) flat_obs = sample_obs.reshape(-1) # BECAUSE 1 centralized critic self.logger.debug(f"[_init_agent_state] flat_obs: {flat_obs.shape}") From 07ee32fd3baa794b55ece634f43ddec1f84583f9 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Thu, 7 May 2026 19:53:49 +0200 Subject: [PATCH 66/96] fix(simulate): actor action dimension updated to new way of calculating (as in training) --- .../used_variables.md | 107 ------------------ scripts/simulate.py | 30 ++++- .../environment/obs_processing.py | 63 ++++------- src/brittle_star_project/evaluation/policy.py | 27 ++++- .../evaluation/rollout.py | 4 +- 5 files changed, 71 insertions(+), 160 deletions(-) delete mode 100644 experiments/debug-experiment-10042026/used_variables.md diff --git a/experiments/debug-experiment-10042026/used_variables.md b/experiments/debug-experiment-10042026/used_variables.md deleted file mode 100644 index 92f23a1..0000000 --- a/experiments/debug-experiment-10042026/used_variables.md +++ /dev/null @@ -1,107 +0,0 @@ -## Default envconfig -task: Task = Task.DIRECTED_LOCOMOTION -simulation_time: float = 500.0 -num_physics_steps_per_control_step: int = 10 -time_scale: int = 2 -camera_ids: list[int] = field(default_factory=lambda: [0, 1]) -render_size: tuple[int, int] = (480, 640) -joint_randomization_noise_scale: float = 0.0 -target_distance: float = 3.0 -light_perlin_noise_scale: int = 0 - - -## Default ppoargs -seed: int = 1 -torch_deterministic: bool = True -cuda: bool = True -track: bool = False -checkpoint_frequency: int = 100 -learning_rate: float = 2.5e-4 -anneal_lr: bool = True -gamma: float = 0.99 -gae_lambda: float = 0.95 -update_epochs: int = 4 -norm_adv: bool = True -clip_vloss: bool = True -max_grad_norm: float = 0.5 -target_kl: float | None = None -batch_size: int = 0 -minibatch_size: int = 0 -num_iterations: int = 0 - -## Used config file: (hpc/debug.yaml) -exp_name: "debug-experiment" -seed: 42 -track: true -wandb_project_name: "Let's-find-that-bug" -wandb_entity: "SEL3-2026-Groep-4" -run_dir: "/data/gent/465/vsc46589" -num_envs: 32 -num_steps: 32 -num_minibatches: 32 -total_timesteps: 409600 -num_arms: 2 -cuda: true - -ent_coef: 0.005 -vf_coef: 1.0 -clip_coef: 0.2 - -anneal_lr: true -learning_rate: 0.0003 - -## Arena config: -size: tuple[float, float] = (10.0, 5.0) -sand_ground_color: bool = True -attach_target: bool = True -wall_height: float = 1.5 -wall_thickness: float = 0.1 - -## Morphology: -num_segments_per_arm: int = 4 -use_p_control: bool = True -use_torque_control: bool = False - -## MLPs: -### Sensor & Feature_extractor: -Both with 3 layers of 300 neurons per layer. - -class GenericDenseLayersWithActivation(nn.Module): - layer_sizes: Sequence[int] = field(default_factory=lambda: [64, 64]) - activation: Callable = nn.tanh - - @nn.compact - def __call__(self, x): - for size in self.layer_sizes: - x = nn.Dense(size, kernel_init=orthogonal(jnp.sqrt(2)))(x) - x = self.activation(x) - return x - -### Actor: -class Actor(nn.Module): - action_dim: int - @nn.compact - def __call__(self, x): - mean = nn.Dense(self.action_dim, kernel_init=orthogonal(0.01), bias_init=constant(0.0))(x) - log_std = self.param("log_std", nn.initializers.zeros, (self.action_dim,)) - return mean, log_std - -### Critic: -class OneDenseLayerMLP(nn.Module): - @nn.compact - def __call__(self, x): - return nn.Dense(1, kernel_init=orthogonal(1), bias_init=constant(0.0))(x) - -### Observations: -_ALLOWED_OBS_KEYS = { - "joint_position", - "joint_velocity", - "joint_actuator_force", - "actuator_force", - "disk_position", - "disk_rotation", - "disk_linear_velocity", - "disk_angular_velocity", - "unit_xy_direction_to_target", - "xy_distance_to_target", -} \ No newline at end of file diff --git a/scripts/simulate.py b/scripts/simulate.py index 11b4a90..5564aa8 100644 --- a/scripts/simulate.py +++ b/scripts/simulate.py @@ -17,12 +17,14 @@ import numpy as np from omegaconf import DictConfig, OmegaConf import yaml +import jax.numpy as jnp + from brittle_star_project import Backend, BrittleStarEnv, BrittleStarEnvFactory from brittle_star_project.configs.main_config import BrittleStarConfig from brittle_star_project.configs.register_configs import register_configs from brittle_star_project.environment.padded_obs_wrapper import compute_padding_masks from brittle_star_project.environment.obs_processing import create_obs_processor -from brittle_star_project.environment.env_config import MorphologyConfig +from brittle_star_project.environment.env_config import MorphMode, MorphologyConfig from brittle_star_project.evaluation.checkpoint import load_metadata, metadata_to_configs from brittle_star_project.evaluation.policy import PolicyAgent @@ -78,10 +80,34 @@ def main(dict_cfg: DictConfig) -> None: segments_per_arm=env_morphology.segments_per_arm, reference_segments_per_arm=training.morphology.segments_per_arm, ) + + segs_per_arm = jnp.array(env_morphology.segments_per_arm) + + needed_copies = 0 + agent_indices = [0, 1, 2, 3, 4] + match env_morphology.morph_mode: + case MorphMode.CENTRALIZED: + needed_copies = 1 + case MorphMode.FULLY_CONNECTED | MorphMode.RING: + agent_mask = segs_per_arm > 0 + agent_indices = jnp.where(agent_mask)[0] + needed_copies = jnp.where(segs_per_arm > 0, 1, 0).sum().item() + case MorphMode.SEGMENT: + agent_mask = segs_per_arm > 0 + agent_indices = jnp.where(agent_mask)[0] + needed_copies = jnp.where(segs_per_arm > 0, 1, 0).sum().item() + needed_copies = (segs_per_arm.sum() + jnp.where(segs_per_arm > 0, 1, 0).sum()).item() + + num_arms = jnp.where(segs_per_arm > 0, 1, 0).sum().item() + obs_processor = create_obs_processor( bounds_dict=training.obs_bounds.to_bounds_dict(), padding_masks=padding_masks, + needed_copies=needed_copies, + num_arms=num_arms, + morph_mode=env_morphology.morph_mode, segments_per_arm=env_morphology.segments_per_arm, + agent_indices=agent_indices, ) # 6. Build environment @@ -105,7 +131,7 @@ def main(dict_cfg: DictConfig) -> None: state0 = env.reset(seed=seed) # Calculate the action dimension the model was trained with - trained_action_dim = sum(training.morphology.segments_per_arm) * 2 + trained_action_dim = raw_env.action_space.shape[0] // needed_copies # 7. Load policy policy = PolicyAgent.from_checkpoint( diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 216b008..550624d 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -6,6 +6,8 @@ from brittle_star_project.environment.env_config import MorphMode from experiment_logger import get_logger +logger = get_logger() + _JOINT_SCALED_KEYS = frozenset( { "joint_position", @@ -55,8 +57,6 @@ def create_obs_processor( segments_per_arm=[4, 4, 4, 4, 4], agent_indices=[0, 1, 2, 3, 4], ): - logger = get_logger() - # made a set to allow O(1) search ordered_keys = frozenset( [ @@ -87,13 +87,6 @@ def create_obs_processor( return new_obs - def _prune_features(obs: dict) -> dict: - pruned = {} - for key, arr in obs.items(): - if key in ordered_keys: - pruned[key] = arr - return pruned - def _normalize_features(obs: dict) -> dict: normalized = {} for key, arr in obs.items(): @@ -108,35 +101,11 @@ def create_obs_processor( normalized[key] = arr return normalized - def _pad_features(obs: dict, agent_count: int) -> dict: - assert padding_masks is not None - - padded = {} - - for key, arr in obs.items(): - if key in _JOINT_SCALED_KEYS: - target_size = padding_masks["target_size_2x"] - out = jnp.zeros((agent_count, target_size), dtype=arr.dtype) - # place structured values at front, rest stays 0 - out = out.at[:, : arr.shape[1]].set(arr) - padded[key] = out - - elif key in _SEGMENT_SCALED_KEYS: - target_size = padding_masks["target_size_1x"] - out = jnp.zeros((agent_count, target_size), dtype=arr.dtype) - out = out.at[:, : arr.shape[1]].set(arr) - padded[key] = out - else: - padded[key] = arr - return padded - def _split_to_agents(obs: dict, morph_mode) -> dict: - key_to_agents = {} + output = {} num_agents = needed_copies # IMPORTANT: number of MLPs - for key, arr in obs.items(): - # TODO Should this still be here? - if arr.size == 0: + if key not in ordered_keys or arr.size == 0: continue logger.debug(f"[INPUT] {key}: {arr.shape}") @@ -144,17 +113,22 @@ def create_obs_processor( if arr.ndim == 0: arr = arr.reshape(1) + # -------- CENTRALIZED -------- if morph_mode == MorphMode.CENTRALIZED: - key_to_agents[key] = arr.reshape(1, -1) + output[key] = arr.reshape(1, -1) + # TODO: padding for centralized continue + # -------- SEGMENTS -------- if key in _SEGMENT_SCALED_KEYS: per_agent = [] - for agent_id in agent_indices: - taken = jnp.take(arr, agent_id, axis=0) # (segs, ...) + for i, agent_id in enumerate(agent_indices): + idx = segment_indices[i] + taken = jnp.take(arr, idx, axis=0) # (segs, ...) logger.debug(f"WHY {taken.shape}") - # pad to 4 + + # pad to 4 (segments per arm?) pad_len = 4 - taken.shape[0] padded = jnp.pad(taken, [(0, pad_len)] + [(0, 0)] * (taken.ndim - 1)) @@ -162,11 +136,13 @@ def create_obs_processor( out = jnp.stack(per_agent) + # -------- JOINTS -------- elif key in _JOINT_SCALED_KEYS: per_agent = [] - for agent_id in agent_indices: - taken = jnp.take(arr, agent_id, axis=0) # (joint_n, ...) + for i, _ in enumerate(agent_indices): + idx = joint_indices[i] + taken = jnp.take(arr, idx, axis=0) # (joint_n, ...) # pad to 8 pad_len = 8 - taken.shape[0] @@ -180,9 +156,9 @@ def create_obs_processor( out = jnp.repeat(arr[None, :], num_agents, axis=0) logger.debug(f"[OUTPUT] {key}: {out.shape}") - key_to_agents[key] = out + output[key] = out - return key_to_agents + return output def _flatten_features(obs: dict) -> jnp.ndarray: """ @@ -214,7 +190,6 @@ def create_obs_processor( def _process_single(obs_dict: dict) -> jnp.ndarray: processed = _add_derived_features(obs_dict) - processed = _prune_features(processed) processed = _normalize_features(processed) processed = _split_to_agents(processed, morph_mode) flat = _flatten_features(processed) # (num_arms, total_feat) diff --git a/src/brittle_star_project/evaluation/policy.py b/src/brittle_star_project/evaluation/policy.py index 5aa2d6e..b26903e 100644 --- a/src/brittle_star_project/evaluation/policy.py +++ b/src/brittle_star_project/evaluation/policy.py @@ -45,7 +45,8 @@ class PolicyAgent: key = f"Dense_{idx}" if key not in dense_params: break - layer_sizes.append(int(np.asarray(dense_params[key]["kernel"]).shape[1])) + + layer_sizes.append(int(np.asarray(dense_params[key]["kernel"]).shape[-1])) idx += 1 if not layer_sizes: @@ -53,8 +54,8 @@ class PolicyAgent: self._sensor = GenericDenseLayersWithActivation(layer_sizes=layer_sizes) self._actor = Actor(action_dim=action_dim) - self._sensor_apply = jax.jit(self._sensor.apply) - self._actor_apply = jax.jit(self._actor.apply) + self._sensor.apply = jax.jit(self._sensor.apply) + self._actor.apply = jax.jit(self._actor.apply) self._params = { "sensor_params": sensor_params, "actor_params": actor_params, @@ -79,11 +80,25 @@ class PolicyAgent: obs_processor=obs_processor, ) + def _apply_per_node(self, net, params, x): + # params: (nodes, ...) + # x: (batch, nodes, feat) + + def apply_single_node(p, x_node): + # x_node: (batch, feat) + return jax.vmap(lambda xi: net.apply(p, xi))(x_node) + + return jax.vmap(apply_single_node, in_axes=(0, 1), out_axes=1)(params, x) + def act(self, *, observations: dict[str, Any]) -> np.ndarray: """Return deterministic action (actor mean, no exploration noise).""" batched_obs = jax.tree.map(lambda x: jnp.asarray(x)[None, ...], observations) - obs = self._obs_processor(batched_obs)[0] - hidden = self._sensor_apply(self._params["sensor_params"], obs) - mean, _log_std = self._actor_apply(self._params["actor_params"], hidden) + obs = self._obs_processor(batched_obs) + + # TODO: message passing + hidden = self._apply_per_node(self._sensor, self._params["sensor_params"], obs) + + # hidden = jax.vmap(...) + mean, _log_std = self._apply_per_node(self._actor, self._params["actor_params"], hidden) return np.asarray(mean, dtype=np.float32).ravel() diff --git a/src/brittle_star_project/evaluation/rollout.py b/src/brittle_star_project/evaluation/rollout.py index 79c86ed..982a564 100644 --- a/src/brittle_star_project/evaluation/rollout.py +++ b/src/brittle_star_project/evaluation/rollout.py @@ -114,18 +114,20 @@ def rollout_viewer( episode_return = 0.0 observations = _get_observations(state) + prev_dist = _get_xy_distance_to_target(observations) if observations else None reached_target = _target_reached(state=state) steps = 0 with mujoco.viewer.launch_passive(model, data) as viewer: step_iter = range(int(max_steps)) if max_steps is not None else itertools.count() - for _step_idx in step_iter: + for _ in step_iter: if not viewer.is_running(): break step_start = time.time() obs_dict = observations or {} + action = policy.act(observations=obs_dict) if action_mask is not None: action = action[action_mask] From 14d719fe7443173613d0f94e3f46203494b7a8b3 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 7 May 2026 22:48:23 +0200 Subject: [PATCH 67/96] refactor: extract mjx evaluation --- .../evaluation/__init__.py | 15 ++ .../evaluation/evaluate_mjx.py | 255 ++++++++++++++++++ 2 files changed, 270 insertions(+) create mode 100644 src/brittle_star_project/evaluation/evaluate_mjx.py diff --git a/src/brittle_star_project/evaluation/__init__.py b/src/brittle_star_project/evaluation/__init__.py index 38a1c8b..2922d04 100644 --- a/src/brittle_star_project/evaluation/__init__.py +++ b/src/brittle_star_project/evaluation/__init__.py @@ -1,20 +1,35 @@ from __future__ import annotations from .checkpoint import load_metadata, load_params, metadata_to_configs, TrainingConfig +from .evaluate_mjx import ( + CheckpointEvalResult, + append_checkpoint_eval_row, + build_eval_rollout_fn, + evaluate_checkpoint_mjx, +) from .policy import PolicyAgent, ControlPolicy from .rollout import rollout_headless, rollout_viewer, EpisodeResult from .video import record_episode, create_evaluation_dir, save_evaluation_metadata __all__ = [ + # checkpoint loading "load_metadata", "load_params", "metadata_to_configs", "TrainingConfig", + # MJX evaluation + "CheckpointEvalResult", + "append_checkpoint_eval_row", + "build_eval_rollout_fn", + "evaluate_checkpoint_mjx", + # policy "PolicyAgent", "ControlPolicy", + # rollout "rollout_headless", "rollout_viewer", "EpisodeResult", + # video "record_episode", "create_evaluation_dir", "save_evaluation_metadata", diff --git a/src/brittle_star_project/evaluation/evaluate_mjx.py b/src/brittle_star_project/evaluation/evaluate_mjx.py new file mode 100644 index 0000000..f281535 --- /dev/null +++ b/src/brittle_star_project/evaluation/evaluate_mjx.py @@ -0,0 +1,255 @@ +"""MJX-based headless checkpoint evaluation. + +This module provides a fast, JIT-compiled evaluation path using the MJX +(JAX-accelerated MuJoCo) backend. It is intended for evaluating checkpoints +*during* or *after* a training run, where the environment and policy are +already fully initialised. + +The key functions are: + +- `build_eval_rollout_fn` — builds and JIT-compiles a single-episode rollout function from the + training environment and policy components. +- `evaluate_checkpoint_mjx` — runs that function for a given set of parameters and returns a typed + `CheckpointEvalResult`. +- `append_checkpoint_eval_row` — persists the result to the run's + ``metrics/checkpoint_evaluation.csv``, migrating old schemas automatically. +""" + +from __future__ import annotations + +import csv +from dataclasses import dataclass +from pathlib import Path +from typing import Any, Callable + +import jax +import jax.numpy as jnp + + +@dataclass +class CheckpointEvalResult: + """Structured result from a single MJX checkpoint evaluation episode.""" + + steps: int + """Number of control steps taken (≤ max_steps).""" + + reached_target: bool + """Whether the robot reached the target (terminated) before max_steps.""" + + eval_return: float + """Accumulated shaped reward over the episode.""" + + final_xy_dist: float + """XY distance to target at episode end. 0.0 when ``reached_target`` is True.""" + + initial_xy_dist: float + """XY distance to target at episode start.""" + + +def build_eval_rollout_fn( + *, + env: Any, + obs_processor: Callable, + sensor_apply: Callable, + actor_apply: Callable, + action_low: jnp.ndarray, + action_high: jnp.ndarray, + reward_fn: Callable, +) -> Callable: + """Build and JIT-compile a single-episode MJX evaluation rollout. + + The returned function has the signature:: + + eval_fn(params: dict, seed: int, max_steps: int) + -> (steps, reached_target, eval_return, final_xy_dist, initial_xy_dist) + + All outputs are JAX arrays. Convert to Python scalars before logging. + + Args: + env: The training environment wrapper. Must expose ``env.raw`` with + ``reset`` and ``step`` methods compatible with ``jax.vmap``. + obs_processor: Observation normalisation / padding callable, as + returned by ``create_obs_processor``. + sensor_apply: The sensor network's ``apply`` method (JIT-compiled). + actor_apply: The actor network's ``apply`` method (JIT-compiled). + action_low: Per-joint action lower bound (JAX array, shape ``(action_dim,)``). + action_high: Per-joint action upper bound (JAX array, shape ``(action_dim,)``). + reward_fn: Shaped reward function with signature + ``reward_fn(env_state, next_env_state) -> jnp.ndarray``. + Typically the module-level ``reward_fn`` from ``PPOTrainer``. + + Returns: + A JIT-compiled callable that runs one deterministic evaluation episode. + """ + # vmap over a batch of 1 so the MJX API is satisfied without any + # extra bookkeeping in the caller. + reset_1 = jax.vmap(env.raw.reset) + step_1 = jax.vmap(env.raw.step) + + def _eval_rollout(params: dict, seed: int, max_steps: int): + rng = jax.random.PRNGKey(seed) + rngs = jnp.asarray(jax.random.split(rng, 1)) + state = reset_1(rng=rngs) + + initial_xy_dist = jnp.squeeze(state.observations["xy_distance_to_target"]) + + t0 = jnp.asarray(0, dtype=jnp.int32) + done0 = jnp.squeeze(state.terminated | state.truncated) + return0 = jnp.asarray(0.0, dtype=jnp.float32) + + def cond(carry): + t, _state, done, _return_ = carry + return jnp.logical_and(t < max_steps, jnp.logical_not(done)) + + def body(carry): + t, state, _done, return_ = carry + + obs = obs_processor(state.observations) + hidden = sensor_apply(params["sensor_params"], obs) + mean, _log_std = actor_apply(params["actor_params"], hidden) + + # Deterministic action: use the actor mean, no exploration noise. + action = jnp.clip(mean, action_low, action_high) + next_state = step_1(state=state, action=action) + + shaped_reward = reward_fn(state, next_state) + return_ = return_ + jnp.squeeze(shaped_reward) + + done_next = jnp.squeeze(next_state.terminated | next_state.truncated) + return (t + 1, next_state, done_next, return_) + + t, final_state, _done, return_ = jax.lax.while_loop(cond, body, (t0, state, done0, return0)) + + reached_target = jnp.squeeze(final_state.terminated) + final_xy_dist_raw = jnp.squeeze(final_state.observations["xy_distance_to_target"]) + # Clamp to 0 when the target was reached so downstream consumers + # don't have to special-case "terminated" themselves. + final_xy_dist = jnp.where(reached_target, 0.0, final_xy_dist_raw) + + return t, reached_target, return_, final_xy_dist, initial_xy_dist + + return jax.jit(_eval_rollout) + + +def evaluate_checkpoint_mjx( + eval_fn: Callable, + params: dict, + *, + seed: int, + max_steps: int, +) -> CheckpointEvalResult: + """Run one deterministic evaluation episode and return typed metrics. + + Args: + eval_fn: A JIT-compiled function as returned by :func:`build_eval_rollout_fn`. + params: Agent parameter dict (e.g. ``agent_state.params``). + seed: Random seed for environment reset (controls target placement). + max_steps: Maximum number of control steps before the episode is cut off. + + Returns: + A :class:`CheckpointEvalResult` with all JAX arrays converted to + plain Python scalars. + """ + steps, reached, eval_return, final_xy_dist, initial_xy_dist = eval_fn(params, seed, max_steps) + return CheckpointEvalResult( + steps=int(steps), + reached_target=bool(reached), + eval_return=float(eval_return), + final_xy_dist=float(final_xy_dist), + initial_xy_dist=float(initial_xy_dist), + ) + + +_FIELDNAMES = [ + "checkpoint", + "trained_timesteps", + "eval_steps", + "eval_return", + "final_xy_dist", + "initial_xy_dist", + "reached_target", +] + + +def _migrate_csv_if_needed(csv_path: Path) -> None: + """Rewrite the CSV with the canonical field names if the schema changed. + + Best-effort: any exception is silently swallowed so that a schema mismatch + never causes a training crash. + """ + try: + with open(csv_path, "r", newline="") as f: + header = next(csv.reader(f), None) + + if header is None or list(header) == _FIELDNAMES: + return # Nothing to migrate. + + migrated_rows: list[dict[str, Any]] = [] + with open(csv_path, "r", newline="") as f: + for row in csv.DictReader(f): + migrated_rows.append( + { + "checkpoint": row.get("checkpoint", row.get("iteration")), + "trained_timesteps": row.get("trained_timesteps"), + "eval_steps": row.get("eval_steps", row.get("steps_to_target")), + "eval_return": row.get("eval_return"), + "final_xy_dist": row.get("final_xy_dist"), + "initial_xy_dist": row.get("initial_xy_dist"), + "reached_target": row.get("reached_target"), + } + ) + + with open(csv_path, "w", newline="") as f: + writer = csv.DictWriter(f, fieldnames=_FIELDNAMES) + writer.writeheader() + writer.writerows(migrated_rows) + except Exception: + pass # Never crash training on a migration issue. + + +def append_checkpoint_eval_row( + run_dir: str | Path, + *, + iteration: int, + trained_timesteps: int, + result: CheckpointEvalResult, +) -> Path: + """Append one evaluation row to ``/metrics/checkpoint_evaluation.csv``. + + Creates the file (including the ``metrics/`` directory) if it does not yet + exist. Migrates the file to the current schema if the header has changed. + + Args: + run_dir: Root directory of the training run (Hydra's output dir). + iteration: Training iteration number, used as the checkpoint identifier. + trained_timesteps: Total environment steps taken at this checkpoint. + result: Evaluation result as returned by :func:`evaluate_checkpoint_mjx`. + + Returns: + Absolute path to the CSV file (useful for W&B sync). + """ + metrics_dir = Path(run_dir) / "metrics" + metrics_dir.mkdir(parents=True, exist_ok=True) + csv_path = metrics_dir / "checkpoint_evaluation.csv" + + if csv_path.exists(): + _migrate_csv_if_needed(csv_path) + + file_exists = csv_path.exists() + with open(csv_path, "a", newline="") as f: + writer = csv.DictWriter(f, fieldnames=_FIELDNAMES) + if not file_exists: + writer.writeheader() + writer.writerow( + { + "checkpoint": int(iteration), + "trained_timesteps": int(trained_timesteps), + "eval_steps": result.steps, + "eval_return": result.eval_return, + "final_xy_dist": result.final_xy_dist, + "initial_xy_dist": result.initial_xy_dist, + "reached_target": result.reached_target, + } + ) + + return csv_path From a7db4c77bbec06649653a9314289c39516933d40 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 7 May 2026 22:50:38 +0200 Subject: [PATCH 68/96] refactor(log): extract w&b file sync --- src/experiment_logger/simple_logger.py | 4 ++++ src/experiment_logger/unified_logger.py | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/experiment_logger/simple_logger.py b/src/experiment_logger/simple_logger.py index 7e4a816..71844dc 100644 --- a/src/experiment_logger/simple_logger.py +++ b/src/experiment_logger/simple_logger.py @@ -71,6 +71,10 @@ class SimpleLogger: def save_final_model(self, params: Any, metadata: Optional[Dict[str, Any]] = None): print("[SAVE] Final model would be saved (SimpleLogger: No-Op)") + def sync_file(self, path: Any): + """No-op for SimpleLogger.""" + pass + def finish(self): print(f"[FINISH] SimpleLogger finished for run: {self.run_name}") diff --git a/src/experiment_logger/unified_logger.py b/src/experiment_logger/unified_logger.py index f37136b..e308d12 100644 --- a/src/experiment_logger/unified_logger.py +++ b/src/experiment_logger/unified_logger.py @@ -432,6 +432,21 @@ class UnifiedLogger: except Exception as e: self.error(f"Error saving final model: {e}") + def sync_file(self, path: Path) -> None: + """Upload a file to W&B if tracking is enabled. + + Best-effort: logs a warning on failure, never raises. + """ + if self.wandb_run is None: + return + try: + import wandb + + # "Simple sync" behavior: wandb will copy this file into the run. + wandb.save(str(path), base_path=str(path.parent)) + except Exception as e: + self.warning(f"Failed to sync file to W&B: {e}") + def finish(self): """Finalize logging and cleanup.""" # Flush remaining metrics From 1f14ccfd4ac9d4b0ff5666f0bbe53986d0198693 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 7 May 2026 23:01:56 +0200 Subject: [PATCH 69/96] refactor: use mjx eval in PPOTrainer --- .../evaluation/evaluate_mjx.py | 11 +- .../trainers/PPOTrainer.py | 241 ++++-------------- 2 files changed, 49 insertions(+), 203 deletions(-) diff --git a/src/brittle_star_project/evaluation/evaluate_mjx.py b/src/brittle_star_project/evaluation/evaluate_mjx.py index f281535..0193d99 100644 --- a/src/brittle_star_project/evaluation/evaluate_mjx.py +++ b/src/brittle_star_project/evaluation/evaluate_mjx.py @@ -58,11 +58,6 @@ def build_eval_rollout_fn( ) -> Callable: """Build and JIT-compile a single-episode MJX evaluation rollout. - The returned function has the signature:: - - eval_fn(params: dict, seed: int, max_steps: int) - -> (steps, reached_target, eval_return, final_xy_dist, initial_xy_dist) - All outputs are JAX arrays. Convert to Python scalars before logging. Args: @@ -141,13 +136,13 @@ def evaluate_checkpoint_mjx( """Run one deterministic evaluation episode and return typed metrics. Args: - eval_fn: A JIT-compiled function as returned by :func:`build_eval_rollout_fn`. + eval_fn: A JIT-compiled function as returned by `build_eval_rollout_fn`. params: Agent parameter dict (e.g. ``agent_state.params``). seed: Random seed for environment reset (controls target placement). max_steps: Maximum number of control steps before the episode is cut off. Returns: - A :class:`CheckpointEvalResult` with all JAX arrays converted to + A `CheckpointEvalResult` with all JAX arrays converted to plain Python scalars. """ steps, reached, eval_return, final_xy_dist, initial_xy_dist = eval_fn(params, seed, max_steps) @@ -223,7 +218,7 @@ def append_checkpoint_eval_row( run_dir: Root directory of the training run (Hydra's output dir). iteration: Training iteration number, used as the checkpoint identifier. trained_timesteps: Total environment steps taken at this checkpoint. - result: Evaluation result as returned by :func:`evaluate_checkpoint_mjx`. + result: Evaluation result as returned by `evaluate_checkpoint_mjx`. Returns: Absolute path to the CSV file (useful for W&B sync). diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index 5ae20ec..8934c83 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -1,17 +1,15 @@ import datetime import random import time -import csv from dataclasses import asdict, dataclass from functools import partial -from pathlib import Path -from typing import Any import jax import jax.numpy as jnp import numpy as np import optax from flax.training.train_state import TrainState +from typing import Any from experiment_logger import get_logger @@ -19,6 +17,11 @@ from brittle_star_project.configs.main_config import BrittleStarConfig from brittle_star_project.dataclasses import EpisodeStatistics from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleStarJaxEnvWrapper from brittle_star_project.environment.obs_processing import create_obs_processor +from brittle_star_project.evaluation.evaluate_mjx import ( + append_checkpoint_eval_row, + build_eval_rollout_fn, + evaluate_checkpoint_mjx, +) from brittle_star_project.MLPs.mlps import ( Actor, AgentParams, @@ -122,8 +125,13 @@ def _step_once( return (agent_state, episode_stats, next_obs, next_done, key, env_state), storage -def _reward_fn(env_state, next_env_state): - # if delta distance positive ==> brittle star walking away from target +def reward_fn(env_state, next_env_state): + """Shaped reward used during training and checkpoint evaluation. + + Public so that ``evaluation.evaluate_mjx`` can import it and produce + metrics that are directly comparable to training-time returns. + """ + # Positive delta_distance means the brittle star is moving *away* from target. delta_distance = ( next_env_state.observations["xy_distance_to_target"] - env_state.observations["xy_distance_to_target"] @@ -142,7 +150,7 @@ def _reward_fn(env_state, next_env_state): def _step_env_wrapped(episode_stats, env_state, action, env_step_fn, obs_processor): next_env_state = env_step_fn(env_state, action) - reward = _reward_fn(env_state, next_env_state) + reward = reward_fn(env_state, next_env_state) terminated = next_env_state.terminated truncated = next_env_state.truncated done = terminated | truncated @@ -327,74 +335,8 @@ class PPOTrainer: self.episode_stats = self._init_episode_stats() self._init_random() - # Lazily created MJX/JAX evaluation rollout (compiled on first use) - self._eval_rollout_mjx_fn = None - - def _get_or_create_eval_rollout_mjx_fn(self): - if self._eval_rollout_mjx_fn is not None: - return self._eval_rollout_mjx_fn - - # Use the same backend as training (typically MJX). - if getattr(self.env, "backend", None) != Backend.MJX: - self.logger.warning( - f"[EVAL]: Training env backend is {self.env.backend}; " - "MJX evaluation may be unavailable/slow." - ) - - # We vmap over a single environment (batch size 1) for simplicity. - reset_1 = jax.vmap(self.env.raw.reset) - step_1 = jax.vmap(self.env.raw.step) - - action_low = self._action_low - action_high = self._action_high - obs_processor = self.obs_processor - sensor_apply = self.sensor.apply - actor_apply = self.actor.apply - - def _eval_rollout(params, seed: int, max_steps: int): - rng = jax.random.PRNGKey(seed) - rngs = jnp.asarray(jax.random.split(rng, 1)) - state = reset_1(rng=rngs) - - initial_xy_dist = jnp.squeeze(state.observations["xy_distance_to_target"]) - - t0 = jnp.asarray(0, dtype=jnp.int32) - done0 = jnp.squeeze(state.terminated | state.truncated) - return0 = jnp.asarray(0.0, dtype=jnp.float32) - - def cond(carry): - t, _state, done, _return_ = carry - return jnp.logical_and(t < max_steps, jnp.logical_not(done)) - - def body(carry): - t, state, _done, return_ = carry - - obs = obs_processor(state.observations) - hidden = sensor_apply(params["sensor_params"], obs) - mean, _log_std = actor_apply(params["actor_params"], hidden) - - action = jnp.clip(mean, action_low, action_high) - next_state = step_1(state=state, action=action) - - # Match training's shaped reward as closely as possible. - shaped_reward = _reward_fn(state, next_state) - return_ = return_ + jnp.squeeze(shaped_reward) - - done_next = jnp.squeeze(next_state.terminated | next_state.truncated) - return (t + 1, next_state, done_next, return_) - - t, final_state, _done, return_ = jax.lax.while_loop( - cond, body, (t0, state, done0, return0) - ) - - reached_target = jnp.squeeze(final_state.terminated) - final_xy_dist_raw = jnp.squeeze(final_state.observations["xy_distance_to_target"]) - final_xy_dist = jnp.where(reached_target, 0.0, final_xy_dist_raw) - - return t, reached_target, return_, final_xy_dist, initial_xy_dist - - self._eval_rollout_mjx_fn = jax.jit(_eval_rollout) - return self._eval_rollout_mjx_fn + # Lazily-built JIT-compiled MJX eval rollout, created on first evaluation. + self._eval_fn = None def _init_random(self): self.logger.info(f"[RANDOM]: Setting random seed to {self.experiment.seed}") @@ -613,104 +555,12 @@ class PPOTrainer: params=self.agent_state.params, step=iteration, metadata=asdict(self.cfg) ) - def _maybe_sync_csv_to_wandb(self, csv_path: Path) -> None: - if not self.logging_cfg.track: - return - try: - import wandb - - if wandb.run is None: - return - - # "Simple sync" behavior: wandb will copy this file into the run. - wandb.save(str(csv_path), base_path=str(csv_path.parent)) - except Exception as e: - self.logger.warning(f"[EVAL]: Failed to sync CSV to wandb: {e}") - - def _append_checkpoint_eval_row( - self, - *, - iteration: int, - trained_timesteps: int, - eval_steps: int, - eval_return: float, - final_xy_dist: float, - initial_xy_dist: float, - reached_target: bool, - ) -> Path: - metrics_dir = Path(self.run_dir) / "metrics" - metrics_dir.mkdir(parents=True, exist_ok=True) - csv_path = metrics_dir / "checkpoint_evaluation.csv" - - fieldnames = [ - "checkpoint", - "trained_timesteps", - "eval_steps", - "eval_return", - "final_xy_dist", - "initial_xy_dist", - "reached_target", - ] - - # If a previous version created this CSV with a different header, migrate it. - if csv_path.exists(): - try: - with open(csv_path, "r", newline="") as f: - reader = csv.reader(f) - header = next(reader, None) - - if header is not None and list(header) != fieldnames: - migrated_rows: list[dict[str, Any]] = [] - with open(csv_path, "r", newline="") as f: - dict_reader = csv.DictReader(f) - for row in dict_reader: - # Support older schemas best-effort. - checkpoint = row.get("checkpoint", row.get("iteration")) - steps = row.get("eval_steps", row.get("steps_to_target")) - migrated_rows.append( - { - "checkpoint": checkpoint, - "trained_timesteps": row.get("trained_timesteps"), - "eval_steps": steps, - "eval_return": row.get("eval_return"), - "final_xy_dist": row.get("final_xy_dist"), - "initial_xy_dist": row.get("initial_xy_dist"), - "reached_target": row.get("reached_target"), - } - ) - - with open(csv_path, "w", newline="") as f: - writer = csv.DictWriter(f, fieldnames=fieldnames) - writer.writeheader() - for row in migrated_rows: - writer.writerow(row) - except Exception: - # Best-effort only; do not fail training on migration issues. - pass - - file_exists = csv_path.exists() - with open(csv_path, "a", newline="") as f: - writer = csv.DictWriter( - f, - fieldnames=fieldnames, - ) - if not file_exists: - writer.writeheader() - writer.writerow( - { - "checkpoint": int(iteration), - "trained_timesteps": int(trained_timesteps), - "eval_steps": int(eval_steps), - "eval_return": float(eval_return), - "final_xy_dist": float(final_xy_dist), - "initial_xy_dist": float(initial_xy_dist), - "reached_target": bool(reached_target), - } - ) - - return csv_path - def _evaluate_checkpoint(self, iteration: int, *, trained_timesteps: int) -> None: + """Evaluate the current checkpoint and persist metrics to CSV. + + Delegates all evaluation logic to `evaluation.evaluate_mjx`. + Best-effort: a failure here must never abort training. + """ if not self.evaluation_cfg.evaluate_checkpoints: return @@ -728,35 +578,36 @@ class PPOTrainer: ) return - # Run evaluation best-effort; never fail training because evaluation failed. try: - eval_fn = self._get_or_create_eval_rollout_mjx_fn() - ( - steps, - reached, - eval_return, - final_xy_dist, - initial_xy_dist, - ) = eval_fn(self.agent_state.params, seed, max_steps) + if self._eval_fn is None: + if getattr(self.env, "backend", None) != Backend.MJX: + self.logger.warning( + f"[EVAL]: Training env backend is {self.env.backend}; " + "MJX evaluation may be unavailable/slow." + ) + self._eval_fn = build_eval_rollout_fn( + env=self.env, + obs_processor=self.obs_processor, + sensor_apply=self.sensor.apply, + actor_apply=self.actor.apply, + action_low=self._action_low, + action_high=self._action_high, + reward_fn=reward_fn, + ) - eval_steps = int(steps) - reached_target = bool(reached) - - # Keep numeric conversions explicit (JAX scalars -> Python scalars). - eval_return_f = float(eval_return) - final_xy_dist_f = float(final_xy_dist) - initial_xy_dist_f = float(initial_xy_dist) - - csv_path = self._append_checkpoint_eval_row( + result = evaluate_checkpoint_mjx( + self._eval_fn, + self.agent_state.params, + seed=seed, + max_steps=max_steps, + ) + csv_path = append_checkpoint_eval_row( + self.run_dir, iteration=iteration, trained_timesteps=int(trained_timesteps), - eval_steps=eval_steps, - eval_return=eval_return_f, - final_xy_dist=final_xy_dist_f, - initial_xy_dist=initial_xy_dist_f, - reached_target=reached_target, + result=result, ) - self._maybe_sync_csv_to_wandb(csv_path) + self.logger.sync_file(csv_path) except Exception as e: self.logger.warning(f"[EVAL]: Checkpoint evaluation failed: {e}") From b88a7ac660d2879bb14b412a69f54e7718aecc02 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 7 May 2026 23:17:54 +0200 Subject: [PATCH 70/96] feat(evaluate): evaluate_policy base --- configs/evaluation/poster.yaml | 20 +++++++ .../configs/config_evaluation.py | 12 +++- .../evaluation/__init__.py | 3 + .../evaluation/evaluate.py | 58 +++++++++++++++++++ .../evaluation/rollout.py | 3 + 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 configs/evaluation/poster.yaml create mode 100644 src/brittle_star_project/evaluation/evaluate.py diff --git a/configs/evaluation/poster.yaml b/configs/evaluation/poster.yaml new file mode 100644 index 0000000..048a785 --- /dev/null +++ b/configs/evaluation/poster.yaml @@ -0,0 +1,20 @@ +# @package evaluation +# Configuration for the models used in the poster comparison. + +# Standard evaluation settings +evaluate_checkpoints: false +eval_max_steps: 5000 +eval_seed: 0 + +# Cross-model comparison settings +# We use 10 episodes to get a more robust average for the final poster results. +comparison_base_seed: 0 +comparison_num_episodes: 10 +comparison_output_csv: "metrics/poster_comparison.csv" + +# Paths to the .cleanrl_model files to be compared (relative to workspace root). +# These are placeholders; replace with actual trained model paths for the poster. +comparison_models: + - "experiments/poster/centralized.cleanrl_model" + - "experiments/poster/decentralized.cleanrl_model" + - "experiments/poster/decentralized_amputated.cleanrl_model" diff --git a/src/brittle_star_project/configs/config_evaluation.py b/src/brittle_star_project/configs/config_evaluation.py index 4eeadbc..69c6609 100644 --- a/src/brittle_star_project/configs/config_evaluation.py +++ b/src/brittle_star_project/configs/config_evaluation.py @@ -1,6 +1,6 @@ from __future__ import annotations -from dataclasses import dataclass +from dataclasses import dataclass, field @dataclass @@ -16,6 +16,16 @@ class EvaluationConfig: eval_max_steps: int = 5000 eval_seed: int = 0 + # Cross-model comparison settings. + # comparison_base_seed is the starting seed for generating episode seeds. + comparison_base_seed: int = 0 + # comparison_num_episodes controls how many target positions to evaluate for each model. + comparison_num_episodes: int = 5 + # comparison_models lists the paths (relative to workspace root) to the .cleanrl_model files. + comparison_models: list[str] = field(default_factory=list) + # Path where the comparison results CSV will be saved (relative to workspace root). + comparison_output_csv: str = "metrics/model_comparison.csv" + def __post_init__(self) -> None: if self.evaluate_checkpoints and self.eval_max_steps <= 0: raise ValueError( diff --git a/src/brittle_star_project/evaluation/__init__.py b/src/brittle_star_project/evaluation/__init__.py index 2922d04..f9ed595 100644 --- a/src/brittle_star_project/evaluation/__init__.py +++ b/src/brittle_star_project/evaluation/__init__.py @@ -7,6 +7,7 @@ from .evaluate_mjx import ( build_eval_rollout_fn, evaluate_checkpoint_mjx, ) +from .evaluate import evaluate_policy from .policy import PolicyAgent, ControlPolicy from .rollout import rollout_headless, rollout_viewer, EpisodeResult from .video import record_episode, create_evaluation_dir, save_evaluation_metadata @@ -22,6 +23,8 @@ __all__ = [ "append_checkpoint_eval_row", "build_eval_rollout_fn", "evaluate_checkpoint_mjx", + # CPU evaluation + "evaluate_policy", # policy "PolicyAgent", "ControlPolicy", diff --git a/src/brittle_star_project/evaluation/evaluate.py b/src/brittle_star_project/evaluation/evaluate.py new file mode 100644 index 0000000..12cc6fc --- /dev/null +++ b/src/brittle_star_project/evaluation/evaluate.py @@ -0,0 +1,58 @@ +"""MJC-based (CPU) checkpoint evaluation. + +This module provides the CPU-bound evaluation path using the standard MJC backend. +It is primarily used by the `evaluate_checkpoints` CLI to compute metrics and +render videos. +""" + +from pathlib import Path + +import numpy as np + +from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleStarJaxEnvWrapper +from brittle_star_project.environment.obs_processing import create_obs_processor +from brittle_star_project.evaluation.policy import PolicyAgent +from brittle_star_project.evaluation.rollout import EpisodeResult, rollout_headless + + +def evaluate_policy( + env: BrittleStarJaxEnvWrapper, + policy_path: str | Path, + seed: int, + max_steps: int, +) -> EpisodeResult: + """Evaluate a trained policy in a CPU-bound environment. + + Args: + env: Initialised CPU environment (MJC backend). + policy_path: Path to the ``.cleanrl_model`` weights file. + seed: Random seed for environment reset. + max_steps: Maximum number of control steps. + + Returns: + Structured result containing return, length, and distance metrics. + """ + obs_processor = create_obs_processor( + bounds_dict=env.cfg.obs_bounds.to_bounds_dict(), + padding_masks=env.padding_masks, + ) + + action_dim = env.single_action_space.shape[0] + + policy = PolicyAgent.from_checkpoint( + model_path=Path(policy_path), + action_dim=action_dim, + obs_processor=obs_processor, + ) + + action_low = np.asarray(env.single_action_space.low, dtype=np.float32) + action_high = np.asarray(env.single_action_space.high, dtype=np.float32) + + return rollout_headless( + env=env, + policy=policy, + seed=seed, + max_steps=max_steps, + action_low=action_low, + action_high=action_high, + ) diff --git a/src/brittle_star_project/evaluation/rollout.py b/src/brittle_star_project/evaluation/rollout.py index 79c86ed..a8eb8db 100644 --- a/src/brittle_star_project/evaluation/rollout.py +++ b/src/brittle_star_project/evaluation/rollout.py @@ -17,6 +17,7 @@ class EpisodeResult: length: int reached_target: bool final_xy_dist: float | None + initial_target_distance: float | None def _get_observations(state: Any) -> dict[str, Any] | None: @@ -61,6 +62,7 @@ def rollout_headless( ep_return = 0.0 observations = _get_observations(state) prev_dist = _get_xy_distance_to_target(observations) if observations else None + initial_target_distance = prev_dist reached_target = _target_reached(state=state) steps = 0 @@ -91,6 +93,7 @@ def rollout_headless( length=steps, reached_target=reached_target, final_xy_dist=final_dist, + initial_target_distance=initial_target_distance, ) From 56afc7ec5d71b8a660f29a715366edb338d625c7 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Thu, 7 May 2026 23:43:39 +0200 Subject: [PATCH 71/96] feat(evaluate): evaluation scripts --- configs/evaluation/poster.yaml | 9 +- .../used_variables.md | 107 --------- scripts/compare_models.py | 204 ++++++++++++++++++ scripts/evaluate_checkpoints.py | 170 +++++++++++++++ .../evaluation/evaluate.py | 2 +- .../evaluation/evaluate_mjx.py | 24 +-- 6 files changed, 390 insertions(+), 126 deletions(-) delete mode 100644 experiments/debug-experiment-10042026/used_variables.md create mode 100644 scripts/compare_models.py create mode 100644 scripts/evaluate_checkpoints.py diff --git a/configs/evaluation/poster.yaml b/configs/evaluation/poster.yaml index 048a785..a09907f 100644 --- a/configs/evaluation/poster.yaml +++ b/configs/evaluation/poster.yaml @@ -9,12 +9,9 @@ eval_seed: 0 # Cross-model comparison settings # We use 10 episodes to get a more robust average for the final poster results. comparison_base_seed: 0 -comparison_num_episodes: 10 -comparison_output_csv: "metrics/poster_comparison.csv" +comparison_num_episodes: 2 +comparison_output_csv: "runs/evaluation/comparison.csv" # Paths to the .cleanrl_model files to be compared (relative to workspace root). -# These are placeholders; replace with actual trained model paths for the poster. comparison_models: - - "experiments/poster/centralized.cleanrl_model" - - "experiments/poster/decentralized.cleanrl_model" - - "experiments/poster/decentralized_amputated.cleanrl_model" + - "runs/input-space-2-arms/2026-05-02/08-14-58/final_model.flax" diff --git a/experiments/debug-experiment-10042026/used_variables.md b/experiments/debug-experiment-10042026/used_variables.md deleted file mode 100644 index 92f23a1..0000000 --- a/experiments/debug-experiment-10042026/used_variables.md +++ /dev/null @@ -1,107 +0,0 @@ -## Default envconfig -task: Task = Task.DIRECTED_LOCOMOTION -simulation_time: float = 500.0 -num_physics_steps_per_control_step: int = 10 -time_scale: int = 2 -camera_ids: list[int] = field(default_factory=lambda: [0, 1]) -render_size: tuple[int, int] = (480, 640) -joint_randomization_noise_scale: float = 0.0 -target_distance: float = 3.0 -light_perlin_noise_scale: int = 0 - - -## Default ppoargs -seed: int = 1 -torch_deterministic: bool = True -cuda: bool = True -track: bool = False -checkpoint_frequency: int = 100 -learning_rate: float = 2.5e-4 -anneal_lr: bool = True -gamma: float = 0.99 -gae_lambda: float = 0.95 -update_epochs: int = 4 -norm_adv: bool = True -clip_vloss: bool = True -max_grad_norm: float = 0.5 -target_kl: float | None = None -batch_size: int = 0 -minibatch_size: int = 0 -num_iterations: int = 0 - -## Used config file: (hpc/debug.yaml) -exp_name: "debug-experiment" -seed: 42 -track: true -wandb_project_name: "Let's-find-that-bug" -wandb_entity: "SEL3-2026-Groep-4" -run_dir: "/data/gent/465/vsc46589" -num_envs: 32 -num_steps: 32 -num_minibatches: 32 -total_timesteps: 409600 -num_arms: 2 -cuda: true - -ent_coef: 0.005 -vf_coef: 1.0 -clip_coef: 0.2 - -anneal_lr: true -learning_rate: 0.0003 - -## Arena config: -size: tuple[float, float] = (10.0, 5.0) -sand_ground_color: bool = True -attach_target: bool = True -wall_height: float = 1.5 -wall_thickness: float = 0.1 - -## Morphology: -num_segments_per_arm: int = 4 -use_p_control: bool = True -use_torque_control: bool = False - -## MLPs: -### Sensor & Feature_extractor: -Both with 3 layers of 300 neurons per layer. - -class GenericDenseLayersWithActivation(nn.Module): - layer_sizes: Sequence[int] = field(default_factory=lambda: [64, 64]) - activation: Callable = nn.tanh - - @nn.compact - def __call__(self, x): - for size in self.layer_sizes: - x = nn.Dense(size, kernel_init=orthogonal(jnp.sqrt(2)))(x) - x = self.activation(x) - return x - -### Actor: -class Actor(nn.Module): - action_dim: int - @nn.compact - def __call__(self, x): - mean = nn.Dense(self.action_dim, kernel_init=orthogonal(0.01), bias_init=constant(0.0))(x) - log_std = self.param("log_std", nn.initializers.zeros, (self.action_dim,)) - return mean, log_std - -### Critic: -class OneDenseLayerMLP(nn.Module): - @nn.compact - def __call__(self, x): - return nn.Dense(1, kernel_init=orthogonal(1), bias_init=constant(0.0))(x) - -### Observations: -_ALLOWED_OBS_KEYS = { - "joint_position", - "joint_velocity", - "joint_actuator_force", - "actuator_force", - "disk_position", - "disk_rotation", - "disk_linear_velocity", - "disk_angular_velocity", - "unit_xy_direction_to_target", - "xy_distance_to_target", -} \ No newline at end of file diff --git a/scripts/compare_models.py b/scripts/compare_models.py new file mode 100644 index 0000000..ceebb89 --- /dev/null +++ b/scripts/compare_models.py @@ -0,0 +1,204 @@ +"""Compare multiple trained policies across shared evaluation conditions. + +For each model listed in evaluation.comparison_models, this script runs +`comparison_num_episodes` headless rollouts (seeded sequentially from +`comparison_base_seed`) and writes a results CSV to `comparison_output_csv`. + +Results include two metrics per episode: +- `eval_return` — shaped reward (same function used during training) +- `max_velocity` — approximated as initial_xy_dist / steps taken + +Usage: + # With the default evaluation config + python scripts/compare_models.py evaluation=poster + + # Override the output path on the fly + python scripts/compare_models.py evaluation=poster \\ + evaluation.comparison_output_csv=metrics/quick_comparison.csv +""" + +from __future__ import annotations + +import csv +import logging +import time +from pathlib import Path + +import hydra +import numpy as np +from omegaconf import DictConfig, OmegaConf + +from brittle_star_project import Backend, BrittleStarEnv, BrittleStarEnvFactory +from brittle_star_project.configs.main_config import BrittleStarConfig +from brittle_star_project.configs.register_configs import register_configs +from brittle_star_project.environment.obs_processing import create_obs_processor +from brittle_star_project.environment.padded_obs_wrapper import compute_padding_masks +from brittle_star_project.evaluation.checkpoint import load_metadata, metadata_to_configs +from brittle_star_project.evaluation.policy import PolicyAgent +from brittle_star_project.evaluation.rollout import rollout_headless + +_FIELDNAMES = [ + "model_path", + "seed", + "reached_target", + "episode_length", + "eval_return", + "initial_target_distance", + "final_xy_dist", + "approx_max_velocity", +] + + +def _approx_max_velocity(result) -> float | None: + """Approximate max velocity as distance covered per step. + + This is a rough upper bound: (initial_dist - final_dist) / steps. + """ + if result.initial_target_distance is None or result.final_xy_dist is None or result.length <= 0: + return None + dist_covered = result.initial_target_distance - result.final_xy_dist + return dist_covered / result.length + + +@hydra.main(config_path="../configs", config_name="main_config", version_base="1.3") +def main(dict_cfg: DictConfig) -> None: + logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") + logger = logging.getLogger(__name__) + + cfg: BrittleStarConfig = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(BrittleStarConfig), dict_cfg) + ) + eval_cfg = cfg.evaluation + + model_paths = [str(p) for p in eval_cfg.comparison_models] + if not model_paths: + raise ValueError( + "evaluation.comparison_models is empty. " + "Add at least one model path in your evaluation config." + ) + + base_seed = int(eval_cfg.comparison_base_seed) + num_episodes = int(eval_cfg.comparison_num_episodes) + max_steps = int(eval_cfg.eval_max_steps) + + seeds = list(range(base_seed, base_seed + num_episodes)) + + output_path = Path(hydra.utils.to_absolute_path(eval_cfg.comparison_output_csv)) + output_path.parent.mkdir(parents=True, exist_ok=True) + + logger.info( + f"Comparing {len(model_paths)} models over {num_episodes} episodes " + f"(seeds {seeds[0]}–{seeds[-1]})." + ) + logger.info(f"Results will be written to: {output_path}") + + with open(output_path, "w", newline="") as csv_file: + writer = csv.DictWriter(csv_file, fieldnames=_FIELDNAMES) + writer.writeheader() + + for model_path_str in model_paths: + model_path = Path(hydra.utils.to_absolute_path(model_path_str)) + logger.info(f"Evaluating model: {model_path.name}") + + # --- Load sidecar metadata + reconstruct configs --- + try: + metadata = load_metadata(model_path) + except FileNotFoundError as e: + logger.warning(f"Skipping model — {e}") + continue + + training = metadata_to_configs(metadata) + + # --- Build padding masks and obs_processor --- + padding_masks = compute_padding_masks( + segments_per_arm=training.morphology.segments_per_arm, + reference_segments_per_arm=training.morphology.segments_per_arm, + ) + obs_processor = create_obs_processor( + bounds_dict=training.obs_bounds.to_bounds_dict(), + padding_masks=padding_masks, + ) + + # --- Build the CPU environment from training config --- + factory = BrittleStarEnvFactory() + raw_env = factory.create_environment( + Backend.MJC, + training.morphology, + training.arena, + training.environment, + ) + env = BrittleStarEnv( + raw_env, + backend=Backend.MJC, + config=training.environment, + morphology_config=training.morphology, + ) + + trained_action_dim = sum(training.morphology.segments_per_arm) * 2 + action_mask = np.asarray(padding_masks["mask_2x"]) + action_space = getattr(raw_env, "action_space", None) + action_low = ( + None + if action_space is None + else np.asarray(action_space.low, dtype=np.float32).ravel() + ) + action_high = ( + None + if action_space is None + else np.asarray(action_space.high, dtype=np.float32).ravel() + ) + + policy = PolicyAgent.from_checkpoint( + model_path, + action_dim=trained_action_dim, + obs_processor=obs_processor, + ) + + # --- Run episodes --- + for seed in seeds: + t0 = time.time() + result = rollout_headless( + env=env, + policy=policy, + seed=seed, + max_steps=max_steps, + action_low=action_low, + action_high=action_high, + action_mask=action_mask, + ) + elapsed = time.time() - t0 + + velocity = _approx_max_velocity(result) + + logger.debug( + f"seed={seed:3d} | " + f"reached={str(result.reached_target):<5} | " + f"return={result.return_:+8.3f} | " + f"steps={result.length:4d} | " + f"final_dist=" + f"{'n/a' if result.final_xy_dist is None else f'{result.final_xy_dist:.3f}'} | " + f"({elapsed:.1f}s)" + ) + + writer.writerow( + { + "model_path": model_path_str, + "seed": seed, + "reached_target": result.reached_target, + "episode_length": result.length, + "eval_return": result.return_, + "initial_target_distance": result.initial_target_distance, + "final_xy_dist": result.final_xy_dist, + "approx_max_velocity": velocity, + } + ) + csv_file.flush() + + env.close() + + logger.info(f"Done. Results saved to {output_path}") + + +if __name__ == "__main__": + register_configs() + main() diff --git a/scripts/evaluate_checkpoints.py b/scripts/evaluate_checkpoints.py new file mode 100644 index 0000000..82475a1 --- /dev/null +++ b/scripts/evaluate_checkpoints.py @@ -0,0 +1,170 @@ +"""Re-evaluate saved checkpoints from a completed training run using MJX. + +This script scans the checkpoint directory of a training run (the `checkpoints/` +folder inside a Hydra output directory), loads each `.flax` checkpoint, runs +one deterministic evaluation episode with `build_eval_rollout_fn`, and appends +the result to the run's `metrics/checkpoint_evaluation.csv`. + +It is intended for post-training analysis when per-checkpoint evaluation was not +enabled during training (`evaluate_checkpoints: false`). + +Usage: + python scripts/evaluate_checkpoints.py \ + simulation.model_path=runs/2024-01-01/12-00-00/final_model.flax \ + evaluation.eval_max_steps=5000 \ + evaluation.eval_seed=0 + +The script resolves the run directory from `simulation.model_path`, discovers +all `*.flax` checkpoints under `checkpoints/`, and evaluates them in order. +""" + +from __future__ import annotations + +import logging +import re +from pathlib import Path + +import hydra +import jax +import numpy as np +from omegaconf import DictConfig, OmegaConf + +from brittle_star_project.configs.main_config import BrittleStarConfig +from brittle_star_project.configs.register_configs import register_configs +from brittle_star_project.environment.BrittleStarJaxEnvWrapper import BrittleStarJaxEnvWrapper +from brittle_star_project.environment.obs_processing import create_obs_processor +from brittle_star_project.environment.padded_obs_wrapper import compute_padding_masks +from brittle_star_project.evaluation.checkpoint import ( + load_metadata, + load_params, + metadata_to_configs, +) +from brittle_star_project.evaluation.evaluate_mjx import ( + append_checkpoint_eval_row, + build_eval_rollout_fn, + evaluate_checkpoint_mjx, +) +from brittle_star_project.trainers.PPOTrainer import reward_fn + + +def _parse_iteration(checkpoint_path: Path) -> int: + """Parse the iteration number from a checkpoint filename like `checkpoint_0042.flax`.""" + match = re.search(r"(\d+)", checkpoint_path.stem) + return int(match.group(1)) if match else -1 + + +@hydra.main(config_path="../configs", config_name="main_config", version_base="1.3") +def main(dict_cfg: DictConfig) -> None: + logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") + logger = logging.getLogger(__name__) + + cfg: BrittleStarConfig = OmegaConf.to_object( + OmegaConf.merge(OmegaConf.structured(BrittleStarConfig), dict_cfg) + ) + sim_cfg = cfg.simulation + eval_cfg = cfg.evaluation + + # --- Resolve the model path to find the run directory --- + model_path_str = sim_cfg.model_path + if model_path_str is None: + raise ValueError( + "simulation.model_path must point to the final_model.flax of a training run." + ) + + model_path = Path(hydra.utils.to_absolute_path(model_path_str)) + run_dir = model_path.parent + + checkpoints_dir = run_dir / "checkpoints" + if not checkpoints_dir.exists(): + raise FileNotFoundError( + f"No checkpoints/ directory found in run directory: {run_dir}\n" + "Make sure simulation.model_path points to a completed training run." + ) + + checkpoints = sorted(checkpoints_dir.glob("*.flax"), key=_parse_iteration) + if not checkpoints: + raise FileNotFoundError(f"No .flax checkpoints found in {checkpoints_dir}") + + logger.info(f"Found {len(checkpoints)} checkpoint(s) in {checkpoints_dir}") + + # --- Load sidecar metadata + reconstruct training config --- + metadata_override = ( + Path(hydra.utils.to_absolute_path(sim_cfg.metadata_path)) + if sim_cfg.metadata_path is not None + else None + ) + metadata = load_metadata(model_path, metadata_override) + training = metadata_to_configs(metadata) + + padding_masks = compute_padding_masks( + segments_per_arm=training.morphology.segments_per_arm, + reference_segments_per_arm=training.morphology.segments_per_arm, + ) + obs_processor = create_obs_processor( + bounds_dict=training.obs_bounds.to_bounds_dict(), + padding_masks=padding_masks, + ) + + env = BrittleStarJaxEnvWrapper( + morphology=training.morphology, + arena=training.arena, + env_config=training.environment, + num_envs=1, + ) + + action_low = np.asarray(env.single_action_space.low, dtype=np.float32) + action_high = np.asarray(env.single_action_space.high, dtype=np.float32) + + from brittle_star_project.MLPs.mlps import Actor, GenericDenseLayersWithActivation + + sensor = GenericDenseLayersWithActivation(layer_sizes=[300, 300, 300]) + actor = Actor(action_dim=env.single_action_space.shape[0]) + sensor.apply = jax.jit(sensor.apply) + actor.apply = jax.jit(actor.apply) + + eval_fn = build_eval_rollout_fn( + env=env, + obs_processor=obs_processor, + sensor_apply=sensor.apply, + actor_apply=actor.apply, + action_low=action_low, + action_high=action_high, + reward_fn=reward_fn, + ) + + seed = int(eval_cfg.eval_seed) + max_steps = int(eval_cfg.eval_max_steps) + + logger.info(f"Evaluating each checkpoint (seed={seed}, max_steps={max_steps}).") + + for checkpoint_path in checkpoints: + iteration = _parse_iteration(checkpoint_path) + try: + params = load_params(checkpoint_path) + except Exception as e: + logger.warning(f"Could not load {checkpoint_path.name}: {e}") + continue + + result = evaluate_checkpoint_mjx(eval_fn, params, seed=seed, max_steps=max_steps) + csv_path = append_checkpoint_eval_row( + run_dir, + iteration=iteration, + trained_timesteps=0, # unknown without training logs + result=result, + ) + + logger.debug( + f"checkpoint={iteration:5d} | " + f"reached={str(result.reached_target):<5} | " + f"return={result.eval_return:+8.3f} | " + f"steps={result.steps:4d} | " + f"final_dist={result.final_xy_dist:.3f}" + ) + + logger.info(f"Done. CSV at: {csv_path}") + env.close() + + +if __name__ == "__main__": + register_configs() + main() diff --git a/src/brittle_star_project/evaluation/evaluate.py b/src/brittle_star_project/evaluation/evaluate.py index 12cc6fc..9d62880 100644 --- a/src/brittle_star_project/evaluation/evaluate.py +++ b/src/brittle_star_project/evaluation/evaluate.py @@ -25,7 +25,7 @@ def evaluate_policy( Args: env: Initialised CPU environment (MJC backend). - policy_path: Path to the ``.cleanrl_model`` weights file. + policy_path: Path to the `.cleanrl_model` weights file. seed: Random seed for environment reset. max_steps: Maximum number of control steps. diff --git a/src/brittle_star_project/evaluation/evaluate_mjx.py b/src/brittle_star_project/evaluation/evaluate_mjx.py index 0193d99..5655744 100644 --- a/src/brittle_star_project/evaluation/evaluate_mjx.py +++ b/src/brittle_star_project/evaluation/evaluate_mjx.py @@ -12,7 +12,7 @@ The key functions are: - `evaluate_checkpoint_mjx` — runs that function for a given set of parameters and returns a typed `CheckpointEvalResult`. - `append_checkpoint_eval_row` — persists the result to the run's - ``metrics/checkpoint_evaluation.csv``, migrating old schemas automatically. + `metrics/checkpoint_evaluation.csv`, migrating old schemas automatically. """ from __future__ import annotations @@ -61,17 +61,17 @@ def build_eval_rollout_fn( All outputs are JAX arrays. Convert to Python scalars before logging. Args: - env: The training environment wrapper. Must expose ``env.raw`` with - ``reset`` and ``step`` methods compatible with ``jax.vmap``. + env: The training environment wrapper. Must expose `env.raw` with + `reset` and `step` methods compatible with `jax.vmap`. obs_processor: Observation normalisation / padding callable, as - returned by ``create_obs_processor``. - sensor_apply: The sensor network's ``apply`` method (JIT-compiled). - actor_apply: The actor network's ``apply`` method (JIT-compiled). - action_low: Per-joint action lower bound (JAX array, shape ``(action_dim,)``). - action_high: Per-joint action upper bound (JAX array, shape ``(action_dim,)``). + returned by `create_obs_processor`. + sensor_apply: The sensor network's `apply` method (JIT-compiled). + actor_apply: The actor network's `apply` method (JIT-compiled). + action_low: Per-joint action lower bound (JAX array, shape `(action_dim,)`). + action_high: Per-joint action upper bound (JAX array, shape `(action_dim,)`). reward_fn: Shaped reward function with signature - ``reward_fn(env_state, next_env_state) -> jnp.ndarray``. - Typically the module-level ``reward_fn`` from ``PPOTrainer``. + `reward_fn(env_state, next_env_state) -> jnp.ndarray`. + Typically the module-level `reward_fn` from `PPOTrainer`. Returns: A JIT-compiled callable that runs one deterministic evaluation episode. @@ -209,9 +209,9 @@ def append_checkpoint_eval_row( trained_timesteps: int, result: CheckpointEvalResult, ) -> Path: - """Append one evaluation row to ``/metrics/checkpoint_evaluation.csv``. + """Append one evaluation row to `/metrics/checkpoint_evaluation.csv`. - Creates the file (including the ``metrics/`` directory) if it does not yet + Creates the file (including the `metrics/` directory) if it does not yet exist. Migrates the file to the current schema if the header has changed. Args: From 7eaf0da4cf6c34081fd803972fcc3198e9711800 Mon Sep 17 00:00:00 2001 From: Tibo De Peuter Date: Fri, 8 May 2026 00:22:59 +0200 Subject: [PATCH 72/96] docs: Repository structure --- README.md | 15 ++++++++++++++ docs/api/evaluation.md | 47 ++++++++++++++++++++++++++++++++++++++++++ docs/api/simulation.md | 2 ++ docs/api/training.md | 14 +++++++++---- 4 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 docs/api/evaluation.md diff --git a/README.md b/README.md index 572fd73..e9cabc6 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,21 @@ To set up the UV module, you can run the following command: uv sync --frozen ``` +## Repository Structure + +```text +. +├── configs/ # Hydra configuration files (YAML) +├── docs/ # Comprehensive documentation and API guides +├── runs/ # Default output directory for Hydra and training artifacts +├── scripts/ # High-level entrypoints for training, simulation, and evaluation +├── src/ +│ └── brittle_star_project/ # Core library and environment logic +│ ├── evaluation/ # Checkpoint evaluation, rollout logic, and metrics persistence +│ └── trainers/ # Training loop implementations (e.g., PPO) +└── tests/ # Unit and integration tests +``` + ## Usage For detailed instructions on how to use the project, please refer to the **[API Documentation](docs/README.md)**. diff --git a/docs/api/evaluation.md b/docs/api/evaluation.md new file mode 100644 index 0000000..a47d056 --- /dev/null +++ b/docs/api/evaluation.md @@ -0,0 +1,47 @@ +# Checkpoint & Model Evaluation + +This guide covers how to evaluate trained brittle star models, both during training and as a post-training analysis step. + +## Checkpoint Evaluation (During Training) + +The `PPOTrainer` can automatically evaluate every saved checkpoint using the fast MJX backend. This is enabled via configuration. + +### Configuration + +In your experiment config or via CLI: +```bash +python scripts/train.py evaluation.evaluate_checkpoints=true evaluation.eval_max_steps=5000 +``` + +Results are saved to `runs//metrics/checkpoint_evaluation.csv` and synced to Weights & Biases if enabled. + +## Cross-Model Comparison + +To compare different architectures or runs, use `scripts/compare_models.py`. + +1. Create or update a YAML file in `configs/evaluation/`. +2. Run the Comparison: + +```bash +python scripts/compare_models.py evaluation=poster +``` + +The script will run the specified number of episodes for each model and produce a single CSV with return and velocity metrics. + +## Post-hoc Checkpoint Evaluation + +If you didn't enable evaluation during training, or want to re-run it with different settings, use `scripts/evaluate_checkpoints.py`. + +```bash +python scripts/evaluate_checkpoints.py \ + simulation.model_path=runs//final_model.flax \ + evaluation.eval_seed=42 +``` + +This script scans the `checkpoints/` directory and evaluates every `.flax` file it finds. + +## Metrics Explained + +- **`eval_return`**: The accumulated shaped reward using the `reward_fn` defined in `PPOTrainer`. +- **`approx_max_velocity`**: Calculated as `(initial_dist - final_dist) / total_steps`. Note that this is an average velocity over the episode. +- **`reached_target`**: Boolean indicating if the robot reached the target within the max steps. diff --git a/docs/api/simulation.md b/docs/api/simulation.md index 0a0e041..1e288b9 100644 --- a/docs/api/simulation.md +++ b/docs/api/simulation.md @@ -37,3 +37,5 @@ uv run scripts/simulate.py \ Videos and evaluation metadata are stored in timestamped folders alongside the model: `runs/your_run/final_model_evaluations/eval_/simulation.mp4` + +For batch evaluation and cross-model comparison, see the **[Evaluation Guide](./evaluation.md)**. diff --git a/docs/api/training.md b/docs/api/training.md index a9678bb..d3e6c51 100644 --- a/docs/api/training.md +++ b/docs/api/training.md @@ -38,12 +38,18 @@ To run with your custom experiment file: uv run python scripts/train.py experiment=my_experiment ``` -### Command-Line Overrides - -You can override any parameter directly from the command line using Hydra's dot notation. This is useful for quick tests: - ```bash uv run python scripts/train.py ppo.learning_rate=0.001 ppo.num_envs=32 logging.track=true ``` +## Evaluation During Training + +By default, the trainer saves checkpoints but does not evaluate them. To enable automatic headless evaluation of every saved checkpoint, set `evaluation.evaluate_checkpoints=true`: + +```bash +uv run python scripts/train.py evaluation.evaluate_checkpoints=true +``` + +For more details on evaluation metrics and comparison tools, see [Evaluation](./evaluation.md). + For more details on tracking your experiments, see [Tracking & Monitoring](./tracking.md). From 34f0b1b80e8d27b442a676966b4412001e872c63 Mon Sep 17 00:00:00 2001 From: Robin Meersman Date: Fri, 8 May 2026 23:46:45 +0200 Subject: [PATCH 73/96] feat(obs_processor): rewrote split method, todo: testing + code cleanup --- configs/morphology/5_arms_damaged.yaml | 6 +++ scripts/train.py | 2 +- simulate.sh | 9 ++++ .../environment/obs_processing.py | 50 +++++++----------- .../environment/obs_processing_tmp.py | 17 ++++++ .../trainers/PPOTrainer.py | 1 - tests/test_obs_processor.py | 0 tmp.txt | 27 ++++++++++ vids/evaluation_metadata.yaml | 9 ++++ vids/simulation.mp4 | Bin 0 -> 1859466 bytes 10 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 configs/morphology/5_arms_damaged.yaml create mode 100755 simulate.sh create mode 100644 src/brittle_star_project/environment/obs_processing_tmp.py create mode 100644 tests/test_obs_processor.py create mode 100644 tmp.txt create mode 100644 vids/evaluation_metadata.yaml create mode 100644 vids/simulation.mp4 diff --git a/configs/morphology/5_arms_damaged.yaml b/configs/morphology/5_arms_damaged.yaml new file mode 100644 index 0000000..2afd643 --- /dev/null +++ b/configs/morphology/5_arms_damaged.yaml @@ -0,0 +1,6 @@ +# 5 Arms Full Morphology Configuration +# Baseline 5-arm brittle star. + +segments_per_arm: [4, 4, 0, 4, 4] +use_p_control: true +use_torque_control: false diff --git a/scripts/train.py b/scripts/train.py index f82d6bc..8e61bd0 100644 --- a/scripts/train.py +++ b/scripts/train.py @@ -42,7 +42,7 @@ def main(dict_cfg: DictConfig): base_dir=os.path.dirname(run_dir), ) logger = get_logger() - logger.set_level(logging.INFO) + logger.set_level(logging.DEBUG) logger.info(f"Hydra-initialized run: {run_name}") logger.info(f"Output directory: {run_dir}") diff --git a/simulate.sh b/simulate.sh new file mode 100755 index 0000000..86a96c1 --- /dev/null +++ b/simulate.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +path=$1 + +uv run scripts/simulate.py \ + simulation.model_path="$path"/final_model.flax \ + simulation.record_video=True \ + simulation.video_output_path=./vids/simulation.mp4 \ + simulation.max_steps=10000 \ No newline at end of file diff --git a/src/brittle_star_project/environment/obs_processing.py b/src/brittle_star_project/environment/obs_processing.py index 550624d..74c60cd 100644 --- a/src/brittle_star_project/environment/obs_processing.py +++ b/src/brittle_star_project/environment/obs_processing.py @@ -102,61 +102,47 @@ def create_obs_processor( return normalized def _split_to_agents(obs: dict, morph_mode) -> dict: + # TODO: cleanup + MORE testing (works for centralized 5 arms + damaged arms) output = {} num_agents = needed_copies # IMPORTANT: number of MLPs for key, arr in obs.items(): - if key not in ordered_keys or arr.size == 0: + if arr.size == 0: continue - logger.debug(f"[INPUT] {key}: {arr.shape}") - if arr.ndim == 0: arr = arr.reshape(1) - # -------- CENTRALIZED -------- - if morph_mode == MorphMode.CENTRALIZED: - output[key] = arr.reshape(1, -1) - # TODO: padding for centralized - continue - - # -------- SEGMENTS -------- if key in _SEGMENT_SCALED_KEYS: per_agent = [] - - for i, agent_id in enumerate(agent_indices): + for i, _ in enumerate(agent_indices): idx = segment_indices[i] - taken = jnp.take(arr, idx, axis=0) # (segs, ...) - logger.debug(f"WHY {taken.shape}") - - # pad to 4 (segments per arm?) + taken = jnp.take(arr, idx, axis=0) pad_len = 4 - taken.shape[0] - padded = jnp.pad(taken, [(0, pad_len)] + [(0, 0)] * (taken.ndim - 1)) + padded = jnp.pad(taken, [(9, pad_len)] + [(0, 0)] * (taken.ndim - 1)) per_agent.append(padded.reshape(-1)) - - out = jnp.stack(per_agent) - - # -------- JOINTS -------- + arr = jnp.stack(per_agent) elif key in _JOINT_SCALED_KEYS: per_agent = [] - for i, _ in enumerate(agent_indices): idx = joint_indices[i] - taken = jnp.take(arr, idx, axis=0) # (joint_n, ...) - # pad to 8 + taken = jnp.take(arr, idx, axis=0) pad_len = 8 - taken.shape[0] - padded = jnp.pad(taken, [(0, pad_len)] + [(0, 0)] * (taken.ndim - 1)) + per_agent.append(padded.reshape(-1)) - - out = jnp.stack(per_agent) - - # -------- GLOBAL -------- + arr = jnp.stack(per_agent) else: - out = jnp.repeat(arr[None, :], num_agents, axis=0) + arr = jnp.repeat(arr[None, :], num_agents, axis=0) - logger.debug(f"[OUTPUT] {key}: {out.shape}") - output[key] = out + if morph_mode == MorphMode.CENTRALIZED: + output[key] = arr.reshape(1, -1) + elif key in _JOINT_SCALED_KEYS: + output[key] = arr.reshape(num_agents, -1) + elif key in _SEGMENT_SCALED_KEYS: + output[key] = arr[:, None] + else: + output[key] = arr return output diff --git a/src/brittle_star_project/environment/obs_processing_tmp.py b/src/brittle_star_project/environment/obs_processing_tmp.py new file mode 100644 index 0000000..e2c6c82 --- /dev/null +++ b/src/brittle_star_project/environment/obs_processing_tmp.py @@ -0,0 +1,17 @@ +obs = {} +segs = set() +joints = set() + +for key, arr in obs.items(): + if key in segs: + # padding using mask 1x + pass + elif key in joints: + # padding using mask 2x + pass + else: + # no padding + pass + + # reshape according to segs, joints, or global + pass diff --git a/src/brittle_star_project/trainers/PPOTrainer.py b/src/brittle_star_project/trainers/PPOTrainer.py index f82ba83..960a176 100644 --- a/src/brittle_star_project/trainers/PPOTrainer.py +++ b/src/brittle_star_project/trainers/PPOTrainer.py @@ -277,7 +277,6 @@ def apply_shared(net, params, x): return jax.vmap(lambda xi: net.apply(params, xi))(x_flattened) -# TODO: update to work with extra dimension + message passing def _rollout_jit( agent_state, episode_stats, diff --git a/tests/test_obs_processor.py b/tests/test_obs_processor.py new file mode 100644 index 0000000..e69de29 diff --git a/tmp.txt b/tmp.txt new file mode 100644 index 0000000..899a63b --- /dev/null +++ b/tmp.txt @@ -0,0 +1,27 @@ +-- 5 arms, 1 disabled +2026-05-08 14:21:57,035 - DEBUG - [INPUT] joint_actuator_force: (32,) +2026-05-08 14:21:57,035 - DEBUG - [OUTPUT] joint_actuator_force: (32,) +2026-05-08 14:21:57,035 - DEBUG - [INPUT] joint_position: (32,) +2026-05-08 14:21:57,035 - DEBUG - [OUTPUT] joint_position: (32,) +2026-05-08 14:21:57,036 - DEBUG - [INPUT] joint_velocity: (32,) +2026-05-08 14:21:57,036 - DEBUG - [OUTPUT] joint_velocity: (32,) +2026-05-08 14:21:57,036 - DEBUG - [INPUT] segment_contact: (16,) +2026-05-08 14:21:57,036 - DEBUG - [OUTPUT] segment_contact: (16,) +2026-05-08 14:21:57,036 - DEBUG - [INPUT] disk_z_tilt: () +2026-05-08 14:21:57,036 - DEBUG - [OUTPUT] disk_z_tilt: (1,) +2026-05-08 14:21:57,036 - DEBUG - [INPUT] robot_direction_to_target: (2,) +2026-05-08 14:21:57,036 - DEBUG - [OUTPUT] robot_direction_to_target: (2,) + +-- 5 arms, none disabled +2026-05-08 14:27:04,472 - DEBUG - [INPUT] joint_actuator_force: (40,) +2026-05-08 14:27:04,472 - DEBUG - [OUTPUT] joint_actuator_force: (40,) +2026-05-08 14:27:04,472 - DEBUG - [INPUT] joint_position: (40,) +2026-05-08 14:27:04,472 - DEBUG - [OUTPUT] joint_position: (40,) +2026-05-08 14:27:04,473 - DEBUG - [INPUT] joint_velocity: (40,) +2026-05-08 14:27:04,473 - DEBUG - [OUTPUT] joint_velocity: (40,) +2026-05-08 14:27:04,473 - DEBUG - [INPUT] segment_contact: (20,) +2026-05-08 14:27:04,473 - DEBUG - [OUTPUT] segment_contact: (20,) +2026-05-08 14:27:04,473 - DEBUG - [INPUT] disk_z_tilt: () +2026-05-08 14:27:04,473 - DEBUG - [OUTPUT] disk_z_tilt: (1,) +2026-05-08 14:27:04,474 - DEBUG - [INPUT] robot_direction_to_target: (2,) +2026-05-08 14:27:04,474 - DEBUG - [OUTPUT] robot_direction_to_target: (2,) \ No newline at end of file diff --git a/vids/evaluation_metadata.yaml b/vids/evaluation_metadata.yaml new file mode 100644 index 0000000..0f59928 --- /dev/null +++ b/vids/evaluation_metadata.yaml @@ -0,0 +1,9 @@ +timestamp: '2026-05-07T20:43:29.612567' +morphology_override: null +seed: 1 +max_steps: 10000 +result: + return: 0.40030128204863225 + length: 6705 + reached_target: true + final_xy_dist: 0.19969871795136748 diff --git a/vids/simulation.mp4 b/vids/simulation.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..9c6c807a22a3185eb4f90d1d1dc428ff1c64300d GIT binary patch literal 1859466 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

Zgwts;>8q=yg4Wh_3aXGr@ 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

!){vmpW9n9Vz3($TEK2~S?L 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

-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

Xbl+e&{Ulw}Vjr0#9~AYOfu$WjY<6Lf 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 j6s)!M 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

A`hFy%T*S97})YNZc1F2F(56d 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