Spaces:
Running
Running
| /** | |
| * Motor Calibration Utilities | |
| * Specialized functions for motor calibration procedures | |
| */ | |
| import { STS3215_PROTOCOL } from "./sts3215-protocol.js"; | |
| import { encodeSignMagnitude } from "./sign-magnitude.js"; | |
| import { | |
| readAllMotorPositions, | |
| writeMotorRegister, | |
| type MotorCommunicationPort, | |
| } from "./motor-communication.js"; | |
| /** | |
| * Reset homing offsets to 0 for all motors | |
| */ | |
| export async function resetHomingOffsets( | |
| port: MotorCommunicationPort, | |
| motorIds: number[] | |
| ): Promise<void> { | |
| for (let i = 0; i < motorIds.length; i++) { | |
| const motorId = motorIds[i]; | |
| try { | |
| const packet = new Uint8Array([ | |
| 0xff, | |
| 0xff, | |
| motorId, | |
| 0x05, | |
| 0x03, | |
| STS3215_PROTOCOL.HOMING_OFFSET_ADDRESS, | |
| 0x00, // Low byte of 0 | |
| 0x00, // High byte of 0 | |
| 0x00, // Checksum | |
| ]); | |
| const checksum = | |
| ~( | |
| motorId + | |
| 0x05 + | |
| 0x03 + | |
| STS3215_PROTOCOL.HOMING_OFFSET_ADDRESS + | |
| 0x00 + | |
| 0x00 | |
| ) & 0xff; | |
| packet[8] = checksum; | |
| await port.write(packet); | |
| try { | |
| await port.read(200); | |
| } catch (error) { | |
| // Silent - response not required | |
| } | |
| } catch (error) { | |
| throw new Error(`Failed to reset homing offset for motor ${motorId}`); | |
| } | |
| } | |
| } | |
| /** | |
| * Write homing offsets to motor registers immediately | |
| */ | |
| export async function writeHomingOffsetsToMotors( | |
| port: MotorCommunicationPort, | |
| motorIds: number[], | |
| motorNames: string[], | |
| homingOffsets: { [motor: string]: number } | |
| ): Promise<void> { | |
| for (let i = 0; i < motorIds.length; i++) { | |
| const motorId = motorIds[i]; | |
| const motorName = motorNames[i]; | |
| const homingOffset = homingOffsets[motorName]; | |
| try { | |
| const encodedOffset = encodeSignMagnitude( | |
| homingOffset, | |
| STS3215_PROTOCOL.SIGN_MAGNITUDE_BIT | |
| ); | |
| const packet = new Uint8Array([ | |
| 0xff, | |
| 0xff, | |
| motorId, | |
| 0x05, | |
| 0x03, | |
| STS3215_PROTOCOL.HOMING_OFFSET_ADDRESS, | |
| encodedOffset & 0xff, | |
| (encodedOffset >> 8) & 0xff, | |
| 0x00, | |
| ]); | |
| const checksum = | |
| ~( | |
| motorId + | |
| 0x05 + | |
| 0x03 + | |
| STS3215_PROTOCOL.HOMING_OFFSET_ADDRESS + | |
| (encodedOffset & 0xff) + | |
| ((encodedOffset >> 8) & 0xff) | |
| ) & 0xff; | |
| packet[8] = checksum; | |
| await port.write(packet); | |
| try { | |
| await port.read(200); | |
| } catch (error) { | |
| // Silent - response not required | |
| } | |
| } catch (error) { | |
| throw new Error(`Failed to write homing offset for ${motorName}`); | |
| } | |
| } | |
| } | |
| /** | |
| * Set homing offsets with immediate writing | |
| */ | |
| export async function setHomingOffsets( | |
| port: MotorCommunicationPort, | |
| motorIds: number[], | |
| motorNames: string[] | |
| ): Promise<{ [motor: string]: number }> { | |
| // Reset existing homing offsets to 0 first | |
| await resetHomingOffsets(port, motorIds); | |
| await new Promise((resolve) => setTimeout(resolve, 100)); | |
| // Read positions (which will be true physical positions) | |
| const currentPositions = await readAllMotorPositions(port, motorIds); | |
| const homingOffsets: { [motor: string]: number } = {}; | |
| const halfTurn = Math.floor((STS3215_PROTOCOL.RESOLUTION - 1) / 2); | |
| for (let i = 0; i < motorNames.length; i++) { | |
| const motorName = motorNames[i]; | |
| const position = currentPositions[i]; | |
| homingOffsets[motorName] = position - halfTurn; | |
| } | |
| // Write homing offsets to motors immediately | |
| await writeHomingOffsetsToMotors(port, motorIds, motorNames, homingOffsets); | |
| return homingOffsets; | |
| } | |
| /** | |
| * Write hardware position limits to motors | |
| */ | |
| export async function writeHardwarePositionLimits( | |
| port: MotorCommunicationPort, | |
| motorIds: number[], | |
| motorNames: string[], | |
| rangeMins: { [motor: string]: number }, | |
| rangeMaxes: { [motor: string]: number } | |
| ): Promise<void> { | |
| for (let i = 0; i < motorIds.length; i++) { | |
| const motorId = motorIds[i]; | |
| const motorName = motorNames[i]; | |
| const minLimit = rangeMins[motorName]; | |
| const maxLimit = rangeMaxes[motorName]; | |
| try { | |
| // Write Min_Position_Limit register | |
| await writeMotorRegister( | |
| port, | |
| motorId, | |
| STS3215_PROTOCOL.MIN_POSITION_LIMIT_ADDRESS, | |
| minLimit | |
| ); | |
| // Write Max_Position_Limit register | |
| await writeMotorRegister( | |
| port, | |
| motorId, | |
| STS3215_PROTOCOL.MAX_POSITION_LIMIT_ADDRESS, | |
| maxLimit | |
| ); | |
| } catch (error) { | |
| throw new Error(`Failed to write position limits for ${motorName}`); | |
| } | |
| } | |
| } | |