Mercurial > hg > fxanalyse
diff FXAnalyse.c @ 245:b1dc2ba9a315
Revise dedrift automatic slope update disable logic
author | Daniele Nicolodi <daniele@grinta.net> |
---|---|
date | Thu, 26 Feb 2015 23:11:01 +0100 |
parents | 7fd5cb857d07 |
children | d6a37eca6d92 |
line wrap: on
line diff
--- a/FXAnalyse.c Thu Feb 26 23:10:06 2015 +0100 +++ b/FXAnalyse.c Thu Feb 26 23:11:01 2015 +0100 @@ -358,10 +358,13 @@ int keep_slope; // keep current slope value when dedrift is disabled double f0; // target frequency double fDDS; // DDS center frequency - double threshold; // maximum allowed frequency change double applied; // currently applied slope double interval; // measurement duration double t0; // beginning of currrent measurement interval + double threshold; // maximum allowed frequency change + int badcount; // number of bad data points encountered consecutively + int badcountmax; // maximum number of consecutive bad data points + int safety; // stop slope update when too many consecutive bad data points are detected struct stat stat; // frequency mean and slope }; @@ -375,67 +378,121 @@ .keep_slope = TRUE, .f0 = 0.0, .fDDS = 70e6, - .threshold = 100.0, .applied = 0.0, .interval = 30.0, .t0 = 0.0 + .threshold = 10.0, + .badcount = 0, + .safety = TRUE, + .badcountmax = 10, }; +void dedrift_update_enable() +{ + logmsg("dedrift: automatic slope update enabled"); + + dedrift.enabled = TRUE; + dedrift.t0 = utc; + stat_zero(&dedrift.stat); + dedrift.stat.previous = NaN; +} + + +void dedrift_update_disable() +{ + logmsg("dedrift: automatic slope update disabled"); + + dedrift.enabled = FALSE; + stat_zero(&dedrift.stat); + + if (! dedrift.keep_slope) { + dedrift.applied = 0.0; + ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); + } + if (! dedrift.keep_freq) { + ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); + } + + SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); + SetCtrlVal(MainPanel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); + SetCtrlVal(MainPanel, PANEL_MEASURE_SLOPE, 0); +} + + +// Wrapper around stat_accumulate() that updates the statistic only if +// the new datapoint `v` is within `threshold` from the data point +// considered in the previous update. If the data point fails this +// criteria it does not contribute to the collected statistics and the +// previous data point is used instead and `count` is incremented by +// one. If the data point is accepted `count` is reset to zero. +int stat_accumulate_resilient(struct stat *stat, double v, double threshold, int *count) +{ + if ((! isnan(stat.previous) && (fabs(v - stat->previous) > threshold)) { + // bad data point + stat_accumulate(stat, stat->previous); + *count++; + return TRUE; + } else { + // good data point + stat_accumulate(stat, v); + *count = 0; + return FALSE; + } +} + + void dedrift_update(double f) -{ - // stop dedrift if the comb is not locked - if ((dedrift.enabled) && - (dedrift.threshold != 0.0) && - (dedrift.stat.previous != 0.0) && - (fabs(f - dedrift.stat.previous) > dedrift.threshold)) { +{ + if (! dedrift.enabled) + return; + + // update measurement + stat_accumulate_resilient(&dedrift.stat, f, dedrift.threshold, &dedrift.badcount); + if (dedrift.badcount) { + // bad data point detected + logmsg("dedrift: bad data point detected"); - logmsg("dedrift stop: frequency jump detected"); - - if (! dedrift.keep_slope) { - dedrift.applied = 0.0; - ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); - SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); - } - if (! dedrift.keep_freq) { - ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); + // too many consecutive bad data points detected + if ((dedrift.safety) && (dedrift.badcount > &dedrift.badcountmax)) { + dedrift_update_disable(); + logmsg("dedrift: maximum number of consecutive bad data points exceeded"); } - - stat_zero(&dedrift.stat); - SetCtrlVal(MainPanel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); - dedrift.enabled = FALSE; - SetCtrlVal(MainPanel, PANEL_MEASURE_SLOPE, 0); } - - // dedrifting - if (dedrift.enabled) { - // update measurement - stat_accumulate(&dedrift.stat, f); - SetCtrlVal(MainPanel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); - - // update applied slope - if ((utc - dedrift.t0) > dedrift.interval) { + // check if the previous check disabled slope update + if (! dedrift.enabled) + return; + + // update display + SetCtrlVal(MainPanel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); + + // update applied slope + if ((utc - dedrift.t0) > dedrift.interval) { - // target frequency - if (dedrift.f0 == 0.0) - dedrift.f0 = dedrift.stat.mean; - - // compute correction - double dt = utc - dedrift.t0; - double corr = dedrift.stat.slope \ - + dedrift.proportional * ((dedrift.stat.mean - dedrift.f0) / dt + 0.5 * dedrift.stat.slope); - - // update - dedrift.applied += dedrift.sign * corr * (dedrift.x2 ? 2 : 1); - ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); - SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); - logmsg("dedrift update: correction=%+3e slope=%+3e", corr, dedrift.applied); - - // start over - dedrift.t0 = utc; - stat_zero(&dedrift.stat); - } + // target frequency + if (dedrift.f0 == 0.0) + dedrift.f0 = dedrift.stat.mean; + + // compute correction + double dt = utc - dedrift.t0; + double corr = dedrift.stat.slope \ + + dedrift.proportional * ((dedrift.stat.mean - dedrift.f0) / dt + 0.5 * dedrift.stat.slope); + + // update + dedrift.applied += dedrift.sign * corr * (dedrift.x2 ? 2 : 1); + ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); + SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); + logmsg("dedrift: update correction=%+3e slope=%+3e", corr, dedrift.applied); + + // start over. keep track of the last updated data point to + // avoid gaps in the detectrion of bad data points based on + // threshold on the difference between current data point and + // previous one + double prev = dedrift.stat.previous; + stat_zero(&dedrift.stat); + dedrift.stat.previous = prev; + dedrift.t0 = utc; } } @@ -1891,28 +1948,13 @@ int CVICALLBACK CB_MeasureSlope (int panel, int control, int event, void *callbackData, int eventData1, int eventData2) { + int enable; switch (event) { case EVENT_COMMIT: - GetCtrlVal(panel, control, &dedrift.enabled); - if (dedrift.enabled) { - dedrift.t0 = utc; - stat_zero(&dedrift.stat); - logmsg("dedrift start"); - } else { - if (! dedrift.keep_slope) { - dedrift.applied = 0.0; - ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); - SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); - } - if (! dedrift.keep_freq) { - ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); - } - stat_zero(&dedrift.stat); - SetCtrlVal(panel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); - logmsg("dedrift stop"); - } - break; + GetCtrlVal(panel, control, &enable); + enable ? dedrift_update_enable() : dedrift_update_disable(); + break; } return 0; } @@ -1926,7 +1968,7 @@ dedrift.applied = 0.0; SetCtrlVal(panel, PANEL_SLOPE_APPLIED, dedrift.applied); ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); - logmsg("dedrift reset"); + logmsg("dedrift: reset"); break; } return 0; @@ -1997,8 +2039,7 @@ switch (event) { case EVENT_COMMIT: - GetCtrlVal(panel, control, &value); - dedrift.threshold = value ? 100.0 : 0.0; + GetCtrlVal(panel, control, &dedrift.safety); break; } return 0;