Closed ghost closed 1 year ago
Thanks for the issue.
The - https://github.com/RobTillaart/RunningAverage - library should not give NaN after 10 inputs normally.
When RA.count == 1
==> you get NaN (by definition).
When the count is above 1 (till 10 ) you should get a number larger or equal to 0. By making the size of the RA object 10 you can get the stddev after every add(). Note: to calculate the stddev the average is needed internally.
The way you calculate stddev over the last 10 inputs works for this library, but it is not meant for a ```running stddev()**.
Does this help? Or can you elaborate on your question?
I need to need clarify everything in similar manner, both Statistic and runningAverage working as aspected. But for std_dev i prefer runningAverage because Statistic currently not have FILO algorithm.
RunningAverage stats(5);
This work
ESP_LOGD("Stats", "%f %f %f", stats.getStandardDeviation(), stats.getAverage(), stats.getMaxInBuffer());
[output] Stats 0.01 0.25 0.26
This not work
ESP_LOGD("Stats", "%f %f", stats.getStandardDeviation(), stats.getMaxInBuffer());
[output] Stats nan 0.26
Forgot runningAverage library, the main purpose of issue is to implement specific window size FILO algorithm in RobTillaart/Statistic.
The purpose of Statistic is calculate stats over a large set of data, not to support a small window, or subset of the data. In fact Statistic does not store individual data internally, so it cannot calculate the stddev over the last n elements of that large set.
I cannot explain immediately why printing 3 parameters work while printing two does not. Need to dive into the code to see if I can reproduce.
Can you run this sketch and post the output? (15 lines will do)
// FILE: ra_test.ino
// AUTHOR: Rob Tillaart
// PUPROSE: test
#include "RunningAverage.h"
RunningAverage myRA(10);
int samples = 0;
void setup(void)
{
Serial.begin(115200);
Serial.println("Demo RunningAverage lib");
Serial.print("Version: ");
Serial.println(RUNNINGAVERAGE_LIB_VERSION);
myRA.clear(); // explicitly start clean
for (int i = 0; i < 10; i++)
{
myRA.add(i * 0.01 + 1 );
Serial.print(myRA.getCount());
Serial.print("\t");
Serial.print(myRA.getAverage(), 3);
Serial.print("\t");
Serial.print(myRA.getStandardDeviation(), 3);
Serial.print("\t");
Serial.println(myRA.getMaxInBuffer(), 3);
}
}
void loop(void)
{
myRA.add(random(100) * 0.01 + 1 );
Serial.print(myRA.getCount());
Serial.print("\t");
Serial.print(myRA.getAverage(), 3);
Serial.print("\t");
Serial.print(myRA.getStandardDeviation(), 3);
Serial.print("\t");
Serial.println(myRA.getMaxInBuffer(), 3);
delay(1000);
}
// -- END OF FILE --
Then the same for this sketch
// FILE: ra_test.ino
// AUTHOR: Rob Tillaart
// PUPROSE: test
#include "RunningAverage.h"
RunningAverage myRA(10);
int samples = 0;
void setup(void)
{
Serial.begin(115200);
Serial.println("Demo RunningAverage lib");
Serial.print("Version: ");
Serial.println(RUNNINGAVERAGE_LIB_VERSION);
myRA.clear(); // explicitly start clean
for (int i = 0; i < 10; i++)
{
myRA.add(i * 0.01 + 1 );
Serial.print(myRA.getStandardDeviation(), 3);
Serial.print("\t");
Serial.println(myRA.getMaxInBuffer(), 3);
}
}
void loop(void)
{
myRA.add(random(100) * 0.01 + 1 );
Serial.print(myRA.getStandardDeviation(), 3);
Serial.print("\t");
Serial.println(myRA.getMaxInBuffer(), 3);
delay(1000);
}
// -- END OF FILE --
Esphome need some modification after that i provide you output result.
Both sketches return an NAN on the first line when count == 1.
ESP_LOGD("Stats", "%f %f", stats.getStandardDeviation(), stats.getMaxInBuffer());
This line has too little information to reproduce.
The best way to analyze is to provide a minimal sketch that shows the problem.
Esphome need some modification after that i provide you output result.
I have no experience with Esphome, however on an ESP32 both libraries works as intended.
ESP_LOGD("Stats", "%f %f", stats.getStandardDeviation(), stats.getMaxInBuffer());
what happens if you assign the values to a variable first?
volatile float std = stats.getStandardDeviation(); // made volatile to suppress compiler optimizations.
volatile float mib = stats.getMaxInBuffer());
ESP_LOGD("Stats", "%f %f", std, mid);
ESP_LOGD("Stats", "%f %f", stats.getStandardDeviation(), stats.getMaxInBuffer()); [output] Stats nan 0.26
Also try
ESP_LOGD("Stats", "%f %f", stats.getStandardDeviation(), stats.getCount());
please post output
Can you run this sketch and post the output? (15 lines will do)
// FILE: ra_test.ino // AUTHOR: Rob Tillaart // PUPROSE: test #include "RunningAverage.h" RunningAverage myRA(10); int samples = 0; void setup(void) { Serial.begin(115200); Serial.println("Demo RunningAverage lib"); Serial.print("Version: "); Serial.println(RUNNINGAVERAGE_LIB_VERSION); myRA.clear(); // explicitly start clean for (int i = 0; i < 10; i++) { myRA.add(i * 0.01 + 1 ); Serial.print(myRA.getCount()); Serial.print("\t"); Serial.print(myRA.getAverage(), 3); Serial.print("\t"); Serial.print(myRA.getStandardDeviation(), 3); Serial.print("\t"); Serial.println(myRA.getMaxInBuffer(), 3); } } void loop(void) { myRA.add(random(100) * 0.01 + 1 ); Serial.print(myRA.getCount()); Serial.print("\t"); Serial.print(myRA.getAverage(), 3); Serial.print("\t"); Serial.print(myRA.getStandardDeviation(), 3); Serial.print("\t"); Serial.println(myRA.getMaxInBuffer(), 3); delay(1000); } // -- END OF FILE --
[01:08:39][D][VERSION:167]: 0.4.3
[01:08:39][D][Test:172]: -0.000 1.000 nan 1.000
[01:08:39][D][Test:172]: 0.000 1.005 0.007 1.010
[01:08:39][D][Test:172]: 0.000 1.010 0.010 1.020
[01:08:39][D][Test:172]: 0.000 1.015 0.013 1.030
[01:08:39][D][Test:172]: 0.000 1.020 0.016 1.040
[01:08:39][D][Test:172]: 0.000 1.025 0.019 1.050
[01:08:40][D][Test:172]: 0.000 1.030 0.022 1.060
[01:08:40][D][Test:172]: 0.000 1.035 0.024 1.070
[01:08:40][D][Test:172]: 0.000 1.040 0.027 1.080
[01:08:40][D][Test:172]: 0.000 1.045 0.030 1.090
[01:08:40][D][Test:175]: 0.000 1.049 0.026 1.090
Then the same for this sketch
// FILE: ra_test.ino // AUTHOR: Rob Tillaart // PUPROSE: test #include "RunningAverage.h" RunningAverage myRA(10); int samples = 0; void setup(void) { Serial.begin(115200); Serial.println("Demo RunningAverage lib"); Serial.print("Version: "); Serial.println(RUNNINGAVERAGE_LIB_VERSION); myRA.clear(); // explicitly start clean for (int i = 0; i < 10; i++) { myRA.add(i * 0.01 + 1 ); Serial.print(myRA.getStandardDeviation(), 3); Serial.print("\t"); Serial.println(myRA.getMaxInBuffer(), 3); } } void loop(void) { myRA.add(random(100) * 0.01 + 1 ); Serial.print(myRA.getStandardDeviation(), 3); Serial.print("\t"); Serial.println(myRA.getMaxInBuffer(), 3); delay(1000); } // -- END OF FILE --
[01:10:53][D][VERSION:167]: 0.4.3
[01:10:53][D][Test:172]: nan 1.000
[01:10:53][D][Test:172]: 0.007 1.010
[01:10:53][D][Test:172]: 0.010 1.020
[01:10:53][D][Test:172]: 0.013 1.030
[01:10:53][D][Test:172]: 0.016 1.040
[01:10:53][D][Test:172]: 0.019 1.050
[01:10:53][D][Test:172]: 0.022 1.060
[01:10:53][D][Test:172]: 0.024 1.070
[01:10:53][D][Test:172]: 0.027 1.080
[01:10:53][D][Test:172]: 0.030 1.090
[01:10:53][D][Test:175]: 0.182 1.620
ESP_LOGD("Stats", "%f %f", stats.getStandardDeviation(), stats.getMaxInBuffer()); [output] Stats nan 0.26
Also try
ESP_LOGD("Stats", "%f %f", stats.getStandardDeviation(), stats.getCount());
please post output The issue is so wierd... The Got distance: 0.84 m are output values provided to runningAverage.
[01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.84 m [01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.83 m [01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.71 m [01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.54 m [01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.44 m [01:14:25][D][sensor:093]: 'Ping Sensor': Sending state 0.84845 m with 3 decimals of accuracy [01:14:25][D][Stats:072]: nan -5486124068793694774077193376186634490938385057925026367753787985335901674201208705258107428552676834622700901594284127560530828493162262565205269470179449410856558896118393471584152670587577693885047222545890015691339878440394965043791461872188297303737712264679017607178892013979610612203518046997839872.00 [01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.68 m [01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.63 m [01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.63 m [01:14:25][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.47 m [01:14:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.81 m [01:14:26][D][sensor:093]: 'Ping Sensor': Sending state 0.81734 m with 3 decimals of accuracy [01:14:26][D][Stats:072]: nan -5486124068793694774077193376186634490938385057925026367753787985335901674201208705258107428552676834622700901594284127560530828493162262565205269470179449410856558896118393471584152670587577693885047222545890015691339878440394965043791461872188297303737712264679017607178892013979610612203518046997839872.00
Issue solves when using this
ESP_LOGD("Stats", "%.2f %.2f %.2f", stats.getStandardDeviation(), stats.getCount(), stats.getAverage());
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.65 m
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.58 m
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.56 m
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.63 m
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.60 m
[01:20:26][D][sensor:093]: 'Ping Sensor': Sending state 0.65478 m with 3 decimals of accuracy
[01:20:26][D][Stats:072]: 0.05 0.00 0.70
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.63 m
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.80 m
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.61 m
[01:20:26][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.77 m
[01:20:27][D][ultrasonic.sensor:040]: 'Ping Sensor' - Got distance: 0.57 m
[01:20:27][D][sensor:093]: 'Ping Sensor': Sending state 0.81205 m with 3 decimals of accuracy
[01:20:27][D][Stats:072]: 0.07 0.00 0.70
It's better to move the issue to it's origin library.
Similar thing can done with runningAverage library but there is issue i need to calculate only std_dev but without getAverage() in config getStandardDeviation() alway return NaN. In current Statistic library need reset() to calculate stream data std_dev.
I need to calculate only standard deviation of over last 10 input .