Metadata-Version: 2.4
Name: dexmotion
Version: 0.4.0
Author-email: Dexmate <contact@dexmate.ai>
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: Robot Framework :: Library
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: <3.14,>=3.10
Description-Content-Type: text/markdown
Requires-Dist: tqdm>=4.67.1
Requires-Dist: ruckig>=0.14.0
Requires-Dist: toppra>=0.6.0
Requires-Dist: pyyaml
Requires-Dist: loguru
Requires-Dist: rich>=13.9.4
Requires-Dist: numpy>=2.0.0
Requires-Dist: tyro
Requires-Dist: setuptools>=68.0.0
Requires-Dist: hydra-core
Requires-Dist: pink-dm-fork
Requires-Dist: dexmate-urdf>=0.5.2
Requires-Dist: casadi
Requires-Dist: viser
Requires-Dist: ruff
Requires-Dist: scipy
Provides-Extra: test
Requires-Dist: pyright; extra == "test"
Requires-Dist: pre-commit; extra == "test"
Requires-Dist: warp-lang>=1.6.0; extra == "test"
Requires-Dist: robot_descriptions>=1.14.0; extra == "test"

<div align="center">
  <h1>🤖 Dexmate Robot Motion Planning API</h1>
</div>

![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)

## 📦 Installation

```shell
pip install dexmotion
```

## 📚 Usage

### 🚀 API Usage Guide

#### Basic Setup

```python
from dexmotion.motion_manager import MotionManager

# Initialize MotionManager
mm = MotionManager()

# Initialize with specific robot type
mm = MotionManager(robot_type = "vega_1")

# Initialize with locked joint regions
mm = MotionManager(robot_type = "vega_1", joint_regions_to_lock=["BASE", "HEAD", "LEFT_HAND", "RIGHT_HAND"])

# Set robot joints (locked or unlocked) before using active joints
initial_config = {
        "L_arm_j1": 0.064,
        "L_arm_j7": 0.03,
        "R_arm_j1": -0.064,
        "torso_j1": 0.42,
        "torso_j2": 0.14,
        "torso_j3": -0.6,
        "head_j1": 0.4,
    }
mm = MotionManager(
        robot_type="vega_1",
        initial_joint_configuration_dict=initial_config,
    )

# Setting custom target frames for dexmotion
mm.target_frames = ["L_ee", "R_arm_j7", "head_l1"]
```

#### Available Robot Types

Dexmotion supports multiple Vega robot variants with different configurations:

**No End Effector:**
- `vega_1` - Full body robot (arms, torso, base, head)
- `vega_1u` - Upper body only (arms, head, no torso/base)
- `vega_1p` - Full body robot variant (arms, torso, base, head)

**Gripper End Effector:**
- `vega_1_gripper` - Full body with gripper hands
- `vega_1u_gripper` - Upper body with gripper hands
- `vega_1p_gripper` - Full body variant with gripper hands

**F5D6 Hand End Effector:**
- `vega_1_f5d6` - Full body with F5D6 dexterous hands
- `vega_1u_f5d6` - Upper body with F5D6 dexterous hands
- `vega_1p_f5d6` - Full body variant with F5D6 dexterous hands

```python
# Example: Initialize with F5D6 hands
mm = MotionManager(robot_type="vega_1_f5d6")

# Example: Initialize upper body variant with grippers
mm = MotionManager(robot_type="vega_1u_gripper")
```

#### Joint Control
```python
# Get current joint positions
joint_pos_dict = mm.get_joint_pos_dict()

# Set joint positions
new_positions = {"L_arm_j1": 0.5, "R_arm_j1": -0.5}
mm.set_joint_pos(new_positions)

# Set joint poses at component level
mm.right_arm.set_joint_pos([-2.5, -0.3, 0.0, 0.0, 0.0, 0.0, 0.0])
mm.torso.set_joint_pos([0.42, 0.14, -0.6])
mm.head.set_joint_pos([0.4, 0.0, 0.0])

# Read full body pose
joint_pos_dict = mm.get_joint_pos_dict()

# Read component pose
updated_head_pos = mm.head.get_joint_pos()
```

#### Forward Kinematics
```python
# Get end-effector poses
poses = mm.fk(["L_ee", "R_ee"])

# Get poses for specific configuration
poses = mm.fk(["L_ee", "R_ee"], qpos=solution)
```

#### End effector control

```python
# Move chosen frame to absolute or realtive pose
mm.right_arm.set_ee_pose(
    right_target_pos, right_target_rot, target_frame="R_arm_j4", relative=True
)

# Move chosen EE about cartesian space
mm.left_arm.move_ee_xyz(np.array([0.0, 0.0, 0.5]))
mm.right_arm.move_ee_rpy(np.array([np.pi / 4, 0.0, 0.0]))
```

#### Inverse Kinematics
```python
# Relative movement IK
solution, collision_status, limits_status = mm.ik(
    target_pos={"L_ee": [0.05, 0.0, 0.02]},
    relative=True,
    type="pink"
)
```

#### Inverse Kinematics with External Obstacle Avoidance
```python
# IK with obstacle avoidance using pink_ext
from dexmotion.configs.ik import LocalPinkExtIKConfig

# Configure external obstacles
obstacle_config = LocalPinkExtIKConfig(
    external_obstacles=[
        {
            "urdf_path": "/path/to/obstacle.urdf",
            "position": [0.5, 0.0, 0.5],
            "orientation": [1.0, 0.0, 0.0, 0.0],
        }
    ]
)

# Initialize with pink_ext solver
mm = MotionManager(
    local_ik_solver_type="pink_ext",
    custom_local_ik_config=obstacle_config
)

# Solve IK avoiding obstacles
solution, collision_status, limits_status = mm.ik(
    target_pos={"L_ee": [0.05, 0.0, 0.02]},
    relative=True,
    type="pink_ext"
)
```

#### Global IK
```python
# Absolute positioning with quaternions
target_configuration_dict, is_in_collision, is_joints_within_limits = mm.global_ik(
    target_pos={"L_ee": [0.4, 0.2, 1.0]},
    target_rot={"L_ee": [1.0, 0.0, 0.0, 0.0]},  # Quaternion [w,x,y,z], RPY [r,p,y]
    type="hybrid"  # "pink", "casadi", or "hybrid"
)

```

#### Motion Planning
```python
# Plan to configuration
waypoints = mm.plan(
    goal_config=goal_config,
    planner_type="ompl"  # "ompl" or "interpolation"
)

# Plan to poses
waypoints = mm.plan(
    goal_pos={"L_ee": [0.1, 0.0, 0.1]},
    target_rot={"L_ee": [3.14, 0.0, 0.0]},
    planner_type="interpolation"
)

### Trajectory Smoothing
smooth_trajectory = mm.smooth_trajectory(
    waypoints=waypoints_qpos,
    method="gaussian",  # "gaussian", "toppra", "ruckig"
    control_frequency=100.0
)

# Extract smoothed data
positions = smooth_trajectory["positions"]
velocities = smooth_trajectory.get("velocities")
```

#### Visualization
```python
# Visualize motion plan
mm.visualize_motion_plan(waypoints, duration=3.0)
```
---

<div align="center">
  <h3>🤝 Ready to build amazing robots?</h3>
  <p>
    <a href="mailto:contact@dexmate.ai">📧 Contact Us</a> •
  </p>
</div>
