jianglongye / cgf

Learning Continuous Grasping Function with a Dexterous Hand from Human Demonstrations, RA-L 2023 & IROS 2023
https://jianglongye.com/cgf
MIT License
12 stars 2 forks source link

How to derive the "assets/geometry/allegro_hand/right_dense_geo.npz"? #4

Closed CodingCatMountain closed 2 months ago

CodingCatMountain commented 2 months ago

May I ask how to derive these two files: right_dense_geo.npz and right_simple_geo.npz? Because I want to change allegro hand with my dexterous hand. Looking forward to your reply. :) Your Sincerely, Kacun.

jianglongye commented 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)