Published
Edited
Dec 17, 2018
Fork of Cargo Race
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function drawWheel(context, vessel) {
}
Insert cell
function drawWindRose(context) {
}
Insert cell
Insert cell
function updatePid(sprite, dt) {
// Use PID feedback to keep bearing on course (see https://en.wikipedia.org/wiki/PID_controller)
const Kp = 0.1;
const Kd = 0.01;
const Ki = 0.01;

const course = Math.atan2(sprite.velocity[1], sprite.velocity[0]);

// reset PID accumulated errors if we are changing course
if (sprite.course != course) {
sprite.integral = 0;
sprite.previousError = 0;
}
sprite.course = course;

const error = clamp(sprite.bearing - course + Math.PI, 0, Math.PI * 2) - Math.PI;
const derivative = error - sprite.previousError / dt;
sprite.integral += (error * dt);

const speed = magnitude(sprite.velocity);

// instant adjustment without physics
// sprite.velocity[0] = speed * Math.cos(bearing);
// sprite.velocity[1] = speed * Math.sin(bearing);

const delta = Kp * error + Kd * derivative + Ki * sprite.integral;
const correction = course + delta;

sprite.velocity[0] = speed * Math.cos(course + delta);
sprite.velocity[1] = speed * Math.sin(course + delta);

sprite.previousError = error;
return error;
}
Insert cell
function distance(a, b) {
return Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
}
Insert cell
function clamp(value, min, max) {
return value > max ? value - max : value < min ? value + max : value;
}
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more