17 The Columbia Grasp Database: Part II
This section contains material describing the CGDB's internal
structure. It is intended for those who wish to modify the CGDB or use
it in more advanced ways than the basic database browser described in
The Columbia Grasp Database - Part I. For the
remainder of this chapter, when we say the "CGDB" we are referring to
the PostgreSQL database, and not to the accompanying geometry files
that the database references.
The CGDB is not only of data, but also a database in the strong sense;
a structured system for encapsulating relationships between various
types of geometric, semantic, and robotic data. The preloaded data
consists of grasps computed by our Eigengrasps Planner on the models
from the Princeton Shape Benchmark with a small number of hands, but
the structure can be expanded with new data in any dimension. Using
the CGDB to the fullest extent requires a substantial knowledge of
SQL, both to add new information to the system and to calculate
statistics and properties of the grasps.
The CGDB follows the following naming conventions:
- every column name is prefixed with the name of its table
- except for fields referencing the primary key of another table
Some tables contain two unique columns. Columns that end with the
suffix "_id" are numeric automatically generated identifiers and are
used as primary keys. Columns that end with the suffix "_name" are
human-readable identifiers intended to simplify interaction with the
database from code and from the GraspIt! browser.
We first describe how 3D model information is stored in the database.
- original_model contains one entry for each geometry file.
- original_model_id is a primary key
- original_model_name is a convenient
human-readable name for the model. For the models
included with the CGDB this is just the model number
from the PSB.
- original_model_geometry_path and
original_model_thumbnail_path contain the
paths - relative to the CGDB_MODEL_ROOT
environment variable - to the geometry file and an
associated thumbnail file.
- original_model_tags contains an array of
text tags that refer to the model. For the models that
come with the CGDB, this field is populated with the
names of the classes and subclasses in the Princeton
Shape Benchmark's fine level classification that apply
to this model.
- original_model_grasping_rescale gives a
conversion from the units in the geometry file to
millimeters, where the model is at its "graspable size"
as discussed in the previous
chapter. For most PSB models we took the
units in the original file to be 10 inches.
- original_approximate_radius contains a
statistical measure of the scale of the original
model. We assume that all points on the surface of a
mesh are normally distributed around a sphere of fixed
radius centered on the center of mass. This value is
that radius, plus 2 standard deviations of that
distribution. It is used by the CGDB planner to find
models at "similar" sizes to other models.
- scaled_model contains one entry for each scaled
copy of an original model. Since grasping is scale-dependent, we
duplicate original models at multiple scales (in this release,
0.75, 1, 1.25 and 1.5 times the original scale).
- scaled_model_id is a primary key
- scaled_model_name contains a human-readable
name for the scaled model. Following the current
convention ("collectionname_scale_modelname") is a
good idea.
- scaled_model_scale contains the rescale
factor relative to the original model.
- original_model_id is a foreign key on the
original_modeltable, linking this scaled model
to an unscaled original model.
To add new models to the CGDB, first place the geometry files (and
preferably, thumbnails) under the CGDB_MODEL_ROOT
directory. Then, create a row in original_model referencing
the new files. There is no need to follow the PSB naming convention
for files as long as the path are stored correctly in the
database. Make sure to store the units-to-millimeters conversion in
original_model_grasping_rescale and the approximate radius
in original_model_approximate_radius. Unfortunately we are
not currently providing code for computing the approximate radius, but
the description of the method above should help those who wish to
recreate it.
The next step is to add at least one row, to scaled_model, or
as many rows as you like. (You can also add new scaled_model
rows for existing models in the database at new scales.) After that,
the model is in the database and will be visible to the browser and to
all CGDB code, although it will not yet have any associated grasps,
alignments, or neighbors.
In this section we describe how hands are stored in the database.
- hand contains one entry for each robotic hand used
in the database by any grasp. We store a unique hand if any
parameter has changed, so for example the Barrett Hand with
different friction coefficients appears more than once.
- hand_id is a primary key
- hand_name is a convenient human-readable
name for the hand.
At the moment, the hand information is tightly coupled to
GraspIt!. While it is possible to add new hands to the database
without doing anything in GraspIt!, the only way to link a database
hand to a GraspIt! hand model is to edit the code. This is not
particularly difficult, but we should fix it in the future.
Now that we have models and hands, we can talk about storing grasps.
- grasp_source lists the possible sources of
grasps. The primary source of grasps in the CGDB is from the
Eigengrasp Planner, but there are some human-created grasp
sources as well. In theory a database-backed planner can
prioritize different sources, say for example preferring human
created grasps to automatically created grasps when both are
available. Our current planner only uses the automated grasps
and so does not do this.
- grasp_source_id is a primary key
- grasp_source_name is a convenient
human-readable name for the grasp source.
- grasp_source_description is a free-form
field for more in depth comments.
- grasp contains one entry for each grasp done with a
hand on a model in the database.
- grasp_id is a primary key
- scaled_model_id references the scaled model
the grasp was performed on.
- hand_id references the hand used to perform the grasp.
- grasp_source_id references the
grasp_source where this grasp was created from.
- grasp_pregrasp_joints and
grasp_pregrasp_position contain the information
necessary to recreate the pregrasp.
- grasp_grasp_joints and
grasp_grasp_position contain the information
necessary to recreate the grasp.
- grasp_contacts is an array of contact points
between the hand and object. Each three numbers forms an
(x,y,z) triple.
- grasp_epsilon_quality and
grasp_volume_quality contain Ferrari-Canny
grasp quality measures.
If you wish to add data from your own planner to the CGDB, we suggest
you create a new entry in grasp_source.
If you wish to add new grasps to the CGDB, you must fill in the
various fields of this table with the grasp information. The
coordinate system of the grasp positions is the model's coordinate
system.
Aside from model and grasp information, the CGDB also stores geometric
relationships between 3D models to assist in grasp planning. If you
wish to use GraspIt!'s built-in CGDB planner on new models that
were not distributed with the PSB, you will need to add information to
this part of the database.
In this section we describe how geometric neighbors are stored in the
database. We store neighbors according to a number of "distance
functions" that measure the similarities between 3D models. At this
time, we do not provide code for calculating such similarities
yourself, but only precomputed neighbor relationships for the existing
models. We are distributing 9 sets of neighbors for each model, as
given by the following distance functions.
- ZERNIKE - Novotni and Klein's Zernike descriptors, as
described
here.
- RANDOM - randomly selected neighbors for benchmarking
purposes.
- PSB - neighbors within the same subclass in the PSB as the
current model. The ordering within the classes is
arbitrary. Used for benchmarking.
- SIFT_12_view_x - A SIFT-PI descriptor, as described in
the CGDB publications, which describes similarity using only
what is visible from one side of the object. There are 6 such
distance function in the database with different view numbers,
and they correspond to descriptors taken from the centers of the
6 sides of the enclosing box.
For each distance function we store the 25 nearest neighbors of each
object, along with the distance to the neighbor (higher distance is
less similar). Note that the neighbor relationships are between
original models and not scaled models, since most measures of
3D similarity are scale independent.
- distance_function contains an entry for each
similarity metric used in comparing 3D models and finding
neighbors. Currently we provide 9 such distance functions (the
10th, "Eigengrasps", is not actually a distance function and is
used as a marker in some experiments that pit the Eigengrasp
Planner against the Database Planner.)
- distance_function_id is a primary key
- distance_function_name is a convenient
human-readable name for the distance function.
- distance_function_description is a more
detailed comment about the distance function.
- neighbors contains an entry for each neighbor
relationship between two models in the database.
- neighbor_id is a primary key
- original_model_id references the model we
are finding neighbors for
- neighbor_original_model_id references the
model that has been found as a neighbor
- distance_function_id references the
distance function used in finding this neighbor
- neighbor_distance gives the distance to the
neighbor (higher is less similar)
To add a new distance function, simply add a new entry to the
distance_function table. This is useful if you want to try
your own shape matching functions.
To add a new neighbor to the database, fill in a new row in the
neighbor table. Note that neighbor relationships are not
automatically symmetric, and so if you want the reverse relationship
to be in the database as well you must add it yourself. As we do not
provide the original descriptors or code used in creating the
neighbors we have distributed, we strongly recommend not adding any
new neighbors to the original distance functions. If you wish to add
new models, we encourage you to create a new distance function for all
the models, including those we have distributed.
To transfer grasps from one model to another we need a transformation
between their coordinate systems. The CGDB currently provides
precomputed rotational alignments for all neighbor relationships that
are in the database; translational alignments are done by colocating
the models' centers of mass. At the moment, we do not provide the
alignment code itself. We currently provide data from 2 alignment
methods:
- TRIMESH_LIB PCA - Models are aligned by aligning their
principle axes. The Trimesh
library was
used to calculate PCAs.
- SIFT_FULL_ICP - A SIFT - based alignment, as described in
the CGDB publications, refined by ICP.
The database structure is as follows:
- alignment_method contains an entry for each method
of computing alignments.
- alignment_method_id is a primary key
- alignment_method_name is a convenient
human-readable name for the alignment method.
- distance_function_description is a more
detailed comment about the alignment method.
- alignment contains an entry for each stored
alignment between two models in the database.
- alignment_id is a primary key
- original_model_id references the model we
are trying to align (the one whose coordinates change)
- alignment_original_model_id references the
model that we are aligning to (the one whose coordinates
remain fixed)
- alignment_method_id references the
alignment method used in creating this alignment.
- aignment gives the transformation as a matrix
To add a new distance function, simply add a new entry to the
alignment_method table.
To add a new alignment to the database, fill in a new row in the
alignment table. Note that alignments are not automatically
symmetric, and so if you want the reverse relationship to be in the
database as well you must add it yourself. As we do not provide the
code used in creating the alignments we have distributed, we strongly
recommend not adding any new alignments to the original alignment
methods.
Along with the data and table structures, several stored procedures
are built into the database to ease use. We briefly describe them
here:
- get_model_id turns a scaled_model_name into a
scaled_model_id
- get_hand_id turns a hand_name into a scaled_model_id
- get_source_id turns a grasp_source_name into a
grasp_source_id
- get_alignment_method_names retrieves a list of
alignment method names
- get_distance_function_names retrieves a list of
distance function names
- get_grasp_type_names retrieves a list of grasp type names
- get_models retrieves basic information about all
scaled models.
- get_model_at_nearest_scales retrieves the largest
scaled version of an original model with approximate radius
smaller than a given radius, and the smallest version larger
than that radius. One of these may not exist (if the radius is
larger than the largest scaled model, or smaller than the
smallest).
- get_saved_neighbors retrieves a list of saved
neighbors for a given model
- get_grasps retrieves a list of saved grasps for a
given model
- get_alignment retrieves a saved alignment between
two models
More functions exist, but serve as helpers for those listed above.
Copyright (C) 2002-2009 Columbia University
| | | 17 The Columbia Grasp Database: Part II | Contents |