Skip to content

Commit fea5a79

Browse files
marknolanclaude
andcommitted
DEV-922 Upstream gen-2 default alignment into SensorLSM6DSV
Replace the identity default-alignment placeholder with the real sensor->ASM matrices, making the driver the single source of truth for gen-2 (LSM6DSV/LIS2MDL) default calibration and letting the parser-side applyGen2DefaultAlignment override in ASM_PC/VerisenseDriver be deleted rather than corrected in two places. The literals are stored in APPLIED form (physical = applied . (raw-bias)/sens), reading exactly as verisense-device-console displays them and as the web SDK declares them (calibrationDefaults.ts, CALIBRATION_SENSORS_GEN2); the driver-form AM handed to the calibration blocks is derived from them by a true matrix inverse, since UtilCalibration applies AM^-1. Accel/gyro share the chip mounting (det +1); the LIS2MDL frame is left-handed (det -1). No hardware-revision gate: only 2nd-generation revisions (SR61>=5, SR68>=9) carry this IMU, so any device instantiating this sensor class is gen-2 by construction. Verisense-only: com.shimmerresearch.sensors .lsm6dsv.SensorLSM6DSV (Shimmer3R) is a separate class and untouched. Builds on the DEV-922 mag-sensitivity fix (PR #281): stacked so the 667 LSB/Gauss change and this land together with one reference-CSV regeneration pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 08ddcdc commit fea5a79

1 file changed

Lines changed: 37 additions & 17 deletions

File tree

ShimmerDriver/src/main/java/com/shimmerresearch/verisense/sensors/SensorLSM6DSV.java

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,12 @@
4747
* calibrated magnetometer output is in GAUSS, consistent with every other Shimmer
4848
* magnetometer and with the per-unit calibration the device stores.
4949
* <p>
50-
* Alignment is left as identity here and corrected by the file parser per hardware
51-
* revision; offsets are zero.
50+
* Default alignment is the real sensor->ASM frame map (accel/gyro share the chip
51+
* mounting; the LIS2MDL frame is left-handed), matching the web SDK's
52+
* CALIBRATION_SENSORS_GEN2 and what verisense-device-console writes to the device.
53+
* No hardware-revision gate is needed: every revision carrying this IMU (SR61 rev
54+
* &gt;= 5, SR68 rev &gt;= 9) shares the same mounting, so a device that has an
55+
* LSM6DSV is second-generation by construction. Offsets are zero.
5256
*
5357
* @author Mark Nolan
5458
*/
@@ -237,12 +241,28 @@ public static final class DatabaseConfigHandle {
237241
CompatibilityInfoForMaps.listOfCompatibleVersionInfoLSM6DSV);
238242

239243
// ----------------- Calibration Start -----------------------
240-
// Identity alignment is a placeholder, NOT the real sensor->ASM map: the file
241-
// parser overrides it per hardware revision at parse time (see
242-
// CalibrationFileManager.applyGen2DefaultAlignment in the VerisenseDriver repo).
243-
// Correcting it here as well would give two sources of truth for the same values.
244244
public static final double[][] DEFAULT_OFFSET_VECTOR_LSM6DSV = {{0},{0},{0}};
245-
public static final double[][] DEFAULT_ALIGNMENT_MATRIX_LSM6DSV = {{1,0,0},{0,1,0},{0,0,1}};
245+
246+
// Default alignment, stored first in APPLIED form - the sensor->ASM map,
247+
// physical = applied . (raw - bias) / sens - so the literals below read exactly
248+
// as verisense-device-console displays them and as the web SDK declares them
249+
// (calibrationDefaults.ts, CALIBRATION_SENSORS_GEN2). Those two and this class
250+
// must stay in agreement; they are the same physical mounting.
251+
/** Applied sensor->ASM alignment for the LSM6DSV accel + gyro; det +1 (a proper rotation). */
252+
public static final double[][] APPLIED_ALIGNMENT_LSM6DSV_ACCEL_GYRO = {{0,1,0},{0,0,1},{1,0,0}};
253+
/** Applied sensor->ASM alignment for the LIS2MDL mag; its frame is left-handed, so det -1 (a reflection). */
254+
public static final double[][] APPLIED_ALIGNMENT_LIS2MDL_MAG = {{1,0,0},{0,0,1},{0,1,0}};
255+
256+
// The driver stores the opposite convention: CalibDetailsKinematic holds AM and
257+
// UtilCalibration computes AM^-1 . SM^-1 . (data - OV), so the matrices handed to
258+
// the calibration blocks below are the INVERSES of the applied form. A true
259+
// inverse, not a transpose: the two coincide only for orthogonal
260+
// signed-permutation defaults like these, and would differ for a rig-measured
261+
// matrix with cross-axis terms.
262+
public static final double[][] DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO =
263+
UtilCalibration.matrixInverse3x3(APPLIED_ALIGNMENT_LSM6DSV_ACCEL_GYRO);
264+
public static final double[][] DEFAULT_ALIGNMENT_LIS2MDL_MAG =
265+
UtilCalibration.matrixInverse3x3(APPLIED_ALIGNMENT_LIS2MDL_MAG);
246266

247267
// Accel sensitivity (LSB per m/s^2) = 32768/(FS_g*9.80665)
248268
public static final double[][] SENS_ACCEL_2G = {{1670.703,0,0},{0,1670.703,0},{0,0,1670.703}};
@@ -274,35 +294,35 @@ public static final class DatabaseConfigHandle {
274294

275295
public CalibDetailsKinematic calibDetailsAccel2g = new CalibDetailsKinematic(
276296
LSM6DSV_ACCEL_RANGE.RANGE_2G.configValue, LSM6DSV_ACCEL_RANGE.RANGE_2G.label,
277-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_ACCEL_2G, DEFAULT_OFFSET_VECTOR_LSM6DSV);
297+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_ACCEL_2G, DEFAULT_OFFSET_VECTOR_LSM6DSV);
278298
public CalibDetailsKinematic calibDetailsAccel4g = new CalibDetailsKinematic(
279299
LSM6DSV_ACCEL_RANGE.RANGE_4G.configValue, LSM6DSV_ACCEL_RANGE.RANGE_4G.label,
280-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_ACCEL_4G, DEFAULT_OFFSET_VECTOR_LSM6DSV);
300+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_ACCEL_4G, DEFAULT_OFFSET_VECTOR_LSM6DSV);
281301
public CalibDetailsKinematic calibDetailsAccel8g = new CalibDetailsKinematic(
282302
LSM6DSV_ACCEL_RANGE.RANGE_8G.configValue, LSM6DSV_ACCEL_RANGE.RANGE_8G.label,
283-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_ACCEL_8G, DEFAULT_OFFSET_VECTOR_LSM6DSV);
303+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_ACCEL_8G, DEFAULT_OFFSET_VECTOR_LSM6DSV);
284304
public CalibDetailsKinematic calibDetailsAccel16g = new CalibDetailsKinematic(
285305
LSM6DSV_ACCEL_RANGE.RANGE_16G.configValue, LSM6DSV_ACCEL_RANGE.RANGE_16G.label,
286-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_ACCEL_16G, DEFAULT_OFFSET_VECTOR_LSM6DSV);
306+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_ACCEL_16G, DEFAULT_OFFSET_VECTOR_LSM6DSV);
287307

