robogym/robot/utils/robot_utils.py (39 lines of code) (raw):

"""Utilities that expand robot interface's capabilities, but that do not necessarily belong to the interface itself.""" from typing import Dict, Iterable, Optional, Type import numpy as np from robogym.robot.robot_interface import Robot def denormalize_actions( robot: Robot, input_actions: Iterable[Dict[str, float]], defaults: Optional[np.ndarray] = None, ) -> np.ndarray: """ Transform position control from the [-1,+1] range into supported joint position range in radians, where 0 represents the midpoint between two extreme positions, for the supplied actuators only, using default values for non-supplied actuators. To supply the actuators to denormalize, provide a dictionary or a batch of dictionaries with the actuator as the key, and the [-1,+1] value as entry value. :param robot: Robot for which we want to denormalize actions. :param input_actions: Batch of dictionaries with actuator as key, and normalized value as value. :param defaults: Default values for actuators not specified in actions. 0 if not set. :return: Batch of arrays with denormalized values for actuators specified in the dictionary and 0 for actuators not specified in the dictionary. """ robot_actuators = robot.actuators() if defaults is None: defaults = robot.zero_control() assert defaults.shape == (len(robot_actuators),) ctrls = [] # for each entry in the batch for action_overrides in input_actions: # create array with desired values for specified actuators normal_positions = np.zeros(len(robot_actuators)) for actuator, value in action_overrides.items(): assert actuator in robot_actuators actuator_id = robot_actuators.index(actuator) normal_positions[actuator_id] = value # denormalize array denormalized_positions = robot.denormalize_position_control(normal_positions) # generate output with denormalized positions only for controls that were specified, and default otherwise ctrl = defaults.copy() for actuator in action_overrides: actuator_id = robot_actuators.index(actuator) ctrl[actuator_id] = denormalized_positions[actuator_id] ctrls.append(ctrl) return np.asarray(ctrls) def find_robot_by_class( top_robot: Robot, desired_class: Type[Robot] ) -> Optional[Robot]: """Examines the given robot to retrieve the first instance that matches the specified desired class. This includes searching in the children of a CompositeRobot. :param top_robot: Robot to search in. This robot can also match the desired class. :param desired_class: Desired specific class we are searching for. :return: First robot found that matches the desired class, or None if no matches are found. """ desired_robot = None from robogym.robot.composite.composite_robot import CompositeRobot if isinstance(top_robot, CompositeRobot): for internal_robot in top_robot.robots: if isinstance(internal_robot, desired_class): desired_robot = internal_robot break elif isinstance(top_robot, desired_class): desired_robot = top_robot return desired_robot