Changeset 175 for drsdaq/HVFeedback.cc


Ignore:
Timestamp:
03/10/10 09:11:58 (15 years ago)
Author:
ogrimm
Message:
Feedback now using DIM for communication with bias server.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • drsdaq/HVFeedback.cc

    r140 r175  
    1212#include "PixelMap.h"
    1313
    14 #include <sys/socket.h>
    15 #include <netdb.h>
    16 #include <signal.h>
    17 
    1814#define PIXMAP_LOCATION "../config/PixelMap.txt"
    1915
     16static const char* FBState_Description[] = {
     17        "Feedback off",
     18        "Feedback active",
     19        "Feedback acquiring new targets",
     20        "Feedback measuring response with first voltage",
     21        "Feedback measuring response with second voltage"
     22};
     23
    2024//
    2125// Constructor: Initialise feedback
    2226//
    23 HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile) {
    24   struct sockaddr_in SocketAddress;
     27HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile):
     28                        EvidenceServer(SERVER_NAME){
    2529
    2630  m = DAQClass;
     31  //fNumberOfChannels = m->fNumberOfChannels;
     32  //fNumberOfChips = m->fNumberOfChips;
     33  fNumberOfChannels = 10;
     34  fNumberOfChips = 2; 
     35 
    2736  PixMap = new PixelMap(PIXMAP_LOCATION, false);
    2837
    29   // Create instance of slow data class for feedback
    30   SlowDataClass = new SlowData("HVFB", m->fSlowDataPath);
    31   if (SlowDataClass->ErrorCode != 0) {
    32     m->PrintMessage("Warning: Could not open feedback slowdata file (%s)\n", strerror(SlowDataClass->ErrorCode));
    33   }
    34   SlowDataClass->NewEntry("Average-Info", "Feedback regulation occurred: Board Chip Channel Average Sigma Correction-Value");
    35   SlowDataClass->NewEntry("Target-Info", "New Target values acquired: Board Chip Channel Target Sigma");
    36   SlowDataClass->NewEntry("Response-Info", "New response measurement: Board Chip Channel Response");
    37 
    3838  // Initialise with zero content
    39   Average    = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels]();
    40   Sigma      = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels]();
    41   Response   = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels]();
    42   Target     = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels]();
    43   Buffer     = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels](); 
     39  Average    = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
     40  Sigma      = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
     41  Response   = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
     42  Target     = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
     43  Buffer     = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax](); 
     44
     45  DIMAverage = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
     46  DIMSigma   = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax]();
    4447
    4548  // Read configuration file
     
    5962    ReadCard("IntHalfWidth",        &fIntHalfWidth,      'U', File);
    6063    ReadCard("DefaultNumAverage",   &fDefaultNumAverage, 'I', File);
    61     ReadCard("HVControlServer",      fHVControlServer,   's', File);
    62     ReadCard("HVControlPort",       &fHVControlPort,     'I', File);
    63     ReadCard("MaxCmdAckDelay",      &fMaxCmdAckDelay,    'I', File);
    64     ReadCard("DefaultResponse",      Response,           'f', File, m->NumBoards*kNumberOfChips*kNumberOfChannels);
    65     ReadCard("DefaultTarget",        Target,             'f', File, m->NumBoards*kNumberOfChips*kNumberOfChannels);
     64    ReadCard("DefaultResponse",      Response,           'f', File, m->NumBoards*fNumberOfChips*fNumberOfChannels);
     65    ReadCard("DefaultTarget",        Target,             'f', File, m->NumBoards*fNumberOfChips*fNumberOfChannels);
    6666    // Add also initial gain to configuration parameters
    6767    fclose(File);
    6868  }
    6969  PrintConfig(MsgToLog);
    70  
     70
     71  // Provide DIM services
     72  FeedbackAverage = new DimService (SERVER_NAME"/Average", "F", DIMAverage, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
     73  FeedbackSigma = new DimService (SERVER_NAME"/Sigma", "F", DIMSigma, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
     74  FeedbackResponse = new DimService (SERVER_NAME"/Response", "F", Response, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
     75  FeedbackTarget = new DimService (SERVER_NAME"/Target", "F", Target, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float));
     76  CountService = new DimService (SERVER_NAME"/Count", Count);
     77
    7178  // Initial state
    7279  Gain = 0.2;
    7380  SetFBMode(FB_Off);
    7481  SetNumAverages(fDefaultNumAverage);
    75 
    76   // Opening socket client to HV control program
    77   if ((SocketDescriptor = socket(PF_INET, SOCK_STREAM, 0)) == -1)
    78     m->PrintMessage("Could not open client socket, no HV control available.\n");
    79 
    80   // Resolve hostname and try to connect to server
    81   struct hostent *hostent = gethostbyname(fHVControlServer);
    82   if (hostent==0)
    83     m->PrintMessage("Could not resolve HV server host name \"%s\".\n", fHVControlServer);
    84   else {
    85     SocketAddress.sin_family = PF_INET;
    86     SocketAddress.sin_port = htons((unsigned short) fHVControlPort);
    87     SocketAddress.sin_addr = *(struct in_addr*) hostent->h_addr;
    88  
    89     if (connect(SocketDescriptor, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress))==-1)
    90       m->PrintMessage("Could not connect to HV server %s at port %d (%s)\n", fHVControlServer, fHVControlPort, strerror(errno));
    91     else m->PrintMessage("\nFeedback connected to HV server %s (port %d).\n", fHVControlServer, fHVControlPort);
    92     signal(SIGPIPE,SIG_IGN);  // Do not kill process if writing to closed socket
    93   }
     82  LastServiceUpdate = 0;
    9483}
    9584
     
    9887//
    9988HVFeedback::~HVFeedback() {
    100   if (SocketDescriptor!=-1) {
    101     close(SocketDescriptor);
    102     m->PrintMessage("Feedback socket closed.\n");
    103   }
     89
     90  delete CountService;
     91  delete FeedbackAverage;
     92  delete FeedbackSigma;
     93  delete FeedbackResponse;
     94  delete FeedbackTarget;
     95
    10496  delete[] Average;     delete[] Response;
    10597  delete[] Target;      delete[] Buffer;
    106   delete SlowDataClass; delete PixMap;
     98  delete PixMap;
    10799}
    108100
     
    113105bool HVFeedback::ProcessEvent() {
    114106  int i,j,k,q;
    115   float Correction, Integral, Difference;
     107  float Correction, Integral;
    116108 
    117109  // Check for LED trigger channel on given channel and if feedback running
    118   if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][(fLedTrigSample+m->TriggerCell[fLedTrigBoard][fLedTrigChip])%kNumberOfBins] < fLedTrigThreshold)
     110  if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][(fLedTrigSample+m->TriggerCell[fLedTrigBoard][fLedTrigChip])%kNumberOfBins] < fLedTrigThreshold) {
    119111    return false;
     112  }
    120113 
    121114  // Calculate average signal of LED pulse as integral of signal
    122   for (i=m->FirstBoard; i<=m->LastBoard; i++)
    123     for (j=0; j<kNumberOfChips; j++)
    124       for (k=0; k<kNumberOfChannels; k++) {
    125         for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++)
     115  for (i=m->FirstBoard; i<=m->LastBoard; i++) {
     116        for (j=0; j<fNumberOfChips; j++) {
     117          for (k=0; k<fNumberOfChannels; k++) {
     118                for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++) {
    126119          Integral += (m->WaveForm[i][j][k][(fLedSignalSample+q+m->TriggerCell[i][j])%kNumberOfBins] - m->WaveForm[i][j][k][(fLedBaselineSample+q+m->TriggerCell[i][j])%kNumberOfBins])*m->drs->GetBoard(i)->GetPrecision();
     120                }
    127121        Integral /= 2*fIntHalfWidth+1;
    128         Average[i][j][k] += Integral;
     122                Average[i][j][k] += Integral;
    129123        Sigma[i][j][k] += pow(Integral,2);
    130124      }
    131 
     125        }
     126  }
     127 
     128  // Update DIM service regularly
     129  if (time(NULL)-LastServiceUpdate > 2) {
     130    LastServiceUpdate = time(NULL);
     131        CountService->updateService();
     132  }
    132133  // Check if acquired number of event requires action
    133134  if (++Count<NumAverages) return false;
    134135
    135   // Make entry in slow data file
    136   switch (FBMode) {
    137     case FB_Active: SlowDataClass->NewEntry("Average");
    138                     break;
    139     case FB_Targets: SlowDataClass->NewEntry("Target");
    140                      break;
    141     case FB_ResponseSecond: SlowDataClass->NewEntry("Response");
    142                             SlowDataClass->AddToEntry("%.3f ",DiffVoltage);
    143                             break;
    144     default: break;  // to suppress warning abount not handled enumeration value
    145   }                     
    146 
    147136  // Feedback action
    148137  for (i=m->FirstBoard; i<=m->LastBoard; i++) {
    149     for (j=0; j<kNumberOfChips; j++) {
    150       for (k=0; k<kNumberOfChannels; k++) {
     138  for (j=0; j<fNumberOfChips; j++) {
     139  for (k=0; k<fNumberOfChannels; k++) {
     140    // Calculate average
    151141        Average[i][j][k] /= Count;
    152142        Sigma[i][j][k] = sqrt(Sigma[i][j][k]/Count-pow(Average[i][j][k],2))/sqrt(Count);
     143        DIMAverage[i][j][k] = Average[i][j][k];
     144        DIMSigma[i][j][k] = Sigma[i][j][k];
     145       
    153146        switch (FBMode) {
    154147          case FB_Active:   // Determine correction from response maxtrix and change voltages
    155             Difference = Target[i][j][k] - Average[i][j][k];
    156             Correction = -Difference*Response[i][j][k]*Gain;
    157             //if (fabs(Correction) > 0.1) Correction = fabs(Correction)/Correction*0.1;   // Limit changes to 100 mV
    158             if(Correction!=0 && Target[i][j][k]!=0 && !PixMap->DRS_to_Pixel(i,j,k).empty()) {
    159               printf("Average of board %d, chip %d, channel %d is %.2f +/- %.2f    Correction %.3f\n",i,j,k,Average[i][j][k],Sigma[i][j][k],Correction);
    160               SlowDataClass->AddToEntry("%d %d %d %.3f %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k],Correction);
    161               if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n");
    162               else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(),Correction);
    163             }
     148            Correction = -(Target[i][j][k] - Average[i][j][k])*Response[i][j][k]*Gain;
     149        if (fabs(Correction) > 0.1) Correction = fabs(Correction)/Correction*0.1;   // Limit changes to 100 mV
     150        if(Correction==0 || Target[i][j][k] ==0 || PixMap->DRS_to_Pixel(i,j,k).empty()) break;
     151
     152        printf("Average of board %d, chip %d, channel %d is %.2f +/- %.2f    Correction %.3f\n",i,j,k,Average[i][j][k],Sigma[i][j][k],Correction);
     153
     154                if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n");
     155                else WriteHVCommand("hv %s %+f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), Correction);
     156
    164157            break;
     158
    165159          case FB_Targets:  // Take average as new targets 
    166160            Target[i][j][k] = Average[i][j][k];
    167             SlowDataClass->AddToEntry("%d %d %d %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k]);
    168161            break;
    169           case FB_ResponseFirst:  // First point of response measurement done 
     162
     163          case FB_ResponseFirst:  // First point of response measurement done 
    170164            Buffer[i][j][k] = Average[i][j][k];
    171             if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage);
     165            if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv %s %+f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage);
    172166            break;
    173           case FB_ResponseSecond: // Determine response from signal variation
     167
     168          case FB_ResponseSecond: // Determine response from signal variation
    174169            if(Buffer[i][j][k] == Average[i][j][k]) {
    175170              m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k);
     
    177172            }
    178173            else Response[i][j][k] = DiffVoltage/(Buffer[i][j][k]-Average[i][j][k]);
    179             SlowDataClass->AddToEntry("%d %d %d %.3f ", i,j,k,Response[i][j][k]);
    180             if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), -DiffVoltage/2);
     174            if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv %s %+f",PixMap->DRS_to_Pixel(i,j,k).c_str(), -DiffVoltage/2);
    181175            break;
     176
    182177          default: break;  // to suppress warning abount not handled enumeration value
    183178        }                       
    184       }
    185     }
    186   }
    187  
     179  } // for() channels
     180  } // for() chips
     181  } // for() boards
     182
     183  // Update DIM service
     184  FeedbackAverage->updateService();
     185  FeedbackSigma->updateService();
     186
    188187  switch (FBMode) {
    189188    case FB_Targets:
     189          FeedbackTarget->updateService();
    190190      m->PrintMessage("HV Feedback: New targets set, switching off.\n");
    191       FBMode = FB_Off;
     191      SetFBMode(FB_Off, true);
    192192      break;
    193193    case FB_ResponseFirst:
    194       FBMode = FB_ResponseSecond;
     194      SetFBMode(FB_ResponseSecond, true);
    195195      m->PrintMessage("HV Feedback: Increasing voltages by %f for response measurement, acquiring data.\n", DiffVoltage);
    196196      break;
    197197    case FB_ResponseSecond:
     198          FeedbackResponse->updateService();
    198199      m->PrintMessage("HV Feedback: Response measurements finished, original voltages set, switching off.\n");
    199       FBMode = FB_Off;
     200      SetFBMode(FB_Off, true);
    200201      break;
    201202    default: break;  // to suppress warning abount not handled enumeration value
    202203  }
    203  
    204   if(m->SlowDataClass->ErrorCode != 0) {
    205     m->PrintMessage("Error, could not write feedback slow data to file (%s), file closed.\n", strerror(m->SlowDataClass->ErrorCode));
    206   }
    207204  ClearAverages();
    208205 
     
    215212void HVFeedback::ClearAverages() {
    216213  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    217     for (int j=0; j<kNumberOfChips; j++)
    218       for (int k=0; k<kNumberOfChannels; k++) {
     214    for (int j=0; j<fNumberOfChips; j++)
     215      for (int k=0; k<fNumberOfChannels; k++) {
    219216        Average[i][j][k] = 0.0;
    220         Sigma[i][j][k] = 0.0;
     217                Sigma[i][j][k] = 0.0;
    221218      }
    222219  Count = 0;
     220  CountService->updateService();
    223221}
    224222
     
    254252// Set feedback mode and clear averages
    255253//
    256 void HVFeedback::SetFBMode(FBState Mode) {
    257   if(Mode==FB_ResponseFirst || Mode==FB_ResponseFirst)
     254void HVFeedback::SetFBMode(FBState Mode, bool Internal) {
     255  if((Mode==FB_ResponseFirst || Mode==FB_ResponseFirst) && !Internal)
    258256      m->PrintMessage("Start reponse measurement by calling MeasureResponse().\n");
    259257  else {
    260258    FBMode = Mode;
     259        if (Mode != FB_ResponseFirst) State(INFO, "%s", FBState_Description[FBMode]);
     260        else State(INFO, "%s (voltage difference %.3f)", FBState_Description[FBMode], DiffVoltage);
    261261    ClearAverages();
    262262  }
     
    267267//
    268268FBState HVFeedback::GetFBMode() {
    269   switch (FBMode) {
    270     case FB_Off: m->PrintMessage("Feedback off.\n");   break;
    271     case FB_Active: m->PrintMessage("Feedback active.\n");   break;
    272     case FB_Targets: m->PrintMessage("Feedback acquiring new targets.\n");   break;
    273     case FB_ResponseFirst: m->PrintMessage("Feedback measuring response with first voltage.\n");   break;
    274     case FB_ResponseSecond: m->PrintMessage("Feedback measuring response with second voltage.\n");   break;
    275   }
    276   return FBMode;                       
     269
     270  m->PrintMessage("%s.\n", FBState_Description[FBMode]);
     271  return FBMode;
    277272}
    278273
     
    288283//
    289284void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) {
    290   if(Board<m->NumBoards && Chip<kNumberOfChips && Channel<kNumberOfChannels)
     285  if(Board<m->NumBoards && Chip<fNumberOfChips && Channel<fNumberOfChannels) {
    291286    Target[Board][Chip][Channel] = TargetVal;
     287        FeedbackTarget->updateService();
     288  }
    292289  else printf("Invalid board, chip or channel number.\n");
    293290}
     
    298295void HVFeedback::GetTargets() {
    299296  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    300     for (int j=0; j<kNumberOfChips; j++) {
     297    for (int j=0; j<fNumberOfChips; j++) {
    301298      m->PrintMessage("Board %d, chip %d:",i,j);
    302       for (int k=0; k<kNumberOfChannels; k++) m->PrintMessage(" %.2f",Target[i][j][k]);
     299      for (int k=0; k<fNumberOfChannels; k++) m->PrintMessage(" %.2f",Target[i][j][k]);
    303300      m->PrintMessage("\n\r");
    304301    }
     
    316313
    317314  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    318     for (int j=0; j<kNumberOfChips; j++)
    319       for (int k=0; k<kNumberOfChannels; k++) {
    320         if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
    321           WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2);
     315    for (int j=0; j<fNumberOfChips; j++)
     316      for (int k=0; k<fNumberOfChannels; k++) {
     317                if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
     318          WriteHVCommand("hv %s %+f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2);
    322319        }
    323320      }
    324321  DiffVoltage = U;
    325   FBMode = FB_ResponseFirst;
    326   ClearAverages(); 
     322  SetFBMode(FB_ResponseFirst, true);
    327323  m->PrintMessage("HV Feedback: Decreasing voltages by %f for response measurement, acquiring data.\n",DiffVoltage/2);
    328324}
     
    333329void HVFeedback::GetResponse() {
    334330  for (int i=m->FirstBoard; i<=m->LastBoard; i++) {
    335     for (int j=0; j<kNumberOfChips; j++) {
     331    for (int j=0; j<fNumberOfChips; j++) {
    336332      m->PrintMessage("Board %d, chip %d:",i,j);
    337       for (int k=0; k<kNumberOfChannels; k++) m->PrintMessage(" %.3f",Response[i][j][k]);
     333      for (int k=0; k<fNumberOfChannels; k++) m->PrintMessage(" %.3f",Response[i][j][k]);
    338334      m->PrintMessage("\n\r");
    339335    }
     
    342338
    343339//
    344 // Write commmand to socket
     340// Write bias voltage commmand
    345341//
    346342bool HVFeedback::WriteHVCommand(const char *Format, ...) {
     343
    347344  char Textbuffer[MAX_COM_SIZE];
    348   fd_set SelectDescriptor;
    349345 
    350346  va_list ArgumentPointer;  va_start(ArgumentPointer, Format);
    351347  vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
    352348
    353   // Write command to socket
    354   if(write(SocketDescriptor, Textbuffer, strlen(Textbuffer)+1)!=(int) strlen(Textbuffer)+1) {
    355     m->PrintMessage("Error: Could not write (entire) command to HV socket (%s)\n", strerror(errno));
    356     return false;
    357   }
    358 
    359   // Wait for command acknowledge from hvcontrol program
    360   FD_ZERO(&SelectDescriptor);   FD_SET(SocketDescriptor, &SelectDescriptor);
    361   struct timeval WaitTime = {fMaxCmdAckDelay, 0};
    362   if (select(((int) SocketDescriptor)+1, &SelectDescriptor, NULL, NULL, &WaitTime)==-1) {
    363     m->PrintMessage("Error with select() in command acknowledge (%s)\n", strerror(errno));
    364     return false;
    365   }
    366  
    367   // Evaluate response
    368   if (!FD_ISSET(SocketDescriptor, &SelectDescriptor)) { // Time-out
    369     m->PrintMessage("Time-out of %d seconds expired before receiving acknowledge from HV socket.\n", fMaxCmdAckDelay);
    370     return false;
    371   }
    372   if (read(SocketDescriptor, Textbuffer, MAX_COM_SIZE) == -1) { // Could not read
    373     m->PrintMessage("Error reading acknowledge from HV socket (%s)\n", strerror(errno));
    374     return false;
    375   }
    376   if (strncmp(Textbuffer, "OK", 2) != 0) { // ERROR response
    377     m->PrintMessage("Did not received OK from hvcontrol.\n");
    378     return false;
    379   }
     349  DimClient::sendCommand("Bias/Command", Textbuffer);
     350
    380351  return true;
    381352}
     
    385356//
    386357void HVFeedback::PrintConfig(int Target) {
     358
    387359  m->PrintMessage(Target, "LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n"
    388360        "LedTrigSample: %d\tLedTrigThreshold: %.2f\n"
    389361        "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n"
    390         "IntHalfWidth:%u\tHVControlServer: %s\tHVControlPort: %d\n"
    391         "MaxCmdAckDelay: %d\n",
     362        "IntHalfWidth:%u\n",
    392363    fLedTrigBoard, fLedTrigChip, fLedTrigChannel, fLedTrigSample,
    393364    fLedTrigThreshold, fLedSignalSample, fLedBaselineSample,
    394     fDefaultNumAverage, fIntHalfWidth, fHVControlServer, fHVControlPort, fMaxCmdAckDelay);
    395 }
     365    fDefaultNumAverage, fIntHalfWidth);
     366}
Note: See TracChangeset for help on using the changeset viewer.