---
sidebar_position: 5
title: Software API
# draft: true
---

## `get_a1z_robot()`

Factory function that creates a configured `ArmRobot` instance:

```python
get_a1z_robot(
    can_channel="can0",           # CAN channel name
    gravity_comp_factor=1.0,      # Gravity compensation factor (0=off, 1=full compensation)
    zero_gravity_mode=True,       # True=zero-force floating, False=position holding
    control_freq_hz=250,          # Control loop frequency (Hz)
    urdf_path=None,               # Override URDF path
    default_kp=None,              # Override default position gain
    default_kd=None,              # Override default velocity gain
) -> ArmRobot
```

## Main `ArmRobot` Methods

<table style="width: 100%; border-collapse: collapse;">
    <thead>
        <tr style="text-align: left;">
            <th style="width: 500px; padding: 8px; border: 1px solid #ddd;">Method</th>
            <th style="width: 500px; padding: 8px; border: 1px solid #ddd;">Description</th>
        </tr>
    </thead>
    <tbody>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">start(initial_kp, initial_kd)</td>
            <td style="padding: 8px; border: 1px solid #ddd;">Enables the motors and starts the control loop.</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">stop()</td>
            <td style="padding: 8px; border: 1px solid #ddd;">Performs a smooth shutdown with 0.3s decay, then disables the motors.</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">get_joint_pos() -&gt; np.ndarray</td>
            <td style="padding: 8px; border: 1px solid #ddd;">Gets the current joint angles (rad).</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">get_joint_state() -&gt; dict</td>
            <td style="padding: 8px; border: 1px solid #ddd;">Gets {`pos`, `vel`, `eff`}.</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">command_joint_pos(pos)</td>
            <td style="padding: 8px; border: 1px solid #ddd;">Sets target joint angles using the default PD gains.</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">command_joint_state(joint_state)</td>
            <td style="padding: 8px; border: 1px solid #ddd;">Sets target joint angles with custom gains.</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">move_joints(target, speed, kp, kd)</td>
            <td style="padding: 8px; border: 1px solid #ddd;">Moves to the target position with linear interpolation (blocking).</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">is_running</td>
            <td style="padding: 8px; border: 1px solid #ddd;">Indicates whether the control loop is running.</td>
        </tr>
    </tbody>
</table>

## `Kinematics`

```python
from a1z.robots.kinematics import Kinematics

kin = Kinematics("/path/to/urdf")

# Forward kinematics -> 4x4 homogeneous transformation matrix
T = kin.fk(q)

# Inverse kinematics (damped least squares)
converged, q_sol = kin.ik(target_pose, init_q=q0)
```

## Joint Limits

<table style="width: 100%; border-collapse: collapse">
    <thead>
        <tr style="text-align: left">
            <th style="width: 300px; padding: 8px; border: 1px solid #ddd">Joint</th>
            <th style="width: 200px; padding: 8px; border: 1px solid #ddd">Name</th>
            <th style="width: 200px; padding: 8px; border: 1px solid #ddd">Mechanical Limit (deg)</th>
            <th style="width: 200px; padding: 8px; border: 1px solid #ddd">Mechanical Limit (rad)</th>
            <th style="width: 200px; padding: 8px; border: 1px solid #ddd">Soft Limit (deg)</th>
            <th style="width: 600px; padding: 8px; border: 1px solid #ddd">Soft Limit (rad)</th>
        </tr>
    </thead>
    <tbody>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">0</td>
            <td style="padding: 8px; border: 1px solid #ddd">arm_joint1</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-130°, 130°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-2.269, 2.269]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-120°, 120°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-2.094, 2.094]</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">1</td>
            <td style="padding: 8px; border: 1px solid #ddd">arm_joint2</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-1.94°, 192.78°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-0.034, 3.365]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[0°, 180°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[0.000, 3.142]</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">2</td>
            <td style="padding: 8px; border: 1px solid #ddd">arm_joint3</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-200.38°, 0°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-3.497, 0.000]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-180°, 0°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-3.142, 0]</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">3</td>
            <td style="padding: 8px; border: 1px solid #ddd">arm_joint4</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-91.88°, 110.38°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-1.604, 1.926]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-85°, 85°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-1.484, 1.484]</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">4</td>
            <td style="padding: 8px; border: 1px solid #ddd">arm_joint5</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-90°, 90°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-1.571, 1.571]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-90°, 90°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-1.484, 1.484]</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">5</td>
            <td style="padding: 8px; border: 1px solid #ddd">arm_joint6</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-120°, 120°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-2.094, 2.094]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-115°, 115°]</td>
            <td style="padding: 8px; border: 1px solid #ddd">[-2.007, 2.007]</td>
        </tr>
    </tbody>
</table>

## Default Control Parameters

<table style="width: 100%; border-collapse: collapse">
    <thead>
        <tr style="text-align: left">
            <th style="width: 500px; padding: 8px; border: 1px solid #ddd">Control Item</th>
            <th style="width: 500px; padding: 8px; border: 1px solid #ddd">Parameter Value</th>
        </tr>
    </thead>
    <tbody>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">Default KP</td>
            <td style="padding: 8px; border: 1px solid #ddd">[30, 30, 30, 20, 5, 5]</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">Default KD</td>
            <td style="padding: 8px; border: 1px solid #ddd">[1, 1, 1, 0.5, 0.5, 0.5]</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">Joint Coordinate Sign</td>
            <td style="padding: 8px; border: 1px solid #ddd">[1, 1, -1, 1, 1, 1] (joint 3 is opposite to the URDF direction)</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">Gravity Torque Scale</td>
            <td style="padding: 8px; border: 1px solid #ddd">[1, 1, 1, 1, 1, 1]</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">Maximum Gravity Torque</td>
            <td style="padding: 8px; border: 1px solid #ddd">[50, 50, 50, 24, 10, 10] Nm</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">Torque Limit</td>
            <td style="padding: 8px; border: 1px solid #ddd">[70, 70, 70, 27, 10, 10] Nm</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">MotorA KT</td>
            <td style="padding: 8px; border: 1px solid #ddd">2.8 (current-to-torque conversion factor)</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">Control Frequency</td>
            <td style="padding: 8px; border: 1px solid #ddd">250 Hz</td>
        </tr>
    </tbody>
</table>

## Control Principles

### 1. MIT Hybrid Force-Position Control

The motor firmware executes:

```bash
τ_motor = kp × (pos_target - pos_actual) + kd × (vel_target - vel_actual) + τ_ff
```

The SDK executes the following at each control cycle (250 Hz by default):

1. Reads feedback from all motors over the CAN bus.
2. Uses Pinocchio RNEA to calculate the gravity compensation torque `τ_g(q)` for the current posture.
3. Performs safety checks: if `|τ_g|` exceeds the threshold, an emergency stop is triggered.
4. Composes the final torque: `τ_motor = (user_torque + τ_g × scale × factor) × joint_sign`.
5. Clips the torque to the safe range and sends it to the motors.

### 2. Zero-Force Floating Mode

`kp=0, kd=small value`. The arm uses gravity compensation torque only to offset gravity, so it can be freely dragged.

### 3. Position Holding Mode

`kp=default gain, kd=default gain`. PD control is combined with gravity compensation.

## Notes

- For first-time use, set `gravity_comp_factor` to a small value, such as 0.3. After confirming that the compensation direction is correct, increase it gradually.
- The system automatically triggers an emergency stop when gravity torque exceeds the safety threshold for any joint.
- During shutdown, gravity compensation decays smoothly within 0.3s and damping is increased to prevent the arm from dropping suddenly after motor disable.
- All target joint angles are clipped to the URDF limit range.
