UNPKG

imu-tools

Version:

Web browser subscription to BLE and MQTT IMU sensor data

68 lines (62 loc) 2.08 kB
export const isMobile = Boolean( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ); export function eulerToQuat(yaw, pitch, roll) { const [c1, s1] = [Math.cos(yaw / 2), Math.sin(yaw / 2)]; const [c2, s2] = [Math.cos(pitch / 2), Math.sin(pitch / 2)]; const [c3, s3] = [Math.cos(roll / 2), Math.sin(roll / 2)]; const w = c1 * c2 * c3 - s1 * s2 * s3; const x = s1 * s2 * c3 + c1 * c2 * s3; const y = s1 * c2 * c3 + c1 * s2 * s3; const z = c1 * s2 * c3 - s1 * c2 * s3; return [x, y, z, w]; } export function quatToEuler(q0, q1, q2, q3) { const rx = Math.atan2(2 * (q0 * q1 + q2 * q3), 1 - 2 * (q1 * q1 + q2 * q2)); const ry = Math.asin(2 * (q0 * q2 - q3 * q1)); const rz = Math.atan2(2 * (q0 * q3 + q1 * q2), 1 - 2 * (q2 * q2 + q3 * q3)); return [rx, ry, rz]; } export function imuQuatToEuler([q0, q1, q2, q3]) { const radians = quatToEuler(q3, q1, q2, q0); const degrees = radians.map((e) => (e * 180) / Math.PI); if (degrees[2] < 0) degrees[2] += 360; return degrees; } /** Convert a quaternion to a 4 x 4 transformation matrix. */ export function quatToMatrix(w, x, y, z) { const x2 = x ** 2; const y2 = y ** 2; const z2 = z ** 2; const wx = w * x; const wy = w * y; const wz = w * z; const xy = x * y; const xz = x * z; const yz = y * z; return [ ...[1 - 2 * (y2 + z2), 2 * (xy - wz), 2 * (xz + wy), 0], ...[2 * (xy + wz), 1 - 2 * (x2 + z2), 2 * (yz - wx), 0], ...[2 * (xz - wy), 2 * (yz + wx), 1 - 2 * (x2 + y2), 0], ...[0, 0, 0, 1], ]; } /** Apply callback no more than once per animation frame. * * @return A function that wraps callback, and queues it to be called on the * next animation frame. */ export function throttled(callback) { const buffer = []; return (data) => { if (buffer.length === 0) { requestAnimationFrame(() => { callback(buffer.pop()); }); } buffer[0] = data; }; }