From 3ce1275bdd9ed82711b82b4025a271bf363e6119 Mon Sep 17 00:00:00 2001 From: Imanuel Pundoko Date: Thu, 15 Oct 2020 19:50:07 +0800 Subject: [PATCH 1/5] tuning setter --- lib/index.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/index.js b/lib/index.js index 3d07030..4bc6d71 100644 --- a/lib/index.js +++ b/lib/index.js @@ -27,19 +27,25 @@ class Controller { // Maximum absolute value of sumError this.i_max = i_max || 0; - this.sumError = 0; + this.sumError = 0; this.lastError = 0; - this.lastTime = 0; + this.lastTime = 0; - this.target = 0; // default value, can be modified with .setTarget + this.target = 0; // default value, can be modified with .setTarget } setTarget(target) { this.target = target; } + setTunings({ k_p, k_i, k_d }) { + this.k_p = k_p || this.k_p; + this.k_i = k_i || this.k_i; + this.k_d = k_d || this.k_d; + } + update(currentValue) { - if(!currentValue) throw new Error("Invalid argument"); + if (!currentValue) throw new Error("Invalid argument"); this.currentValue = currentValue; // Calculate dt @@ -58,22 +64,22 @@ class Controller { } let error = (this.target - this.currentValue); - this.sumError = this.sumError + error*dt; + this.sumError = this.sumError + error * dt; if (this.i_max > 0 && Math.abs(this.sumError) > this.i_max) { let sumSign = (this.sumError > 0) ? 1 : -1; this.sumError = sumSign * this.i_max; } - let dError = (error - this.lastError)/dt; + let dError = (error - this.lastError) / dt; this.lastError = error; - return (this.k_p*error) + (this.k_i * this.sumError) + (this.k_d * dError); + return (this.k_p * error) + (this.k_i * this.sumError) + (this.k_d * dError); } reset() { - this.sumError = 0; + this.sumError = 0; this.lastError = 0; - this.lastTime = 0; + this.lastTime = 0; } } From a39f6883d641d28aaa248c6e42c086f44688db02 Mon Sep 17 00:00:00 2001 From: Imanuel Pundoko Date: Mon, 19 Oct 2020 18:13:42 +0800 Subject: [PATCH 2/5] Add tuning setter method --- index.d.ts | 3 +++ lib/index.js | 43 ++++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/index.d.ts b/index.d.ts index 4586022..4560729 100644 --- a/index.d.ts +++ b/index.d.ts @@ -31,6 +31,9 @@ declare class Controller { public setTarget(target: number): void; + public setTuning(options: Controller.Options); + public setTuning(k_p?: number, k_i?: number, k_d?: number, dt?: number); + public update(currentValue: number): number; public reset(): number; diff --git a/lib/index.js b/lib/index.js index 4bc6d71..02c0fe8 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,6 +5,21 @@ */ class Controller { constructor(k_p, k_i, k_d, dt) { + + this.setTuning(k_p, k_i, k_d, dt); + + this.sumError = 0; + this.lastError = 0; + this.lastTime = 0; + + this.target = 0; // default value, can be modified with .setTarget + } + + setTarget(target) { + this.target = target; + } + + setTuning(k_p, k_i, k_d, dt) { let i_max; if (typeof k_p === 'object') { let options = k_p; @@ -16,32 +31,18 @@ class Controller { } // PID constants - this.k_p = (typeof k_p === 'number') ? k_p : 1; - this.k_i = k_i || 0; - this.k_d = k_d || 0; + if (typeof k_p !== 'number') k_p = this.k_p || 1; + + this.k_p = k_p; + this.k_i = k_i || this.k_i || 0; + this.k_d = k_d || this.k_d || 0; // Interval of time between two updates // If not set, it will be automatically calculated - this.dt = dt || 0; + this.dt = dt || this.dt || 0; // Maximum absolute value of sumError - this.i_max = i_max || 0; - - this.sumError = 0; - this.lastError = 0; - this.lastTime = 0; - - this.target = 0; // default value, can be modified with .setTarget - } - - setTarget(target) { - this.target = target; - } - - setTunings({ k_p, k_i, k_d }) { - this.k_p = k_p || this.k_p; - this.k_i = k_i || this.k_i; - this.k_d = k_d || this.k_d; + this.i_max = i_max || this.i_max || 0; } update(currentValue) { From 44e7e3ec6cd5ab3009068f03633ea7468127c74b Mon Sep 17 00:00:00 2001 From: Imanuel Pundoko Date: Mon, 19 Oct 2020 18:14:05 +0800 Subject: [PATCH 3/5] Update testing --- test/index.js | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/test/index.js b/test/index.js index 9684b3a..7c4f0d7 100644 --- a/test/index.js +++ b/test/index.js @@ -40,6 +40,24 @@ describe('pid-controller', () => { ctr.dt.should.equal(options.dt); }); + it('should have set the coefficient from an new options object', () => { + let newOptions = { + k_p: 0.7, + k_i: 0.2, + k_d: 0.3, + dt: 10 + } + + ctr.setTuning(newOptions.k_p, newOptions.k_i, newOptions.k_d, newOptions.dt); + + ctr.k_p.should.equal(newOptions.k_p); + ctr.k_i.should.equal(newOptions.k_i); + ctr.k_d.should.equal(newOptions.k_d); + ctr.dt.should.equal(newOptions.dt); + + ctr.setTuning(options); // Reset tunings + }); + it('should set the target', () => { let v = 120; // 120km/h ctr.setTarget(v); @@ -60,15 +78,22 @@ describe('pid-controller', () => { }); it('should return the correction for the given update interval', () => { - ctr.dt = 2; // 2 seconds between updates + ctr.setTuning({ + dt: 2 // 2 seconds between updates + }) let correction = ctr.update(115); correction.should.equal(4); - ctr.dt = options.dt; // Reset dt + + ctr.setTuning({ + dt: options.dt // Reset dt + }) }); it('should return the correction with sumError <= i_max', () => { let ctr = new Controller(options); - ctr.i_max = 5; // sumError will be 10 + ctr.setTuning({ + i_max: 5 // sumError will be 10 + }); ctr.setTarget(120); let correction = ctr.update(110); correction.should.equal(7.5); @@ -83,7 +108,7 @@ describe('pid-controller', () => { }); it('should throw error when updating a NaN value', () => { - let ctr = new Controller(0,0,0); + let ctr = new Controller(0, 0, 0); ctr.setTarget(20); should.throws(() => { ctr.update(NaN); From 0edcfc4bd3c697eb8e0d09afcffad6251766681e Mon Sep 17 00:00:00 2001 From: Imanuel Pundoko Date: Mon, 19 Oct 2020 18:14:21 +0800 Subject: [PATCH 4/5] Update README --- .gitignore | 4 +++- README.md | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 057a577..c18b9b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules temp.js -temp \ No newline at end of file +temp + +package-lock.json \ No newline at end of file diff --git a/README.md b/README.md index f992949..1b94f82 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,19 @@ You can also pass options as arguments: let ctr = new Controller(0.25, 0.01, 0.01, 1); // k_p, k_i, k_d, dt ``` +### Re-set the tuning + +```js +ctr.setTuning(0.25, 0.01, 0.01, 1); // k_p, k_i, k_d, dt + +ctr.setTuning({ // as object + k_p: 0.25, + k_i: 0.01, + k_d: 0.01, + dt: 1 +}); +``` + ### Set the target ```js From 57c4f874261747ac0d884cb6738548e15cbd4204 Mon Sep 17 00:00:00 2001 From: Imanuel Pundoko Date: Mon, 19 Oct 2020 22:26:50 +0800 Subject: [PATCH 5/5] Fix "Invalid argument" issue #12 --- .gitignore | 3 +-- lib/index.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index c18b9b0..916e75c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ node_modules temp.js temp - -package-lock.json \ No newline at end of file +package-lock.json diff --git a/lib/index.js b/lib/index.js index 02c0fe8..f5418a5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -46,7 +46,7 @@ class Controller { } update(currentValue) { - if (!currentValue) throw new Error("Invalid argument"); + if (isNaN(currentValue)) throw new Error("Invalid argument"); this.currentValue = currentValue; // Calculate dt