- Timestamp:
- 03/11/13 11:27:01 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/ratecontrol.cc
r14991 r15027 14 14 15 15 #include "HeadersFTM.h" 16 #include "HeadersDrive.h" 16 17 #include "HeadersRateScan.h" 17 18 #include "HeadersRateControl.h" … … 40 41 DimDescribedState fDimFTM; 41 42 DimDescribedState fDimRS; 43 DimDescribedState fDimDrive; 42 44 43 45 DimDescribedService fDimThreshold; … … 49 51 uint16_t fThresholdReference; 50 52 53 deque<pair<Time,float>> fCurrents; 54 51 55 bool fVerbose; 56 bool fCalibrateByCurrent; 52 57 53 58 uint64_t fCounter; … … 362 367 const FTM::DimTriggerRates &sdata = *static_cast<const FTM::DimTriggerRates*>(evt.GetData()); 363 368 364 if (GetCurrentState()==RateControl::State::kSettingGlobalThreshold )369 if (GetCurrentState()==RateControl::State::kSettingGlobalThreshold && !fCalibrateByCurrent) 365 370 return ProcessCamera(sdata); 366 371 … … 369 374 370 375 return GetCurrentState(); 376 } 377 378 int HandleCalibratedCurrents(const EventImp &evt) 379 { 380 // Check if received event is valid 381 if (!CheckEventSize(evt, (416+6)*4)) 382 return GetCurrentState(); 383 384 // Record only currents when the drive is tracking to avoid 385 // bias from the movement 386 if (fDimDrive.state()<Drive::State::kTracking) 387 return GetCurrentState(); 388 389 // Get time and median current (FIXME: check N?) 390 const Time &time = evt.GetTime(); 391 const float med = evt.Get<float>(416*4+4+4); 392 393 // Keep all median currents of the past 10 seconds 394 fCurrents.push_back(make_pair(time, med)); 395 while (fCurrents.size()>0) 396 if (time-fCurrents.front().first>boost::posix_time::seconds(10)) 397 fCurrents.pop_front(); 398 399 // If we are not doing a calibration no further action necessary 400 if (!fCalibrateByCurrent) 401 return GetCurrentState(); 402 403 if (GetCurrentState()!=RateControl::State::kSettingGlobalThreshold) 404 return GetCurrentState(); 405 406 // We want at least 8 values for averaging 407 if (fCurrents.size()<8) 408 return GetCurrentState(); 409 410 // Calculate avera and rms of median 411 double avg = 0; 412 double rms = 0; 413 for (auto it=fCurrents.begin(); it!=fCurrents.end(); it++) 414 { 415 avg += it->second; 416 rms += it->second*it->second; 417 } 418 avg /= fCurrents.size(); 419 rms /= fCurrents.size(); 420 421 rms = sqrt(rms-avg*avg); 422 423 fThresholdMin = 36.0833*pow(avg, 0.638393)+184.037; 424 fThresholds.assign(160, fThresholdMin); 425 426 const RateControl::DimThreshold data = { fThresholdMin, fCalibrationTimeStart.Mjd(), Time().Mjd() }; 427 fDimThreshold.setQuality(0); 428 fDimThreshold.Update(data); 429 430 ostringstream out; 431 out << setprecision(3); 432 out << "Measured average current " << avg << "uA +- " << rms << "uA [N=" << fCurrents.size() << "]... mininum threshold set to " << fThresholdMin; 433 Info(out); 434 435 return RateControl::State::kGlobalThresholdSet; 371 436 } 372 437 … … 388 453 fCounter = 0; 389 454 455 fCalibrateByCurrent = false; 390 456 fCalibrationTimeStart = Time(); 391 457 … … 397 463 } 398 464 465 int CalibrateByCurrent() 466 { 467 if (!fTriggerOn) 468 { 469 Info("Physics trigger not enabled... CALIBRATE command ignored."); 470 return RateControl::State::kGlobalThresholdSet; 471 } 472 473 if (fDimDrive.state()<Drive::State::kMoving) 474 Warn("Drive not even moving..."); 475 476 fCounter = 0; 477 fCalibrateByCurrent = true; 478 fCalibrationTimeStart = Time(); 479 480 ostringstream out; 481 out << "Rate calibration by current " << fThresholdReference << " with a target rate of " << fTargetRate << " Hz"; 482 Info(out); 483 484 return RateControl::State::kSettingGlobalThreshold; 485 } 486 399 487 int StopRC() 400 488 { … … 429 517 Out() << fDimFTM << endl; 430 518 Out() << fDimRS << endl; 519 Out() << fDimDrive << endl; 431 520 432 521 return GetCurrentState(); … … 449 538 450 539 // All subsystems are not connected 451 if (fDimFTM.state()<FTM::State::kConnected )540 if (fDimFTM.state()<FTM::State::kConnected || fDimDrive.state()<Drive::State::kConnected) 452 541 return RateControl::State::kDisconnected; 453 542 … … 476 565 fDimFTM("FTM_CONTROL"), 477 566 fDimRS("RATE_SCAN"), 567 fDimDrive("DRIVE_CONTROL"), 478 568 479 569 fDimThreshold("RATE_CONTROL/THRESHOLD", "S:1;D:1;D:1", … … 498 588 Subscribe("FTM_CONTROL/STATIC_DATA") 499 589 (bind(&StateMachineRateControl::HandleStaticData, this, placeholders::_1)); 590 Subscribe("FEEDBACK/CALIBRATED_CURRENTS") 591 (bind(&StateMachineRateControl::HandleCalibratedCurrents, this, placeholders::_1)); 500 592 501 593 // State names … … 521 613 (bind(&StateMachineRateControl::Calibrate, this)) 522 614 ("Start a search for a reasonable minimum global threshold"); 615 616 AddEvent("CALIBRATE_BY_CURRENT") 617 (bind(&StateMachineRateControl::CalibrateByCurrent, this)) 618 ("Set the global threshold from the median current"); 523 619 524 620 AddEvent("STOP", RateControl::State::kSettingGlobalThreshold, RateControl::State::kGlobalThresholdSet, RateControl::State::kInProgress)
Note:
See TracChangeset
for help on using the changeset viewer.