Skip to content

Instantly share code, notes, and snippets.

@stackola
Created May 31, 2020 11:15
Show Gist options
  • Save stackola/f50967f46b8c2171e1bd0e3890e64268 to your computer and use it in GitHub Desktop.
Save stackola/f50967f46b8c2171e1bd0e3890e64268 to your computer and use it in GitHub Desktop.
// How to use:
// Step 1: go to https://iss-sim.spacex.com/
// Step 2: Let everything load, click on "Begin" and wait 10 seconds
// Step 3: Copy this whole programm into your browser's console
// Step 4: Hit enter!
class Controller {
constructor(k_p, k_i, k_d, dt) {
let i_max;
if (typeof k_p === "object") {
let 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
}
setTarget(target) {
this.target = target;
}
update(currentValue) {
if (!currentValue) throw new Error("Invalid argument");
this.currentValue = currentValue;
// Calculate dt
let dt = this.dt;
if (!dt) {
let 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;
}
let error = this.target - this.currentValue;
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;
this.lastError = error;
return this.k_p * error + this.k_i * this.sumError + this.k_d * dError;
}
reset() {
this.sumError = 0;
this.lastError = 0;
this.lastTime = 0;
}
}
async function playGame() {
zeroRotationAxis("Y");
zeroRotationAxis("X");
zeroRotationAxis("Z");
timeout(25 * 1000);
zeroTranslationAxis("x");
zeroTranslationAxis("y");
timeout(20 * 1000);
zeroTranslationAxis("z");
}
async function zeroTranslationAxis(axis) {
let ctr = new Controller({
k_p: 5,
k_i: 0.0,
k_d: 0,
});
if (axis == "z") {
ctr.setTarget(-149.87);
} else {
ctr.setTarget(0);
}
while (true) {
let speed = window.motionVector[axis] * 20 * -1;
let pos = window.camera.position[axis];
if (!pos) {
pos = 0.0001;
}
//now PID maybe?
let pid = ctr.update(pos) * -1;
if (axis == "x") {
if (Math.round(pid) > speed && speed < 0.4) {
window.translateLeft();
} else if (Math.round(pid) < speed && speed > -0.4) {
window.translateRight();
}
}
if (axis == "y") {
if (Math.round(pid) > speed && speed < 0.4) {
window.translateDown();
} else if (Math.round(pid) < speed && speed > -0.4) {
window.translateUp();
}
}
if (axis == "z") {
if (Math.round(pid) > speed * 20 && speed < 0.8) {
window.translateForward();
} else if (Math.round(pid) < speed * 20 && speed > -0.8) {
window.translateBackward();
}
}
await timeout();
}
}
async function zeroRotationAxis(axis) {
let ctr = new Controller({
k_p: 1,
k_i: 0.0,
k_d: 0,
});
ctr.setTarget(0);
while (true) {
let speed = window["rateRotation" + axis];
let pos = Number(window["fixedRotation" + axis]) * 5;
if (!pos) {
pos = 0.0001;
}
//now PID maybe?
let pid = ctr.update(pos) * -2;
if (axis == "Y") {
if (Math.round(pid) > speed && speed < 4) {
window.yawRight();
} else if (Math.round(pid) < speed && speed > -4) {
window.yawLeft();
}
}
if (axis == "X") {
if (Math.round(pid) > speed && speed < 4) {
window.pitchDown();
} else if (Math.round(pid) < speed && speed > -4) {
window.pitchUp();
}
}
if (axis == "Z") {
if (Math.round(pid) > speed && speed < 4) {
window.rollRight();
} else if (Math.round(pid) < speed && speed > -4) {
window.rollLeft();
}
}
await timeout();
}
}
playGame();
function timeout(time = 50) {
return new Promise((resolve) => setTimeout(resolve, time));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment