How to get Torque Values [of robot joints] with RMPFlow Motion Policy in Franka's Pick-and-Place Task

I have followed the official documentation to create a pick-and-place task with the Franka manipulator arm: pick and place.

As I understand it, the pick-and-place controller class utilizes RMPFlow under the hood. RMPFlow outputs the desired joint positions and joint velocities for the next time frame.

To gain a better understanding of the joint forces and torques, I utilized the get_applied_joint_efforts() method from the Franka class and printed out the Joint Efforts. However, the output I received was an array with all values set to zero.

Now, my question is: since the robot is simulating and picking up an object while moving from the initial position to the picking location, how is it possible to have zero joint efforts? Could you please assist me with this?

For reference, I am attaching the code that I have written.

from omni.isaac.kit import SimulationApp

simulation_app = SimulationApp({"headless": False})

from omni.isaac.core import World
from omni.isaac.franka import Franka
from omni.isaac.core.objects import DynamicCuboid
from omni.isaac.franka.controllers import PickPlaceController
import numpy as np


class FrankaSim:
    """A Isaac-Sim based franka panda physics simulation"""

    def __init__(self):
        self._init_sim()

    def _init_sim(self):
        """Setup the scene for physics simulation of franka panda"""
        self._world = World(
            physics_dt= 1/60.0,
            rendering_dt=1.0/60,
            stage_units_in_meters=1,
            physics_prim_path="/World/physicsScene",
        )

        # add ground plane to the scene
        self._world.scene.add_default_ground_plane()

        # add cube to the scene
        self._cube = self._world.scene.add(
            DynamicCuboid(
                prim_path="/World/cube",
                name="cube",
                position=np.array([0.6, -0.2, 0.025]),
                scale=np.array([0.05, 0.05, 0.05]),
                color=np.array([0, 0, 1.0]),
            )
        )

        # add franka robot to the scene
        self._franka = self._world.scene.add(
            Franka(
                prim_path="/World/franka_panda",
                name="franka_panda",
            )
        )

        # Initialize the controller 
        self._controller = PickPlaceController(
            name="pick_place_controller",
            gripper=self._franka.gripper,
            robot_articulation=self._franka,
            events_dt = [0.008, 0.005, 1, 0.1, 0.05, 0.05, 0.0025, 1, 0.008, 0.08]
            # [0.001, 0.005, 0.1, 0.1, 0.0025, 0.001, 0.0025, 1, 0.008, 0.001]
        )

        # hook the callback functions
        self._world.add_physics_callback(
            "physics_callback", self._physics_step_callback
        )


    def _physics_step_callback(self, step_size):
        print("\n>>>>>>>>>>>>>>>>>>>>>>> $$ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
        print("Executing the event no: ", self._controller.get_current_event(), "|| current time is: ", self._world. current_time)

        # get global poses
        cube_position, _ = self._cube.get_world_pose()
        goal_position = np.array([-0.3, -0.3, 0.025])

        current_joint_positions = self._franka.get_joint_positions()
        current_joint_velocities = self._franka.get_joint_velocities()

        # print for info
        print("current CUBE position:\n ", cube_position)
        print("current JOINTS positions [in radians]:\n ", current_joint_positions)
        print("current JOINTS velocities [in radians/sec]:\n ", current_joint_velocities)
        print("JOint efforts: ", self._franka.get_applied_joint_efforts())


        # get the actions for the next time frame
        actions = self._controller.forward(
            picking_position=cube_position,
            placing_position=goal_position,
            current_joint_positions=current_joint_positions,
        )

        # apply articulation action on franka joints
        self._franka.apply_action(actions)



    def simulate_physics(self):

        # some information
        print("""
        A simple pick and place task, executed in 10 phases.
        Each phase runs for 1 second
        Dt of each phase/ event step is defined
        - Phase 0: Move end_effector above the cube center at the 'end_effector_initial_height'.  [dt = 0.008]
        - Phase 1: Lower end_effector down to encircle the target cube [dt = 0.005]
        - Phase 2: Wait for Robot's inertia to settle. []dt = 0.1]
        - Phase 3: close grip. [dt = 0.1]
        - Phase 4: Move end_effector up again, keeping the grip tight (lifting the block). [dt = 0.0.0025]
        - Phase 5: Smoothly move the end_effector toward the goal xy, keeping the height constant. [dt = 0.001]
        - Phase 6: Move end_effector vertically toward goal height at the 'end_effector_initial_height'. [dt = 0.0025]
        - Phase 7: loosen the grip. [dt = 1]
        - Phase 8: Move end_effector vertically up again at the 'end_effector_initial_height' [dt = 0.008]
        - Phase 9: Move end_effector towards the old xy position. [dt = 0.008]
        """)
        
        # first reset the world to initialze the physics handles
        print(">>>>>>>>>>>>>>>>>> Resetting the world >>>>>>>>>>>\n")
        self._world.reset()
        ## After reset, physics handles will be enabled, means we 
        ## can start interacting with articulation i.e robot joints and links
        ## Initially robot joints are in same positions as we defined in urdf file
        print(">>>>>>>>>>>>>>>>>> Joint Default State >>>>>>>>>>>>\n", self._franka.get_joints_default_state().positions)


        #set the joint positions of franka
        print(">>>>>>>>>>>>>>>>>> Setting initial joint positions of Franka >>>>>>>>>>>\n")
        new_joint_pos = [0 ,0, 0, -1.57, 0, 1.57, -0.7853,0.00545289, 0.00730873]
        self._franka.set_joint_positions(positions = new_joint_pos)

        print(">>>>>>>>>>>>>>>>>> Opening Gripper >>>>>>>>>>>\n")
        # open the gripper
        self._franka.gripper.set_joint_positions(
            self._franka.gripper.joint_opened_positions
        )

        while 1:
            self._world.step(render=True)
            if self._controller.is_done():
                break
        print("\n>>>>>>>>>>>>>>>>>> Pick and Place Task Done <<<<<<<<<<<<<<<<<<<<<<<<<<<<")


if __name__ == "__main__":
    obj = FrankaSim()
    obj.simulate_physics()
    simulation_app.close()

Could anyone please update on this thread ?

Hi @ksu1rng - Thank you for your patience. Someone from our team will review and respond to your question.

Hi @ksu1rng - Each physics step you can set joint position targets, joint velocity targets or joint efforts. The get_applied_joint_efforts is meant to return efforts that you applied but not the computed values. We will release extra apis to get the computed joint efforts in the upcoming release. These are not exposed for now.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.