feat: quaternion relative
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "computercraft-mutil",
|
"name": "computercraft-mutil",
|
||||||
"version": "1.0.9",
|
"version": "1.0.10",
|
||||||
"description": "",
|
"description": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"author": "",
|
"author": "",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export interface PIDParameters {
|
|||||||
kP: number;
|
kP: number;
|
||||||
kI: number;
|
kI: number;
|
||||||
kD: number;
|
kD: number;
|
||||||
errorWrap?: (error: number) => number;
|
calculateError?: (setpoint: number, measuredValue: number) => number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PIDReport = {
|
export type PIDReport = {
|
||||||
@@ -46,10 +46,9 @@ export class PID {
|
|||||||
public update(measuredValue: number): number {
|
public update(measuredValue: number): number {
|
||||||
const currentTime = os.epoch("utc");
|
const currentTime = os.epoch("utc");
|
||||||
|
|
||||||
const rawError = this.setpoint - measuredValue;
|
const error = this.params.calculateError
|
||||||
const error = this.params.errorWrap
|
? this.params.calculateError(this.setpoint, measuredValue)
|
||||||
? this.params.errorWrap(rawError)
|
: this.setpoint - measuredValue;
|
||||||
: rawError;
|
|
||||||
|
|
||||||
let deltaTime = 0;
|
let deltaTime = 0;
|
||||||
if (this.lastTime !== null) {
|
if (this.lastTime !== null) {
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import { Vec3 } from "./vec";
|
|||||||
const math = globalThis.math;
|
const math = globalThis.math;
|
||||||
|
|
||||||
export class Quaternion {
|
export class Quaternion {
|
||||||
public constructor(
|
constructor(
|
||||||
public x: number,
|
public x: number,
|
||||||
public y: number,
|
public y: number,
|
||||||
public z: number,
|
public z: number,
|
||||||
public w: number,
|
public w: number,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
public static fromXYZ({
|
static fromXYZ({
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
z,
|
z,
|
||||||
@@ -45,6 +45,62 @@ export class Quaternion {
|
|||||||
|
|
||||||
return new Vec3(roll, pitch, yaw);
|
return new Vec3(roll, pitch, yaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public normalized(): Quaternion {
|
||||||
|
const mag = math.sqrt(
|
||||||
|
this.w * this.w + this.x * this.x + this.y * this.y + this.z * this.z,
|
||||||
|
);
|
||||||
|
return new Quaternion(
|
||||||
|
this.x / mag,
|
||||||
|
this.y / mag,
|
||||||
|
this.z / mag,
|
||||||
|
this.w / mag,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public inverse(): Quaternion {
|
||||||
|
// assuming unit quaternion
|
||||||
|
return new Quaternion(-this.x, -this.y, -this.z, this.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public multiply(q: Quaternion): Quaternion {
|
||||||
|
const w1 = this.w,
|
||||||
|
x1 = this.x,
|
||||||
|
y1 = this.y,
|
||||||
|
z1 = this.z;
|
||||||
|
const w2 = q.w,
|
||||||
|
x2 = q.x,
|
||||||
|
y2 = q.y,
|
||||||
|
z2 = q.z;
|
||||||
|
|
||||||
|
return new Quaternion(
|
||||||
|
x1 * w2 + w1 * x2 + y1 * z2 - z1 * y2,
|
||||||
|
y1 * w2 + w1 * y2 + z1 * x2 - x1 * z2,
|
||||||
|
z1 * w2 + w1 * z2 + x1 * y2 - y1 * x2,
|
||||||
|
w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns rotation error to target as axis and angle (in radians) */
|
||||||
|
public getErrorTo(target: Quaternion): { axis: Vec3; angle: number } {
|
||||||
|
// q_error = q_target * inverse(q_current)
|
||||||
|
const q_error = target.multiply(this.inverse()).normalized();
|
||||||
|
|
||||||
|
const angle = 2 * math.acos(math.min(math.max(q_error.w, -1), 1));
|
||||||
|
const s = math.sqrt(1 - q_error.w * q_error.w);
|
||||||
|
|
||||||
|
let axis: Vec3;
|
||||||
|
if (s < 1e-6) {
|
||||||
|
axis = new Vec3(1, 0, 0); // arbitrary
|
||||||
|
} else {
|
||||||
|
axis = new Vec3(q_error.x / s, q_error.y / s, q_error.z / s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap angle to [-PI, PI]
|
||||||
|
const wrappedAngle = angle > Math.PI ? angle - 2 * Math.PI : angle;
|
||||||
|
|
||||||
|
return { axis, angle: wrappedAngle };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fast sign without zero
|
// fast sign without zero
|
||||||
|
|||||||
Reference in New Issue
Block a user