Mercurial > hg > fxanalyse
comparison 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 |
comparison
equal
deleted
inserted
replaced
244:4db8746bd575 | 245:b1dc2ba9a315 |
---|---|
356 int x2; // double the applied correction | 356 int x2; // double the applied correction |
357 int keep_freq; // keep current frequency value when dedrift is disabled | 357 int keep_freq; // keep current frequency value when dedrift is disabled |
358 int keep_slope; // keep current slope value when dedrift is disabled | 358 int keep_slope; // keep current slope value when dedrift is disabled |
359 double f0; // target frequency | 359 double f0; // target frequency |
360 double fDDS; // DDS center frequency | 360 double fDDS; // DDS center frequency |
361 double threshold; // maximum allowed frequency change | |
362 double applied; // currently applied slope | 361 double applied; // currently applied slope |
363 double interval; // measurement duration | 362 double interval; // measurement duration |
364 double t0; // beginning of currrent measurement interval | 363 double t0; // beginning of currrent measurement interval |
364 double threshold; // maximum allowed frequency change | |
365 int badcount; // number of bad data points encountered consecutively | |
366 int badcountmax; // maximum number of consecutive bad data points | |
367 int safety; // stop slope update when too many consecutive bad data points are detected | |
365 struct stat stat; // frequency mean and slope | 368 struct stat stat; // frequency mean and slope |
366 }; | 369 }; |
367 | 370 |
368 struct dedrift dedrift = { | 371 struct dedrift dedrift = { |
369 .enabled = FALSE, | 372 .enabled = FALSE, |
373 .x2 = FALSE, | 376 .x2 = FALSE, |
374 .keep_freq = TRUE, | 377 .keep_freq = TRUE, |
375 .keep_slope = TRUE, | 378 .keep_slope = TRUE, |
376 .f0 = 0.0, | 379 .f0 = 0.0, |
377 .fDDS = 70e6, | 380 .fDDS = 70e6, |
378 .threshold = 100.0, | |
379 .applied = 0.0, | 381 .applied = 0.0, |
380 .interval = 30.0, | 382 .interval = 30.0, |
381 .t0 = 0.0 | 383 .t0 = 0.0 |
384 .threshold = 10.0, | |
385 .badcount = 0, | |
386 .safety = TRUE, | |
387 .badcountmax = 10, | |
382 }; | 388 }; |
383 | 389 |
384 | 390 |
391 void dedrift_update_enable() | |
392 { | |
393 logmsg("dedrift: automatic slope update enabled"); | |
394 | |
395 dedrift.enabled = TRUE; | |
396 dedrift.t0 = utc; | |
397 stat_zero(&dedrift.stat); | |
398 dedrift.stat.previous = NaN; | |
399 } | |
400 | |
401 | |
402 void dedrift_update_disable() | |
403 { | |
404 logmsg("dedrift: automatic slope update disabled"); | |
405 | |
406 dedrift.enabled = FALSE; | |
407 stat_zero(&dedrift.stat); | |
408 | |
409 if (! dedrift.keep_slope) { | |
410 dedrift.applied = 0.0; | |
411 ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); | |
412 } | |
413 if (! dedrift.keep_freq) { | |
414 ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); | |
415 } | |
416 | |
417 SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); | |
418 SetCtrlVal(MainPanel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); | |
419 SetCtrlVal(MainPanel, PANEL_MEASURE_SLOPE, 0); | |
420 } | |
421 | |
422 | |
423 // Wrapper around stat_accumulate() that updates the statistic only if | |
424 // the new datapoint `v` is within `threshold` from the data point | |
425 // considered in the previous update. If the data point fails this | |
426 // criteria it does not contribute to the collected statistics and the | |
427 // previous data point is used instead and `count` is incremented by | |
428 // one. If the data point is accepted `count` is reset to zero. | |
429 int stat_accumulate_resilient(struct stat *stat, double v, double threshold, int *count) | |
430 { | |
431 if ((! isnan(stat.previous) && (fabs(v - stat->previous) > threshold)) { | |
432 // bad data point | |
433 stat_accumulate(stat, stat->previous); | |
434 *count++; | |
435 return TRUE; | |
436 } else { | |
437 // good data point | |
438 stat_accumulate(stat, v); | |
439 *count = 0; | |
440 return FALSE; | |
441 } | |
442 } | |
443 | |
444 | |
385 void dedrift_update(double f) | 445 void dedrift_update(double f) |
386 { | 446 { |
387 // stop dedrift if the comb is not locked | 447 if (! dedrift.enabled) |
388 if ((dedrift.enabled) && | 448 return; |
389 (dedrift.threshold != 0.0) && | 449 |
390 (dedrift.stat.previous != 0.0) && | 450 // update measurement |
391 (fabs(f - dedrift.stat.previous) > dedrift.threshold)) { | 451 stat_accumulate_resilient(&dedrift.stat, f, dedrift.threshold, &dedrift.badcount); |
452 if (dedrift.badcount) { | |
453 // bad data point detected | |
454 logmsg("dedrift: bad data point detected"); | |
392 | 455 |
393 logmsg("dedrift stop: frequency jump detected"); | 456 // too many consecutive bad data points detected |
394 | 457 if ((dedrift.safety) && (dedrift.badcount > &dedrift.badcountmax)) { |
395 if (! dedrift.keep_slope) { | 458 dedrift_update_disable(); |
396 dedrift.applied = 0.0; | 459 logmsg("dedrift: maximum number of consecutive bad data points exceeded"); |
397 ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); | |
398 SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); | |
399 } | 460 } |
400 if (! dedrift.keep_freq) { | 461 } |
401 ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); | 462 |
402 } | 463 // check if the previous check disabled slope update |
464 if (! dedrift.enabled) | |
465 return; | |
466 | |
467 // update display | |
468 SetCtrlVal(MainPanel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); | |
469 | |
470 // update applied slope | |
471 if ((utc - dedrift.t0) > dedrift.interval) { | |
472 | |
473 // target frequency | |
474 if (dedrift.f0 == 0.0) | |
475 dedrift.f0 = dedrift.stat.mean; | |
403 | 476 |
477 // compute correction | |
478 double dt = utc - dedrift.t0; | |
479 double corr = dedrift.stat.slope \ | |
480 + dedrift.proportional * ((dedrift.stat.mean - dedrift.f0) / dt + 0.5 * dedrift.stat.slope); | |
481 | |
482 // update | |
483 dedrift.applied += dedrift.sign * corr * (dedrift.x2 ? 2 : 1); | |
484 ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); | |
485 SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); | |
486 logmsg("dedrift: update correction=%+3e slope=%+3e", corr, dedrift.applied); | |
487 | |
488 // start over. keep track of the last updated data point to | |
489 // avoid gaps in the detectrion of bad data points based on | |
490 // threshold on the difference between current data point and | |
491 // previous one | |
492 double prev = dedrift.stat.previous; | |
404 stat_zero(&dedrift.stat); | 493 stat_zero(&dedrift.stat); |
405 SetCtrlVal(MainPanel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); | 494 dedrift.stat.previous = prev; |
406 dedrift.enabled = FALSE; | 495 dedrift.t0 = utc; |
407 SetCtrlVal(MainPanel, PANEL_MEASURE_SLOPE, 0); | |
408 } | |
409 | |
410 // dedrifting | |
411 if (dedrift.enabled) { | |
412 | |
413 // update measurement | |
414 stat_accumulate(&dedrift.stat, f); | |
415 SetCtrlVal(MainPanel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); | |
416 | |
417 // update applied slope | |
418 if ((utc - dedrift.t0) > dedrift.interval) { | |
419 | |
420 // target frequency | |
421 if (dedrift.f0 == 0.0) | |
422 dedrift.f0 = dedrift.stat.mean; | |
423 | |
424 // compute correction | |
425 double dt = utc - dedrift.t0; | |
426 double corr = dedrift.stat.slope \ | |
427 + dedrift.proportional * ((dedrift.stat.mean - dedrift.f0) / dt + 0.5 * dedrift.stat.slope); | |
428 | |
429 // update | |
430 dedrift.applied += dedrift.sign * corr * (dedrift.x2 ? 2 : 1); | |
431 ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); | |
432 SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); | |
433 logmsg("dedrift update: correction=%+3e slope=%+3e", corr, dedrift.applied); | |
434 | |
435 // start over | |
436 dedrift.t0 = utc; | |
437 stat_zero(&dedrift.stat); | |
438 } | |
439 } | 496 } |
440 } | 497 } |
441 | 498 |
442 | 499 |
443 // recenter | 500 // recenter |
1889 } | 1946 } |
1890 | 1947 |
1891 int CVICALLBACK CB_MeasureSlope (int panel, int control, int event, | 1948 int CVICALLBACK CB_MeasureSlope (int panel, int control, int event, |
1892 void *callbackData, int eventData1, int eventData2) | 1949 void *callbackData, int eventData1, int eventData2) |
1893 { | 1950 { |
1894 switch (event) | 1951 int enable; |
1895 { | 1952 switch (event) |
1896 case EVENT_COMMIT: | 1953 { |
1897 GetCtrlVal(panel, control, &dedrift.enabled); | 1954 case EVENT_COMMIT: |
1898 if (dedrift.enabled) { | 1955 GetCtrlVal(panel, control, &enable); |
1899 dedrift.t0 = utc; | 1956 enable ? dedrift_update_enable() : dedrift_update_disable(); |
1900 stat_zero(&dedrift.stat); | 1957 break; |
1901 logmsg("dedrift start"); | |
1902 } else { | |
1903 if (! dedrift.keep_slope) { | |
1904 dedrift.applied = 0.0; | |
1905 ad9956_set_sweep_rate_w(&ad9956, dedrift.applied); | |
1906 SetCtrlVal(MainPanel, PANEL_SLOPE_APPLIED, dedrift.applied); | |
1907 } | |
1908 if (! dedrift.keep_freq) { | |
1909 ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); | |
1910 } | |
1911 stat_zero(&dedrift.stat); | |
1912 SetCtrlVal(panel, PANEL_SLOPE_MEASURED, dedrift.stat.slope); | |
1913 logmsg("dedrift stop"); | |
1914 } | |
1915 break; | |
1916 } | 1958 } |
1917 return 0; | 1959 return 0; |
1918 } | 1960 } |
1919 | 1961 |
1920 int CVICALLBACK CB_OnResetSlope (int panel, int control, int event, | 1962 int CVICALLBACK CB_OnResetSlope (int panel, int control, int event, |
1924 { | 1966 { |
1925 case EVENT_COMMIT: | 1967 case EVENT_COMMIT: |
1926 dedrift.applied = 0.0; | 1968 dedrift.applied = 0.0; |
1927 SetCtrlVal(panel, PANEL_SLOPE_APPLIED, dedrift.applied); | 1969 SetCtrlVal(panel, PANEL_SLOPE_APPLIED, dedrift.applied); |
1928 ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); | 1970 ad9956_set_w(&ad9956, dedrift.fDDS, dedrift.applied); |
1929 logmsg("dedrift reset"); | 1971 logmsg("dedrift: reset"); |
1930 break; | 1972 break; |
1931 } | 1973 } |
1932 return 0; | 1974 return 0; |
1933 } | 1975 } |
1934 | 1976 |
1995 { | 2037 { |
1996 int value; | 2038 int value; |
1997 switch (event) | 2039 switch (event) |
1998 { | 2040 { |
1999 case EVENT_COMMIT: | 2041 case EVENT_COMMIT: |
2000 GetCtrlVal(panel, control, &value); | 2042 GetCtrlVal(panel, control, &dedrift.safety); |
2001 dedrift.threshold = value ? 100.0 : 0.0; | |
2002 break; | 2043 break; |
2003 } | 2044 } |
2004 return 0; | 2045 return 0; |
2005 } | 2046 } |
2006 | 2047 |