Obs relative delta controller dict
Air Force Research Laboratory (AFRL) Autonomous Capabilities Team (ACT3) Reinforcement Learning (RL) Core.
This is a US Government Work not subject to copyright protection in the US.
The use, dissemination or disclosure of data in this file is subject to limitation or restriction. See accompanying README and LICENSE for details.
AvailablePlatforms
RelativeObsDeltaActionDict (BaseDictWrapperGlue, RelativeObsDeltaAction)
¤
RelativeObsDeltaActionDict is a glue class that wraps another glue class. It treats the actions passed to it as a delta from a linked observation E.G. if the wrapped action space has has roll as one of the controls, then a delta action of 0.2 would move the absolute roll position 0.2 higher than it is as measured by the linked roll sensor.
Source code in corl/glues/controller_wrappers/obs_relative_delta_controller_dict.py
class RelativeObsDeltaActionDict(BaseDictWrapperGlue, RelativeObsDeltaAction): # type: ignore[misc]
"""
RelativeObsDeltaActionDict is a glue class that wraps another glue class.
It treats the actions passed to it as a delta from a linked observation
E.G. if the wrapped action space has has roll as one of the controls, then a delta action of
0.2 would move the absolute roll position 0.2 higher than it is as measured by the linked roll sensor.
"""
def __init__(self, **kwargs) -> None: # pylint: disable=super-init-not-called
self.config: RelativeObsDeltaActionDictValidator # type: ignore[assignment]
BaseDictWrapperGlue.__init__(**kwargs)
self._logger = logging.getLogger(RelativeObsDeltaActionDict.__name__)
controller_keys = self.glues().keys()
if 'controller' not in controller_keys:
raise KeyError('Missing key: controller')
if 'sensor' not in controller_keys:
raise KeyError('Missing key: sensor')
self.controller: ControllerGlue = typing.cast(ControllerGlue, self.glues()["controller"])
if not isinstance(self.controller, ControllerGlue):
raise RuntimeError(
"Error: RelativeObsDeltaActionDict expects the glue wrapped on the 'controller' key to be a ControllerGlue, "
f"got {self.controller}"
)
self.relative_obs_glue: ObserveSensor = typing.cast(ObserveSensor, self.glues()["sensor"])
if not isinstance(self.relative_obs_glue, ObserveSensor):
raise RuntimeError(
"Error: RelativeObsDeltaActionDict expects the glue wrapped on the 'sensor' key to be a ObserveSensor, "
f"got {self.relative_obs_glue}"
)
# verify that the config setup is not going to get the user into a situation where they are
# only accessing one part of the obs but applying that obs as the base position for multiple actions
if self.config.obs_index and len(list(self.controller.action_space().values())[0].low) != 1:
raise RuntimeError(
f"ERROR: your glue {self.get_unique_name()} has an action space length of more than 1, "
"but you specified though obs_index to access only 1 component of the obs "
"from the wrapped observe Sensor, to fix this error in your config for this glue define 'obs_index': null"
)
self.step_size = EnvSpaceUtil.convert_config_param_to_space(
action_space=self.controller.action_space(), parameter=self.config.step_size
)
self._is_wrap = self.config.is_wrap
self.saved_action_deltas = OrderedDict()
for space_name, space in self.action_space().items():
if self.config.initial_value is not None:
self.saved_action_deltas[space_name] = np.asarray([self.config.initial_value], dtype=np.float32)
else:
self.saved_action_deltas[space_name] = space.low
@property
def get_validator(self) -> typing.Type[RelativeObsDeltaActionDictValidator]: # type: ignore[override]
return RelativeObsDeltaActionDictValidator
get_validator: Type[corl.glues.controller_wrappers.obs_relative_delta_controller_dict.RelativeObsDeltaActionDictValidator]
property
readonly
¤
returns the validator for this class
Returns:
Type | Description |
---|---|
Type[corl.glues.controller_wrappers.obs_relative_delta_controller_dict.RelativeObsDeltaActionDictValidator] |
BaseAgentGlueValidator -- A pydantic validator to be used to validate kwargs |
RelativeObsDeltaActionDictValidator (BaseDictWrapperGlueValidator)
pydantic-model
¤
A dict that contains a floating point scalar for each action in the action space,
by which the corresponding delta action is scaled prior to converting the action
to the wrapped space.
e.g. A throttle DeltaAction.apply_action([0.2]) with step_size=[.05] would move the
absolute throttle position to 0.01 higher than it was at the end of the last step.
Source code in corl/glues/controller_wrappers/obs_relative_delta_controller_dict.py
class RelativeObsDeltaActionDictValidator(BaseDictWrapperGlueValidator):
"""
step_size: A dict that contains a floating point scalar for each action in the action space,
by which the corresponding delta action is scaled prior to converting the action
to the wrapped space.
e.g. A throttle DeltaAction.apply_action([0.2]) with step_size=[.05] would move the
absolute throttle position to 0.01 higher than it was at the end of the last step.
"""
step_size: float = 1.0
obs_index: typing.Optional[int] = 0
is_wrap: bool = False
initial_value: typing.Optional[float] = None
@validator("step_size")
@classmethod
def check_step_scale(cls, v):
"""
verifies range of step scale values
"""
if v >= 1.0 or v < 0:
raise ValueError("RelativeObsDeltaActionValidator got step size of more that 1.0 or less than 0")
return v
check_step_scale(v)
classmethod
¤
verifies range of step scale values
Source code in corl/glues/controller_wrappers/obs_relative_delta_controller_dict.py
@validator("step_size")
@classmethod
def check_step_scale(cls, v):
"""
verifies range of step scale values
"""
if v >= 1.0 or v < 0:
raise ValueError("RelativeObsDeltaActionValidator got step size of more that 1.0 or less than 0")
return v