initial commit

This commit is contained in:
2026-03-22 03:21:45 +02:00
commit 897fea9f4e
15431 changed files with 2548840 additions and 0 deletions

3
node_modules/node-pid-controller/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
node_modules
temp.js
temp

16
node_modules/node-pid-controller/Makefile generated vendored Normal file
View File

@@ -0,0 +1,16 @@
MOCHA_OPTS=
REPORTER = dot
test:
@NODE_ENV=test ./node_modules/.bin/mocha \
--reporter $(REPORTER) \
$(MOCHA_OPTS)
test-w:
@NODE_ENV=test ./node_modules/.bin/mocha \
--reporter $(REPORTER) \
--growl \
--watch \
$(MOCHA_OPTS)
.PHONY: test test-w

77
node_modules/node-pid-controller/README.md generated vendored Normal file
View File

@@ -0,0 +1,77 @@
# node-pid-controller
Simple Node.js PID controller.
![pid](http://upload.wikimedia.org/wikipedia/commons/9/91/PID_en_updated_feedback.svg)
## Installation
```
$ npm install node-pid-controller
```
## Example
Let's take the example of a car cruise control. We want the car driving at 120km/h.
### Create a Controller instance
`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.
```js
var Controller = require('node-pid-controller');
var ctr = new Controller({
k_p: 0.25,
k_i: 0.01,
k_d: 0.01,
dt: 1
});
```
You can also pass options as arguments:
```js
var ctr = new Controller(0.25, 0.01, 0.01, 1); // k_p, k_i, k_d, dt
```
### Set the target
```js
ctr.setTarget(120); // 120km/h
```
### Get the correction
```js
var correction = ctr.update(110); // 110km/h is the current speed
```
### Real example
Normally, you use the correction to a measure, in a closed loop.
```js
var goalReached = false
while (!goalReached) {
var output = measureFromSomeSensor();
var input = ctr.update(output);
applyInputToActuator(input);
goalReached = (input === 0) ? true : false; // in the case of continuous control, you let this variable 'false'
}
```
## Options
* `k_p`, `k_i`, `k_d`: the PID's coefficients
* `dt`: interval of time (in seconds) between two measures. If not provided, it will be automatically calculated.
* `i_max`: the maximum absolute value of the integral term (optional)
## Test
```js
mocha test
```
## Author
Philmod <philippe.modard@gmail.com>

1
node_modules/node-pid-controller/index.js generated vendored Normal file
View File

@@ -0,0 +1 @@
module.exports = require('./lib/index.js');

75
node_modules/node-pid-controller/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,75 @@
/**
* PID Controller.
*/
var Controller = function(k_p, k_i, k_d, dt) {
var i_max;
if (typeof k_p === 'object') {
var options = k_p;
k_p = options.k_p;
k_i = options.k_i;
k_d = options.k_d;
dt = options.dt;
i_max = options.i_max;
}
// PID constants
this.k_p = (typeof k_p === 'number') ? k_p : 1;
this.k_i = k_i || 0;
this.k_d = k_d || 0;
// Interval of time between two updates
// If not set, it will be automatically calculated
this.dt = 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
};
Controller.prototype.setTarget = function(target) {
this.target = target;
};
Controller.prototype.update = function(currentValue) {
this.currentValue = currentValue;
// Calculate dt
var dt = this.dt;
if (!dt) {
var currentTime = Date.now();
if (this.lastTime === 0) { // First time update() is called
dt = 0;
} else {
dt = (currentTime - this.lastTime) / 1000; // in seconds
}
this.lastTime = currentTime;
}
if (typeof dt !== 'number' || dt === 0) {
dt = 1;
}
var error = (this.target - this.currentValue);
this.sumError = this.sumError + error*dt;
if (this.i_max > 0 && Math.abs(this.sumError) > this.i_max) {
var sumSign = (this.sumError > 0) ? 1 : -1;
this.sumError = sumSign * this.i_max;
}
var dError = (error - this.lastError)/dt;
this.lastError = error;
return (this.k_p*error) + (this.k_i * this.sumError) + (this.k_d * dError);
};
Controller.prototype.reset = function() {
this.sumError = 0;
this.lastError = 0;
this.lastTime = 0;
};
module.exports = Controller;

34
node_modules/node-pid-controller/package.json generated vendored Normal file
View File

@@ -0,0 +1,34 @@
{
"name": "node-pid-controller",
"version": "0.1.2",
"description": "Node.js PID controller",
"keywords": [
"pid",
"controller",
"robotic",
"drone",
"system"
],
"author": "Philmod <philippe.modard@gmail.com>",
"homepage": "http://github.com/philmod/node-pid-controller",
"engines": {
"node": ">= v0.8.0"
},
"dependencies": {},
"devDependencies": {
"should": "",
"mocha": ""
},
"scripts": {
"test": "make test"
},
"main": "index",
"directories": {
"test": "test"
},
"repository": {
"type": "git",
"url": "git://github.com/Philmod/node-pid-controller.git"
},
"license": "BSD"
}

83
node_modules/node-pid-controller/test/index.js generated vendored Normal file
View File

@@ -0,0 +1,83 @@
/**
* Module dependencies.
*/
var Controller = require('../')
, should = require('should')
, assert = require('assert')
;
/**
* Tests
*/
describe('pid-controller', function(){
var options = {
k_p: 0.5,
k_i: 0.1,
k_d: 0.2,
dt: 1
};
// Create the controller
var ctr = new Controller(options.k_p, options.k_i, options.k_d, options.dt);
it('should have set the coefficient', function() {
ctr.k_p.should.equal(options.k_p);
ctr.k_i.should.equal(options.k_i);
ctr.k_d.should.equal(options.k_d);
ctr.dt.should.equal(options.dt);
});
it('should have set the coefficient from an options object', function(){
var ctr = new Controller(options);
ctr.k_p.should.equal(options.k_p);
ctr.k_i.should.equal(options.k_i);
ctr.k_d.should.equal(options.k_d);
ctr.dt.should.equal(options.dt);
});
it('should set the target', function(){
var v = 120; // 120km/h
ctr.setTarget(v);
ctr.target.should.equal(v);
});
it('should return the correction', function(){
var vt = 110; // current speed
var correction = ctr.update(vt);
correction.should.equal(8);
});
it('should reset the controller', function(){
ctr.reset();
ctr.sumError.should.equal(0);
ctr.lastError.should.equal(0);
ctr.lastTime.should.equal(0);
});
it('should return the correction for the given update interval', function(){
ctr.dt = 2; // 2 seconds between updates
var correction = ctr.update(115);
correction.should.equal(4);
ctr.dt = options.dt; // Reset dt
});
it('should return the correction with sumError <= i_max', function() {
var ctr = new Controller(options);
ctr.i_max = 5; // sumError will be 10
ctr.setTarget(120);
var correction = ctr.update(110);
correction.should.equal(7.5);
ctr.sumError.should.be.belowOrEqual(ctr.i_max);
});
it('should return a null correction', function(){
var ctr = new Controller(0, 0, 0);
ctr.setTarget(120);
var correction = ctr.update(110);
correction.should.equal(0);
});
});