288308
public CalibDetailsKinematic calibDetailsGyro125dps = new CalibDetailsKinematic(
289309
LSM6DSV_GYRO_RANGE.RANGE_125DPS.configValue, LSM6DSV_GYRO_RANGE.RANGE_125DPS.label,
290-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_GYRO_125DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
310+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_GYRO_125DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
291311
public CalibDetailsKinematic calibDetailsGyro250dps = new CalibDetailsKinematic(
292312
LSM6DSV_GYRO_RANGE.RANGE_250DPS.configValue, LSM6DSV_GYRO_RANGE.RANGE_250DPS.label,
293-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_GYRO_250DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
313+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_GYRO_250DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
294314
public CalibDetailsKinematic calibDetailsGyro500dps = new CalibDetailsKinematic(
295315
LSM6DSV_GYRO_RANGE.RANGE_500DPS.configValue, LSM6DSV_GYRO_RANGE.RANGE_500DPS.label,
296-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_GYRO_500DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
316+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_GYRO_500DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
297317
public CalibDetailsKinematic calibDetailsGyro1000dps = new CalibDetailsKinematic(
298318
LSM6DSV_GYRO_RANGE.RANGE_1000DPS.configValue, LSM6DSV_GYRO_RANGE.RANGE_1000DPS.label,
299-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_GYRO_1000DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
319+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_GYRO_1000DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
300320
public CalibDetailsKinematic calibDetailsGyro2000dps = new CalibDetailsKinematic(
301321
LSM6DSV_GYRO_RANGE.RANGE_2000DPS.configValue, LSM6DSV_GYRO_RANGE.RANGE_2000DPS.label,
302-
DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_GYRO_2000DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
322+
DEFAULT_ALIGNMENT_LSM6DSV_ACCEL_GYRO, SENS_GYRO_2000DPS, DEFAULT_OFFSET_VECTOR_LSM6DSV);
303323

304324
public CalibDetailsKinematic calibDetailsMag = new CalibDetailsKinematic(
305-
0, "Default", DEFAULT_ALIGNMENT_MATRIX_LSM6DSV, SENS_MAG, DEFAULT_OFFSET_VECTOR_LSM6DSV);
325+
0, "Default", DEFAULT_ALIGNMENT_LIS2MDL_MAG, SENS_MAG, DEFAULT_OFFSET_VECTOR_LSM6DSV);
306326

307327
public CalibDetailsKinematic mCurrentCalibDetailsAccel = calibDetailsAccel4g;
308328
public CalibDetailsKinematic mCurrentCalibDetailsGyro = calibDetailsGyro500dps;

0 commit comments

Comments
 (0)