Closed CodingCatMountain closed 2 months ago
Sorry for the delayed response! I’ve found a script that can generate the geometry files for the Allegro Hand. Here's the code:
import numpy as np
import trimesh
import xml.etree.ElementTree as ET
def generate_geometry(urdf, remash=True, verbose=False):
links = urdf.findall("link")
geos = {}
for link in links:
origin = link.find("collision/origin")
box = link.find("collision/geometry/box")
sphere = link.find("collision/geometry/sphere")
rpy = None if origin is None else [float(x) for x in origin.get("rpy").split()]
xyz = None if origin is None else [float(x) for x in origin.get("xyz").split()]
size = None if box is None else [float(x) for x in box.get("size").split()]
radius = None if sphere is None else float(sphere.get("radius"))
name = link.get("name")
if box is None and sphere is None:
print(f"Link {name} has no geometry")
continue
type = "box" if box is not None else "sphere"
geos[name] = {"rpy": rpy, "xyz": xyz, "size": size, "radius": radius, "type": type}
result = {}
for link_name, geo in geos.items():
if geo["type"] == "box":
box = trimesh.creation.box(geo["size"])
vert = np.asarray(box.vertices)
faces = np.asarray(box.faces)
if remash:
if "base" in link_name:
vert, faces = trimesh.remesh.subdivide_to_size(vert, faces, 0.015)
else:
vert, faces = trimesh.remesh.subdivide_to_size(vert, faces, 0.0075)
if verbose:
print(f"{link_name} box: {vert.shape}")
xyz = geo["xyz"]
vert += np.array(xyz)
assert np.all(np.array(geo["rpy"]) == 0)
result[f"{link_name}_verts"] = vert
result[f"{link_name}_faces"] = faces
else:
if remash:
sphere = trimesh.creation.icosphere(3, geo["radius"])
else:
sphere = trimesh.creation.icosphere(1, geo["radius"])
vert = np.asarray(sphere.vertices)
faces = np.asarray(sphere.faces)
if verbose:
print(f"{link_name} sphere: {vert.shape}")
if geo["xyz"] is not None:
assert np.all(np.array(geo["xyz"]) == 0)
if geo["rpy"] is not None:
assert np.all(np.array(geo["rpy"]) == 0)
result[f"{link_name}_verts"] = vert
result[f"{link_name}_faces"] = faces
return result
if __name__ == "__main__":
urdf_data = ET.parse("assets/robot/allegro_hand_description/allegro_hand_free.urdf")
dense_geom = generate_geometry(urdf_data, remash=True, verbose=True)
simple_geom = generate_geometry(urdf_data, remash=False, verbose=True)
May I ask how to derive these two files:
right_dense_geo.npz
andright_simple_geo.npz
? Because I want to change allegro hand with my dexterous hand. Looking forward to your reply. :) Your Sincerely, Kacun.