Source code for tbp.monty.frameworks.models.motor_system_state
# Copyright 2025 Thousand Brains Project
#
# Copyright may exist in Contributors' modifications
# and/or contributions to the work.
#
# Use of this source code is governed by the MIT
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.
from typing import Any, Dict, TypedDict
import numpy as np
[docs]class SensorState(TypedDict):
"""The proprioceptive state of a sensor.
TODO: Change into dataclass
"""
position: Any # TODO: Stop using magnum.Vector3 and decide on Monty standard
"""The sensor's position relative to the agent."""
rotation: Any # TODO: Stop using quaternion.quaternion and decide on Monty standard
"""The sensor's rotation relative to the agent."""
[docs]class AgentState(TypedDict):
"""The proprioceptive state of an agent.
TODO: Change into dataclass
"""
sensors: Dict[str, SensorState]
"""The proprioceptive state of the agent's sensors."""
position: Any # TODO: Stop using magnum.Vector3 and decide on Monty standard
"""The agent's position relative to some global reference frame."""
rotation: Any # TODO: Stop using quaternion.quaternion and decide on Monty standard
"""The agent's rotation relative to some global reference frame."""
[docs]class ProprioceptiveState(Dict[str, AgentState]):
"""The proprioceptive state of the motor system.
TODO: Change into dataclass
"""
[docs]class MotorSystemState(Dict[str, Any]):
"""The state of the motor system.
TODO: Currently, ProprioceptiveState can be cast to MotorSystemState since
MotorSystemState is a generic dictionary. In the future, make
ProprioceptiveState a param on MotorSystemState to more clearly distinguish
between the two.
"""
[docs] def convert_motor_state(self):
"""Convert the motor state into something that can be pickled/saved to JSON.
i.e. substitute vector and quaternion objects; note e.g. copy.deepcopy does not
work.
TODO ?clean this up with a recursive algorithm, or use BufferEncoder in
buffer.py
Returns:
(dict): Copy of the motor state.
"""
state_copy = {}
for key in self.keys():
state_copy[key] = {}
for key_inner in self[key].keys():
if type(self[key][key_inner]) is dict:
state_copy[key][key_inner] = {}
# We need to go deeper
for key_inner_inner in self[key][key_inner].keys():
state_copy[key][key_inner][key_inner_inner] = {}
if type(self[key][key_inner][key_inner_inner]) is dict:
# We need to go even deeper...
# (**Hans Zimmer music intensifies**)
for key_i_i_i in self[key][key_inner][key_inner_inner]:
state_copy[key][key_inner][key_inner_inner][
key_i_i_i
] = {}
try:
state_copy[key][key_inner][key_inner_inner][
key_i_i_i
] = np.array(
list(
self[key][key_inner][key_inner_inner][
key_i_i_i
]
)
)
except TypeError:
# Quaternions
state_copy[key][key_inner][key_inner_inner][
key_i_i_i
] = [
self[key][key_inner][key_inner_inner][
key_i_i_i
].real
] + list(
self[key][key_inner][key_inner_inner][
key_i_i_i
].imag
)
elif type(self[key][key_inner]) is bool:
pass
else:
try:
state_copy[key][key_inner] = np.array(
list(self[key][key_inner])
)
except TypeError:
# Quaternions
state_copy[key][key_inner] = [self[key][key_inner].real] + list(
self[key][key_inner].imag
)
return state_copy