/** * @param sensorRevolveCount センサーから取得した合計回転数 * @param sensorUpdatedTime センサー時刻(1/1024秒単位で刻まれる) * @return 更新が行われたらtrue */ public boolean update(int sensorRevolveCount, int sensorUpdatedTime) { sensorRevolveCount &= BleSpeedCadenceUtil.SENSOR_16BIT_MASK; sensorUpdatedTime &= BleSpeedCadenceUtil.SENSOR_16BIT_MASK; if (mLastUpdatedRevolveCount < 0 || mStartRevolveCount < 0) { mStartRevolveCount = sensorRevolveCount; mLastUpdatedRevolveCount = sensorRevolveCount; mLastUpdatedSensorTime = sensorUpdatedTime; return false; } final double oldSensorRPM = getRpm(); // 古いRPM // 回転差分と時間差分を取得する final int offsetRevolve = BleSpeedCadenceUtil.get16bitOffset(mLastUpdatedRevolveCount, sensorRevolveCount); final int offsetTimeMs = (int) (BleSpeedCadenceUtil.sensorTimeToSeconds( BleSpeedCadenceUtil.get16bitOffset(mLastUpdatedSensorTime, sensorUpdatedTime)) * 1000.0); // 指定秒経過していなかったら時間単位の精度が低いため何もしない if (offsetTimeMs < mStatusCheckIntervalMs) { // AppLog.cadence("abort interval (%d ms < %d ms)", offsetTimeMs, // mStatusCheckIntervalMs); return false; } AppLog.bleData(String.format("Revolve(+%d) Time(+%d ms) ", offsetRevolve, offsetTimeMs)); // 計算する { // 1minuteが基本 final double mult = (1000.0 * 60.0) / (double) offsetTimeMs; // 指定時間に行われた回転数から、1分間の回転数を求める mRpm = (double) offsetRevolve * mult; if (mRpm > 600) { // 何らかのエラー // 600RPMを超えると、ロードバイクなら時速220kmを超えることになり、世界記録を超えてしまうためこれはエラーと判断出来る mRpm = oldSensorRPM; } } // 値を上書きする if (BleSpeedCadenceUtil.is16bitOverflow(mLastUpdatedRevolveCount, sensorRevolveCount)) { // 回転数がオーバーフローしたので、カウンタを回す ++mRevolvingOverflowCount; } mLastUpdatedRevolveCount = sensorRevolveCount; mLastUpdatedSensorTime = sensorUpdatedTime; mUpdatedTime = mClock.now(); return true; }
@Test public void _16bit加算値が正常に差分取得できることを確認する() throws Exception { assertEquals(BleSpeedCadenceUtil.get16bitOffset(0, 1), 1); assertEquals(BleSpeedCadenceUtil.get16bitOffset(0xFFFE, 0), 2); assertEquals(BleSpeedCadenceUtil.get16bitOffset(0xFFFF, 0x00010000), 1); assertEquals(BleSpeedCadenceUtil.get16bitOffset(1, 0x007FFFF), (0xFFFF - 1)); assertEquals(BleSpeedCadenceUtil.get16bitOffset(0, 0x1234FFFF), 0xFFFF); // 適当な回数だけ加算し、ループを含めて正常に差分値が取得できることを確認する int time = 0; while (time < (0xFFFF * 2)) { int diff = (int) (10.0 + Math.random() * 1000); int oldTime = time; time += diff; assertTrue(BleSpeedCadenceUtil.get16bitOffset(oldTime, time) > 0); assertEquals(BleSpeedCadenceUtil.get16bitOffset(oldTime, time), diff); } }
@Test public void 低精度時計が秒に変換できることを確認する() throws Exception { assertEquals(BleSpeedCadenceUtil.sensorTimeToSeconds(1024), 1.0, 0.0001); assertEquals(BleSpeedCadenceUtil.sensorTimeToSeconds(1024 * 60), 60.0, 0.0001); assertEquals(BleSpeedCadenceUtil.sensorTimeToSeconds(1024 / 2), 0.5, 0.0001); }