Spaces:
Running
Running
/** | |
* SO-100 device configurations | |
* Defines the differences between leader and follower devices | |
* Mirrors Python lerobot device configuration approach | |
*/ | |
import type { SO100CalibrationConfig } from "../types/calibration.js"; | |
import { SerialPort } from "serialport"; | |
/** | |
* Common motor names for all SO-100 devices | |
*/ | |
const SO100_MOTOR_NAMES = [ | |
"shoulder_pan", | |
"shoulder_lift", | |
"elbow_flex", | |
"wrist_flex", | |
"wrist_roll", | |
"gripper", | |
]; | |
/** | |
* Common motor IDs for all SO-100 devices (STS3215 servos) | |
*/ | |
const SO100_MOTOR_IDS = [1, 2, 3, 4, 5, 6]; | |
/** | |
* Protocol configuration for STS3215 motors used in SO-100 devices | |
*/ | |
interface STS3215Protocol { | |
resolution: number; | |
homingOffsetAddress: number; | |
homingOffsetLength: number; | |
presentPositionAddress: number; | |
presentPositionLength: number; | |
minPositionLimitAddress: number; | |
minPositionLimitLength: number; | |
maxPositionLimitAddress: number; | |
maxPositionLimitLength: number; | |
signMagnitudeBit: number; // Bit 11 is sign bit for Homing_Offset encoding | |
} | |
/** | |
* STS3215 Protocol Configuration | |
* These addresses and settings are specific to the STS3215 servo motors | |
*/ | |
export const STS3215_PROTOCOL: STS3215Protocol = { | |
resolution: 4096, // 12-bit resolution (0-4095) | |
homingOffsetAddress: 31, // Address for Homing_Offset register | |
homingOffsetLength: 2, // 2 bytes for Homing_Offset | |
presentPositionAddress: 56, // Address for Present_Position register | |
presentPositionLength: 2, // 2 bytes for Present_Position | |
minPositionLimitAddress: 9, // Address for Min_Position_Limit register | |
minPositionLimitLength: 2, // 2 bytes for Min_Position_Limit | |
maxPositionLimitAddress: 11, // Address for Max_Position_Limit register | |
maxPositionLimitLength: 2, // 2 bytes for Max_Position_Limit | |
signMagnitudeBit: 11, // Bit 11 is sign bit for Homing_Offset encoding | |
} as const; | |
/** | |
* SO-100 Follower Configuration | |
* Robot arm that performs tasks autonomously | |
* Drive modes match Python lerobot exactly: all motors use drive_mode=0 | |
*/ | |
export function createSO100FollowerConfig( | |
port: SerialPort | |
): SO100CalibrationConfig { | |
return { | |
deviceType: "so100_follower", | |
port, | |
motorNames: SO100_MOTOR_NAMES, | |
motorIds: SO100_MOTOR_IDS, | |
protocol: STS3215_PROTOCOL, | |
// Python lerobot uses drive_mode=0 for all motors (current format) | |
driveModes: [0, 0, 0, 0, 0, 0], | |
// Calibration modes (not used in current implementation, but kept for compatibility) | |
calibModes: ["DEGREE", "DEGREE", "DEGREE", "DEGREE", "DEGREE", "LINEAR"], | |
// Follower limits - these are not used in calibration file format | |
limits: { | |
position_min: [-180, -90, -90, -90, -90, -90], | |
position_max: [180, 90, 90, 90, 90, 90], | |
velocity_max: [100, 100, 100, 100, 100, 100], | |
torque_max: [50, 50, 50, 50, 25, 25], | |
}, | |
}; | |
} | |
/** | |
* SO-100 Leader Configuration | |
* Teleoperator arm that humans use to control the follower | |
* Drive modes match Python lerobot exactly: all motors use drive_mode=0 | |
*/ | |
export function createSO100LeaderConfig( | |
port: SerialPort | |
): SO100CalibrationConfig { | |
return { | |
deviceType: "so100_leader", | |
port, | |
motorNames: SO100_MOTOR_NAMES, | |
motorIds: SO100_MOTOR_IDS, | |
protocol: STS3215_PROTOCOL, | |
// Python lerobot uses drive_mode=0 for all motors (current format) | |
driveModes: [0, 0, 0, 0, 0, 0], | |
// Same calibration modes as follower | |
calibModes: ["DEGREE", "DEGREE", "DEGREE", "DEGREE", "DEGREE", "LINEAR"], | |
// Leader limits - these are not used in calibration file format | |
limits: { | |
position_min: [-120, -60, -60, -60, -180, -45], | |
position_max: [120, 60, 60, 60, 180, 45], | |
velocity_max: [80, 80, 80, 80, 120, 60], | |
torque_max: [30, 30, 30, 30, 20, 15], | |
}, | |
}; | |
} | |
/** | |
* Get configuration for any SO-100 device type | |
*/ | |
export function getSO100Config( | |
deviceType: "so100_follower" | "so100_leader", | |
port: SerialPort | |
): SO100CalibrationConfig { | |
switch (deviceType) { | |
case "so100_follower": | |
return createSO100FollowerConfig(port); | |
case "so100_leader": | |
return createSO100LeaderConfig(port); | |
default: | |
throw new Error(`Unknown SO-100 device type: ${deviceType}`); | |
} | |
} | |