123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- #include "string.h"
- #include "stdbool.h"
- #include "stdlib.h"
- #define _USE_MATH_DEFINES
- #include "math.h"
- #include "PowerDecoder.h"
- #include "RecordOutput.h"
- #include "DecodePowerOnly.h"
- static BPSAMPLER stState;
- static PowerRecordReceiver prrPtr;
- static double dRecordInterval;
- static double dReSyncInterval;
- #define UPDATE_EVENT_BYTE 1
- #define PEDAL_BALANCE_BYTE 2
- #define INST_CADENCE_BYTE 3
- #define ACCUM_POWER_LSB 4
- #define ACCUM_POWER_MSB 5
- #define INST_POWER_LSB 6
- #define INST_POWER_MSB 7
- void DecodePowerOnly_Init(double dRecordInterval_, double dTimeBase_, double dReSyncInterval_, PowerRecordReceiver powerRecordReceiverPtr_)
- {
- ResamplerOutput_Init(&stState, (int)(dRecordInterval_* PO_TIME_QUANTIZATION), dRecordInterval_, (int)(dTimeBase_ * PO_TIME_QUANTIZATION));
- prrPtr = powerRecordReceiverPtr_;
- dRecordInterval = dRecordInterval_;
- dReSyncInterval = dReSyncInterval_;
- }
- void DecodePowerOnly_Message(double dTime_, unsigned char messagePayload_[])
- {
-
- if (stState.ucLastEventCount != messagePayload_[1])
- {
- if ((dTime_ - stState.dLastMessageTime) > dReSyncInterval)
- {
- DecodePowerOnly_Resync(dTime_, messagePayload_);
- }
- else
- {
- DecodePowerOnly(dTime_, messagePayload_);
- }
- stState.dLastMessageTime = dTime_;
- stState.ucLastEventCount = messagePayload_[1];
- }
- }
- void DecodePowerOnly_SetTimeBase(double dTimeBase_)
- {
-
- stState.usTimeBase = (int)(dTimeBase_ * PO_TIME_QUANTIZATION);
- }
- void DecodePowerOnly_Resync(double dCurrentTime_, unsigned char messagePayload_[])
- {
- unsigned short usCurrentAccumPower;
- unsigned char ucCurrentEventCount = messagePayload_[UPDATE_EVENT_BYTE];
- double dCurrentRecordEpoch = (floor(dCurrentTime_ / dRecordInterval)) * dRecordInterval;
- if ((stState.dLastRecordTime != 0)
- && (dCurrentRecordEpoch - stState.dLastRecordTime > 0)
- && (dCurrentRecordEpoch - stState.dLastRecordTime < MAXIMUM_TIME_GAP))
- {
- stState.ucRecordGapCount = (unsigned char)((dCurrentRecordEpoch - stState.dLastRecordTime + dRecordInterval * 0.5)
- / dRecordInterval);
-
- stState.fGapEnergy = stState.fAccumEnergy;
- stState.fGapRotation = stState.fAccumRotation;
-
- RecordOutput_FillGap(prrPtr, &stState);
- }
- usCurrentAccumPower = messagePayload_[ACCUM_POWER_LSB];
- usCurrentAccumPower += ((unsigned short)messagePayload_[ACCUM_POWER_MSB]) << 8;
- stState.ucCadence = messagePayload_[INST_CADENCE_BYTE];
- stState.fAccumEnergy = 0;
- stState.fPendingEnergy = 0;
- stState.fGapEnergy = 0;
- stState.fAccumRotation = 0;
- stState.fPendingRotation = 0;
- stState.fGapRotation = 0;
- stState.ucRecordGapCount = 0;
- stState.ulEventTime = 0;
- stState.ulLastRecordTime = 0;
- stState.dLastMessageTime = dCurrentTime_;
-
- stState.dLastRecordTime = dCurrentRecordEpoch;
- stState.usLastAccumPeriod = 0;
- stState.ucLastRotationTicks = messagePayload_[UPDATE_EVENT_BYTE];
- stState.ucLastEventCount = messagePayload_[UPDATE_EVENT_BYTE];
- stState.usLastAccumTorque = usCurrentAccumPower;
- }
- void DecodePowerOnly(double dTime_, unsigned char messagePayload_[])
- {
- unsigned long ulNewEventTime;
- unsigned short usCurrentAccumPower;
- unsigned short usDeltaPeriod;
- unsigned short usDeltaPowerPeriod;
- unsigned short usDeltaPower;
- unsigned short usInstPower;
- unsigned char ucEventBalance = messagePayload_[PEDAL_BALANCE_BYTE];
- unsigned char ucCurrentEventCount = messagePayload_[UPDATE_EVENT_BYTE];
- unsigned char ucDeltaTicks;
- float fEventEnergy;
- usCurrentAccumPower = messagePayload_[ACCUM_POWER_LSB];
- usCurrentAccumPower += ((unsigned short)messagePayload_[ACCUM_POWER_MSB]) << 8;
- usInstPower = messagePayload_[INST_POWER_LSB];
- usInstPower += ((unsigned short)messagePayload_[INST_POWER_MSB]) << 8;
- usDeltaPower = usCurrentAccumPower - stState.usLastAccumTorque;
- ucDeltaTicks = messagePayload_[UPDATE_EVENT_BYTE] - stState.ucLastEventCount;
- stState.ucCadence = messagePayload_[INST_CADENCE_BYTE];
-
- if ((usInstPower > 0) && (usDeltaPower > 100 * usInstPower))
- {
- usDeltaPower = usInstPower;
- }
- if (stState.ucCadence > 0)
- {
- usDeltaPeriod = (unsigned short)(((unsigned long)ucDeltaTicks * PO_TIME_QUANTIZATION * 60L + (stState.ucCadence >> 1)) / stState.ucCadence);
- }
- else
- {
- usDeltaPeriod = 0xFFFF;
- usDeltaPower = 0;
- }
- if (stState.usTimeBase != 0)
- {
-
- ulNewEventTime = stState.ulEventTime + (unsigned long)stState.usTimeBase*ucDeltaTicks;
- #if defined (TIMEBASE_DRIFT_CORRECTION)
-
-
- if ((dTime_ - stState.dLastRecordTime) > (RECORD_INTERVAL * 2))
- {
-
- ulNewEventTime += stState.usRecordInterval;
- }
- #endif
-
-
-
- usDeltaPowerPeriod = stState.usTimeBase*ucDeltaTicks;
- fEventEnergy = (float)usDeltaPower;
- }
- else
- {
-
- usDeltaPowerPeriod = usDeltaPeriod;
- ulNewEventTime = stState.ulEventTime + (unsigned long)usDeltaPeriod;
- fEventEnergy = (float)usDeltaPower*usDeltaPeriod / PO_TIME_QUANTIZATION / ucDeltaTicks;
- }
- if (((unsigned short)(ulNewEventTime - stState.ulLastRecordTime)) >= stState.usRecordInterval)
- {
-
-
-
- stState.ucRecordGapCount = (unsigned char)((ulNewEventTime / stState.usRecordInterval) - (stState.ulLastRecordTime / stState.usRecordInterval) - 1);
-
- stState.fPendingEnergy = stState.fAccumEnergy + fEventEnergy * ((float)(stState.usRecordInterval - (stState.ulEventTime % stState.usRecordInterval))) / ((float)usDeltaPowerPeriod);
-
- stState.fAccumEnergy = fEventEnergy * ((float)(ulNewEventTime % stState.usRecordInterval)) / ((float)usDeltaPowerPeriod);
-
- stState.fGapEnergy = fEventEnergy * ((unsigned short)stState.ucRecordGapCount * stState.usRecordInterval) / ((float)usDeltaPowerPeriod);
-
- stState.fPendingRotation = stState.fAccumRotation + (float)ucDeltaTicks * ((float)(stState.usRecordInterval - (stState.ulEventTime % stState.usRecordInterval))) / ((float)usDeltaPeriod);
- stState.fAccumRotation = (float)ucDeltaTicks * ((float)(ulNewEventTime % stState.usRecordInterval)) / ((float)usDeltaPeriod);
- stState.fGapRotation = (float)ucDeltaTicks * ((unsigned short)stState.ucRecordGapCount * stState.usRecordInterval) / ((float)usDeltaPeriod);
- }
- else
- {
-
-
- stState.fAccumEnergy += fEventEnergy;
- if (stState.usTimeBase != 0)
- {
- stState.fAccumRotation += (float)ucDeltaTicks * (float)(stState.ucCadence) / 60.0f;
- }
- else
- {
- stState.fAccumRotation += (float)ucDeltaTicks;
- }
- stState.fPendingEnergy = 0;
- stState.fPendingRotation = 0;
- stState.ucRecordGapCount = 0;
- }
- stState.ulEventTime = ulNewEventTime;
- if (((unsigned short)(stState.ulEventTime - stState.ulLastRecordTime)) >= stState.usRecordInterval)
- {
- RecordOutput(prrPtr, &stState);
- }
- else
- {
-
-
-
- if ((dTime_ - stState.dLastRecordTime) > dRecordInterval)
- {
- while ((dTime_ - stState.dLastRecordTime) > dRecordInterval)
- {
- stState.dLastRecordTime += ((double)stState.usRecordInterval) / PO_TIME_QUANTIZATION;
- (prrPtr)(stState.dLastRecordTime, stState.dTotalRotation, stState.dTotalEnergy, 0.0, 0.0);
- }
- }
- }
-
- stState.ucLastRotationTicks = messagePayload_[UPDATE_EVENT_BYTE];
- stState.ucLastEventCount = messagePayload_[UPDATE_EVENT_BYTE];
- stState.usLastAccumTorque = usCurrentAccumPower;
- }
|