# ----------------------------------------------------------------------------
# Copyright (c) 2021-2026 DexForce Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
from __future__ import annotations
import os
import open3d as o3d
from embodichain.data.dataset import EmbodiChainDataset
from embodichain.data.constants import (
EMBODICHAIN_DOWNLOAD_PREFIX,
EMBODICHAIN_DEFAULT_DATA_ROOT,
)
__all__ = [
"DH_PGC_140_50",
"DH_PGI_140_80",
"DH_PGC_140_50_M",
"DH_AG95",
"ZH_CTM2F110",
"BrainCoHandRevo1",
"InspireHand",
"Robotiq",
"Robotiq2F85",
"WheelTecFA2F",
"PikaGripper",
]
eef_assets = "eef_assets"
[docs]
class DH_PGC_140_50(EmbodiChainDataset):
"""Dataset class for the DH Robotics PGC-140-50 end-effector gripper.
Reference:
https://www.dh-robotics.com/product/pgc
Directory structure:
DH_PGC_140_50/
DH_PGC_140_50.urdf
Example usage:
>>> from embodichain.data.eef_dataset import DH_PGC_140_50
>>> dataset = DH_PGC_140_50()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("DH_PGC_140_50/DH_PGC_140_50.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "DH_PGC_140_50.zip"),
"c2a642308a76e99b1b8b7cb3a11c5df3",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class DH_PGI_140_80(EmbodiChainDataset):
"""Dataset class for the DH Robotics PGI-140-80 end-effector gripper.
Reference:
https://www.dh-robotics.com/product/pgia###
Directory structure:
DH_PGI_140_80/
DH_PGI_140_80.urdf
Example usage:
>>> from embodichain.data.eef_dataset import DH_PGI_140_80
>>> dataset = DH_PGI_140_80()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("DH_PGI_140_80/DH_PGI_140_80.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "DH_PGI_140_80.zip"),
"05a1a08b13c6250cc12affeeda3a08ba",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class DH_PGC_140_50_M(EmbodiChainDataset):
"""Dataset class for the DH Robotics PGC-140-50 end-effector gripper.
DexForce modified connector and finger.
Reference:
https://www.dh-robotics.com/product/pgc
Directory structure:
DH_PGC_140_50_M/
DH_PGC_140_50_M.urdf
Example usage:
>>> from embodichain.data.eef_dataset import DH_PGC_140_50_M
>>> dataset = DH_PGC_140_50_M()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("DH_PGC_140_50_M/DH_PGC_140_50_M.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(
EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "DH_PGC_140_50_M.zip"
),
"3a9ab5f32639e03afb38dc033b44bb62",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class DH_AG95(EmbodiChainDataset):
"""Dataset class for the DH Robotics AG95 end-effector gripper.
DexForce modified connector and finger.
Reference:
https://www.dh-robotics.com/product/ag
Directory structure:
DH_AG95/
dh_ag95.urdf
Example usage:
>>> from embodichain.data.eef_dataset import DH95
>>> dataset = DH_AG95()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("DH_AG95/dh_ag95.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "DH_AG95.zip"),
"34b6f3c2f649697ea7f12814b6a50529",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class ZH_CTM2F110(EmbodiChainDataset):
"""Dataset class for the Zhixing Robot Technology CTM2F110 end-effector gripper.
Reference:
https://www.changingtek.com/service
Directory structure:
ZH_CTM2F110/
ZH_CTM2F110.urdf
Example usage:
>>> from embodichain.data.eef_dataset import ZH_CTM2F110
>>> dataset = ZH_CTM2F110()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("ZH_CTM2F110/ZH_CTM2F110.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "ZH_CTM2F110.zip"),
"0e7c3310425609797fe010b2a76fe465",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class BrainCoHandRevo1(EmbodiChainDataset):
"""Dataset class for the BrainCo Hand Revo 1 robotic hand.
Reference:
https://www.brainco-hz.com/docs/revolimb-hand/revo1/parameters.html
Directory structure:
BrainCoHandRevo1/
BrainCoRightHand/BrainCoRightHand.urdf
BrainCoLeftHand/BrainCoLeftHand.urdf
Example usage:
>>> from embodichain.data.eef_dataset import BrainCoHandRevo1
>>> dataset = BrainCoHandRevo1()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("BrainCoHandRevo1/BrainCoRightHand/BrainCoRightHand.urdf"))
>>> print(get_data_path("BrainCoHandRevo1/BrainCoLeftHand/BrainCoLeftHand.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(
EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "BrainCoHandRevo01.zip"
),
"ff9ac77e7e1493fd32d40c87fecbee6c",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class InspireHand(EmbodiChainDataset):
"""Dataset class for the Inspire Hand robotic hand.
Reference:
https://en.inspire-robots.com/product/rh56bfx
Directory structure:
InspireHand/
InspireLeftHand/InspireLeftHand.urdf
InspireRightHand/InspireRightHand.urdf
inspire_joint_data.csv
inspire_joint_data.npy
Example usage:
>>> from embodichain.data.eef_dataset import InspireHand
>>> dataset = InspireHand()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("InspireHand/InspireLeftHand/InspireLeftHand.urdf"))
>>> print(get_data_path("InspireHand/InspireRightHand/InspireRightHand.urdf"))
>>> print(get_data_path("InspireHand/inspire_joint_data.csv"))
>>> print(get_data_path("InspireHand/inspire_joint_data.npy"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "InspireHand.zip"),
"c60132a6f03866fb021cca5b6d72845e",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class Robotiq(EmbodiChainDataset):
"""Dataset class for the Robotiq robotic gripper.
Reference:
https://robotiq.com/products/adaptive-grippers#Two-Finger-Gripper
Directory structure:
Robotiq/
robotiq_arg2f_85/
robotiq_arg2f_85.urdf
robotiq_arg2f_140/
robotiq_arg2f_140.urdf
Example usage:
>>> from embodichain.data.eef_dataset import Robotiq
>>> dataset = Robotiq()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("Robotiq/robotiq_arg2f_85/robotiq_arg2f_85.urdf"))
>>> print(get_data_path("Robotiq/robotiq_arg2f_140/robotiq_arg2f_140.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "Robotiq_V2.zip"),
"9bcbf92946b200c903938d59323e7b2c",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class Robotiq2F85(EmbodiChainDataset):
"""Dataset class for the Robotiq 2F85 robotic gripper.
Reference:
https://robotiq.com/products/adaptive-grippers#Two-Finger-Gripper
Directory structure:
Robotiq2F85/
Robotiq2F85.urdf
Example usage:
>>> from embodichain.data.eef_dataset import Robotiq2F85
>>> dataset = Robotiq2F85()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("Robotiq2F85/Robotiq2F85.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "Robotiq2F85.zip"),
"53ecbf2c953f43f1134aa7223e592292",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class WheelTecFA2F(EmbodiChainDataset):
"""Dataset class for the WheelTec FA 2 fingers robotic gripper.
Reference:
https://www.wheeltec.net/
Directory structure:
WheelTecFA2F/
WheelTecFA2F.urdf
Example usage:
>>> from embodichain.data.eef_dataset import WheelTecFA2F
>>> dataset = WheelTecFA2F()
or
>>> from embodichain.data import get_data_path
>>> print(get_data_path("WheelTecFA2F/WheelTecFA2F.urdf"))
"""
[docs]
def __init__(self, data_root: str = None):
data_descriptor = o3d.data.DataDescriptor(
os.path.join(EMBODICHAIN_DOWNLOAD_PREFIX, eef_assets, "WheelTecFA2F.zip"),
"feaf13f25b1c6ce58d011b1f2fa72f58",
)
prefix = type(self).__name__
path = EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root
super().__init__(prefix, data_descriptor, path)
[docs]
class PikaGripper(EmbodiChainDataset):
"""Standalone Pika parallel gripper with visual and collision meshes.
Resolve the URDF with
``get_data_path("PikaGripper/PikaGripper.urdf")``. ``FINGER1_JOINT`` is
actuated over 0–0.05 m (closed to open); ``FINGER2_JOINT`` mimics it.
Mount the asset through ``GRIPPER_ROOT_LINK``.
Args:
data_root: Optional cache root; defaults to ``EMBODICHAIN_DATA_ROOT``.
"""
[docs]
def __init__(self, data_root: str | None = None) -> None:
filename = f"{eef_assets}/PikaGripper.zip"
hub_prefix = (
"https://huggingface.co/datasets/DexForceAI/embodichain_data/resolve/main/"
)
urls = [f"{EMBODICHAIN_DOWNLOAD_PREFIX}{filename}"]
# New assets may precede mirror synchronization.
if EMBODICHAIN_DOWNLOAD_PREFIX != hub_prefix:
urls.append(f"{hub_prefix}{filename}")
descriptor = o3d.data.DataDescriptor(urls, "8a9d0779e7dbfa7bf5d4713175df014e")
super().__init__(
type(self).__name__,
descriptor,
EMBODICHAIN_DEFAULT_DATA_ROOT if data_root is None else data_root,
)