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