Unverified Commit 882f7c04 authored by Nikita Rudin's avatar Nikita Rudin Committed by GitHub

Adds approximate torque calculation for implicit actuator (#364)

# Description

Adds torque computation to implicit actuators. Previously the reported
torque was always zero.

## Type of change

- Bug fix (non-breaking change which fixes an issue)

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./orbit.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have run all the tests with `./orbit.sh --test` and they pass
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there
parent b579c503
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.10.14" version = "0.10.15"
# Description # Description
title = "ORBIT framework for Robot Learning" title = "ORBIT framework for Robot Learning"
......
Changelog Changelog
--------- ---------
0.10.15 (2024-01-29)
~~~~~~~~~~~~~~~~~~~~
Fixed
^^^^^
* Fixed joint torque computation for implicit actuators. Earlier, the torque was always zero for implicit
actuators. Now, it is computed approximately by applying the PD law.
0.10.14 (2024-01-22) 0.10.14 (2024-01-22)
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
......
...@@ -234,3 +234,14 @@ class ActuatorBase(ABC): ...@@ -234,3 +234,14 @@ class ActuatorBase(ABC):
raise ValueError("The parameter value is None and no default value is provided.") raise ValueError("The parameter value is None and no default value is provided.")
return param return param
def _clip_effort(self, effort: torch.Tensor) -> torch.Tensor:
"""Clip the desired torques based on the motor limits.
Args:
desired_torques: The desired torques to clip.
Returns:
The clipped torques.
"""
return torch.clip(effort, min=-self.effort_limit, max=self.effort_limit)
...@@ -54,7 +54,13 @@ class ImplicitActuator(ActuatorBase): ...@@ -54,7 +54,13 @@ class ImplicitActuator(ActuatorBase):
def compute( def compute(
self, control_action: ArticulationActions, joint_pos: torch.Tensor, joint_vel: torch.Tensor self, control_action: ArticulationActions, joint_pos: torch.Tensor, joint_vel: torch.Tensor
) -> ArticulationActions: ) -> ArticulationActions:
# we do not need to do anything here """Compute the aproximmate torques for the actuated joint (physX does not compute this explicitly)."""
# store approximate torques for reward computation
error_pos = control_action.joint_positions - joint_pos
error_vel = control_action.joint_velocities - joint_vel
self.computed_effort = self.stiffness * error_pos + self.damping * error_vel + control_action.joint_efforts
# clip the torques based on the motor limits
self.applied_effort = self._clip_effort(self.computed_effort)
return control_action return control_action
...@@ -115,21 +121,6 @@ class IdealPDActuator(ActuatorBase): ...@@ -115,21 +121,6 @@ class IdealPDActuator(ActuatorBase):
control_action.joint_velocities = None control_action.joint_velocities = None
return control_action return control_action
"""
Helper functions.
"""
def _clip_effort(self, effort: torch.Tensor) -> torch.Tensor:
"""Clip the desired torques based on the motor limits.
Args:
desired_torques: The desired torques to clip.
Returns:
The clipped torques.
"""
return torch.clip(effort, min=-self.effort_limit, max=self.effort_limit)
class DCMotor(IdealPDActuator): class DCMotor(IdealPDActuator):
r""" r"""
......
...@@ -685,20 +685,14 @@ class Articulation(RigidObject): ...@@ -685,20 +685,14 @@ class Articulation(RigidObject):
if control_action.joint_efforts is not None: if control_action.joint_efforts is not None:
self._joint_effort_target_sim[:, actuator.joint_indices] = control_action.joint_efforts self._joint_effort_target_sim[:, actuator.joint_indices] = control_action.joint_efforts
# update state of the actuator model # update state of the actuator model
if isinstance(actuator, ImplicitActuator): # -- torques
# TODO read torque from simulation (#127) self._data.computed_torque[:, actuator.joint_indices] = actuator.computed_effort
pass self._data.applied_torque[:, actuator.joint_indices] = actuator.applied_effort
# self._data.computed_torques[:, actuator.joint_indices] = ??? # -- actuator data
# self._data.applied_torques[:, actuator.joint_indices] = ??? self._data.soft_joint_vel_limits[:, actuator.joint_indices] = actuator.velocity_limit
else: # TODO: find a cleaner way to handle gear ratio. Only needed for variable gear ratio actuators.
# -- torques if hasattr(actuator, "gear_ratio"):
self._data.computed_torque[:, actuator.joint_indices] = actuator.computed_effort self._data.gear_ratio[:, actuator.joint_indices] = actuator.gear_ratio
self._data.applied_torque[:, actuator.joint_indices] = actuator.applied_effort
# -- actuator data
self._data.soft_joint_vel_limits[:, actuator.joint_indices] = actuator.velocity_limit
# TODO: find a cleaner way to handle gear ratio. Only needed for variable gear ratio actuators.
if hasattr(actuator, "gear_ratio"):
self._data.gear_ratio[:, actuator.joint_indices] = actuator.gear_ratio
""" """
Internal helpers -- Debugging. Internal helpers -- Debugging.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment