BerkeleyAutomation / dex-net

Repository for reading the Dex-Net 2.0 HDF5 database of 3D objects, parallel-jaw grasps, and robust grasp metrics
https://berkeleyautomation.github.io/dex-net/code.html
Other
296 stars 97 forks source link

How to generate Database data #76

Closed elevenjiang1 closed 2 years ago

elevenjiang1 commented 2 years ago

Hello,I am now trying to make dataset from my own 3D models. I find that there are code for generation gqcnn dataset,but there are not code for generation database code. I know that there are some demo code in grasping_test.py,database_test.py and dexnet-cli.py,but are there any whole code for generating database code?

Thank you~

elevenjiang1 commented 2 years ago

Here is my code to generate h5py from obj file. tools/generate_gqcnn_dataset.py need:

  1. graspable_object
  2. stable_poses
  3. grasps
  4. grasp_metrics

The code is reference test/database_test.py and test/grasping_test.py.The data generate have tested to generate gqcnn data and train dex-net 2.0.. If there is mistake in this code,welcome to contact me~

Best

"""
Specify a path which contains .obj files
Generate h5py file,including:
1. create graspable objects with MeshProcesser
3. calculate grasps
4. calculate grasp metrics
"""

from tqdm import tqdm
import copy
import IPython
import logging
import numpy as np
import os
import sys
import time
from unittest import TestCase, TestSuite, TextTestRunner

from autolab_core import RigidTransform, YamlConfig

from perception import CameraIntrinsics, RenderMode

from meshpy.obj_file import ObjFile
from meshpy.mesh_renderer import ViewsphereDiscretizer, VirtualCamera

from dexnet.constants import READ_WRITE_ACCESS,READ_ONLY_ACCESS,WRITE_ACCESS
from dexnet.database import Hdf5Database, MeshProcessor, RescalingType
from dexnet.grasping import ParallelJawPtGrasp3D,GraspableObject3D, AntipodalGraspSampler, GraspQualityConfigFactory, GraspQualityFunctionFactory, RobotGripper

def create_database(config_path,generate_path,objs_path):
    #1: load config file
    config_data=YamlConfig(config_path)
    config_data['obj_rescaling_type'] = RescalingType.RELATIVE

    #2: create database and dataset
    if not os.path.exists(generate_path):
        print("generate_path not exist,generate a new database")
        database=Hdf5Database(generate_path,access_level=READ_WRITE_ACCESS)
    else:
        print("generate_path exist,read this database")
        database=Hdf5Database(generate_path,access_level=READ_WRITE_ACCESS)

    dataset=database.create_dataset("mini_test")
    database.close()

    database=Hdf5Database(generate_path,access_level=READ_WRITE_ACCESS)
    dataset=database.dataset("mini_test")

    #3: load graspable objects
    for obj_file in os.listdir(objs_path):
        obj_path=os.path.join(objs_path,obj_file)

        mesh_processor=MeshProcessor(obj_path,config_data['cache_dir'])
        mesh_processor.generate_graspable(config_data)

        dataset.create_graspable(mesh_processor.key,mesh_processor.mesh,mesh_processor.sdf,mesh_processor.stable_poses,mass=1.0)

    #4: add dataset.metric
    for metric_name in config_data['metrics'].keys():
        print("******Add metric_name:{}******".format(metric_name))
        metric_config=config_data['metrics'][metric_name]
        dataset.create_metric(metric_name,metric_config)

    #5: add object's grasp and grasp metirc
    #init antipodal grasp sampler
    GRIPPER_NAME = 'yumi_metal_spline'
    gripper=RobotGripper.load(GRIPPER_NAME)
    ags = AntipodalGraspSampler(gripper, config_data)
    NUM_TEST_CASES=100

    rfc_quality_config = GraspQualityConfigFactory.create_config(config_data['metrics']['robust_ferrari_canny'])
    setattr(rfc_quality_config, 'force_limits', gripper.force_limit)
    setattr(rfc_quality_config, 'finger_radius', gripper.finger_radius)

    for key in dataset.object_keys:
        print("*****Generating {} grasps and grasp metrics*****".format(key))
        graspable_object_3d=dataset.graspable(key)
        #init 'force_closure grasp quality' and 'robust_ferrari_canny quality' function        
        rfc_quality_fn = GraspQualityFunctionFactory.create_quality_function(graspable_object_3d, rfc_quality_config)

        #5.1: generate and save grasps
        grasps=ags.generate_grasps(graspable_object_3d,target_num_grasps=NUM_TEST_CASES)
        dataset.store_grasps(key,grasps,gripper=GRIPPER_NAME)

        #5.2: generate and save grasp_metrics
        loaded_grasps=dataset.grasps(key)#must use loaded_grasps,otherwise grasp will not have grasp.id
        grasp_metrics = {}
        for grasp in tqdm(loaded_grasps,total=len(loaded_grasps)):
            #get metric
            rfc_metric=rfc_quality_fn(grasp).quality

            #save metirc
            grasp_metrics[grasp.id]={}
            grasp_metrics[grasp.id]['robust_ferrari_canny']=rfc_metric

        dataset.store_grasp_metrics(key,grasp_metrics,gripper=GRIPPER_NAME)

    #N: close database
    print("!!!!!!Generate Finish,close data!!!!!!")
    database.close()

