rxpoweredup
Version:
A Typescript RxJS-based library for controlling LEGO Powered UP hubs & peripherals.
202 lines (201 loc) • 11.4 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { inject, injectable } from 'tsyringe';
import { MOTOR_ACC_DEC_DEFAULT_PROFILE_ID, MOTOR_LIMITS, MessageType, MotorServoEndState, MotorUseProfile, OutputSubCommand, PortModeName, PortOperationCompletionInformation, PortOperationStartupInformation, WELL_KNOWN_PORT_MODE_IDS, } from '../../constants';
import { concatUintArraysToUint8Array, numberToUint16LEArray, numberToUint32LEArray } from '../../helpers';
import { WriteDirectModeDataBuilder } from './write-direct-mode-data-builder';
let PortOutputCommandOutboundMessageFactory = class PortOutputCommandOutboundMessageFactory {
writeDirectModeDataBuilder;
constructor(writeDirectModeDataBuilder) {
this.writeDirectModeDataBuilder = writeDirectModeDataBuilder;
}
startPower(portId, power, powerModeId = WELL_KNOWN_PORT_MODE_IDS.motor[PortModeName.power], startupMode = PortOperationStartupInformation.executeImmediately, completionMode = PortOperationCompletionInformation.commandFeedback) {
this.ensureLpfPowerIsWithinLimits(power);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId,
payload: this.writeDirectModeDataBuilder.buildWriteDirectModeData({
portId,
startupInformation: startupMode ?? PortOperationStartupInformation.executeImmediately,
completionInformation: completionMode ?? PortOperationCompletionInformation.commandFeedback,
modeId: powerModeId,
payload: [power],
}),
waitForFeedback: completionMode === PortOperationCompletionInformation.commandFeedback,
};
}
startSpeed(portId, speed, power = MOTOR_LIMITS.maxPower, profile = MotorUseProfile.dontUseProfiles, startupMode = PortOperationStartupInformation.executeImmediately, completionMode = PortOperationCompletionInformation.commandFeedback) {
this.ensureSpeedIsWithinLimits(speed);
this.ensurePowerIsWithinLimits(power);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId,
payload: new Uint8Array([portId, startupMode | completionMode, OutputSubCommand.startSpeed, speed, power, profile]),
waitForFeedback: completionMode === PortOperationCompletionInformation.commandFeedback,
};
}
startRotationSynchronized(virtualPortId, speed1, speed2, power = MOTOR_LIMITS.maxPower, useProfile = MotorUseProfile.dontUseProfiles, startupMode = PortOperationStartupInformation.executeImmediately, completionMode = PortOperationCompletionInformation.commandFeedback) {
this.ensureSpeedIsWithinLimits(speed1);
this.ensureSpeedIsWithinLimits(speed2);
this.ensurePowerIsWithinLimits(power);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId: virtualPortId,
payload: new Uint8Array([virtualPortId, startupMode | completionMode, OutputSubCommand.startSpeedSynchronized, speed1, speed2, power, useProfile]),
waitForFeedback: completionMode === PortOperationCompletionInformation.commandFeedback,
};
}
goToAbsolutePosition(portId, absolutePosition, speed = MOTOR_LIMITS.maxSpeed, power = MOTOR_LIMITS.maxPower, endState = MotorServoEndState.hold, profile = MotorUseProfile.dontUseProfiles, startupMode = PortOperationStartupInformation.executeImmediately, completionMode = PortOperationCompletionInformation.commandFeedback) {
this.ensureSpeedIsWithinLimits(speed);
this.ensurePowerIsWithinLimits(power);
this.ensureAbsolutePositionIsWithinLimits(absolutePosition);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId,
payload: new Uint8Array([
portId,
startupMode | completionMode,
OutputSubCommand.gotoAbsolutePosition,
...numberToUint32LEArray(absolutePosition),
speed,
power,
endState,
profile,
]),
waitForFeedback: completionMode === PortOperationCompletionInformation.commandFeedback,
};
}
startSpeedForDegrees(portId, degree, speed = MOTOR_LIMITS.maxSpeed, power = MOTOR_LIMITS.maxPower, endState = MotorServoEndState.hold, useProfile = MotorUseProfile.dontUseProfiles, startupMode = PortOperationStartupInformation.executeImmediately, completionMode = PortOperationCompletionInformation.commandFeedback) {
this.ensureSpeedIsWithinLimits(speed);
this.ensurePowerIsWithinLimits(power);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId,
payload: new Uint8Array([
portId,
startupMode | completionMode,
OutputSubCommand.startSpeedForDegrees,
...numberToUint32LEArray(degree),
speed,
power,
endState,
useProfile,
]),
waitForFeedback: completionMode === PortOperationCompletionInformation.commandFeedback,
};
}
goToAbsolutePositionSynchronized(virtualPortId, absolutePosition1, absolutePosition2, speed = MOTOR_LIMITS.maxSpeed, power = MOTOR_LIMITS.maxPower, endState = MotorServoEndState.hold, useProfile = MotorUseProfile.dontUseProfiles, startupMode = PortOperationStartupInformation.executeImmediately, completionMode = PortOperationCompletionInformation.commandFeedback) {
this.ensureAbsolutePositionIsWithinLimits(absolutePosition1);
this.ensureAbsolutePositionIsWithinLimits(absolutePosition2);
this.ensureSpeedIsWithinLimits(speed);
this.ensurePowerIsWithinLimits(power);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId: virtualPortId,
payload: new Uint8Array([
virtualPortId,
startupMode | completionMode,
OutputSubCommand.gotoAbsolutePositionSynchronized,
...numberToUint32LEArray(absolutePosition1),
...numberToUint32LEArray(absolutePosition2),
speed,
power,
endState,
useProfile,
]),
waitForFeedback: completionMode === PortOperationCompletionInformation.commandFeedback,
};
}
presetEncoder(portId, absolutePosition, positionModeId) {
this.ensureAbsolutePositionIsWithinLimits(absolutePosition);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId,
payload: this.writeDirectModeDataBuilder.buildWriteDirectModeData({
portId,
startupInformation: PortOperationStartupInformation.bufferIfNecessary,
completionInformation: PortOperationCompletionInformation.commandFeedback,
modeId: positionModeId,
payload: numberToUint32LEArray(absolutePosition),
}),
waitForFeedback: true,
};
}
setAccelerationTime(portId, timeMs, profileId = MOTOR_ACC_DEC_DEFAULT_PROFILE_ID, startupMode = PortOperationStartupInformation.bufferIfNecessary, completionMode = PortOperationCompletionInformation.commandFeedback) {
this.ensureAccDecTimeIsWithinLimits(timeMs);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId,
payload: concatUintArraysToUint8Array(new Uint8Array([portId, startupMode | completionMode, OutputSubCommand.setAccTime]), new Uint16Array(numberToUint16LEArray(timeMs)), new Uint8Array([profileId])),
waitForFeedback: completionMode === PortOperationCompletionInformation.commandFeedback,
};
}
setDecelerationTime(portId, timeMs, profileId = MOTOR_ACC_DEC_DEFAULT_PROFILE_ID, startupMode = PortOperationStartupInformation.bufferIfNecessary, completionMode = PortOperationCompletionInformation.commandFeedback) {
this.ensureAccDecTimeIsWithinLimits(timeMs);
return {
header: {
messageType: MessageType.portOutputCommand,
},
portId,
payload: concatUintArraysToUint8Array(new Uint8Array([portId, startupMode | completionMode, OutputSubCommand.setDecTime]), new Uint16Array(numberToUint16LEArray(timeMs)), new Uint8Array([profileId])),
waitForFeedback: completionMode === PortOperationCompletionInformation.commandFeedback,
};
}
ensureAccDecTimeIsWithinLimits(timeMs) {
if (timeMs > MOTOR_LIMITS.maxAccDecTime || timeMs < MOTOR_LIMITS.minAccDecTime) {
throw new Error(`Acceleration/deceleration time must be between ${MOTOR_LIMITS.minAccDecTime} and ${MOTOR_LIMITS.maxAccDecTime}. Got ${timeMs}`);
}
}
ensureSpeedIsWithinLimits(speed) {
if (speed > MOTOR_LIMITS.maxSpeed || speed < MOTOR_LIMITS.minSpeed) {
throw new Error(`Speed must be between ${MOTOR_LIMITS.minSpeed} and ${MOTOR_LIMITS.maxSpeed}. Got ${speed}`);
}
}
ensurePowerIsWithinLimits(power) {
if (power > MOTOR_LIMITS.maxPower || power < MOTOR_LIMITS.minPower) {
throw new Error(`Power must be between ${MOTOR_LIMITS.minPower} and ${MOTOR_LIMITS.maxPower}. Got ${power}`);
}
}
ensureLpfPowerIsWithinLimits(power) {
if (Math.abs(power) > MOTOR_LIMITS.maxPower) {
throw new Error(`Power must be between -${MOTOR_LIMITS.maxPower} and ${MOTOR_LIMITS.maxPower}. Got ${power}`);
}
}
ensureAbsolutePositionIsWithinLimits(absolutePosition) {
if (absolutePosition > MOTOR_LIMITS.maxRawAngle || absolutePosition < MOTOR_LIMITS.minRawAngle) {
throw new Error(`Absolute position must be between ${MOTOR_LIMITS.minRawAngle} and ${MOTOR_LIMITS.maxRawAngle}. Got ${absolutePosition}`);
}
}
};
PortOutputCommandOutboundMessageFactory = __decorate([
injectable(),
__param(0, inject(WriteDirectModeDataBuilder)),
__metadata("design:paramtypes", [WriteDirectModeDataBuilder])
], PortOutputCommandOutboundMessageFactory);
export { PortOutputCommandOutboundMessageFactory };