/// <summary>
        /// When updates are time synchronous, interpret the two given messages to determine if the
        /// wheel is not rotating.
        ///
        /// I would think that you would probably want to count how many times this happens in a
        /// row and then once it passes some threshold interpert that as zero speed (?).
        /// </summary>
        /// <param name="message1">The most recent WheelTorqueDataPage message recieved.</param>
        /// <param name="message2">The second most recent WheelTorqueDataPage message recieved.
        /// </param>
        /// <returns><c>True</c> if the speed appears to be zero.</returns>
        public static bool IsZeroVelocityTimeSynchronous(WheelTorqueDataPage message1, WheelTorqueDataPage message2)
        {
            // See ANT+ Device Profile - Bicycle Power, page 36 (ver. 4.2)
            // https://www.thisisant.com/resources/bicycle-power/

            return(message1.WheelTicks == message2.WheelTicks);
        }
        /// <summary>
        /// Calculates distance travelled in m.
        /// </summary>
        /// <param name="message1">The most recent WheelTorqueDataPage message recieved.</param>
        /// <param name="message2">The second most recent WheelTorqueDataPage message recieved.
        /// </param>
        /// <param name="circumference">The circumference of the bicycle wheel, in m.</param>
        /// <returns>The distance travelled in m.</returns>
        public static float CalculateDistance(WheelTorqueDataPage message1, WheelTorqueDataPage message2, float circumference)
        {
            // See ANT+ Device Profile - Bicycle Power, page 37 (ver. 4.2)
            // https://www.thisisant.com/resources/bicycle-power/

            return(circumference * AntUtilFunctions.rolloverDiff(message1.WheelTicks, message2.WheelTicks));
        }
        /// <summary>
        /// Calculates the average speed in m/s.
        /// </summary>
        /// <param name="message1">The most recent WheelTorqueDataPage message recieved.</param>
        /// <param name="message2">The second most recent WheelTorqueDataPage message recieved.
        /// </param>
        /// <param name="circumference">The circumference of the bicycle wheel, in m.</param>
        /// <returns>The average linear speed of the bike in m/s.</returns>
        public static float CalculateAvgSpeed(WheelTorqueDataPage message1, WheelTorqueDataPage message2, float circumference)
        {
            // See ANT+ Device Profile - Bicycle Power, page 36 (ver. 4.2)
            // https://www.thisisant.com/resources/bicycle-power/

            return(circumference * AntUtilFunctions.rolloverDiff(message1.UpdateEventCount, message2.UpdateEventCount) /
                   (AntUtilFunctions.rolloverDiff(message1.WheelPeriod, message2.WheelPeriod) / 2048f));
        }
        /// <summary>
        /// When updates are event synchronous, interpret the two given messages to determine if
        /// the wheel is not rotating.
        ///
        /// I would think that you would probably want to count how many times this happens in a
        /// row and then once it passes some threshold interpert that as zero speed (?).
        /// </summary>
        /// <param name="message1">The most recent WheelTorqueDataPage message recieved.</param>
        /// <param name="message2">The second most recent WheelTorqueDataPage message recieved.
        /// </param>
        /// <returns><c>True</c> if the speed appears to be zero.</returns>
        public static bool IsZeroVelocityEventSynchronous(WheelTorqueDataPage message1, WheelTorqueDataPage message2)
        {
            // See ANT+ Device Profile - Bicycle Power, page 36 (ver. 4.2)
            // https://www.thisisant.com/resources/bicycle-power/

            return((message1.UpdateEventCount == message2.UpdateEventCount) &&
                   (message1.WheelPeriod == message2.WheelPeriod) &&
                   (message1.WheelTicks == message2.WheelTicks));
        }
