From 9071354b731df418db63af95cd05f7e6c8485d09 Mon Sep 17 00:00:00 2001 From: Drew Hoener Date: Fri, 8 Aug 2025 14:14:51 -0400 Subject: [PATCH 1/7] chore(eslint): Enforce newline at EOF with `eol-last` rule Signed-off-by: Drew Hoener --- eslint.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eslint.config.js b/eslint.config.js index 9fa51b227..6aa12ab57 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -61,7 +61,8 @@ export default tseslint.config( quotes: [2, 'single'], 'no-proto': 2, 'linebreak-style': 2, - 'key-spacing': [2, {afterColon: true}] + 'key-spacing': [2, {afterColon: true}], + 'eol-last': ['error', 'always'], }, files: ['**/*.{js,jsx,ts,tsx,cjs}'], } From e8807274dc9d330f9fa1c0204afb282119a0f997 Mon Sep 17 00:00:00 2001 From: Drew Hoener Date: Fri, 8 Aug 2025 02:24:53 -0400 Subject: [PATCH 2/7] refactor(math): Rename files to TS. This commit will have lint/compile errors but is necessary for git continuity. Without it, git will think the files have been deleted and recreated because of the diff. Signed-off-by: Drew Hoener --- src/math/{Pose.js => Pose.ts} | 0 src/math/{Quaternion.js => Quaternion.ts} | 0 src/math/{Transform.js => Transform.ts} | 0 src/math/{Vector3.js => Vector3.ts} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/math/{Pose.js => Pose.ts} (100%) rename src/math/{Quaternion.js => Quaternion.ts} (100%) rename src/math/{Transform.js => Transform.ts} (100%) rename src/math/{Vector3.js => Vector3.ts} (100%) diff --git a/src/math/Pose.js b/src/math/Pose.ts similarity index 100% rename from src/math/Pose.js rename to src/math/Pose.ts diff --git a/src/math/Quaternion.js b/src/math/Quaternion.ts similarity index 100% rename from src/math/Quaternion.js rename to src/math/Quaternion.ts diff --git a/src/math/Transform.js b/src/math/Transform.ts similarity index 100% rename from src/math/Transform.js rename to src/math/Transform.ts diff --git a/src/math/Vector3.js b/src/math/Vector3.ts similarity index 100% rename from src/math/Vector3.js rename to src/math/Vector3.ts From 52857525213a664148eb385190805ba8a5d6f684 Mon Sep 17 00:00:00 2001 From: Drew Hoener Date: Fri, 8 Aug 2025 01:18:19 -0400 Subject: [PATCH 3/7] refactor(Vector3): Refactor Vector3 to typescript module, add interface to represent structure and type methods. Signed-off-by: Drew Hoener --- src/math/Vector3.ts | 59 +++++++++++++++++++++++++++++---------------- src/math/index.ts | 2 +- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/math/Vector3.ts b/src/math/Vector3.ts index 3d9f933e2..f1d580903 100644 --- a/src/math/Vector3.ts +++ b/src/math/Vector3.ts @@ -3,64 +3,81 @@ * @author David Gossow - dgossow@willowgarage.com */ -import Quaternion from './Quaternion.js'; +import { type IQuaternion } from './Quaternion.js'; +import { type PartialNullable } from '../types/interface-types.js'; + +export interface IVector3 { + /** + * The x value. + */ + x: number; + /** + * The y value. + */ + y: number; + /** + * The z value. + */ + z: number; +} /** * A 3D vector. */ -export default class Vector3 { - /** - * @param {Object} [options] - * @param {number} [options.x=0] - The x value. - * @param {number} [options.y=0] - The y value. - * @param {number} [options.z=0] - The z value. - */ - constructor(options) { - options = options || {}; - this.x = options.x || 0; - this.y = options.y || 0; - this.z = options.z || 0; +export default class Vector3 implements IVector3 { + x: number; + y: number; + z: number; + + constructor(options?: PartialNullable | null) { + this.x = options?.x ?? 0; + this.y = options?.y ?? 0; + this.z = options?.z ?? 0; } + /** * Set the values of this vector to the sum of itself and the given vector. * * @param {Vector3} v - The vector to add with. */ - add(v) { + add(v: IVector3): void { this.x += v.x; this.y += v.y; this.z += v.z; } + /** * Set the values of this vector to the difference of itself and the given vector. * * @param {Vector3} v - The vector to subtract with. */ - subtract(v) { + subtract(v: IVector3): void { this.x -= v.x; this.y -= v.y; this.z -= v.z; } + /** * Multiply the given Quaternion with this vector. * * @param {Quaternion} q - The quaternion to multiply with. */ - multiplyQuaternion(q) { - var ix = q.w * this.x + q.y * this.z - q.z * this.y; - var iy = q.w * this.y + q.z * this.x - q.x * this.z; - var iz = q.w * this.z + q.x * this.y - q.y * this.x; - var iw = -q.x * this.x - q.y * this.y - q.z * this.z; + multiplyQuaternion(q: IQuaternion) { + const ix = q.w * this.x + q.y * this.z - q.z * this.y; + const iy = q.w * this.y + q.z * this.x - q.x * this.z; + const iz = q.w * this.z + q.x * this.y - q.y * this.x; + const iw = -q.x * this.x - q.y * this.y - q.z * this.z; this.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y; this.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z; this.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x; } + /** * Clone a copy of this vector. * * @returns {Vector3} The cloned vector. */ - clone() { + clone(): Vector3 { return new Vector3(this); } } diff --git a/src/math/index.ts b/src/math/index.ts index 8260ddf71..c549309bb 100644 --- a/src/math/index.ts +++ b/src/math/index.ts @@ -1,4 +1,4 @@ export { default as Pose } from './Pose.js'; export { default as Quaternion } from './Quaternion.js'; export { default as Transform } from './Transform.js'; -export { default as Vector3 } from './Vector3.js'; +export { default as Vector3, type IVector3 } from './Vector3.js'; From e9341cd9b8105788e5e3fff6a603c6865e50877b Mon Sep 17 00:00:00 2001 From: Drew Hoener Date: Fri, 8 Aug 2025 01:18:48 -0400 Subject: [PATCH 4/7] refactor(Quaternion): Refactor Quaternion to typescript module, add interface to represent structure and type methods. Signed-off-by: Drew Hoener --- src/math/Quaternion.ts | 74 ++++++++++++++++++++++++++++-------------- src/math/index.ts | 2 +- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/math/Quaternion.ts b/src/math/Quaternion.ts index c43919dfb..ed161dcd5 100644 --- a/src/math/Quaternion.ts +++ b/src/math/Quaternion.ts @@ -2,46 +2,69 @@ * @fileOverview * @author David Gossow - dgossow@willowgarage.com */ +import { type PartialNullable } from '../types/interface-types.js'; + +export interface IQuaternion { + /** + * The x value. + */ + x: number; + + /** + * The y value. + */ + y: number; + + /** + * The z value. + */ + z: number; + + /** + * The w value. + */ + w: number; +} /** * A Quaternion. */ -export default class Quaternion { - /** - * @param {Object} [options] - * @param {number|null} [options.x=0] - The x value. - * @param {number|null} [options.y=0] - The y value. - * @param {number|null} [options.z=0] - The z value. - * @param {number|null} [options.w=1] - The w value. - */ - constructor(options) { - options = options || {}; - this.x = options.x || 0; - this.y = options.y || 0; - this.z = options.z || 0; - this.w = typeof options.w === 'number' ? options.w : 1; +export default class Quaternion implements IQuaternion { + x: number; + y: number; + z: number; + w: number; + + constructor(options?: PartialNullable | null) { + this.x = options?.x ?? 0; + this.y = options?.y ?? 0; + this.z = options?.z ?? 0; + this.w = typeof options?.w === 'number' ? options.w : 1; } + /** * Perform a conjugation on this quaternion. */ - conjugate() { + conjugate(): void { this.x *= -1; this.y *= -1; this.z *= -1; } + /** * Return the norm of this quaternion. */ - norm() { + norm(): number { return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); } + /** * Perform a normalization on this quaternion. */ - normalize() { - var l = Math.sqrt( + normalize(): void { + let l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); if (l === 0) { @@ -67,24 +90,25 @@ export default class Quaternion { /** * Set the values of this quaternion to the product of itself and the given quaternion. * - * @param {Quaternion} q - The quaternion to multiply with. + * @param {IQuaternion} q - The quaternion to multiply with. */ - multiply(q) { - var newX = this.x * q.w + this.y * q.z - this.z * q.y + this.w * q.x; - var newY = -this.x * q.z + this.y * q.w + this.z * q.x + this.w * q.y; - var newZ = this.x * q.y - this.y * q.x + this.z * q.w + this.w * q.z; - var newW = -this.x * q.x - this.y * q.y - this.z * q.z + this.w * q.w; + multiply(q: IQuaternion): void { + const newX = this.x * q.w + this.y * q.z - this.z * q.y + this.w * q.x; + const newY = -this.x * q.z + this.y * q.w + this.z * q.x + this.w * q.y; + const newZ = this.x * q.y - this.y * q.x + this.z * q.w + this.w * q.z; + const newW = -this.x * q.x - this.y * q.y - this.z * q.z + this.w * q.w; this.x = newX; this.y = newY; this.z = newZ; this.w = newW; } + /** * Clone a copy of this quaternion. * * @returns {Quaternion} The cloned quaternion. */ - clone() { + clone(): Quaternion { return new Quaternion(this); } } diff --git a/src/math/index.ts b/src/math/index.ts index c549309bb..c15f6257c 100644 --- a/src/math/index.ts +++ b/src/math/index.ts @@ -1,4 +1,4 @@ export { default as Pose } from './Pose.js'; -export { default as Quaternion } from './Quaternion.js'; +export { default as Quaternion, type IQuaternion } from './Quaternion.js'; export { default as Transform } from './Transform.js'; export { default as Vector3, type IVector3 } from './Vector3.js'; From 5f96801b197205dfad88a21d8334c99a76adddba Mon Sep 17 00:00:00 2001 From: Drew Hoener Date: Fri, 8 Aug 2025 01:27:23 -0400 Subject: [PATCH 5/7] feat(types): Add utility types Signed-off-by: Drew Hoener --- src/types/interface-types.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/types/interface-types.ts diff --git a/src/types/interface-types.ts b/src/types/interface-types.ts new file mode 100644 index 000000000..1fbe2a89c --- /dev/null +++ b/src/types/interface-types.ts @@ -0,0 +1,16 @@ +/** + * Represents a type that can either be a value of type `T` or `undefined`. + */ +export type Optional = T | undefined; + +/** + * Represents a type that can either be a value of type `T` or `null`. + */ +export type Nullable = T | null; + +/** + * Represents an object type where all properties are optional, and included properties can be null or undefined. + */ +export type PartialNullable = { + [P in keyof T]?: Nullable; +}; From 547b69aa189e830f769527c2c3badffbcbeac2dd Mon Sep 17 00:00:00 2001 From: Drew Hoener Date: Fri, 8 Aug 2025 01:31:42 -0400 Subject: [PATCH 6/7] refactor(Transform): Refactor Transform to typescript module, add interface to represent structure and type methods. Signed-off-by: Drew Hoener --- src/math/Transform.ts | 31 +++++++++++++++++++++---------- src/math/index.ts | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/math/Transform.ts b/src/math/Transform.ts index 4139f63aa..176423edf 100644 --- a/src/math/Transform.ts +++ b/src/math/Transform.ts @@ -3,29 +3,40 @@ * @author David Gossow - dgossow@willowgarage.com */ -import Vector3 from './Vector3.js'; -import Quaternion from './Quaternion.js'; +import Vector3, { type IVector3 } from './Vector3.js'; +import Quaternion, { type IQuaternion } from './Quaternion.js'; + +export interface ITransform { + /** + * The ROSLIB.Vector3 describing the translation. + */ + translation: IVector3; + /** + * The ROSLIB.Quaternion describing the rotation. + */ + rotation: IQuaternion; +} /** * A Transform in 3-space. Values are copied into this object. */ -export default class Transform { - /** - * @param {Object} options - * @param {Vector3} options.translation - The ROSLIB.Vector3 describing the translation. - * @param {Quaternion} options.rotation - The ROSLIB.Quaternion describing the rotation. - */ - constructor(options) { +export default class Transform implements ITransform { + + translation: Vector3; + rotation: Quaternion; + + constructor(options: ITransform) { // Copy the values into this object if they exist this.translation = new Vector3(options.translation); this.rotation = new Quaternion(options.rotation); } + /** * Clone a copy of this transform. * * @returns {Transform} The cloned transform. */ - clone() { + clone(): Transform { return new Transform(this); } } diff --git a/src/math/index.ts b/src/math/index.ts index c15f6257c..3889f7aa1 100644 --- a/src/math/index.ts +++ b/src/math/index.ts @@ -1,4 +1,4 @@ export { default as Pose } from './Pose.js'; export { default as Quaternion, type IQuaternion } from './Quaternion.js'; -export { default as Transform } from './Transform.js'; +export { default as Transform, type ITransform } from './Transform.js'; export { default as Vector3, type IVector3 } from './Vector3.js'; From 07c0d12d435332344685c09ef8cd9e31346ae2e0 Mon Sep 17 00:00:00 2001 From: Drew Hoener Date: Fri, 8 Aug 2025 01:32:47 -0400 Subject: [PATCH 7/7] refactor(Pose): Refactor Pose to typescript module, add interface to represent structure and type methods. Signed-off-by: Drew Hoener --- src/math/Pose.ts | 57 ++++++++++++++++++++++++++++------------------- src/math/index.ts | 2 +- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/math/Pose.ts b/src/math/Pose.ts index adb84eaec..5ab924169 100644 --- a/src/math/Pose.ts +++ b/src/math/Pose.ts @@ -2,67 +2,78 @@ * @fileOverview * @author David Gossow - dgossow@willowgarage.com */ +import Vector3, { type IVector3 } from './Vector3.js'; +import Quaternion, { type IQuaternion } from './Quaternion.js'; +import { type ITransform } from './Transform.js'; +import { PartialNullable } from '../types/interface-types.js'; -import Vector3 from './Vector3.js'; -import Quaternion from './Quaternion.js'; -import Transform from './Transform.js'; +export interface IPose { + /** + * The ROSLIB.Vector3 describing the position. + */ + position: IVector3; + /** + * The ROSLIB.Quaternion describing the orientation. + */ + orientation: IQuaternion; +} /** * A Pose in 3D space. Values are copied into this object. */ -export default class Pose { - /** - * @param {Object} [options] - * @param {Vector3} [options.position] - The ROSLIB.Vector3 describing the position. - * @param {Quaternion} [options.orientation] - The ROSLIB.Quaternion describing the orientation. - */ - constructor(options) { - options = options || {}; - // copy the values into this object if they exist - options = options || {}; - this.position = new Vector3(options.position); - this.orientation = new Quaternion(options.orientation); +export default class Pose implements IPose { + + position: Vector3; + orientation: Quaternion; + + constructor(options?: PartialNullable) { + this.position = new Vector3(options?.position); + this.orientation = new Quaternion(options?.orientation); } + /** * Apply a transform against this pose. * - * @param {Transform} tf - The transform to be applied. + * @param {ITransform} tf - The transform to be applied. */ - applyTransform(tf) { + applyTransform(tf: ITransform) { this.position.multiplyQuaternion(tf.rotation); this.position.add(tf.translation); - var tmp = tf.rotation.clone(); + const tmp = new Quaternion(tf.rotation); tmp.multiply(this.orientation); this.orientation = tmp; } + /** * Clone a copy of this pose. * * @returns {Pose} The cloned pose. */ - clone() { + clone(): Pose { return new Pose(this); } + /** * Multiply this pose with another pose without altering this pose. * * @returns {Pose} The result of the multiplication. */ - multiply(pose) { - var p = pose.clone(); + multiply(pose: Pose): Pose { + const p = pose.clone(); p.applyTransform({ rotation: this.orientation, translation: this.position }); return p; } + /** * Compute the inverse of this pose. * * @returns {Pose} The inverse of the pose. */ - getInverse() { - var inverse = this.clone(); + getInverse(): Pose { + const inverse = this.clone(); inverse.orientation.invert(); inverse.position.multiplyQuaternion(inverse.orientation); inverse.position.x *= -1; diff --git a/src/math/index.ts b/src/math/index.ts index 3889f7aa1..6192483fa 100644 --- a/src/math/index.ts +++ b/src/math/index.ts @@ -1,4 +1,4 @@ -export { default as Pose } from './Pose.js'; +export { default as Pose, type IPose } from './Pose.js'; export { default as Quaternion, type IQuaternion } from './Quaternion.js'; export { default as Transform, type ITransform } from './Transform.js'; export { default as Vector3, type IVector3 } from './Vector3.js';