def check_database(database_path):
    """
    Use for show database_path file info
    """
    #1: load datasetbase and see datasets name
    database=Hdf5Database(database_path,access_level=READ_ONLY_ACCESS)
    print("load database,it has {} dataset,their names are:".format(len(database.datasets)))
    for dataset in database.datasets:
        print(dataset.name)

    #select first dataset
    dataset=database.dataset(database.datasets[0].name)

    #2: see graspable in dataset
    print("dataset has {} objects,their names are:".format(len(dataset.objects)))
    for key in dataset.object_keys: 
        print(key)

        #3: see stable poses
        stable_poses=dataset.stable_poses(key)
        print("{} has {} stable poses,first is:".format(key,len(stable_poses)))
        print(stable_poses[0].T_obj_table)

        #4: see grasps 
        grasps=dataset.grasps(key)
        print(len(grasps))

        #5: see grasps metrics
        grasp_metrics=dataset.grasp_metrics(key,grasps)
        print(len(grasp_metrics))

if __name__ == '__main__':
    print("********begin function***********")
    config_path="path/to/test/config.yaml"
    generate_path="path/to/new_database.hdf5"
    objs_path="path/to/models"#models is a Folder which only contain .obj files
    create_database(config_path,generate_path,objs_path)
    check_database(generate_path)
    print("********end function***********")
dong329 commented 2 years ago

How did you solve the problem of importing CameraIntrisics from perception? I saw ur comment after another issue about this one. THX!

elevenjiang1 commented 2 years ago

How did you solve the problem of importing CameraIntrisics from perception? I saw ur comment after another issue about this one. THX!

This problem is mainly depend on which version of autolab_core autolab_perception you use. In dexnet setup,I use python2 on Ubuntu 16.04, the version of each package are:

SDFGen:github->branch:master
Boosh.Numpy:github->branch:master
autolab_core:pip2 install autolab_core==0.0.5
perceptoin:github->branch:dev_danielseita
meshpy:github->branch:master
gqcnn:github->branch:develop
visualization:pip2 install visualization==0.0.7

In old version, CameraIntrinsics is still in perception


Then, I also setup gqcnn by python3,which clone from github->branch:master;Still on Ubuntu16.04, the version of each package are:

autolab_core:pip3 install autolab_core==1.1.0
visualization:pip3 install visualization==1.0.0

Then in this version,all from perception import xxx can change to from autolab_core import xxx

Maybe there are still some detail I don't give, feel free to ask more~