Changeset 15027 for trunk


Ignore:
Timestamp:
03/11/13 11:27:01 (12 years ago)
Author:
tbretz
Message:
Added CALIBRATE_BY_CURRENT command which allows to set the global minimum threshold from the measured current.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/ratecontrol.cc

    r14991 r15027  
    1414
    1515#include "HeadersFTM.h"
     16#include "HeadersDrive.h"
    1617#include "HeadersRateScan.h"
    1718#include "HeadersRateControl.h"
     
    4041    DimDescribedState fDimFTM;
    4142    DimDescribedState fDimRS;
     43    DimDescribedState fDimDrive;
    4244
    4345    DimDescribedService fDimThreshold;
     
    4951    uint16_t fThresholdReference;
    5052
     53    deque<pair<Time,float>> fCurrents;
     54
    5155    bool fVerbose;
     56    bool fCalibrateByCurrent;
    5257
    5358    uint64_t fCounter;
     
    362367        const FTM::DimTriggerRates &sdata = *static_cast<const FTM::DimTriggerRates*>(evt.GetData());
    363368
    364         if (GetCurrentState()==RateControl::State::kSettingGlobalThreshold)
     369        if (GetCurrentState()==RateControl::State::kSettingGlobalThreshold && !fCalibrateByCurrent)
    365370            return ProcessCamera(sdata);
    366371
     
    369374
    370375        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;
    371436    }
    372437
     
    388453        fCounter      = 0;
    389454
     455        fCalibrateByCurrent = false;
    390456        fCalibrationTimeStart = Time();
    391457
     
    397463    }
    398464
     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
    399487    int StopRC()
    400488    {
     
    429517        Out() << fDimFTM << endl;
    430518        Out() << fDimRS << endl;
     519        Out() << fDimDrive << endl;
    431520
    432521        return GetCurrentState();
     
    449538
    450539        // All subsystems are not connected
    451         if (fDimFTM.state()<FTM::State::kConnected)
     540        if (fDimFTM.state()<FTM::State::kConnected || fDimDrive.state()<Drive::State::kConnected)
    452541            return RateControl::State::kDisconnected;
    453542
     
    476565        fDimFTM("FTM_CONTROL"),
    477566        fDimRS("RATE_SCAN"),
     567        fDimDrive("DRIVE_CONTROL"),
    478568
    479569        fDimThreshold("RATE_CONTROL/THRESHOLD", "S:1;D:1;D:1",
     
    498588        Subscribe("FTM_CONTROL/STATIC_DATA")
    499589            (bind(&StateMachineRateControl::HandleStaticData,   this, placeholders::_1));
     590        Subscribe("FEEDBACK/CALIBRATED_CURRENTS")
     591            (bind(&StateMachineRateControl::HandleCalibratedCurrents, this, placeholders::_1));
    500592
    501593        // State names
     
    521613            (bind(&StateMachineRateControl::Calibrate, this))
    522614            ("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");
    523619
    524620        AddEvent("STOP", RateControl::State::kSettingGlobalThreshold, RateControl::State::kGlobalThresholdSet, RateControl::State::kInProgress)
Note: See TracChangeset for help on using the changeset viewer.