Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OperationSpaceController to docs and tests and implement corresponding action/action_cfg classes #913

Open
wants to merge 87 commits into
base: main
Choose a base branch
from

Conversation

ozhanozen
Copy link
Contributor

@ozhanozen ozhanozen commented Aug 31, 2024

Description

This PR adds the OperationalSpaceController to the docs and provides some tests for its parametric features. Moreover, it implements the corresponding OperationalSpaceControllerAction and OperationalSpaceControllerActionCfg classes so they can be used with manager-based environments.

Fixes #873

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

Checklist

  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there
    ``

@ozhanozen
Copy link
Contributor Author

@Dhoeller19, I have created this PR to replace #879 but haven't worked much on it yet. It is far from complete at the moment. I am currently working on it and will ping once it reaches a state worth reviewing. Sorry for the confusion.

@jtigue-bdai jtigue-bdai marked this pull request as draft September 3, 2024 13:12
@jtigue-bdai
Copy link
Collaborator

Converted to a draft util ready for full review. @ozhanozen i will continue to work with you on this branch. Thanks for doing this!

@ozhanozen
Copy link
Contributor Author

ozhanozen commented Oct 4, 2024

@jtigue-bdai, I have finished the following:

  • Added the feature to define an arbitrary frame (i.e., task reference frame) according to which all the targets could be defined. For example, if one wants to apply a force perpendicular to a tilted wall surface, it is easier to define the force targets w.r.t. a frame that is on the wall. All the relevant matrices/vectors (motion/force selection matrices, relative rotation vector, stiffness values, etc) are transformed according to this task reference frame now. I believe this would be useful: the recent Forge paper followed a similar approach and got promising results. It works well according to my tests, but I haven't included this in the Action class, as this requires tracking a frame external to the robot asset. I will check how to do this later. I have added this to the OperationalSpaceControllerAction: one can now provide the path of a RigidObject representing the task reference frame, and the action class creates a FrameTransformer within to keep track of the frame pose.

  • Added a tutorial script under source/standalone/tutorials/05_controllers/run_osc.py and a tutorial documentation under docs/source/tutorials/05_controllers/run_osc.rst that explains the controller and the script on an example in which the robot applies hybrid control on a tilted surface. However, I didn't manage to render the .rst file correctly on my side, so there might be problems with the format.

From my side, the PR is ready to be merged in terms of features, and I will be happy to integrate your feedback/reviews. Once it is merged, I will create other PRs for the other potential features as discussed.

Copy link
Collaborator

@jtigue-bdai jtigue-bdai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@OOmotuyi this looks great. Just a few docstring/formatting stuff. If you are ready it seems like you can pull it out of draft and make it ready for review from the wider team.

self._task_frame_transformer.data.target_quat_w[:, 0, :],
)

def _preprocess_actions(self, actions: torch.Tensor):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add google style docstrings for arguments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def _preprocess_actions(self, actions: torch.Tensor):
    """Pre-processes the raw actions for operational space control.

    Args:
        actions (torch.Tensor): The raw actions for operational space control. It is a tensor of
            shape (num_envs, action_dim).
    """

return rigid_child_prim_path

def _resolve_command_indexes(self):
"""Resolves the indexes for the various command elements within the command tensor."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add google style docstrings for the exceptions raised

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def _resolve_command_indexes(self):
    """Resolves the indexes for the various command elements within the command tensor.

    Raises:
        ValueError: If any command index is left unresolved.
    """

"""

