Signal manager
signal_manager
¶
SignalManager
dataclass
¶
SignalManager(
export_path: Path,
target_buffer_bytes: int = 8 * 1024 * 1024,
record_decimation: int = 1,
unit_system: UnitSystem | None = None,
_buffer_row_idx: int = 0,
_step_count: int = -1,
_n_cols: int = 0,
)
target_buffer_bytes
class-attribute
instance-attribute
¶
target_buffer_bytes: int = 8 * 1024 * 1024
Approximate in-memory buffer size, in bytes, before flushing to a part file. The actual row capacity is derived from this and the current column count (see _recompute_capacity), so flush frequency stays roughly memory/file-size bounded as signals are registered, rather than fixed at a row count regardless of width. Defaults to 8 MB.
record_decimation
class-attribute
instance-attribute
¶
record_decimation: int = 1
How many steps between each recording should be performed.
unit_system
class-attribute
instance-attribute
¶
When set, the time column's concrete unit is resolved from unit_system.time (e.g. "second", "millisecond"). Always tagged with dimension="[time]" regardless.
track
¶
track(
getter: Callable[[], float],
category: SignalCategory | str,
subgroups: tuple[str, ...] = (),
*,
attr: str | None = None,
metadata: dict[str, Any] | None = None,
)
Registers getter to be called and posted on every recorded step, under the same category/subgroups/attr namespace as post.
getter is called fresh on every recorded step, so it should look up a value that changes over the course of the simulation (e.g. a variable updated each step, an attribute, or an indexing operation) rather than a constant computed once. If the underlying value never changes after registration, track will simply keep posting that same value every step.
Examples:
| Python Console Session | |
|---|---|
| Python Console Session | |
|---|---|
Source code in src/mujoco_mojo/runtime/signal_manager.py
post
¶
post(
value: float,
category: SignalCategory | str,
subgroups: tuple[str, ...] = (),
*,
attr: str | None = None,
metadata: dict[str, Any] | None = None,
)
Injects a value into the telemetry ledger using a hierarchical namespace.
This method constructs a structured key that the dashboard uses to build a navigable tree view. The naming convention follows a folder-like structure to group related signals (e.g., all axes of a body's position).
Format
Category/Subgroup:Attribute (e.g., "Bodies/Link_1:xpos_x")
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
float
|
The numeric data to record. |
required |
category
|
SignalCategory | str
|
Top level category (e.g., "Bodies") |
required |
subgroups
|
tuple[str, ...]
|
The second-level organizational folders. Defaults to an empty tuple. |
()
|
attr
|
str | None
|
The specific signal or component name (e.g., "qpos" or "x"). Defaults to None. |
None
|
metadata
|
dict[str, Any] | None
|
Arbitrary metadata for this signal, persisted into the telemetry file's footer. Only consulted the first time this signal is registered (ignored on later calls for the same signal). Two keys are validated via Pint if present: |
None
|
Examples:
| Python Console Session | |
|---|---|
| Python Console Session | |
|---|---|
| Python Console Session | |
|---|---|
Source code in src/mujoco_mojo/runtime/signal_manager.py
| Python | |
|---|---|
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | |
record
¶
Executes all samplers and advances the buffer index. Flushes if due.
Source code in src/mujoco_mojo/runtime/signal_manager.py
flush
¶
Writes the memory buffer to a new part file; parts are merged into export_path on close().
Source code in src/mujoco_mojo/runtime/signal_manager.py
resolve_signal_manager
¶
resolve_signal_manager(
signal_manager: SignalManager | None,
) -> SignalManager | None
Returns signal_manager if given, otherwise falls back to the SignalManager of the innermost enclosing RuntimeManager with block.
The result may still be None if that RuntimeManager simply has no SignalManager configured (telemetry recording disabled for this trial). Callers should treat None as "nothing to record to" rather than an error. Raises only if there is no active RuntimeManager context at all.