Skip to content

Adds position to set external forces and torques #1680

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

Conversation

AntoineRichard
Copy link
Contributor

Description

This PR adds the option to set wrench positions to set_external_force_and_torque. This is a non-breaking change as the positions are passed as an optional argument. When no positions are set, the function defaults to the original implementation, that is, no positions are passed to PhysX. The PR also adds tests to check that the position values are correctly set into their buffer, but does not check if the resulting wrenches are correct. I did test the Quadcopter task before and after this PR and the training results are exactly the same.

As of now, the function follows the original layout. But it could make sense to offer the option to set the position in either the link frame or the CoM frame. This would follow the recent changes made to the set_pose and set_velocity methods for instance. However, this would be a breaking change. Hence, for now, this has not been implemented. One could also argue, that this could be done prior to feeding the positions outside this method. Please let me know what you feel is best, and I'll update the PR accordingly.

If one wanted to test the resulting wrenches, it would require a simple test articulation like a 1kg sphere that would be used to accurately compute the expected velocities. This is also feasible, but I feel like this test is more on the PhysX side of things, let me know.

This change will require an update of the API documentation to include the position argument.

Fixes #1678

Type of change

  • 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

@kellyguo11
Copy link
Contributor

Thanks for adding in the wrench positions. I think your current implementation is good for now. We are trying to address the com/link frame issue from the physics side so that we can avoid the additional transformations on our end.

Comment on lines 702 to 703
articulation.write_root_link_pose_to_sim(root_state[:, :7])
articulation.write_root_com_velocity_to_sim(root_state[:, 7:])
Copy link
Collaborator

Choose a reason for hiding this comment

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

FYI update to the latest main you will find that we have reverted the "root_link" vs "root_com" deprecation. Please use the previous "root_" API.

Comment on lines 197 to 200
# Reset the external wrench after writing to the simulation.
self.uses_external_wrench_positions = False
# Fill the positions tensor with zeros to avoid applying the wrench at the same position in the next step.
self._external_wrench_positions_b.fill_(0.0)
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm since the external force is applied over multiple simulation steps under the environment decimation loop, resetting here will cause issues.

torque_data=self._external_torque_b.view(-1, 3),
position_data=None,
indices=self._ALL_INDICES,
is_global=False,
Copy link
Contributor

Choose a reason for hiding this comment

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

Shall we also expose is_global flag?

Related MR: #1223

@AntoineRichard
Copy link
Contributor Author

Sorry for the delay on this I've been meaning to update it but I was waiting on 4.5 before rebasing, and now I'm stuck in IROS submissions.

@Mayankm96 Yes, indeed! I fixed it on my branch, but we're still using 4.2.

For the application in the global frame I'm wondering if it wouldn't be better to perform the transformation on IsaacLab's side, this way some indices could be global while others could be local?

Let me know!

@AntoineRichard AntoineRichard force-pushed the add_position_to_set_external_forces_and_torques branch from ff071b6 to 39fb0b9 Compare March 21, 2025 17:31
@AntoineRichard AntoineRichard marked this pull request as ready for review March 21, 2025 17:48
@kellyguo11 kellyguo11 changed the title Add position to set external forces and torques Adds position to set external forces and torques May 3, 2025
@bikcrum
Copy link
Contributor

bikcrum commented May 20, 2025

@AntoineRichard

Suggestion: Would it be possible to extend this functionality to rigid bodies as well? Specifically, it would involve updating rigid_object.py and rigid_object_collection.py, since the set_external_force_and_torque function is also defined there and we’d want to support similar behavior.

@AntoineRichard AntoineRichard force-pushed the add_position_to_set_external_forces_and_torques branch from 99c3e68 to 2781c43 Compare July 14, 2025 08:42
torque_data=self._external_torque_b.view(-1, 3),
position_data=self._external_wrench_positions_b.view(-1, 3),
indices=self._ALL_INDICES,
is_global=False,
Copy link
Contributor

Choose a reason for hiding this comment

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

should we expose this in the same PR for simplicity?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not fond of exposing the global flag. The main issue I have with this is say we do:

art.set_external_force_and_torque(force, torque, position=position, body_id = body_1, global=True)
art.set_external_force_and_torque(force, torque, position=position, body_id = body_2, global=False)

Then it will use global = false for both. I think it's misleading.

Copy link
Contributor Author

@AntoineRichard AntoineRichard Jul 15, 2025

Choose a reason for hiding this comment

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

Or we could raise a warning / error if the global flag is changed more than once in a single simulation step for a given articulation / body(ies). But still it feels wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, would it make sense to have it as a parameter in either the simulation cfg or articulation cfg? so it can be specified on a per-sim level or per-articulation level

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's do it on a per articulation level. Default will be local.

Copy link
Contributor

Choose a reason for hiding this comment

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

hmm, I guess the downside with this approach is we can't control the frame for rigid bodies that are not an articulation. would that make sense to support if we expose the flag for RigidObjectCfg and RigidObjectCollectionCfg as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yes, sorry it completely skipped my that I had to replicate it on the other assets...

@kellyguo11 kellyguo11 merged commit ce2ae92 into isaac-sim:main Jul 23, 2025
5 of 6 checks passed
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.

[Proposal] Add an option to "set_external_force_and_torque" to choose where the forces should be applied.
5 participants