---
sidebar_position: 5
title: 软件接口
# draft: true
---
## `get_a1z_robot()`

工厂函数，创建配置好的 ArmRobot 实例：
```python
get_a1z_robot(
    can_channel="can0",           # CAN 通道名
    gravity_comp_factor=1.0,      # 重力补偿比例 (0=关闭, 1=全补偿)
    zero_gravity_mode=True,       # True=零力漂浮, False=位置保持
    control_freq_hz=250,          # 控制回路频率 (Hz)
    urdf_path=None,               # 覆盖 URDF 路径
    default_kp=None,              # 覆盖默认位置增益
    default_kd=None,              # 覆盖默认速度增益
) -> ArmRobot
```

## `ArmRobot` 主要方法

<table style="width: 100%; border-collapse: collapse;">
    <thead>
        <tr style="text-align: left;">
            <th style="width: 500px; padding: 8px; border: 1px solid #ddd;">方法</th>
            <th style="width: 500px; padding: 8px; border: 1px solid #ddd;">说明</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;">使能电机，启动控制回路</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;">平滑停机（0.3s 衰减），失能电机</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">get_joint_pos() -> np.ndarray</td>
            <td style="padding: 8px; border: 1px solid #ddd;">获取当前关节角 (rad)</td>
        </tr>
        <tr style="text-align: left;">
            <td style="padding: 8px; border: 1px solid #ddd;">get_joint_state() -> dict</td>
            <td style="padding: 8px; border: 1px solid #ddd;">获取 {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;">设置目标关节角（使用默认 PD 增益）</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;">设置目标关节角 + 自定义增益</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;">线性插值移动到目标位置（阻塞）</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;">控制回路是否在运行</td>
        </tr>
    </tbody>
</table>

## `Kinematics` 运动学

```python
from a1z.robots.kinematics import Kinematics

kin = Kinematics("/path/to/urdf")

# 正运动学 → 4x4 齐次变换矩阵
T = kin.fk(q)

# 逆运动学 (阻尼最小二乘)
converged, q_sol = kin.ik(target_pose, init_q=q0)
```

## 关节限位

<table style="width: 100%; border-collapse: collapse">
    <thead>
        <tr style="text-align: left">
            <th style="width: 300px; padding: 8px; border: 1px solid #ddd">关节 </th>
            <th style="width: 200px; padding: 8px; border: 1px solid #ddd">名称</th>
            <th style="width: 200px; padding: 8px; border: 1px solid #ddd">机械限位 (°)</th>
            <th style="width: 200px; padding: 8px; border: 1px solid #ddd">机械限位 (rad)</th>
            <th style="width: 200px; padding: 8px; border: 1px solid #ddd">软限位 (°)</th>
            <th style="width: 600px; padding: 8px; border: 1px solid #ddd">软限位 (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>



## 默认控制参数

<table style="width: 100%; border-collapse: collapse">
    <thead>
        <tr style="text-align: left">
            <th style="width: 500px; padding: 8px; border: 1px solid #ddd">控制项</th>
            <th style="width: 500px; padding: 8px; border: 1px solid #ddd">参数值</th>
        </tr>
    </thead>
    <tbody>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">默认 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">默认 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">关节坐标系符号</td>
            <td style="padding: 8px; border: 1px solid #ddd">[1, 1, -1, 1, 1, 1] (关节3与URDF方向相反)</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">重力扭矩缩放</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">最大重力扭矩</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">扭矩限幅</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 (电流→扭矩转换系数)</td>
        </tr>
        <tr style="text-align: left">
            <td style="padding: 8px; border: 1px solid #ddd">控制频率</td>
            <td style="padding: 8px; border: 1px solid #ddd">250 Hz</td>
        </tr>                         
    </tbody>
</table>


## 控制原理
### 1. MIT 力位混控
电机固件执行：
```bash
τ_motor = kp × (pos_target − pos_actual) + kd × (vel_target − vel_actual) + τ_ff
```

SDK在每个控制周期（默认 250 Hz）执行：
1. 从 CAN 总线读取所有电机反馈
2. 通过 Pinocchio RNEA 计算当前姿态下的重力补偿扭矩 τ_g(q)
3. 安全检查：|τ_g| 超过阈值则紧急停止
4. 合成最终扭矩：τ_motor = (user_torque + τ_g × scale × factor) × joint_sign
5. 裁剪到安全范围后下发

### 2. 零力漂浮模式
`kp=0, kd=较小值`，仅靠重力补偿扭矩抵消重力，机械臂可自由拖拽。

### 3. 位置保持模式
`kp=默认增益, kd=默认增益`，PD 控制 + 重力补偿。


## 注意事项

- 首次使用请将 `gravity_comp_factor` 设为较小值（如 0.3），确认补偿方向正确后再逐步增大
- 重力扭矩超过每关节安全阈值时会自动紧急停止
- 停机时会在 0.3s 内平滑衰减重力补偿并增加阻尼，避免突然失能导致机械臂下落
- 所有目标关节角会被裁剪到 URDF 限位范围内