There is no point in having the averagers pre-know their number of samples.
The user should know this information. Therefore we have a more flexible
solution and avoid a signal to return the averate to the user when that user is
very likely to want to call a command instead.
command void reset();
/* Submit a value to the averager, to be averaged into the next average. */
- command void submit(val_t);
+ command void submit(val_t value);
- /* Submit a null value to the averager. Each null submitted counts as one
- * of the expected values for calculating the average. Each null submitted
- * reduces the divisor for the subsequent average by one.
+ /* Return the number of values submitted since the last
+ * <code>reset()</code> or <code>average()</code>.
*/
- command void null();
+ command uint16_t count();
- /* Signalled after the expected number of samples + nulls have been delivered
- * and their set have been used to calculate a new average.
+ /* Ask for the average of the values submitted since the last
+ * <code>reset()</code> or <code>average()</code>. <code>average()</code>
+ * also performs a <code>reset()</code>.
*/
- event void average(val_t);
+ command val_t average();
}
* @author R. Steve McKown <rsmckown@gmail.com>
*/
-generic module AverageAngleC(uint16_t samples) {
+#include "AeroVane.h" /* For AEROVANE_VECTOR_NULL */
+
+generic module AverageAngleC() {
provides interface Average<uint16_t>;
}
implementation {
init();
}
- task void signalAverage()
- {
- int16_t angle;
-
- if (m_angle > 0)
- angle = (m_angle + (m_count / 2)) / m_count;
- else {
- angle = (m_angle - (m_count / 2)) / m_count;
- while (m_angle < 0)
- angle += 1024;
- }
- angle &= 0x03ff; /* %= 1024 */
- init();
-
- /* Inform the consumer of the average angle */
- signal Average.average(angle);
- }
-
int distance(int angle1, int angle2)
{
int d = angle2 - angle1;
command void Average.submit(uint16_t angle)
{
- m_lastAngle += distance(m_lastAngle, angle);
+ if (m_count++ == 0)
+ m_lastAngle = angle;
+ else
+ m_lastAngle += distance(m_lastAngle, angle);
m_angle += m_lastAngle;
- if (++m_count == samples)
- post signalAverage();
}
- command void Average.null()
+ command uint16_t Average.average()
+ {
+ uint16_t angle;
+
+ if (m_count == 0)
+ angle = AEROVANE_VECTOR_NULL;
+ else {
+ angle = m_angle;
+
+ if (angle > 0)
+ angle = (angle + (m_count / 2)) / m_count;
+ else if (angle < 0) {
+ angle = (angle - (m_count / 2)) / m_count;
+ while (angle < 0)
+ angle += 1024;
+ }
+ angle &= 0x03ff; /* %= 1024 */
+ }
+ init();
+ return angle;
+ }
+
+ command uint16_t Average.count()
{
- if (++m_count == samples)
- post signalAverage();
+ return m_count;
}
}
generic module AveragePolarC(uint16_t samples) {
provides interface Average<aerovector_t>;
uses {
- interface Average<int16_t> as AverageAngle;
+ interface Average<uint16_t> as AverageAngle;
interface Average<uint16_t> as AverageSpeed;
}
}
implementation {
int m_count;
- aerovector_t vector;
command void Average.reset()
{
AverageSpeed.init();
}
- event void AverageAngle.average(uint16_t angle)
+ command uint16_t Average.submit(aerovector_t vector)
{
- vector.dir = angle;
- if (++m_count == 2)
- signal Average.average(vector);
+ call AverageAngle.submit(vector.dir);
+ call AverageSpeed.submit(vector.speed);
}
- event void AverageSpeed.average(uint16_t speed)
+ command aerovector_t Average.average()
{
- vector.speed = speed;
- if (++m_count == 2)
- signal Average.average(vector);
- }
+ aerovector_t vector;
- command void Average.submit(aerovector_t vector)
- {
- call AverageAngle.submit(vector.dir);
- call AverageSpeed.submit(vector.speed);
+ vector.dir = call AverageAngle.average();
+ vector.speed = call AverageSpeed.average();
+ init();
+ return vector;
}
- command void Average.null()
+ command uint16_t Average.count()
{
- call AverageAngle.submit(vector.dir);
- call AverageSpeed.submit(vector.speed);
+ return call AverageAngle.count();
}
}
#include "AeroVane.h"
-generic module AverageU16(uint16_t samples) {
- provides interface Average<aerovector_t>;
+generic module AverageU16() {
+ provides interface Average<uint16_t>;
}
implementation {
- uint8_t m_count;
+ uint16_t m_count;
uint16_t m_value;
inline void init()
init();
}
- task void signalAverage()
+ command Average.submit(uint16_t value)
{
- uint16_t value;
-
- value = (m_value + (m_count / 2)) / m_count;
- init();
-
- /* Inform the consumer of the vector */
- signal Average.average(vector);
+ m_count++;
+ m_value += value;
}
- command Average.submit(uint16_t value)
+ command uint16_t Average.average()
{
- m_value += value;
- if (++m_count == samples)
- post signalAverage();
+ uint16_t value = 0;
+
+ if (m_count) {
+ value = (m_value + (m_count / 2)) / m_count;
+ init();
+ }
+ return value;
}
- command Average.null()
+ command uint16_t Average.count()
{
- if (++m_count == samples)
- post signalAverage();
+ return m_count;
}
}