Skip to content

Commit

Permalink
ESC: deprecate speed(percent), introduce throttle(us).
Browse files Browse the repository at this point in the history
- Eliminates "history" memory leak
- Deprecates speed()
- Introduces throttle(us)
  • Loading branch information
rwaldron committed Aug 11, 2019
1 parent b3c5df9 commit 0d5ca14
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 291 deletions.
170 changes: 59 additions & 111 deletions lib/esc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var Controllers = {
var state = priv.get(this);

this.address = opts.address || 0x40;
this.pwmRange = opts.pwmRange || [544, 2400];
this.pwmRange = opts.pwmRange || [1000, 2000];
this.frequency = opts.frequency || 50;

state.expander = Expander.get({
Expand All @@ -32,9 +32,9 @@ var Controllers = {
},
write: {
writable: true,
value: function(pin, microseconds) {
value: function(pin, us) {
var state = priv.get(this);
state.expander.servoWrite(pin, microseconds);
state.expander.servoWrite(pin, us);
}
}
},
Expand All @@ -56,20 +56,19 @@ var Controllers = {
},
write: {
writable: true,
value: function(pin, microseconds) {
microseconds |= 0;
this.io.servoWrite(pin, microseconds);
value: function(pin, us) {
this.io.servoWrite(pin, us | 0);
}
}
}
};


var Devices = {
FORWARD: {
deviceName: {
get: function() {
return "FORWARD";
}
value: "FORWARD",
writable: false,
},
dir: {
value: function(speed, dir) {
Expand All @@ -81,9 +80,8 @@ var Devices = {
},
FORWARD_REVERSE: {
deviceName: {
get: function() {
return "FORWARD_REVERSE";
}
value: "FORWARD_REVERSE",
writable: false,
},
dir: {
value: function(speed, dir) {
Expand All @@ -97,9 +95,8 @@ var Devices = {
},
FORWARD_BRAKE_REVERSE: {
deviceName: {
get: function() {
return "FORWARD_BRAKE_REVERSE";
}
value: "FORWARD_BRAKE_REVERSE",
writable: false,
},
dir: {
value: function(speed, dir) {
Expand Down Expand Up @@ -140,14 +137,7 @@ function ESC(opts) {
var pinValue;
var device;
var state = {
// All speed history for this ESC
// history = [
// {
// timestamp: Date.now(),
// speed: speed
// }
// ];
history: [],
last: { speed: null },
value: 0
};

Expand All @@ -157,12 +147,19 @@ function ESC(opts) {

priv.set(this, state);

this.startAt = typeof opts.startAt !== "undefined" ? opts.startAt : null;
this.neutral = opts.neutral;
this.range = opts.range || [0, 100];
this.pwmRange = opts.pwmRange || [544, 2400];
this.pwmRange = opts.pwmRange || [1000, 2000];
this.neutral = opts.neutral || this.pwmRange[0];
this.interval = null;

// Scale to pwm range
if (typeof this.neutral !== "undefined" && this.neutral <= 100) {
this.neutral = Fn.scale(this.neutral, 0, 100, this.pwmRange[0], this.pwmRange[1]);
}

// Enforce pwm range on neutral point
this.neutral = Fn.constrain(this.neutral, this.pwmRange[0], this.pwmRange[1]);

// StandardFirmata on Arduino allows controlling
// servos from analog pins.
// If we're currently operating with an Arduino
Expand Down Expand Up @@ -209,34 +206,22 @@ function ESC(opts) {
return state.value;
}
},
history: {
get: function() {
return state.history.slice(-5);
}
},
last: {
get: function() {
return state.history[state.history.length - 1] || {
last: null
};
return state.last;
}
}
}));

this.initialize(opts);

if (this.deviceName !== "FORWARD") {
if (Number.isNaN(+this.neutral)) {
throw new Error("Directional speed controllers require a neutral point from 0-100 (number)");
if (this.neutral === this.pwmRange[0]) {
throw new Error("Bidirectional speed controllers require a non-zero neutral point");
}

this.startAt = this.neutral;
}

// Match either null or undefined, but not 0
if (this.startAt !== null && this.startAt !== undefined) {
this.speed(this.startAt);
}
this.throttle(this.neutral);
}

util.inherits(ESC, Emitter);
Expand All @@ -249,11 +234,11 @@ util.inherits(ESC, Emitter);
* @param {Float} speed 0...100 (full range)
*
* @return {ESC} instance
* @deprecated Will be deleted in version 1.0.0. Use throttle(us) instead.
*/

ESC.prototype.speed = function(speed) {
/* istanbul ignore next */
ESC.prototype.speed = util.deprecate(function(speed) {
var state = priv.get(this);
var history = state.history;
var noInterval = false;
var steps = 0;
var lspeed, hspeed;
Expand All @@ -263,7 +248,7 @@ ESC.prototype.speed = function(speed) {
if (this.interval) {
// Bail out if speed is the same as whatever was
// last _provided_
if (this.value === speed) {
if (state.value === speed) {
return this;
} else {
clearInterval(this.interval);
Expand All @@ -276,18 +261,18 @@ ESC.prototype.speed = function(speed) {
// This is the very first speed command being received.
// Safe to assume that the ESC and Brushless motor are
// not yet moving.
if (history.length === 0) {
if (state.last.speed === null) {
noInterval = true;
state.last.speed = this.neutral;
} else {
// Bail out if speed is the same as whatever was
// last _written_
if (state.last.speed === speed) {
return this;
}
}

// Bail out if speed is the same as whatever was
// last _written_

if (this.last.speed === speed) {
return this;
}

lspeed = this.last.speed;
lspeed = state.last.speed;
hspeed = speed;
steps = Math.ceil(Math.abs(lspeed - hspeed));

Expand All @@ -298,10 +283,7 @@ ESC.prototype.speed = function(speed) {
if (noInterval) {
this.write(this.pin, Fn.fscale(speed, 0, 100, this.pwmRange[0], this.pwmRange[1]));

history.push({
timestamp: Date.now(),
speed: speed
});
state.last.speed = speed;
return this;
}

Expand All @@ -317,10 +299,7 @@ ESC.prototype.speed = function(speed) {

this.write(this.pin, Fn.fscale(throttle, 0, 100, this.pwmRange[0], this.pwmRange[1]));

history.push({
timestamp: Date.now(),
speed: throttle
});
state.last.speed = throttle;

if (steps) {
steps--;
Expand All @@ -333,24 +312,29 @@ ESC.prototype.speed = function(speed) {
}.bind(this), 1);

return this;
};
}, "ESC.prototype.speed: Use `throttle(μs)` (544-2400μs) instead");


/**
* throttle
*
* Throttle the ESC's speed by setting the pulse
*
* @param {Integer} throttle pwmRange[0]...pwmRange[1] (full usec range)
*
* @return {ESC} instance
*/
ESC.prototype.throttle = function(pulse) {
this.write(this.pin, Fn.constrain(pulse, this.pwmRange[0], this.pwmRange[1]));
return this;
};

/**
* brake Stop the ESC by hitting the brakes ;)
* @return {Object} instance
*/
ESC.prototype.brake = function() {
var state = priv.get(this);
var speed = this.neutral || 0;

this.speed(speed);

state.history.push({
timestamp: Date.now(),
speed: speed
});

this.write(this.pin, this.neutral);
return this;
};

Expand Down Expand Up @@ -394,17 +378,7 @@ ESC.prototype.brake = function() {
* @return {Object} instance
*/
ESC.prototype.stop = function() {
var state = priv.get(this);
var history = state.history;
var speed = this.type === "bidirectional" ? this.neutral : 0;

this.write(this.pin, Fn.fscale(speed, 0, 100, this.pwmRange[0], this.pwmRange[1]));

history.push({
timestamp: Date.now(),
speed: speed
});

this.write(this.pin, this.neutral);
return this;
};

Expand All @@ -428,32 +402,6 @@ function ESCs(numsOrObjects) {

util.inherits(ESCs, Collection);

/**
*
* ESCs, speed(0-100%)
*
* set all escs to the specified speed from 0-100%
*
* eg. array.min();
* ESCs, min()
*
* set all escs to the minimum throttle
*
* eg. array.min();
* ESCs, max()
*
* set all escs to the maximum throttle
*
* eg. array.max();
* ESCs, stop()
*
* stop all escs
*
* eg. array.stop();
*/

Collection.installMethodForwarding(
ESCs.prototype, ESC.prototype
Expand Down
Loading

0 comments on commit 0d5ca14

Please sign in to comment.