powerfun-unity/Assets/Scripts/Devices/Ble/Characteristic/CyclingSpeedCadenceMeasurement.cs

274 lines
8.4 KiB
C#

using Assets.Scripts.Ble;
using Assets.Scripts.Devices.Ble.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Assets.Scripts.Devices.Ble.Extension;
namespace Assets.Scripts.Devices.Ble.Characteristic
{
public class CyclingSpeedCadenceMeasurement : ICharacteristic
{
private CyclingSpeedCadenceMeasurement.IUpdate _currentUpdate;
private CyclingSpeedCadenceMeasurement.IUpdate _previousUpdate = new CyclingSpeedCadenceMeasurement.NullUpdate();
private const byte MaxNoEvents = (byte)4;
private byte _noCadenceEventCount;
private byte _noSpeedEventCount;
public Guid Uuid => ServiceUuids.Characteristics.CscMeasurement;
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.CyclingSpeedCadence).IdGuid;
public bool IsOptional => false;
public double Speed { get; private set; }
public int Cadence { get; private set; }
public double WheelCircumference { private get; set; }
public CyclingSpeedCadenceMeasurement(double wheelCircumference)
{
this.WheelCircumference = wheelCircumference;
}
public void HandleAttributeReceived(byte[] data)
{
//throw new NotImplementedException();
//Debug.Log(string.Join(",", data));
this._currentUpdate = new CyclingSpeedCadenceMeasurement.Update(data);
this.HandleCadenceUpdate();
this.HandleSpeedUpdate();
this._previousUpdate = this._currentUpdate;
}
private void HandleCadenceUpdate()
{
if (this._currentUpdate.HasCadence && (int)this._currentUpdate.CadenceEventCount != (int)this._previousUpdate.CadenceEventCount)
{
this._noCadenceEventCount = (byte)0;
if (this.CadenceTimeDifference() <= 0)
return;
this.Cadence = this.CalculateCadence();
}
else
{
this._noCadenceEventCount = (byte)((uint)this._noCadenceEventCount + 1U);
if ((int)this._noCadenceEventCount < 4)
return;
this.Cadence = 0;
}
Debug.Log("踏频值:" + this.Cadence);
}
private void HandleSpeedUpdate()
{
if (this._currentUpdate.HasSpeed && (int)this._currentUpdate.SpeedEventCount != (int)this._previousUpdate.SpeedEventCount)
{
this._noSpeedEventCount = (byte)0;
double num = this.CalculateSpeed();
if (num >= 150.0)
return;
this.Speed = num;
}
else
{
this._noSpeedEventCount = (byte)((uint)this._noSpeedEventCount + 1U);
if ((int)this._noSpeedEventCount < 4)
return;
this.Speed = 0.0;
}
}
private int CalculateCadence()
{
int num = this.CadenceEventDifference() * 61440 / this.CadenceTimeDifference();
if (num > (int)byte.MaxValue)
return 0;
//return (int)byte.MaxValue;
if (num < 0)
return 0;
return num;
}
private int CadenceTimeDifference()
{
if ((int)this._currentUpdate.CadenceTime1024 > (int)this._previousUpdate.CadenceTime1024)
return (int)this._currentUpdate.CadenceTime1024 - (int)this._previousUpdate.CadenceTime1024;
return (int)ushort.MaxValue - (int)this._previousUpdate.CadenceTime1024 + (int)this._currentUpdate.CadenceTime1024 + 1;
}
private int CadenceEventDifference()
{
if ((int)this._currentUpdate.CadenceEventCount > (int)this._previousUpdate.CadenceEventCount)
return (int)this._currentUpdate.CadenceEventCount - (int)this._previousUpdate.CadenceEventCount;
return (int)ushort.MaxValue - (int)this._previousUpdate.CadenceEventCount + (int)this._currentUpdate.CadenceEventCount + 1;
}
private double CalculateSpeed()
{
double num = (double)(ulong)(this.WheelCircumference / 10.0 * 36864.0 * (double)this.SpeedEventDifference() / (double)this.SpeedTimeDifference()) / 1000.0;
if (num >= 0.0)
return num;
return 0.0;
}
private int SpeedTimeDifference()
{
if ((int)this._currentUpdate.SpeedTime1024 > (int)this._previousUpdate.SpeedTime1024)
return (int)this._currentUpdate.SpeedTime1024 - (int)this._previousUpdate.SpeedTime1024;
return (int)ushort.MaxValue - (int)this._previousUpdate.SpeedTime1024 + (int)this._currentUpdate.SpeedTime1024 + 1;
}
private uint SpeedEventDifference()
{
if (this._currentUpdate.SpeedEventCount > this._previousUpdate.SpeedEventCount)
return this._currentUpdate.SpeedEventCount - this._previousUpdate.SpeedEventCount;
return (uint)(-1 - (int)this._previousUpdate.SpeedEventCount + (int)this._currentUpdate.SpeedEventCount + 1);
}
public void SetUnavailable()
{
//throw new NotImplementedException();
}
private interface IUpdate
{
bool HasCadence { get; }
bool HasSpeed { get; }
uint SpeedEventCount { get; }
ushort SpeedTime1024 { get; }
ushort CadenceEventCount { get; }
ushort CadenceTime1024 { get; }
}
private class Update : CyclingSpeedCadenceMeasurement.IUpdate
{
private static readonly byte WheelRevolutionsFlagBit = (byte)0;
private static readonly byte CrankRevolutionsFlagBit = (byte)1;
private readonly byte[] _data;
private byte Flags
{
get
{
return this._data[0];
}
}
public bool HasCadence
{
get
{
return PrimitiveExtensions.IsBitSet(this.Flags, (int)CyclingSpeedCadenceMeasurement.Update.CrankRevolutionsFlagBit);
}
}
public bool HasSpeed
{
get
{
return PrimitiveExtensions.IsBitSet(this.Flags, (int)CyclingSpeedCadenceMeasurement.Update.WheelRevolutionsFlagBit);
}
}
public uint SpeedEventCount
{
get
{
return BitConvertHelper.ToUInt32(this._data, 1);
}
}
public ushort SpeedTime1024
{
get
{
return BitConvertHelper.ToUInt16(this._data, 5);
}
}
public ushort CadenceEventCount
{
get
{
return BitConvertHelper.ToUInt16(this._data, this.HasSpeed ? 7 : 1);
}
}
public ushort CadenceTime1024
{
get
{
return BitConvertHelper.ToUInt16(this._data, this.HasSpeed ? 9 : 3);
}
}
public Update(byte[] data)
{
this._data = data;
}
}
private class NullUpdate : CyclingSpeedCadenceMeasurement.IUpdate
{
public bool HasCadence
{
get
{
return false;
}
}
public bool HasSpeed
{
get
{
return false;
}
}
public uint SpeedEventCount
{
get
{
return 0U;
}
}
public ushort SpeedTime1024
{
get
{
return (ushort)0;
}
}
public ushort CadenceEventCount
{
get
{
return (ushort)0;
}
}
public ushort CadenceTime1024
{
get
{
return (ushort)0;
}
}
}
}
}