Exemplo n.º 5
0
        void WheelTorqueReceived(object sender, EventArgs e)
        {
            WheelTorqueDataPage wheelTorque = (WheelTorqueDataPage)sender;

            if (lastWheelTorque != null)
            {
                float speed = WheelTorqueDataPage.CalculateAvgSpeed(wheelTorque, lastWheelTorque, bikeData.BikeWheelDiameter * (float) Math.PI);

                if (WheelTorqueDataPage.IsZeroVelocityEventSynchronous(wheelTorque, lastWheelTorque))
                {
                    if (++zeroSpeedCount > zeroSpeedCountThreshold)
                    {
                        if (zeroSpeedCount == zeroSpeedCountThreshold + 1)
                            //Debug.LogFormat("Zero speed detected (zeroSpeedCountThreshold was {0})",
                            //    zeroSpeedCountThreshold);

                            speed = 0f;
                    }
                }
                else
                {
                    if (zeroSpeedCountThreshold > ZERO_SPEED_COUNT_IDLE_THRESHOLD)
                    {
                        zeroSpeedCounts.Reset();
                        zeroSpeedCounts.Add(ZERO_SPEED_COUNT_MIN_THRESHOLD);
                    }
                    else
                    {
                        zeroSpeedCounts.Add(AntUtilFunctions.IntegerClamp(
                            ZERO_SPEED_COUNT_THRESHOLD_OFFSET + zeroSpeedCount,
                            ZERO_SPEED_COUNT_MIN_THRESHOLD,
                            ZERO_SPEED_COUNT_MAX_THRESHOLD));
                    }
                    zeroSpeedCountThreshold = zeroSpeedCounts.Average();

                    //Debug.LogFormat("zeroSpeedCount reset at {0} (zeroSpeedCountThreshold updated to {1})",
                    //    zeroSpeedCount, zeroSpeedCountThreshold);

                    zeroSpeedCount = 0;
                }

                if (!float.IsNaN(speed))
                    bikeData.AntSpeed = speed;
            }

            lastWheelTorque = wheelTorque;
        }
        /// <summary>
        /// When updates are time synchronous, interpret the two given messages to determine if the
        /// wheel is not rotating.
        /// 
        /// I would think that you would probably want to count how many times this happens in a 
        /// row and then once it passes some threshold interpert that as zero speed (?).
        /// </summary>
        /// <param name="message1">The most recent WheelTorqueDataPage message recieved.</param>
        /// <param name="message2">The second most recent WheelTorqueDataPage message recieved.
        /// </param>
        /// <returns><c>True</c> if the speed appears to be zero.</returns>
        public static bool IsZeroVelocityTimeSynchronous(WheelTorqueDataPage message1, WheelTorqueDataPage message2)
        {
            // See ANT+ Device Profile - Bicycle Power, page 36 (ver. 4.2)
            // https://www.thisisant.com/resources/bicycle-power/

            return (message1.WheelTicks == message2.WheelTicks);
        }
        /// <summary>
        /// Calculates distance travelled in m.
        /// </summary>
        /// <param name="message1">The most recent WheelTorqueDataPage message recieved.</param>
        /// <param name="message2">The second most recent WheelTorqueDataPage message recieved.
        /// </param>
        /// <param name="circumference">The circumference of the bicycle wheel, in m.</param>
        /// <returns>The distance travelled in m.</returns>
        public static float CalculateDistance(WheelTorqueDataPage message1, WheelTorqueDataPage message2, float circumference)
        {
            // See ANT+ Device Profile - Bicycle Power, page 37 (ver. 4.2)
            // https://www.thisisant.com/resources/bicycle-power/

            return circumference * AntUtilFunctions.rolloverDiff(message1.WheelTicks, message2.WheelTicks);
        }
        /// <summary>
        /// Calculates the average speed in m/s.
        /// </summary>
        /// <param name="message1">The most recent WheelTorqueDataPage message recieved.</param>
        /// <param name="message2">The second most recent WheelTorqueDataPage message recieved.
        /// </param>
        /// <param name="circumference">The circumference of the bicycle wheel, in m.</param>
        /// <returns>The average linear speed of the bike in m/s.</returns>
        public static float CalculateAvgSpeed(WheelTorqueDataPage message1, WheelTorqueDataPage message2, float circumference)
        {
            // See ANT+ Device Profile - Bicycle Power, page 36 (ver. 4.2)
            // https://www.thisisant.com/resources/bicycle-power/

            return circumference * AntUtilFunctions.rolloverDiff(message1.UpdateEventCount, message2.UpdateEventCount) /
                   (AntUtilFunctions.rolloverDiff(message1.WheelPeriod, message2.WheelPeriod) / 2048f);
        }