Skip to content

Commit e84e460

Browse files
committed
Merge pull request #3 from emersion/master
Adds update interval support, minor fixes
2 parents f6c8624 + ffe3426 commit e84e460

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
Let's take the example of a car cruise control. We want the car driving at 120km/h.
1313

1414
### Create a Controller instance
15+
`k_p`, `k_i` and `k_d` are the proportional, integral and derivative terms. `dt` is the interval of time between two measures. If not set, it will be automatically calculated.
1516
```js
1617
var Controller = require('node-pid-controller');
17-
var ctr = new Controller(0.25, 0.01, 0.01); // k_p, k_i, k_d
18+
var ctr = new Controller(0.25, 0.01, 0.01, 1); // k_p, k_i, k_d, dt
1819
```
1920

2021
### Set the target
@@ -46,4 +47,4 @@ mocha test
4647

4748
## Author
4849

49-
Philmod <[email protected]>
50+
Philmod <[email protected]>

lib/index.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
/**
22
* PID Controller.
33
*/
4-
var Controller = function(k_p, k_i, k_d) {
5-
this.k_p = k_p || 1;
4+
var Controller = function(k_p, k_i, k_d, dt) {
5+
// PID constants
6+
this.k_p = (typeof k_p === 'number') ? k_p : 1;
67
this.k_i = k_i || 0;
78
this.k_d = k_d || 0;
89

10+
// Interval of time between two updates
11+
// If not set, it will be automatically calculated
12+
this.dt = dt || 0;
13+
914
this.sumError = 0;
1015
this.lastError = 0;
1116
this.lastTime = 0;
@@ -17,12 +22,27 @@ Controller.prototype.setTarget = function(target) {
1722
this.target = target;
1823
};
1924

20-
Controller.prototype.update = function(current_value) {
21-
this.current_value = current_value;
22-
23-
var error = (this.target - this.current_value);
24-
this.sumError = this.sumError + error;
25-
var dError = error - this.lastError;
25+
Controller.prototype.update = function(currentValue) {
26+
this.currentValue = currentValue;
27+
28+
// Calculate dt
29+
var dt = this.dt;
30+
if (!dt) {
31+
var currentTime = Date.now();
32+
if (this.lastTime === 0) { // First time update() is called
33+
dt = 0;
34+
} else {
35+
dt = (currentTime - this.lastTime) / 1000; // in seconds
36+
}
37+
this.lastTime = currentTime;
38+
}
39+
if (typeof dt !== 'number' || dt === 0) {
40+
dt = 1;
41+
}
42+
43+
var error = (this.target - this.currentValue);
44+
this.sumError = this.sumError + error*dt;
45+
var dError = (error - this.lastError)/dt;
2646
this.lastError = error;
2747

2848
return (this.k_p*error) + (this.k_i * this.sumError) + (this.k_d * dError);

test/index.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ var Controller = require('../')
1212
*/
1313
describe('pid-controller', function(){
1414

15-
var k_p = 0.5
16-
, k_i = 0.1
17-
, k_d = 0.2
18-
;
15+
var k_p = 0.5,
16+
k_i = 0.1,
17+
k_d = 0.2,
18+
dt = 1;
1919

2020
// Create the controller
21-
var ctr = new Controller(k_p, k_i, k_d);
21+
var ctr = new Controller(k_p, k_i, k_d, dt);
2222

2323
it('should have set the coefficient', function() {
2424
ctr.k_p.should.equal(k_p);
@@ -45,4 +45,17 @@ describe('pid-controller', function(){
4545
ctr.lastTime.should.equal(0);
4646
});
4747

48+
it('should return the correction for the given update interval', function(){
49+
ctr.dt = 2; // 2 seconds between updates
50+
var correction = ctr.update(115);
51+
correction.should.equal(4);
52+
});
53+
54+
it('should return a null correction', function(){
55+
var ctr = new Controller(0, 0, 0);
56+
ctr.setTarget(120);
57+
var correction = ctr.update(110);
58+
correction.should.equal(0);
59+
});
60+
4861
});

0 commit comments

Comments
 (0)