const world = World(Vec2(0, 0));
-canvas.width = 500;
-canvas.height = 500;
+canvas.width = window.innerWidth;
+canvas.height = window.innerHeight;
const PPM = 30;
-const targetX = 10;
+var targetX = 10;
const targetY = -2.5;
// Define the box properties
box.createFixture({
shape: Box(boxWidth, boxHeight),
density: 1.0,
+ friction: 0.01,
});
-MENU.initMenu();
const pid = new PIDController();
+MENU.initMenu(pid);
+
+canvas.addEventListener("click", function(event) {
+ targetX = (event.clientX - canvas.getBoundingClientRect().left) / PPM;
+ console.log("Updated targetX:", targetX);
+});
// Render the box on the canvas
function render() {
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);
+ //console.log(r);
var force = {x: r, y: 0};
box.applyForce(force, box.getWorldCenter());
}
import {Pane} from "tweakpane";
-function initMenu()
+function initMenu(pid)
{
const pane = new Pane();
- const tab = pane.addTab({
- pages: [{title: "Creative Mode"}, {title: "Preset"}]
+ const pidSettings = pane.addFolder({
+ title: "PID settings"
+ });
+ pidSettings.addInput(
+ pid.PIDParams, "proportionalGain",
+ {min: 0, max: 10, step: 0.1}
+ );
+
+ pidSettings.addInput(
+ pid.PIDParams, "derivativeGain",
+ {min: 0, max: 10, step: 0.1}
+ );
+
+ pidSettings.addInput(
+ pid.PIDParams, "integralGain",
+ {min: 0, max: 10, step: 0.1}
+ );
+ pane.addMonitor(pid.PIDParams, "force", {
+ title: "Force (N)",
+ view: "graph",
+ min: -10000,
+ max: +10000,
});
-
}
export {initMenu};
// ErrorRateOfChange
//}
constructor() {
- this.PIDParams = {proportionalGain: 50, integralGain: 0.01, derivativeGain: 35, outputMin: -1, outputMax: 1, integralSaturation: false, derivativeInitialized: false};
+ 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};
this.valueLast;
this.errorLast;
- this.integrationStored;
+ this.integrationStored = 0;
this.velocity;
}
Reset() {
var P = this.PIDParams.proportionalGain * error;
- this.integrationStored = Math.min(Math.max(this.integrationStored + (error * dt), -this.integralSaturation), -this.integralSaturation);
- var I = this.integralGain * this.integrationStored;
+ 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;
this.errorLast = error;
} else {
this.derivativeInitialized = true;
}
-
var D = this.PIDParams.derivativeGain * deriveMeasure;
- var result = P + D;
- return result;
+ var result = P + I + D;
+ result *= this.PIDParams.magnitude;
+ this.PIDParams.force = result * 60; /* this routine is called ~60seconds */
- //return Math.min(Math.max((result, this.outputMin), this.outputMax));
+ //console.log(result*60 + " N");
+ return result;
+ //return Math.min(Math.max((result, this.PIDParams.outputMin), this.PIDParams.outputMax));
}
-
- // float AngleDifference(float a, float b) {
- // return (a - b + 540) % 360 - 180; //calculate modular difference, and remap to [-180, 180]
- // }
-
- // public float UpdateAngle(float dt, float currentAngle, float targetAngle) {
- // if (dt <= 0) throw new ArgumentOutOfRangeException(nameof(dt));
- // float error = AngleDifference(targetAngle, currentAngle);
-
- // //calculate P term
- // float P = proportionalGain * error;
-
- // //calculate I term
- // integrationStored = Mathf.Clamp(integrationStored + (error * dt), -integralSaturation, integralSaturation);
- // float I = integralGain * integrationStored;
-
- // //calculate both D terms
- // float errorRateOfChange = AngleDifference(error, errorLast) / dt;
- // errorLast = error;
-
- // float valueRateOfChange = AngleDifference(currentAngle, valueLast) / dt;
- // valueLast = currentAngle;
- // velocity = valueRateOfChange;
-
- // //choose D term to use
- // float deriveMeasure = 0;
-
- // if (derivativeInitialized) {
- // if (derivativeMeasurement == DerivativeMeasurement.Velocity) {
- // deriveMeasure = -valueRateOfChange;
- // } else {
- // deriveMeasure = errorRateOfChange;
- // }
- // } else {
- // derivativeInitialized = true;
- // }
-
- // float D = derivativeGain * deriveMeasure;
-
- // float result = P + I + D;
-
- // return Mathf.Clamp(result, outputMin, outputMax);
- // }
}
export default PIDController;