# Isaac Sim 2023.1.1: Jacobian differs from roboticstoolbox; Franka FR3 joint position limit

Hello. I’m using the orbit framework (Link) to simulate a Franka robot arm in Isaac Sim 2023.1.1. I was also using the roboticstoolbox package to calculate the Jacobian for each link of the robot arm, given the current joint angle. I have two questions about the Jacobian and the Franka arm model:

1. I followed the tutorial from this webpage and the USD path of the robot is: usd_path=f"{ISAAC_ORBIT_NUCLEUS_DIR}/Robots/FrankaEmika/panda_instanceable.usd"
For my application, I need to control the Cartesian velocity of each link. During the simulation, I read the positions of each link of the robot arm with robot.data.body_state_w, and Jacobians associating the Cartesian coordinates to the joint velocity with robot.root_physx_view.get_jacobians(). As I understand the body_state_w and the root_physx_view Jacobians, the first Jacobian matrix should correspond to how the linear & angular velocity of the link 1 (defined in the following figure from the Franka webpage) is affected by the joint velocities.
According to the Panda’s kinematic chain from the Franka website, link 1 and link 2 are defined right at the center of the 2nd joint, which means their Cartesian position will not move (they won’t translate) with the rotation of joints. This also reflects in the read position from the simulation: at any joint configuration, only the z-coordinate of the first link is larger than 0, and is a constant robot.data.body_state_w[0, 1, 0:3] = (tensor([5.8484e-10, 9.5358e-07, 3.3300e-01], device='cuda:0'); also computed with the roboticstoolbox, the position of the link 1 is [0.0, 0.0, 0.333].
However, with the Jacobians, the result read from the simulation with robot.root_physx_view.get_jacobians() differs from the computed result from roboticstoolbox. I picked a pre-set joint configuration panda.qr from the roboticstoolbox:
panda = rtb.models.Panda()

and get the Jacobian for the first link expressed in the root frame:

[[**0.** 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0. 0.]]

Then I tried to drive the robot arm to the same joint position target with robot.set_joint_position_target(joint_pos_des, joint_ids=robot_entity_cfg.joint_ids) (I also tried to directly write the joint position into simulation with robot.write_joint_state_to_sim(position=joint_pos_des.float(), velocity=torch.tensor([[0., 0., 0., 0., 0., 0., 0.]], device=sim.device).float(), joint_ids=robot_entity_cfg.joint_ids)). The first jacobian matrix read from robot.root_physx_view.get_jacobians()[0, 0, :, robot_entity_cfg.joint_ids] is then:

tensor([[ **3.1254e-02**,  0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,
0.0000e+00,  0.0000e+00],
[ 2.0865e-04,  0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,
0.0000e+00,  0.0000e+00],
[-1.1846e-08,  0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,
0.0000e+00,  0.0000e+00],
[ 3.7948e-07,  0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,
0.0000e+00,  0.0000e+00],
[ 2.3021e-08,  0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,
0.0000e+00,  0.0000e+00],
[ 1.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,  0.0000e+00,
0.0000e+00,  0.0000e+00]], device='cuda:0')

where you can see from the first entry of the matrix that 1 rad/s joint velocity of the first joint in configuration space corresponds to 0.03m/s velocity of link 1 at the x direction in Cartesian space, which I don’t think should happen (link 1 shouldn’t translate at all) and doesn’t align with the result from roboticstoolbox. I used the Jacobian from roboticstoolbox on a real Franka arm and it worked well. I also tried to apply the Jacobian matrices from the roboticstoolbox into the simulation, but then the simulated robot didn’t move as expected (whereas the Jacobian from robot.root_physx_view.get_jacobians() worked in simulation).

I’m writing to ask whether there is any misunderstanding such as I read Jacobian from the wrong data or the Jacobian from robot.root_physx_view.get_jacobians() doesn’t associate the Cartesian velocities of the links and the joint velocities.

1. I read from the update note of Isaac Sim 2023.1.1 that the new Franka arm FR3 is now included. But it seems that Orbit hasn’t included it yet. As Franka Panda and Franka FR3 have different joint limits, I tried to import the FR3 model with Orbit. I followed the structure of the code in /orbit/source/extensions/omni.isaac.orbit_assets/omni/isaac/orbit_assets/franka.py to spawn the FR3 model from USD path usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Franka/FR3/fr3.usd" with ArticulationCfg, where the joint velocity limit can be defined using
FRANKA_FR3_CFG = ArticulationCfg(
spawn=sim_utils.UsdFileCfg(
usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Franka/FR3/fr3.usd", ...)
...
actuators={
"fr3_shoulder": ImplicitActuatorCfg( **velocity_limit**= ..., stiffness=..., damping=..., ...}
...

But I didn’t find a place to specify the joint position limit. I’d like to ask where I could define joint position limit for the Franka FR3 robot or if it’s already included somewhere.

Thank you!