const PPM = 30;
var targetX = 10;
-const targetY = -2.5;
+var targetY = -2.5;
// Define the box properties
const boxWidth = 1;
canvas.addEventListener("click", function(event) {
targetX = (event.clientX - canvas.getBoundingClientRect().left) / PPM;
- console.log("Updated targetX:", targetX);
+ targetY = -(event.clientY) / PPM
+ console.log("Updated target:", targetX, targetY);
});
// Render the box on the canvas
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "white";
- ctx.fillRect(targetX * PPM, (-position.y * PPM), 30, 30);
+ ctx.fillRect(targetX * PPM, (-targetY * PPM), 30, 30);
// Draw the box
ctx.save();
ctx.fillStyle = "blue";
ctx.fillRect(position.x * PPM, (-position.y * PPM), boxWidth * PPM, boxHeight * PPM);
ctx.restore();
- var r = pid.Update(1/60, position.x, targetX);
- //console.log(r);
- var force = {x: r, y: 0};
+ var force = pid.Update(1/60, {x: position.x, y: position.y}, {x: targetX, y: targetY});
box.applyForce(force, box.getWorldCenter());
}
class PIDController {
constructor() {
- this.PIDParams = {proportionalGain: 2, integralGain: 0.0, derivativeGain: 2, iMin: -1, iMax: 1, integralSaturation: false, derivativeInitialized: false, outputMax: 1, outputMin: -1, magnitude: 10, force: 0, derivativeMeasurement: "Velocity"};
- this.valueLast;
- this.errorLast;
- this.integrationStored = 0;
- this.velocity;
+ this.PIDParams = {
+ proportionalGain: 2,
+ integralGain: 0.0,
+ derivativeGain: 2,
+ iMin: -1,
+ iMax: 1,
+ integralSaturation: false,
+ derivativeInitialized: false,
+ outputMax: 1,
+ outputMin: -1,
+ magnitude: 10,
+ force: {x: 0, y: 0},
+ forceMagnitude: 0,
+ derivativeMeasurement: "Velocity"
+ };
+ this.valueLast = {x: 0, y: 0};
+ this.errorLast = {x: 0, y: 0};
+ this.integrationStored = {x: 0, y: 0};
+ this.velocity = {x: 0, y: 0};
}
+
Reset() {
this.derivativeInitialized = false;
}
+
Update(dt, currentValue, targetValue) {
if (dt <= 0) {
- return;
+ return {x: 0, y: 0};
}
- var error = targetValue - currentValue;
-
- var P = this.PIDParams.proportionalGain * error;
-
- this.integrationStored = Math.min(Math.max(this.integrationStored + (error * dt), this.PIDParams.iMin), this.PIDParams.iMax);
- var I = this.PIDParams.integralGain * this.integrationStored;
-
- var errorRateOfChange = (error - this.errorLast) / dt;
+
+ const error = {
+ x: targetValue.x - currentValue.x,
+ y: targetValue.y - currentValue.y
+ };
+
+ const P = {
+ x: this.PIDParams.proportionalGain * error.x,
+ y: this.PIDParams.proportionalGain * error.y
+ };
+
+ this.integrationStored = {
+ x: Math.min(
+ Math.max(this.integrationStored.x + (error.x * dt), this.PIDParams.iMin),
+ this.PIDParams.iMax
+ ),
+ y: Math.min(
+ Math.max(this.integrationStored.y + (error.y * dt), this.PIDParams.iMin),
+ this.PIDParams.iMax
+ )
+ };
+
+ const I = {
+ x: this.PIDParams.integralGain * this.integrationStored.x,
+ y: this.PIDParams.integralGain * this.integrationStored.y
+ };
+
+ const errorRateOfChange = {
+ x: (error.x - this.errorLast.x) / dt,
+ y: (error.y - this.errorLast.y) / dt
+ };
+
this.errorLast = error;
- var valueRateOfChange = (currentValue - this.valueLast) / dt;
+ const valueRateOfChange = {
+ x: (currentValue.x - this.valueLast.x) / dt,
+ y: (currentValue.y - this.valueLast.y) / dt
+ };
+
this.valueLast = currentValue;
this.velocity = valueRateOfChange;
- var deriveMeasure = 0;
+ let deriveMeasure = {x: 0, y: 0};
if (this.derivativeInitialized) {
- if (this.PIDParams.derivativeMeasurement == "Velocity") {
- deriveMeasure = -valueRateOfChange;
+ if (this.PIDParams.derivativeMeasurement === "Velocity") {
+ deriveMeasure = {
+ x: -valueRateOfChange.x,
+ y: -valueRateOfChange.y
+ };
} else {
- deriveMeasure = errorRateOfChange;
+ deriveMeasure = errorRateOfChange;
}
} else {
this.derivativeInitialized = true;
}
- var D = this.PIDParams.derivativeGain * deriveMeasure;
- var result = P + I + D;
- result *= this.PIDParams.magnitude;
- this.PIDParams.force = result * 60; /* this routine is called ~60seconds */
+
+ const D = {
+ x: this.PIDParams.derivativeGain * deriveMeasure.x,
+ y: this.PIDParams.derivativeGain * deriveMeasure.y
+ };
+
+ const result = {
+ x: P.x + I.x + D.x,
+ y: P.y + I.y + D.y
+ };
+
+ result.x *= this.PIDParams.magnitude;
+ result.y *= this.PIDParams.magnitude;
+
+ this.PIDParams.force = {
+ x: result.x * 60, // this routine is called ~60 seconds
+ y: result.y * 60
+ };
+
+ this.PIDParams.forceMagnitude = Math.sqrt(result.x ** 2 + result.y ** 2) * 60;
return result;
- //return Math.min(Math.max((result, this.PIDParams.outputMin), this.PIDParams.outputMax));
}
}
-
export default PIDController;