-
Notifications
You must be signed in to change notification settings - Fork 265
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
URDFs for robots missing tip #263
Comments
Hello, Since nobody bothered to reply and the solution described in #201 does not seem to work, I offer another solution to this problem: Reconstructing the kinematics from RLBench by querying the sim. import numpy as np
from collections import defaultdict
from dataclasses import dataclass
from pyrep.objects.object import ObjectType
from scipy.spatial.transform import Rotation
@dataclass
class Joint:
name : str
type : str
parent : str
child : str
position_xyz : tuple[float, float, float]
rotation_rpy : tuple[float, float, float]
q_limits : tuple[float, float] = None
qd_limit : float = None
@dataclass
class Link:
name : str
def make_flat_kinematic(fk_chain):
links = {'ROOT_LINK': Link('ROOT_LINK')}
joints = {}
for parent, obj in zip([None] + fk_chain[:-1], fk_chain):
parent_T_child = obj.get_matrix(relative_to=parent)
position_xyz = tuple(parent_T_child[:3, 3])
# Need to reverse the tuple because we store the order of rotation left-to-right
rotation_rpy = tuple(Rotation.from_matrix(parent_T_child[:3, :3]).as_euler('ZYX'))[::-1]
link = Link(f'{obj.get_name()}_LINK')
links[link.name] = link
if obj.get_type() == ObjectType.JOINT:
joint = Joint(f'{obj.get_name()}_JOINT',
'revolute',
f'{parent.get_name()}_LINK' if parent is not None else 'ROOT_LINK',
link.name,
position_xyz,
rotation_rpy,
# REALLY STUPID: COPPELLIA RETURNS A FLAG THAT SEEMS TO INDICATE ABSOLUTENESS OF UPPER BOUND. WAT?!
(((lb:=obj.get_joint_interval()[1][0]), lb+obj.get_joint_interval()[1][1]) if not obj.get_joint_interval()[0] else obj.get_joint_interval()[1][1]),
obj.get_joint_upper_velocity_limit())
else:
joint = Joint(f'{obj.get_name()}_JOINT',
'fixed',
f'{parent.get_name()}_LINK' if parent is not None else 'ROOT_LINK',
link.name,
position_xyz,
rotation_rpy,
)
joints[joint.name] = joint
return links, joints
def get_robot_ee_kinematic(pyrep_robot):
pyrep_robot.set_joint_positions(np.zeros(len(pyrep_robot.joints)), disable_dynamics=True)
ik_tip = pyrep_robot.get_tip()
inv_fk_chain = [ik_tip]
while (parent:=inv_fk_chain[-1].get_parent()) is not None:
inv_fk_chain.append(parent)
filtered_chain = [ik_tip]
for body in inv_fk_chain[1:]:
if body.get_type() == ObjectType.JOINT:
filtered_chain.append(body)
fk_chain = list(reversed(filtered_chain))
# Reversal should not really matter...
return make_flat_kinematic(fk_chain) + (fk_chain,)
def make_urdf(name : str, links : dict[str, Link], joints : dict[str, Joint]) -> str:
out = f'<robot name="{name}">\n'
for link in links.values():
out += f' <link name="{link.name}"/>\n'
for j in joints.values():
out += f' <joint name="{j.name}" type="{j.type}">\n'
out += f' <origin xyz="{j.position_xyz[0]} {j.position_xyz[1]} {j.position_xyz[2]}" rpy="{j.rotation_rpy[0]} {j.rotation_rpy[1]} {j.rotation_rpy[2]}"/>\n'
out += f' <parent link="{j.parent}" />\n <child link="{j.child}" />\n'
if j.type == 'revolute':
out += ' <axis xyz="0 0 1" />\n'
out += f' <limit effort="1000" upper="{j.q_limits[1]}" lower="{j.q_limits[0]}" velocity="{j.qd_limit}" />\n'
out += ' </joint>\n'
out += '</robot>'
return out Using this code you can use NOTE
To the devs: Feel free to include this code in RLBench, if you want to. As someone from a more classical robotics background I found it very surprising/troubling/infuriating that there's no way to obtain the actual FK of the robots short of querying the simulator. This bars researchers from using any external MPC tool to control the robot. |
To add some more context to Adrian's response: the kinematics generated by RLBench (CoppeliaSim) are different than the ones generated, for example, by RTB when using the exported URDF. Hope this is helpful to anymore struggling with this. |
#201 describes how to export the URDFs for the robots.
However, these URDFs are missing the IK tip.
Step 4 says 'In the generated urdf file, manually convert Pandatip from a visual to a link.'
However, even for the Panda the tip is not part of the exported URDF at all.
What am I missing?
Coppeliasim version is 4.8
The text was updated successfully, but these errors were encountered: