Skip to content

Commit fe367a5

Browse files
marknolanclaude
andcommitted
DEV-958: use the ST datasheet accel sensitivity for the gen-2 LSM6DSV
SensorLSM6DSV derived accel sensitivity as 32768/(FS_g*9.80665), while the firmware seed, the web SDK catalog and the driver's own gen-1 classes all use the ST datasheet mg/LSB figure - a 0.0576% split, and the only such divergence left in the gen-2 chain. +-2 g 1670.703 -> 1671.665922915 +-4 g 835.3517 -> 835.832961457 +-8 g 417.6759 -> 417.916480729 +-16 g 208.8379 -> 208.958240364 Worth being explicit that the old values were not a mistake, and this is not a correctness fix. Checked against ST's own vendored driver (lsm6dsv_reg.c): every printed accel figure - 0.061 / 0.122 / 0.244 / 0.488 mg/LSB - is exactly 32768/FS rounded to three significant figures, because the accel really does span the full 16-bit range at nominal full scale. So the derived form was the more precise of the two, and moving to the datasheet figure trades a little accuracy for agreement. Agreement is worth more here. The firmware seeds these values into the on-device calibration blob, so they are what the device reports and what becomes the source of truth once per-unit calibration is honoured; keeping the exact form would leave a 0.0576% step change in calibrated output waiting to surface on that day. 0.0576% is far inside per-unit sensitivity variation. The gyro is a genuinely different case and is deliberately left alone: 4.375 mdps/LSB implies a real full scale of 143.4 dps on the +-125 dps setting, which is where the part is observed to saturate, so there a 32768/FS derivation is wrong by ~14.7% rather than by a rounding. The comment now spells out the distinction so the two are not "fixed" to match each other later. API_00008 CAL locks updated (accel +-4 g literal); 51 driver tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent edc3f7d commit fe367a5

2 files changed

Lines changed: 37 additions & 13 deletions

File tree

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

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
* {@code VerisenseDevice.parseDataBlockDataLsm6dsv(...)}. This class provides the
4242
* channel definitions, configuration and calibration.
4343
* <p>
44-
* Sensitivities: 32768/(FS*9.80665) LSB per m/s^2 for accel, the ST angular-rate
44+
* Sensitivities: the ST datasheet nominal for every axis - 0.061 mg/LSB at +-2 g
4545
* spec of 4.375 mdps/LSB at +-125 dps for gyro, and 667 LSB/Gauss for the LIS2MDL
4646
* mag - the last taken from {@link SensorLIS2MDL} rather than duplicated here, so
4747
* calibrated magnetometer output is in GAUSS, consistent with every other Shimmer
@@ -285,16 +285,38 @@ public static final class DatabaseConfigHandle {
285285
* det +1 and computes canonical 0.0 entries, so it stays derived.) */
286286
public static final double[][] DEFAULT_ALIGNMENT_LIS2MDL_MAG = {{1,0,0},{0,0,1},{0,1,0}};
287287

288-
// Accel sensitivity (LSB per m/s^2) = 32768/(FS_g*9.80665)
289-
public static final double[][] SENS_ACCEL_2G = {{1670.703,0,0},{0,1670.703,0},{0,0,1670.703}};
290-
public static final double[][] SENS_ACCEL_4G = {{835.3517,0,0},{0,835.3517,0},{0,0,835.3517}};
291-
public static final double[][] SENS_ACCEL_8G = {{417.6759,0,0},{0,417.6759,0},{0,0,417.6759}};
292-
public static final double[][] SENS_ACCEL_16G = {{208.8379,0,0},{0,208.8379,0},{0,0,208.8379}};
288+
// Accel sensitivity (LSB per m/s^2) from the ST datasheet linear-acceleration
289+
// sensitivity: 0.061 / 0.122 / 0.244 / 0.488 mg/LSB, i.e. 1/(mg_per_LSB/1000)/9.80665.
290+
//
291+
// These were previously derived as 32768/(FS_g*9.80665), which is the exact form:
292+
// unlike the gyro (see below) the accel really does span the full 16-bit range at
293+
// its nominal full scale, so ST's printed figures are just 32768/FS rounded to
294+
// three significant figures (2/32768 g = 0.06103516 mg/LSB -> "0.061"). The exact
295+
// derivation is therefore 0.0576% larger and, on its own terms, slightly more
296+
// accurate.
297+
//
298+
// We use the datasheet figures anyway, for agreement rather than precision. The
299+
// firmware seeds these exact values into the on-device calibration blob
300+
// (SC_ACCEL_SENS in asm_calibration.c), so they are what the device itself
301+
// reports and what becomes the source of truth once per-unit calibration is
302+
// loaded; the web SDK catalog and the gen-1 SensorLSM6DS3/SensorLIS2DW12 classes
303+
// use them too, as does ST's own reference driver (lsm6dsv_from_fs2_to_mg
304+
// multiplies by 0.061f). Keeping the exact form here would leave a 0.0576% step
305+
// change in calibrated output waiting to appear the day the device blob is
306+
// honoured. 0.0576% is far inside per-unit sensitivity variation, so consistency
307+
// is worth more than the last digit.
308+
public static final double[][] SENS_ACCEL_2G = {{1671.665922915,0,0},{0,1671.665922915,0},{0,0,1671.665922915}};
309+
public static final double[][] SENS_ACCEL_4G = {{835.832961457,0,0},{0,835.832961457,0},{0,0,835.832961457}};
310+
public static final double[][] SENS_ACCEL_8G = {{417.916480729,0,0},{0,417.916480729,0},{0,0,417.916480729}};
311+
public static final double[][] SENS_ACCEL_16G = {{208.958240364,0,0},{0,208.958240364,0},{0,0,208.958240364}};
293312

294313
// Gyro sensitivity (LSB per dps) from the ST datasheet angular-rate sensitivity
295314
// (4.375 mdps/LSB at +-125 dps, doubling per range) - the same spec/values as the
296-
// gen-1 LSM6DS3. NOTE: the gyro does NOT span the full 16-bit range at its nominal
297-
// full scale (unlike the accel), so a 32768/FS derivation is ~12.8% off.
315+
// gen-1 LSM6DS3. NOTE: unlike the accel above, the gyro genuinely does NOT span
316+
// the full 16-bit range at its nominal full scale - 4.375 mdps/LSB implies a real
317+
// full scale of 143.4 dps for the +-125 dps setting, which is exactly where the
318+
// part is observed to saturate - so here a 32768/FS derivation is not a rounding
319+
// difference but plainly wrong (~14.7%).
298320
public static final double[][] SENS_GYRO_125DPS = {{228.571428571,0,0},{0,228.571428571,0},{0,0,228.571428571}};
299321
public static final double[][] SENS_GYRO_250DPS = {{114.285714286,0,0},{0,114.285714286,0},{0,0,114.285714286}};
300322
public static final double[][] SENS_GYRO_500DPS = {{57.142857143,0,0},{0,57.142857143,0},{0,0,57.142857143}};

ShimmerDriver/src/test/java/com/shimmerresearch/verisense/API_00008_VerisenseLsm6dsvTaggedFifoParsing.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,16 @@ public void test001_accelGyroMagInterleaved() throws Exception {
142142
// CAL assertions - regression-locks the calibration constants against
143143
// LITERAL expected values (the gyro sensitivity was ~12.8% wrong before the
144144
// DEV-793 round-2 review fix; deriving the expectation from the class
145-
// constants would defeat the lock). Defaults: accel +/-4 g = 835.3517
146-
// LSB/(m/s^2); gyro +/-500 dps = 57.142857 LSB/dps (ST 17.50 mdps/LSB);
145+
// constants would defeat the lock). Defaults: accel +/-4 g = 835.832961457
146+
// LSB/(m/s^2) (ST 0.122 mg/LSB - see the sensitivity note in SensorLSM6DSV
147+
// for why the datasheet figure is used and not the exact 32768/FS form);
148+
// gyro +/-500 dps = 57.142857 LSB/dps (ST 17.50 mdps/LSB);
147149
// mag 667 LSB/Gauss (LIS2MDL 1.5 mGauss/LSB, legacy rounding of 666.67).
148150
// Since DEV-922 the defaults also apply the gen-2 sensor->ASM alignment:
149151
// accel/gyro calibrated X/Y/Z come from raw Y/Z/X, mag X/Y/Z from raw X/Z/Y.
150-
assertEquals(-200 / 835.3517, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_ACC_X), 0.0001);
151-
assertEquals(300 / 835.3517, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_ACC_Y), 0.0001);
152-
assertEquals(100 / 835.3517, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_ACC_Z), 0.0001);
152+
assertEquals(-200 / 835.832961457, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_ACC_X), 0.0001);
153+
assertEquals(300 / 835.832961457, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_ACC_Y), 0.0001);
154+
assertEquals(100 / 835.832961457, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_ACC_Z), 0.0001);
153155
assertEquals(-20 / 57.142857143, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_GYRO_X), 0.0001);
154156
assertEquals(30 / 57.142857143, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_GYRO_Y), 0.0001);
155157
assertEquals(10 / 57.142857143, cal(aligned0, SensorLSM6DSV.ObjectClusterSensorName.LSM6DSV_GYRO_Z), 0.0001);

0 commit comments

Comments
 (0)