Adding power and brightness ramping back in
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
63f1c10fcc
commit
5fde49c0c2
@ -44,6 +44,7 @@ export class AbsoluteMotor extends TachoMotor {
|
||||
if (this.isWeDo2SmartHub) {
|
||||
throw new Error("Absolute positioning is not available on the WeDo 2.0 Smart Hub");
|
||||
}
|
||||
this.cancelEventTimer();
|
||||
return new Promise((resolve) => {
|
||||
this._busy = true;
|
||||
if (speed === undefined || speed === null) {
|
||||
@ -78,6 +79,7 @@ export class AbsoluteMotor extends TachoMotor {
|
||||
if (this.isWeDo2SmartHub) {
|
||||
throw new Error("Absolute positioning is not available on the WeDo 2.0 Smart Hub");
|
||||
}
|
||||
this.cancelEventTimer();
|
||||
return new Promise((resolve) => {
|
||||
this._busy = true;
|
||||
let message;
|
||||
@ -97,6 +99,7 @@ export class AbsoluteMotor extends TachoMotor {
|
||||
}
|
||||
|
||||
public async calibrateServo () {
|
||||
this.cancelEventTimer();
|
||||
const oldMode = this.mode;
|
||||
let currentAngle = 0;
|
||||
const listener = ({ angle }: { angle: number }) => {
|
||||
@ -142,6 +145,7 @@ export class AbsoluteMotor extends TachoMotor {
|
||||
}
|
||||
|
||||
public async resetServo (angle: number) {
|
||||
this.cancelEventTimer();
|
||||
const oldMode = this.mode;
|
||||
let currentAngle = 0;
|
||||
const listener = ({ angle }: { angle: number }) => {
|
||||
|
@ -4,7 +4,7 @@ import { IDeviceInterface } from "../interfaces";
|
||||
|
||||
import * as Consts from "../consts";
|
||||
|
||||
import { mapSpeed } from "../utils";
|
||||
import { calculateRamp, mapSpeed } from "../utils";
|
||||
|
||||
export class BasicMotor extends Device {
|
||||
|
||||
@ -20,7 +20,10 @@ export class BasicMotor extends Device {
|
||||
* @param {number} power For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0.
|
||||
* @returns {Promise} Resolved upon successful completion of command.
|
||||
*/
|
||||
public setPower (power: number) {
|
||||
public setPower (power: number, interrupt: boolean = true) {
|
||||
if (interrupt) {
|
||||
this.cancelEventTimer();
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
this.writeDirect(0x00, Buffer.from([mapSpeed(power)]));
|
||||
return resolve();
|
||||
@ -28,12 +31,33 @@ export class BasicMotor extends Device {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ramp the motor power.
|
||||
* @method BasicMotor#rampPower
|
||||
* @param {number} fromPower For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0.
|
||||
* @param {number} toPower For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0.
|
||||
* @param {number} time How long the ramp should last (in milliseconds).
|
||||
* @returns {Promise} Resolved upon successful completion of command.
|
||||
*/
|
||||
public rampPower (fromPower: number, toPower: number, time: number) {
|
||||
this.cancelEventTimer();
|
||||
return new Promise((resolve) => {
|
||||
calculateRamp(this, fromPower, toPower, time)
|
||||
.on("changePower", (power) => {
|
||||
this.setPower(power, false);
|
||||
})
|
||||
.on("finished", resolve);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the motor.
|
||||
* @method BasicMotor#stop
|
||||
* @returns {Promise} Resolved upon successful completion of command.
|
||||
*/
|
||||
public stop () {
|
||||
this.cancelEventTimer();
|
||||
return this.setPower(0);
|
||||
}
|
||||
|
||||
@ -44,6 +68,7 @@ export class BasicMotor extends Device {
|
||||
* @returns {Promise} Resolved upon successful completion of command.
|
||||
*/
|
||||
public brake () {
|
||||
this.cancelEventTimer();
|
||||
return this.setPower(127);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ export class Device extends EventEmitter {
|
||||
|
||||
private _isWeDo2SmartHub: boolean;
|
||||
private _isVirtualPort: boolean = false;
|
||||
private _eventTimer: NodeJS.Timer | null = null;
|
||||
|
||||
constructor (hub: IDeviceInterface, portId: number, modeMap: {[event: string]: number} = {}, type: Consts.DeviceType = Consts.DeviceType.UNKNOWN) {
|
||||
super();
|
||||
@ -136,6 +137,17 @@ export class Device extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
public setEventTimer (timer: NodeJS.Timer) {
|
||||
this._eventTimer = timer;
|
||||
}
|
||||
|
||||
public cancelEventTimer () {
|
||||
if (this._eventTimer) {
|
||||
clearTimeout(this._eventTimer);
|
||||
this._eventTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private _ensureConnected () {
|
||||
if (!this.connected) {
|
||||
throw new Error("Device is not connected");
|
||||
|
@ -3,6 +3,7 @@ import { Device } from "./device";
|
||||
import { IDeviceInterface } from "../interfaces";
|
||||
|
||||
import * as Consts from "../consts";
|
||||
import { calculateRamp } from "../utils";
|
||||
|
||||
export class Light extends Device {
|
||||
|
||||
@ -14,11 +15,14 @@ export class Light extends Device {
|
||||
|
||||
/**
|
||||
* Set the light brightness.
|
||||
* @method Light#brightness
|
||||
* @method Light#setBrightness
|
||||
* @param {number} brightness Brightness value between 0-100 (0 is off)
|
||||
* @returns {Promise} Resolved upon successful completion of command.
|
||||
*/
|
||||
public setBrightness (brightness: number) {
|
||||
public setBrightness (brightness: number, interrupt: boolean = true) {
|
||||
if (interrupt) {
|
||||
this.cancelEventTimer();
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
this.writeDirect(0x00, Buffer.from([brightness]));
|
||||
return resolve();
|
||||
@ -26,4 +30,24 @@ export class Light extends Device {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ramp the light brightness.
|
||||
* @method Light#rampBrightness
|
||||
* @param {number} fromBrightness Brightness value between 0-100 (0 is off)
|
||||
* @param {number} toBrightness Brightness value between 0-100 (0 is off)
|
||||
* @param {number} time How long the ramp should last (in milliseconds).
|
||||
* @returns {Promise} Resolved upon successful completion of command.
|
||||
*/
|
||||
public rampBrightness (fromBrightness: number, toBrightness: number, time: number) {
|
||||
this.cancelEventTimer();
|
||||
return new Promise((resolve) => {
|
||||
calculateRamp(this, fromBrightness, toBrightness, time)
|
||||
.on("changePower", (power) => {
|
||||
this.setBrightness(power, false);
|
||||
})
|
||||
.on("finished", resolve);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ export class TachoMotor extends BasicMotor {
|
||||
if (this.isWeDo2SmartHub) {
|
||||
throw new Error("Motor speed is not available on the WeDo 2.0 Smart Hub");
|
||||
}
|
||||
this.cancelEventTimer();
|
||||
return new Promise((resolve) => {
|
||||
this._busy = true;
|
||||
if (speed === undefined || speed === null) {
|
||||
@ -81,6 +82,7 @@ export class TachoMotor extends BasicMotor {
|
||||
if (this.isWeDo2SmartHub) {
|
||||
throw new Error("Rotation is not available on the WeDo 2.0 Smart Hub");
|
||||
}
|
||||
this.cancelEventTimer();
|
||||
return new Promise((resolve) => {
|
||||
this._busy = true;
|
||||
if (speed === undefined || speed === null) {
|
||||
|
33
src/utils.ts
33
src/utils.ts
@ -1,3 +1,6 @@
|
||||
import { EventEmitter } from "events";
|
||||
import { Device } from "./devices/device";
|
||||
|
||||
// @ts-ignore
|
||||
export const isWebBluetooth = (typeof navigator !== "undefined" && navigator && navigator.bluetooth);
|
||||
|
||||
@ -55,3 +58,33 @@ export const roundAngleToNearest90 = (angle: number) => {
|
||||
}
|
||||
return -180;
|
||||
};
|
||||
|
||||
export const calculateRamp = (device: Device, fromPower: number, toPower: number, time: number) => {
|
||||
const emitter = new EventEmitter();
|
||||
const steps = Math.abs(toPower - fromPower);
|
||||
let delay = time / steps;
|
||||
let increment = 1;
|
||||
if (delay < 50 && steps > 0) {
|
||||
increment = 50 / delay;
|
||||
delay = 50;
|
||||
}
|
||||
if (fromPower > toPower) {
|
||||
increment = -increment;
|
||||
}
|
||||
let i = 0;
|
||||
const interval = setInterval(() => {
|
||||
let power = Math.round(fromPower + (++i * increment));
|
||||
if (toPower > fromPower && power > toPower) {
|
||||
power = toPower;
|
||||
} else if (fromPower > toPower && power < toPower) {
|
||||
power = toPower;
|
||||
}
|
||||
emitter.emit("changePower", power);
|
||||
if (power === toPower) {
|
||||
clearInterval(interval);
|
||||
emitter.emit("finished");
|
||||
}
|
||||
}, delay);
|
||||
device.setEventTimer(interval);
|
||||
return emitter;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user