def _first_RigidObject_child_path(self):
"""Finds the first RigidObject child under the articulation asset."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add google style docstrings for the exceptions raised

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def _first_RigidObject_child_path(self):
    """Finds the first RigidObject child under the articulation asset.

    Raises:
        ValueError: If no child RigidObject is found under the articulation asset.

    Returns:
        str: The path to the first RigidObject child under the articulation asset.
    """

Comment on lines +581 to +588
def _run_op_space_controller(
self,
robot: Articulation,
osc: OperationalSpaceController,
ee_frame_name: str,
arm_joint_names: list[str],
target_set: torch.tensor,
):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add docstrings for this function

Copy link
Contributor Author

@ozhanozen ozhanozen Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    """Run the operational space controller with the given parameters.

    Args:
        robot (Articulation): The robot to control.
        osc (OperationalSpaceController): The operational space controller.
        ee_frame_name (str): The name of the end-effector frame.
        arm_joint_names (list[str]): The names of the arm joints.
        target_set (torch.tensor): The target set to track.
    """

Comment on lines +734 to +741
def _update_target(
self,
osc: OperationalSpaceController,
root_pose_w: torch.tensor,
ee_pose_b: torch.tensor,
target_set: torch.tensor,
current_goal_idx: int,
):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add docstrings for this function

Copy link
Contributor Author

@ozhanozen ozhanozen Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    """Update the target for the operational space controller.

    Args:
        osc (OperationalSpaceController): The operational space controller.
        root_pose_w (torch.tensor): The root pose in the world frame.
        ee_pose_b (torch.tensor): The end-effector pose in the body frame.
        target_set (torch.tensor): The target set to track.
        current_goal_idx (int): The current goal index.

    Returns:
        command (torch.tensor): The target command.
        ee_target_pose_b (torch.tensor): The end-effector target pose in the body frame.
        ee_target_pose_w (torch.tensor): The end-effector target pose in the world frame.
        next_goal_idx (int): The next goal index.

    Raises:
        ValueError: If the target type is undefined.
    """

Comment on lines 770 to 773
def _convert_to_task_frame(
self, osc: OperationalSpaceController, command: torch.tensor, ee_target_pose_b: torch.tensor
):
command = command.clone()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add docstrings for this function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    """Convert the target command to the task frame if required.

    Args:
        osc (OperationalSpaceController): The operational space controller.
        command (torch.tensor): The target command to convert.
        ee_target_pose_b (torch.tensor): The end-effector target pose in the body frame.

    Returns:
        command (torch.tensor): The converted target command.
        task_frame_pose_b (torch.tensor): The task frame pose in the body frame.

    Raises:
        ValueError: If the frame is invalid.
    """

Comment on lines +810 to +817
def _check_convergence(
self,
osc: OperationalSpaceController,
ee_pose_b: torch.tensor,
ee_target_pose_b: torch.tensor,
ee_force_b: torch.tensor,
ee_target_b: torch.tensor,
):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add docstrings for this function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    """Check the convergence to the target.

    Args:
        osc (OperationalSpaceController): The operational space controller.
        ee_pose_b (torch.tensor): The end-effector pose in the body frame.
        ee_target_pose_b (torch.tensor): The end-effector target pose in the body frame.
        ee_force_b (torch.tensor): The end-effector force in the body frame.
        ee_target_b (torch.tensor): The end-effector target in the body frame.

    Raises:
        AssertionError: If the convergence is not achieved.
        ValueError: If the target type is undefined.
    """

Comment on lines +687 to +692
def _update_states(
self,
robot: Articulation,
ee_frame_idx: int,
arm_joint_ids: list[int],
):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add docstrings for this function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    """Update the states of the robot and obtain the relevant quantities for the operational space controller.

    Args:
        robot (Articulation): The robot to control.
        ee_frame_idx (int): The index of the end-effector frame.
        arm_joint_ids (list[int]): The indices of the arm joints.

    Returns:
        jacobian_b (torch.tensor): The Jacobian in the root frame.
        mass_matrix (torch.tensor): The mass matrix.
        gravity (torch.tensor): The gravity vector.
        ee_pose_b (torch.tensor): The end-effector pose in the root frame.
        ee_vel_b (torch.tensor): The end-effector velocity in the root frame.
        root_pose_w (torch.tensor): The root pose in the world frame.
        ee_pose_w (torch.tensor): The end-effector pose in the world frame.
        ee_force_b (torch.tensor): The end-effector force in the root frame.
    """

@ozhanozen ozhanozen marked this pull request as ready for review October 11, 2024 20:12
@ozhanozen
Copy link
Contributor Author

@OOmotuyi this looks great. Just a few docstring/formatting stuff. If you are ready it seems like you can pull it out of draft and make it ready for review from the wider team.

@jtigue-bdai, Thanks a lot! I have addressed all your comments, updated the changelog, and marked the PR as ready for review.

@ozhanozen
Copy link
Contributor Author

Hi @jtigue-bdai,

I’ve addressed the comments (primarily regarding docstrings) currently marked as unresolved. Would it be okay if I go ahead and mark them as resolved?

I’ve also merged the latest changes from main and updated the relevant documentation. The CHANGELOG entries remain as [unreleased], assuming the version/date will be finalized when merging to main.

On a separate branch, I’ve implemented the nullspace controller feature for OSC and successfully deployed a trained policy on a real robot to test it. It’s working well, and I observed it significantly improves learning. I’ll create a new PR for it once this one is merged.

Thanks again for your review and feedback! 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Question] Implementation status of the operational space and joint impedance controllers
3 participants