- Timestamp:
- 06/01/15 12:10:01 (9 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/HeadersFeedback.h
r17025 r18191 18 18 kWaitingForData, 19 19 kInProgress, 20 21 kWarning, 22 kCritical, 23 kOnStandby, 24 25 20 26 }; 21 27 } -
trunk/FACT++/src/feedback.cc
r17647 r18191 63 63 Time fTimeCalib; 64 64 Time fTimeTemp; 65 Time fTimeCritical; 65 66 66 67 double fUserOffset; 68 double fVoltageReduction; 67 69 vector<double> fTempOffset; 68 70 float fTempOffsetAvg; … … 78 80 uint16_t fCalibStep; 79 81 82 uint16_t fTimeoutCritical; 83 80 84 // ============================= Handle Services ======================== 81 85 … … 88 92 } 89 93 90 if (fDimBias.state()==BIAS::State::kVoltageOff && GetCurrentState() ==Feedback::State::kInProgress)94 if (fDimBias.state()==BIAS::State::kVoltageOff && GetCurrentState()>=Feedback::State::kInProgress) 91 95 return Feedback::State::kCalibrated; 92 96 … … 116 120 fVoltGapd.assign(evt.Ptr<float>(), evt.Ptr<float>()+416); 117 121 fBiasR9.assign(evt.Ptr<float>()+2*416, evt.Ptr<float>()+3*416); 122 123 for (int i=0; i<320; i++) 124 fVoltGapd[i] += 1.1; 125 118 126 Info("Nominal bias voltages and calibration resistor received."); 119 127 } … … 330 338 } 331 339 340 int CheckLimits(const float *I) 341 { 342 const float fAbsoluteMedianCurrentLimit = 85; 343 const float fRelativePixelCurrentLimit3 = 20; 344 const float fRelativePixelCurrentLimit0 = 45; 345 346 const float fAbsolutePixelCurrentLimit3 = fAbsoluteMedianCurrentLimit + fRelativePixelCurrentLimit3; 347 const float fAbsolutePixelCurrentLimit0 = fAbsoluteMedianCurrentLimit + fRelativePixelCurrentLimit0; 348 349 const float fRelativeCurrentLimitWarning = 10;//10; 350 const float fRelativeCurrentLimitCritical = 15;//20; 351 const float fRelativeCurrentLimitShutdown = 25; 352 353 fTimeoutCritical = 3000; // 5s 354 355 // Copy the calibrated currents 356 vector<float> v(I, I+320); 357 358 // Exclude the crazy patches (that's currently the best which could be done) 359 v[66] = 0; 360 v[191] = 0; 361 v[193] = 0; 362 363 sort(v.begin(), v.end()); 364 365 const float &imax0 = v[319]; 366 const float &imax3 = v[316]; 367 const float &imed = v[161]; 368 369 const bool shutdown = 370 imed >fAbsoluteMedianCurrentLimit+fRelativeCurrentLimitShutdown || 371 imax3>fAbsolutePixelCurrentLimit3+fRelativeCurrentLimitShutdown || 372 imax0>fAbsolutePixelCurrentLimit0+fRelativeCurrentLimitShutdown; 373 374 const bool critical = 375 imed >fAbsoluteMedianCurrentLimit+fRelativeCurrentLimitCritical || 376 imax3>fAbsolutePixelCurrentLimit3+fRelativeCurrentLimitCritical || 377 imax0>fAbsolutePixelCurrentLimit0+fRelativeCurrentLimitCritical; 378 379 const bool warning = 380 imed >fAbsoluteMedianCurrentLimit+fRelativeCurrentLimitWarning || 381 imax3>fAbsolutePixelCurrentLimit3+fRelativeCurrentLimitWarning || 382 imax0>fAbsolutePixelCurrentLimit0+fRelativeCurrentLimitWarning; 383 384 bool standby = GetCurrentState()==Feedback::State::kOnStandby; 385 386 if (standby) 387 { 388 // On Standby 389 if (fVoltageReduction==0 && 390 imed <fAbsoluteMedianCurrentLimit && 391 imax3<fAbsolutePixelCurrentLimit3 && 392 imax0<fAbsolutePixelCurrentLimit0) 393 { 394 // Currents are back at nominal value and currents are again 395 // below the current limit, switching back to standard operation. 396 return Feedback::State::kInProgress; 397 } 398 } 399 400 // Shutdown level 401 if (!standby && shutdown) 402 { 403 // Currents exceed the shutdown limit, operation is switched 404 // immediately to voltage reduced operation 405 406 // Just in case (FIXME: Is that really the right location?) 407 Dim::SendCommandNB("FAD_CONTROL/CLOSE_ALL_OPEN_FILES"); 408 409 Error("Current limit for shutdown exceeded.... swtching to standby mode."); 410 411 standby = true; 412 } 413 414 // Critical level 415 if (!standby && critical) 416 { 417 // This is a state transition from InProgress or Warning to Critical. 418 // Keep the transition time. 419 if (GetCurrentState()==Feedback::State::kInProgress || GetCurrentState()==Feedback::State::kWarning) 420 { 421 Info("Critical current limit exceeded.... waiting for "+to_string(fTimeoutCritical)+" ms."); 422 fTimeCritical = Time(); 423 } 424 425 // Critical is only allowed for fTimeoutCritical milliseconds. 426 // After this time, the operation is changed to reduced voltage. 427 if (Time()<fTimeCritical+boost::posix_time::milliseconds(fTimeoutCritical)) 428 return Feedback::State::kCritical; 429 430 // Just in case (FIXME: Is that really the right location?) 431 Dim::SendCommandNB("FAD_CONTROL/CLOSE_ALL_OPEN_FILES"); 432 433 // Currents in critical state 434 Warn("Critical current limit exceeded timeout.... switching to standby mode."); 435 436 standby = true; 437 } 438 439 // Warning level (is just informational) 440 if (!standby && warning) 441 return Feedback::State::kWarning; 442 443 // keep voltage 444 return standby ? Feedback::State::kOnStandby : Feedback::State::kInProgress; 445 } 446 332 447 int HandleBiasCurrent(const EventImp &evt) 333 448 { … … 349 464 return GetCurrentState(); 350 465 466 // We are waiting but biasctrl is still in ramping (this might 467 // be the case if the feedback was started with a new overvoltage 468 // while the last ramping command was still in progress) 469 if (GetCurrentState()==Feedback::State::kWaitingForData && 470 fDimBias.state()==BIAS::State::kRamping) 471 return GetCurrentState(); 472 351 473 // We are already in progress but no valid temperature update anymore 352 if (GetCurrentState() ==Feedback::State::kInProgress &&474 if (GetCurrentState()>=Feedback::State::kInProgress && 353 475 (!fTimeTemp.IsValid() || Time()-fTimeTemp>boost::posix_time::minutes(5))) 354 476 { … … 373 495 374 496 // Nominal overvoltage (w.r.t. the bias setup values) 375 const double overvoltage= GetCurrentState()<Feedback::State::kWaitingForData ? 0 : fUserOffset;497 const double voltageoffset = GetCurrentState()<Feedback::State::kWaitingForData ? 0 : fUserOffset; 376 498 377 499 double avg[2] = { 0, 0 }; … … 405 527 dim_data data; 406 528 407 data.Unom = overvoltage;529 data.Unom = voltageoffset; 408 530 data.dUtemp = fTempOffsetAvg; 409 531 410 532 vector<float> vec(416); 411 533 412 /* 413 if (fEnableOldAlgorithm) 414 { 415 // ================================= old ======================= 416 // Pixel 583: 5 31 == 191 (5) C2 B3 P3 417 // Pixel 830: 2 2 == 66 (4) C0 B8 P1 418 // Pixel 1401: 6 1 == 193 (5) C2 B4 P0 419 420 // 3900 Ohm/n + 1000 Ohm + 1100 Ohm (with n=4 or n=5) 421 const double R[2] = { 3075, 2870 }; 422 423 const float *Iavg = fCalibration.data(); // Offset at U=fCalibrationOffset 424 const float *Ravg = fCalibration.data()+BIAS::kNumChannels*2; // Measured resistance 425 426 for (int i=0; i<320; i++) 427 { 428 const PixelMapEntry &hv = fMap.hv(i); 429 if (!hv) 430 continue; 431 432 // Average measured current 433 const double Im = Imes[i] * 1e6; // [uA] 434 435 // Group index (0 or 1) of the of the pixel (4 or 5 pixel patch) 436 const int g = hv.group(); 437 438 // Serial resistors in front of the G-APD 439 double Rg = R[g]; 440 441 // This is assuming that the broken pixels have a 390 Ohm instead of 3900 Ohm serial resistor 442 if (i==66) // Pixel 830(66) 443 Rg = 2400; // 2400 = (3/3900 + 1/390) + 1000 + 1100 444 if (i==191 || i==193) // Pixel 583(191) / Pixel 1401(193) 445 Rg = 2379; // 2379 = (4/3900 + 1/390) + 1000 + 1100 446 447 const double r = 1./(1./Rg + 1./Ravg[i]); // [Ohm] 448 449 // Offset induced by the voltage above the calibration point 450 const double Ubd = fVoltGapd[i] + fTempOffsets[i]; 451 const double U0 = Ubd + overvoltage - fCalibVoltage[5][i]; // appliedOffset-fCalibrationOffset; 452 const double dI = U0/Ravg[i]; // [V/Ohm] 453 454 // Offset at the calibration point (make sure that the calibration is 455 // valid (Im[i]>Iavg[i]) and we operate above the calibration point) 456 const double I = Im>Iavg[i] ? Im - Iavg[i] : 0; // [uA] 457 458 // Make sure that the averaged resistor is valid 459 const double dU = Ravg[i]>10000 ? r*(I*1e-6 - dI) : 0; 460 461 vec[i] = Ubd + overvoltage + dU; 462 463 // Calculate statistics only for channels with a valid calibration 464 if (Iavg[i]>0) 465 { 466 med[g][num[g]] = dU; 467 avg[g] += dU; 468 num[g]++; 469 470 if (dU<min[g]) 471 min[g] = dU; 472 if (dU>max[g]) 473 max[g] = dU; 474 475 data.I[i] = Imes[i]*1e6 - fBiasVolt[i]/Ravg[i]*1e6; 476 data.I[i] /= hv.count(); 477 478 if (i==66) 479 data.I[i] /= 1.3; 480 if (i==191 || i==193) 481 data.I[i] /= 1.4; 482 483 data.Iavg += data.I[i]; 484 data.Irms += data.I[i]*data.I[i]; 485 486 med[2][num[2]++] = data.I[i]; 487 } 488 } 489 } 490 */ 534 // ================================= old ======================= 535 // Pixel 583: 5 31 == 191 (5) C2 B3 P3 536 // Pixel 830: 2 2 == 66 (4) C0 B8 P1 537 // Pixel 1401: 6 1 == 193 (5) C2 B4 P0 491 538 492 539 double UdrpAvg = 0; … … 503 550 504 551 // Average measured ADC value for this channel 552 // FIXME: This is a workaround for the problem with the 553 // readout of bias voltage channel 263 505 554 const double adc = Imes[i]/* * (5e-3/4096)*/; // [A] 506 555 … … 521 570 const double U9 = fBiasVolt[i]; 522 571 572 // new I8 - I9*100/fCalibR8 100 573 // change = --- = ---------------------- = -------- = 0.8 574 // old I8*fCalibR8/100 - I9 fCalibR8 575 523 576 // Serial resistors (one 1kOhm at the output of the bias crate, one 1kOhm in the camera) 524 577 const double R4 = 2000; 525 578 526 // Serial resistor of the individual G-APDs 527 double R5 = 3900./N ;579 // Serial resistor of the individual G-APDs plus 50 Ohm termination 580 double R5 = 3900./N + 50; 528 581 529 582 // This is assuming that the broken pixels have a 390 Ohm instead of 3900 Ohm serial resistor … … 559 612 const double Udrp = Iout<0 ? 0 : R*Iout; 560 613 561 // Nominal breakdown voltage with correction for temperature dependence562 const double U bd= fVoltGapd[i] + fVoltOffset[i] + fTempOffset[i];614 // Nominal operation voltage with correction for temperature dependence 615 const double Uop = fVoltGapd[i] + fVoltOffset[i] + fTempOffset[i]; 563 616 564 617 // Current overvoltage (at a G-APD with the correct 3900 Ohm resistor) 565 //const double Uov = U9-Udrp-Ubd>0 ? U9-Udrp-Ubd : 0; 566 const double Uov = U9-Udrp-Ubd>-0.44/*-0.34*/ ? U9-Udrp-Ubd : -0.44/*-0.34*/; 567 568 // Iout linear with U9 above Ubd 569 // 570 // Rx = (U9-Ubd)/Iout 571 // I' = (U9'-Ubd) / Rx 572 // Udrp' = R*I' 573 // Uov = U9' - Udrp' - Ubd 574 // Uov = overvoltage 575 // 576 // overvoltage = U9' - Udrp' - Ubd 577 // overvoltage = U9' - R*I' - Ubd 578 // overvoltage = U9' - R*((U9'-Ubd)/Rx) - Ubd 579 // overvoltage = U9' - U9'*R/Rx + Ubd*R/Rx - Ubd 580 // overvoltage = U9'*(1 - R/Rx) + Ubd*R/Rx - Ubd 581 // overvoltage - Ubd*R/Rx +Ubd = U9'*(1 - R/Rx) 582 // U9' = [ overvoltage - Ubd*R/Rx +Ubd ] / (1 - R/Rx) 583 // 618 // expressed w.r.t. to the operation voltage 619 const double Uov = (U9-Udrp)-Uop>-1.4 ? (U9-Udrp)-Uop : -1.4; 584 620 585 621 // The current through one G-APD is the sum divided by the number of G-APDs … … 619 655 Iapd = Iout/(N-1); 620 656 621 622 // 3900 + Rapd = I0 -> Uapd = Utot - 3900*I0623 // 3900 + Rapd = I0 -> Uapd = Utot - 3900*I0624 // 3900 + Rapd = I0 -> Uapd = Utot - 3900*I0625 // 390 + Rx = Ix -> Uapd = Utot - 390*Ix626 627 // Iout = N*I0 + Ix628 629 657 // The differential resistance of the G-APD, i.e. the dependence of the 630 658 // current above the breakdown voltage, is given by … … 634 662 635 663 // Estimate set point for over-voltage (voltage drop at the target point) 636 //const double Uset = Ubd + overvoltage + R*Iov*N; 637 //const double Uset = Uov<0.3 ? Ubd + overvoltage + Udrp : Ubd + overvoltage + Udrp*pow(overvoltage/Uov, 1.66); 638 const double Uset = 639 640 // Uov<0 ? 641 // Ubd + overvoltage + Udrp*pow(overvoltage/0.44/*0.34*/+1, 1.85/*1.66*/) : 642 // Ubd + overvoltage + Udrp*pow((overvoltage+0.44/*0.34*/)/(Uov+0.44/*0.34*/), 1.85/*1.66*/); 643 644 // Uov<0 ? 645 // Ubd + overvoltage + Udrp*pow(overvoltage+0.44, 1.3213+0.2475*(overvoltage+0.44)) : 646 // Ubd + overvoltage + Udrp*pow(overvoltage+0.44, 1.3213+0.2475*(overvoltage+0.44))/pow(Uov+0.44, 1.3213+0.2475*(Uov+0.44)); 647 648 // This estimation is based on the linear increase of the 649 // gain with voltage and the increase of the crosstalk with 650 // voltage, as measured with the overvoltage-tests (OVTEST) 651 652 Uov+0.44<0.022 ? 653 Ubd + overvoltage + Udrp* 654 exp(0.6*(overvoltage-Uov))*pow((overvoltage+0.44), 0.6) : 655 Ubd + overvoltage + Udrp* 656 exp(0.6*(overvoltage-Uov))*pow((overvoltage+0.44)/(Uov+0.44), 0.6); 657 658 659 660 661 if (fabs(overvoltage-Uov)>0.033) 664 // This estimation is based on the linear increase of the 665 // gain with voltage and the increase of the crosstalk with 666 // voltage, as measured with the overvoltage-tests (OVTEST) 667 /* 668 Uov+0.44<0.022 ? 669 Ubd + overvoltage + Udrp*exp(0.6*(overvoltage-Uov))*pow((overvoltage+0.44), 0.6) : 670 Ubd + overvoltage + Udrp*exp(0.6*(overvoltage-Uov))*pow((overvoltage+0.44)/(Uov+0.44), 0.6); 671 */ 672 const double Uset = 673 Uov+1.4<0.022 ? 674 Uop + voltageoffset + Udrp*exp(0.6*(voltageoffset-Uov))*pow((voltageoffset+1.4), 0.6) : 675 Uop + voltageoffset + Udrp*exp(0.6*(voltageoffset-Uov))*pow((voltageoffset+1.4)/(Uov+1.4), 0.6); 676 677 if (fabs(voltageoffset-Uov)>0.033) 662 678 Ndev[0]++; 663 if (fabs( overvoltage-Uov)>0.022)679 if (fabs(voltageoffset-Uov)>0.022) 664 680 Ndev[1]++; 665 if (fabs( overvoltage-Uov)>0.011)681 if (fabs(voltageoffset-Uov)>0.011) 666 682 Ndev[2]++; 667 683 668 684 // Voltage set point 669 685 vec[i] = Uset; 670 671 /*672 if (fDimBias.state()==BIAS::State::kVoltageOn && GetCurrentState()==Feedback::State::kInProgress &&673 fabs(Uov-overvoltage)>0.033)674 cout << setprecision(4) << setw(3) << i << ": Uov=" << Uov << " Udrp=" << Udrp << " Iapd=" << Iapd*1e6 << endl;675 */676 686 677 687 // Calculate statistics only for channels with a valid calibration … … 704 714 } 705 715 716 717 // ---------------------------- Calculate statistics ---------------------------------- 718 719 // average and rms 720 data.Iavg /= num[2]; 721 data.Irms /= num[2]; 722 data.Irms -= data.Iavg*data.Iavg; 723 724 data.N = num[2]; 725 data.Irms = data.Irms<0 ? 0: sqrt(data.Irms); 726 727 // median 728 sort(med[2].data(), med[2].data()+num[2]); 729 730 data.Imed = num[2]%2 ? med[2][num[2]/2] : (med[2][num[2]/2-1]+med[2][num[2]/2])/2; 731 732 // deviation 733 for (int i=0; i<num[2]; i++) 734 med[2][i] = fabs(med[2][i]-data.Imed); 735 736 sort(med[2].data(), med[2].data()+num[2]); 737 738 data.Idev = med[2][uint32_t(0.682689477208650697*num[2])]; 739 740 // time difference to calibration 741 data.Tdiff = evt.GetTime().UnixTime()-fTimeCalib.UnixTime(); 742 743 // Average overvoltage 744 const double Uov = (avg[0]+avg[1])/(num[0]+num[1]); 745 706 746 // ------------------------------- Update voltages ------------------------------------ 707 747 708 if (GetCurrentState()!=Feedback::State::kCalibrated) // WaitingForData, InProgress 748 int newstate = GetCurrentState(); 749 750 if (GetCurrentState()!=Feedback::State::kCalibrated) // WaitingForData, OnStandby, InProgress, kWarning, kCritical 709 751 { 710 752 if (fDimBias.state()!=BIAS::State::kRamping) 711 753 { 754 newstate = CheckLimits(data.I); 755 756 // standby and change reduction level of voltage 757 if (newstate==Feedback::State::kOnStandby) 758 { 759 // Calculate average applied overvoltage and estimate an offset 760 // to reach fAbsoluteMedianCurrentLimit 761 float fAbsoluteMedianCurrentLimit = 85; 762 const double deltaU = (Uov+1.4)*(1-pow(fAbsoluteMedianCurrentLimit/data.Imed, 1./1.7)); 763 764 if (fVoltageReduction+deltaU<0.033) 765 fVoltageReduction = 0; 766 else 767 { 768 fVoltageReduction += deltaU; 769 770 for (int i=0; i<320; i++) 771 vec[i] -= fVoltageReduction; 772 } 773 } 774 775 // FIXME: What if the brightest pixel gets too bright??? 776 // FIXME: What if fVolatgeReduction > U1.4V? 777 778 // set voltage in 262 -> current in 262/263 779 vec[263] = vec[262]-fVoltGapd[262]+fVoltGapd[263]; 780 781 // if (fDimBias.state()!=BIAS::State::kRamping) 782 // { 712 783 DimClient::sendCommandNB("BIAS_CONTROL/SET_ALL_CHANNELS_VOLTAGE", 713 784 vec.data(), BIAS::kNumChannels*sizeof(float)); … … 720 791 ostringstream msg; 721 792 msg << fixed; 722 msg << setprecision(2) << " Sending U:dU(" << fTemp << "degC)="793 msg << setprecision(2) << "dU(" << fTemp << "degC)=" 723 794 << setprecision(3) << fTempOffsetAvg << "V+-" << fTempOffsetRms << " Udrp=" 724 795 << UdrpAvg << "V+-" << UdrpRms; 725 796 msg.unsetf(ios_base::floatfield); 726 msg << " Unom=" << overvoltage << "V Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0) << " [N=" << Ndev[0] << "/" << Ndev[1] << "/" << Ndev[2] << "]"; 797 798 if (fVoltageReduction==0) 799 msg << " Unom=" << voltageoffset << "V"; 800 else 801 msg << " Ured=" << fVoltageReduction << "V"; 802 803 msg << " Uov=" << Uov; 804 msg << " Imed=" << data.Imed << "uA [N=" << Ndev[0] << "/" << Ndev[1] << "/" << Ndev[2] << "]"; 727 805 Info(msg); 728 806 } … … 733 811 { 734 812 ostringstream msg; 735 msg << setprecision(4) << "Current status: dU(" << fTemp << "degC)=" << fTempOffsetAvg << "V+-" << fTempOffsetRms << ", Unom=" << overvoltage<< "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0) << " [N=" << Ndev[0] << "/" << Ndev[1] << "/" << Ndev[2] << "]";813 msg << setprecision(4) << "Current status: dU(" << fTemp << "degC)=" << fTempOffsetAvg << "V+-" << fTempOffsetRms << ", Unom=" << voltageoffset << "V, Uov=" << (num[0]+num[1]>0?(avg[0]+avg[1])/(num[0]+num[1]):0) << " [N=" << Ndev[0] << "/" << Ndev[1] << "/" << Ndev[2] << "]"; 736 814 Info(msg); 737 815 } 738 739 } 740 741 if (GetCurrentState()==Feedback::State::kInProgress && 742 fDimBias.state()==BIAS::State::kRamping) 743 return GetCurrentState(); 816 } 817 818 //if (GetCurrentState()>=Feedback::State::kOnStandby && 819 // fDimBias.state()==BIAS::State::kRamping) 820 // return newstate; 744 821 745 822 // --------------------------------- Console out -------------------------------------- 746 823 747 if ( num[0]>0 && num[1]>0 &&fIsVerbose && !fDimBias.state()==BIAS::State::kRamping)824 if (fIsVerbose && !fDimBias.state()==BIAS::State::kRamping) 748 825 { 749 826 sort(med[0].begin(), med[0].begin()+num[0]); … … 769 846 // ---------------------------- Calibrated Currents ----------------------------------- 770 847 771 if (num[2]>0) 772 { 773 data.Iavg /= num[2]; 774 data.Irms /= num[2]; 775 data.Irms -= data.Iavg*data.Iavg; 776 777 data.N = num[2]; 778 data.Irms = data.Irms<0 ? 0: sqrt(data.Irms); 779 780 sort(med[2].data(), med[2].data()+num[2]); 781 782 data.Imed = num[2]%2 ? med[2][num[2]/2] : (med[2][num[2]/2-1]+med[2][num[2]/2])/2; 783 784 for (int i=0; i<num[2]; i++) 785 med[2][i] = fabs(med[2][i]-data.Imed); 786 787 sort(med[2].data(), med[2].data()+num[2]); 788 789 data.Idev = med[2][uint32_t(0.682689477208650697*num[2])]; 790 791 data.Tdiff = evt.GetTime().UnixTime()-fTimeCalib.UnixTime(); 792 793 // FIXME: 794 // + Current overvoltage 795 // + Temp offset 796 // + User offset 797 // + Command overvoltage 798 fDimCurrents.setQuality(GetCurrentState()); 799 fDimCurrents.setData(&data, sizeof(dim_data)); 800 fDimCurrents.Update(evt.GetTime()); 801 } 802 803 return GetCurrentState()==Feedback::State::kCalibrated ? Feedback::State::kCalibrated : Feedback::State::kInProgress; 848 // FIXME: 849 // + Current overvoltage 850 // + Temp offset 851 // + User offset 852 // + Command overvoltage 853 fDimCurrents.setQuality(GetCurrentState()); 854 fDimCurrents.setData(&data, sizeof(dim_data)); 855 fDimCurrents.Update(evt.GetTime()); 856 857 // FIXME: To be checked 858 return GetCurrentState()==Feedback::State::kCalibrated ? Feedback::State::kCalibrated : newstate; 804 859 } 805 860 … … 906 961 return kSM_FatalError; 907 962 963 /* 908 964 if (fDimBias.state()==BIAS::State::kRamping) 909 965 { 910 966 Warn("Feedback can not be started when biasctrl is in state Ramping."); 911 967 return GetCurrentState(); 912 } 913 914 fUserOffset = evt.GetFloat(); 968 }*/ 969 970 fUserOffset = evt.GetFloat()-1.1; 971 fVoltageReduction = 0; 915 972 916 973 fCursorCur = 0; … … 977 1034 return GetCurrentState(); 978 1035 } 1036 1037 int SaveCalibration() 1038 { 1039 ofstream fout("feedback-calib.bin"); 1040 1041 double mjd = fTimeCalib.Mjd(); 1042 fout.write((char*)&mjd, sizeof(double)); 1043 fout.write((char*)fCalibDeltaI.data(), BIAS::kNumChannels*sizeof(float)); 1044 fout.write((char*)fCalibR8.data(), BIAS::kNumChannels*sizeof(float)); 1045 1046 return GetCurrentState(); 1047 } 1048 1049 int LoadCalibration() 1050 { 1051 ifstream fin("feedback-calib.bin"); 1052 1053 double mjd; 1054 1055 vector<float> di(BIAS::kNumChannels); 1056 vector<float> r8(BIAS::kNumChannels); 1057 1058 fin.read((char*)&mjd, sizeof(double)); 1059 fin.read((char*)di.data(), BIAS::kNumChannels*sizeof(float)); 1060 fin.read((char*)r8.data(), BIAS::kNumChannels*sizeof(float)); 1061 1062 if (!fin) 1063 { 1064 Warn("Reading of calibration failed."); 1065 return GetCurrentState(); 1066 } 1067 1068 fTimeCalib.Mjd(mjd); 1069 fCalibDeltaI = di; 1070 fCalibR8 = r8; 1071 1072 return Feedback::State::kCalibrated; 1073 } 1074 979 1075 980 1076 … … 1040 1136 "Calibration of R8" 1041 1137 "|DeltaI[uA]:Average offset" 1042 "|R8[ uA]:Measured effective resistor R8"),1138 "|R8[Ohm]:Measured effective resistor R8"), 1043 1139 fDimCurrents("FEEDBACK/CALIBRATED_CURRENTS", "F:416;F:1;F:1;F:1;F:1;I:1;F:1;F:416;F:1;F:1", 1044 1140 "Calibrated currents" … … 1050 1146 "|N[uint16]:Number of valid values" 1051 1147 "|T_diff[s]:Time difference to calibration" 1052 "|U_ov[V]:Calculated overvoltage "1053 "|U_nom[V]:Nominal overvoltage "1148 "|U_ov[V]:Calculated overvoltage w.r.t. operation voltage" 1149 "|U_nom[V]:Nominal overvoltage w.r.t. operation voltage" 1054 1150 "|dU_temp[V]:Correction calculated from temperature" 1055 1151 ), … … 1097 1193 AddStateName(Feedback::State::kWaitingForData, "WaitingForData", 1098 1194 "Current control started, waiting for valid temperature and current data."); 1195 1196 AddStateName(Feedback::State::kOnStandby, "OnStandby", 1197 "Current control in progress but with limited voltage."); 1099 1198 AddStateName(Feedback::State::kInProgress, "InProgress", 1100 1199 "Current control in progress."); 1200 AddStateName(Feedback::State::kWarning, "Warning", 1201 "Current control in progress but current warning level exceeded."); 1202 AddStateName(Feedback::State::kCritical, "Critical", 1203 "Current control in progress but critical current limit exceeded."); 1101 1204 1102 1205 … … 1125 1228 AddEvent("RESET_OFFSETS", Feedback::State::kConnected, Feedback::State::kCalibrated) 1126 1229 (bind(&StateMachineFeedback::ResetOffset, this)) 1230 (""); 1231 1232 1233 AddEvent("SAVE_CALIBRATION", Feedback::State::kCalibrated) 1234 (bind(&StateMachineFeedback::SaveCalibration, this)) 1235 (""); 1236 AddEvent("LOAD_CALIBRATION", Feedback::State::kConnected) 1237 (bind(&StateMachineFeedback::LoadCalibration, this)) 1127 1238 (""); 1128 1239
Note:
See TracChangeset
for help on using the changeset viewer.