source: trunk/FACT++/src/smartfact.cc@ 13532

Last change on this file since 13532 was 13529, checked in by tbretz, 14 years ago
Removed debug status in output file.
File size: 24.6 KB
Line 
1#include "Dim.h"
2#include "Event.h"
3#include "Shell.h"
4#include "StateMachineDim.h"
5#include "Connection.h"
6#include "Configuration.h"
7#include "Console.h"
8#include "Converter.h"
9#include "DimServiceInfoList.h"
10#include "PixelMap.h"
11
12#include "tools.h"
13#include "DimData.h"
14
15#include "LocalControl.h"
16
17#include "HeadersFAD.h"
18#include "HeadersBIAS.h"
19#include "HeadersFTM.h"
20
21namespace ba = boost::asio;
22namespace bs = boost::system;
23namespace dummy = ba::placeholders;
24
25using namespace std;
26
27// ------------------------------------------------------------------------
28
29#include "DimDescriptionService.h"
30
31// ------------------------------------------------------------------------
32
33class StateMachineSmartFACT : public StateMachineDim, public DimInfoHandler
34{
35private:
36 enum states_t
37 {
38 kStateDimNetworkNA = 1,
39 kStateRunning,
40 };
41
42 // ------------------------- Internal variables -----------------------
43
44 PixelMap fPixelMap;
45
46 Time fLastUpdate;
47
48 // ----------------------------- Data storage -------------------------
49
50 enum weather_t { kTemp = 0, kDew, kHum, kPress, kWind, kGusts, kDir };
51 float fMagicWeatherData[7];
52
53 vector<float> fFeedbackCalibration;
54 vector<float> fBiasControlVoltageVec;
55
56 float fBiasControlVoltageMed;
57 float fBiasControlCurrentMed;
58 float fBiasControlCurrentMax;
59
60 deque<float> fBiasControlCurrentHist;
61
62 float fDriveControlPointingZd;
63 string fDriveControlPointingAz;
64 float fDriveControlTrackingDev;
65 string fDriveControlSourceName;
66
67 float fFtmControlTriggerRateCam;
68 deque<float> fFtmControlTriggerRateHist;
69
70 uint8_t fFadControlEventCounter;
71
72 // ------------- Initialize variables before the Dim stuff ------------
73
74 DimServiceInfoList fNetwork;
75
76 pair<Time, int> fStatusDim;
77 pair<Time, int> fStatusDriveControl;
78 pair<Time, int> fStatusMagicWeather;
79 pair<Time, int> fStatusFeedback;
80 pair<Time, int> fStatusBiasControl;
81 pair<Time, int> fStatusFtmControl;
82 pair<Time, int> fStatusFadControl;
83
84 DimStampedInfo fDim;
85
86 DimStampedInfo fDimDriveControl;
87 DimStampedInfo fDimDriveControlPointing;
88 DimStampedInfo fDimDriveControlTracking;
89 DimStampedInfo fDimDriveControlSource;
90
91 DimStampedInfo fDimMagicWeather;
92 DimStampedInfo fDimMagicWeatherData;
93
94 DimStampedInfo fDimFeedback;
95 DimStampedInfo fDimFeedbackCalibration;
96
97 DimStampedInfo fDimBiasControl;
98 DimStampedInfo fDimBiasControlVoltage;
99 DimStampedInfo fDimBiasControlCurrent;
100
101 DimStampedInfo fDimFtmControl;
102 DimStampedInfo fDimFtmControlTriggerRates;
103
104 DimStampedInfo fDimFadControl;
105 DimStampedInfo *fDimFadControlEventData;
106
107 // -------------------------------------------------------------------
108
109 pair<Time, int> GetNewState(DimStampedInfo &info) const
110 {
111 const bool disconnected = info.getSize()==0;
112
113 // Make sure getTimestamp is called _before_ getTimestampMillisecs
114 const int tsec = info.getTimestamp();
115 const int tms = info.getTimestampMillisecs();
116
117 return make_pair(Time(tsec, tms*1000),
118 disconnected ? -2 : info.getQuality());
119 }
120
121 bool UpdateState(DimInfo *curr, DimStampedInfo &service, pair<Time,int> &rc)
122 {
123 if (curr!=&service)
124 return false;
125
126 rc = GetNewState(service);
127 return true;
128 }
129
130 bool HandleService(DimInfo *curr, const DimInfo &service, void (StateMachineSmartFACT::*handle)(const DimData &))
131 {
132 if (curr!=&service)
133 return false;
134
135 (this->*handle)(DimData(curr));
136 return true;
137 }
138
139
140 bool CheckDataSize(const DimData &d, const char *name, size_t size)
141 {
142 if (d.data.size()==size)
143 return true;
144
145 ostringstream msg;
146 msg << name << " - Received service has " << d.data.size() << " bytes, but expected " << size << ".";
147 Warn(msg);
148 return false;
149 }
150
151
152 // -------------------------------------------------------------------
153
154 template<class T>
155 void WriteBinary(const string &fname, const T &t, double scale, double offset=0)
156 {
157 vector<uint8_t> val(t.size(), 0);
158 for (uint64_t i=0; i<t.size(); i++)
159 {
160 float range = nearbyint(128*(t[i]+offset)/scale); // [-2V; 2V]
161 if (range>127)
162 range=127;
163 if (range<0)
164 range=0;
165 val[i] = (uint8_t)range;
166 }
167
168 const char *ptr = reinterpret_cast<char*>(val.data());
169
170 ofstream fout("www/"+fname+".bin");
171 fout.write(ptr, val.size()*sizeof(uint8_t));
172 }
173
174 // -------------------------------------------------------------------
175
176 void HandleMagicWeatherData(const DimData &d)
177 {
178 if (!CheckDataSize(d, "MagicWeather:Data", 7*4+2))
179 return;
180
181 // FIXME: Check size (7*4+2)
182
183 //const uint16_t status = d.get<uint16_t>();
184 memcpy(fMagicWeatherData, d.ptr<float>(2), 7*sizeof(float));
185
186 ostringstream out;
187 out << uint64_t(d.time.UnixTime()*1000) << '\n';
188
189 for (int i=0; i<7; i++)
190 out << "#ffffff\t" << fMagicWeatherData[i] << '\n';
191
192 ofstream fout("www/magicweather.txt");
193 fout << out.str();
194 }
195
196 void HandleDriveControlPointing(const DimData &d)
197 {
198 if (!CheckDataSize(d, "DriveControl:Pointing", 7*4+2))
199 return;
200
201 fDriveControlPointingZd = d.get<double>();
202
203 const double az = d.get<double>(8);
204
205 static const char *dir[] =
206 {
207 "N", "NNE", "NE", "ENE",
208 "E", "ESE", "SE", "SSE",
209 "S", "SSW", "SW", "WSW",
210 "W", "WNW", "NW", "NNW"
211 };
212
213 const uint16_t i = uint16_t(floor(fmod(az+11.25, 360)/22));
214 fDriveControlPointingAz = dir[i];
215
216 ostringstream out;
217 out << uint64_t(d.time.UnixTime()*1000) << '\n';
218
219 out << setprecision(5);
220 out << fDriveControlPointingZd << '\n';
221 out << az << '\n';
222
223 ofstream fout("www/drive-pointing.txt");
224 fout << out.str();
225 }
226
227 void HandleDriveControlTracking(const DimData &d)
228 {
229 if (!CheckDataSize(d, "DriveControl:Tracking", 7*4+2))
230 return;
231
232 const double zd = d.get<double>(4*8) * M_PI / 180;
233 const double dzd = d.get<double>(6*8) * M_PI / 180;
234 const double daz = d.get<double>(7*8) * M_PI / 180;
235
236 // Correct:
237 // const double d = cos(del) - sin(zd+dzd)*sin(zd)*(1.-cos(daz));
238
239 // Simplified:
240 const double dev = cos(dzd) - sin(zd)*sin(zd)*(1.-cos(daz));
241 fDriveControlTrackingDev = acos(dev) * 180 / M_PI;
242 }
243
244 void HandleDriveControlSource(const DimData &d)
245 {
246 if (!CheckDataSize(d, "DriveControl:Source", 7*4+2))
247 return;
248
249 const double *ptr = d.ptr<double>();
250
251 const double ra = ptr[0]; // Ra[h]
252 const double dec = ptr[1]; // Dec[deg]
253 const double woff = ptr[4]; // Wobble offset [deg]
254 const double wang = ptr[5]; // Wobble angle [deg]
255
256 fDriveControlSourceName = d.ptr<char>(6*8);
257
258 ostringstream out;
259 out << uint64_t(d.time.UnixTime()*1000) << '\n';
260
261 out << fDriveControlSourceName << '\n';
262 out << setprecision(5);
263 out << "#ffffff\t" << ra << '\n';
264 out << "#ffffff\t" << dec << '\n';
265 out << setprecision(3);
266 out << "#ffffff\t" << woff << '\n';
267 out << "#ffffff\t" << wang << '\n';
268
269 ofstream fout("www/drive.txt");
270 fout << out.str();
271 }
272
273 void HandleFeedbackCalibration(const DimData &d)
274 {
275 if (!CheckDataSize(d, "Feedback:Calibration", 3*4*416))
276 {
277 fFeedbackCalibration.clear();
278 return;
279 }
280
281 const float *ptr = d.ptr<float>();
282 fFeedbackCalibration.assign(ptr+2*416, ptr+3*416);
283 }
284
285 void HandleBiasControlVoltage(const DimData &d)
286 {
287 if (!CheckDataSize(d, "BiasControl:Voltage", 1664))
288 {
289 fBiasControlVoltageVec.clear();
290 return;
291 }
292
293 fBiasControlVoltageVec.assign(d.ptr<float>(), d.ptr<float>()+320);
294
295 vector<float> v(fBiasControlVoltageVec);
296 sort(v.begin(), v.end());
297
298 fBiasControlVoltageMed = (v[159]+v[160])/2;
299
300 const char *ptr = d.ptr<char>();
301
302 ofstream fout("www/biascontrol-voltage.bin");
303 fout.write(ptr, 320*sizeof(float));
304 }
305
306 void HandleBiasControlCurrent(const DimData &d)
307 {
308 if (!CheckDataSize(d, "BiasControl:Current", 832))
309 return;
310
311 // Convert dac counts to uA
312 vector<float> v(320);
313 for (int i=0; i<320; i++)
314 v[i] = d.ptr<uint16_t>()[i] * 5000./4096;
315
316 // Calibrate the data (subtract offset)
317 if (fFeedbackCalibration.size()>0 && fBiasControlVoltageVec.size()>0)
318 for (int i=0; i<320; i++)
319 v[i] -= fBiasControlVoltageVec[i]/fFeedbackCalibration[i]*1e6;
320
321 // Get the maximum of each patch
322 vector<float> val(160, 0);
323 for (int i=0; i<160; i++)
324 val[i] = max(v[i*2], v[i*2+1]);
325
326 // Write the 160 patch values to a file
327 WriteBinary("biascontrol-current", val, 1000);
328
329 // Now sort them to determine the median
330 sort(v.begin(), v.end());
331
332 // Exclude the three crazy channels
333 fBiasControlCurrentMed = (v[159]+v[160])/2;
334 fBiasControlCurrentMax = v[316];
335
336 // Store a history of the last 60 entries
337 fBiasControlCurrentHist.push_back(fBiasControlCurrentMed);
338 if (fBiasControlCurrentHist.size()>60)
339 fBiasControlCurrentHist.pop_front();
340
341 // write the history to a file
342 WriteBinary("biascontrol-current-hist", fBiasControlCurrentHist, 1000);
343 }
344
345 void HandleFtmControlTriggerRates(const DimData &d)
346 {
347 if (!CheckDataSize(d, "FtmControl:TriggerRates", 24+160+640+8))
348 return;
349
350 fFtmControlTriggerRateCam = d.get<float>(20);
351
352 const float *brates = d.ptr<float>(24); // Board rate
353 const float *prates = d.ptr<float>(24+160); // Patch rate
354
355 // Store a history of the last 60 entries
356 fFtmControlTriggerRateHist.push_back(fFtmControlTriggerRateCam);
357 if (fFtmControlTriggerRateHist.size()>60)
358 fFtmControlTriggerRateHist.pop_front();
359
360 WriteBinary("ftmcontrol-triggerrate-hist",
361 fFtmControlTriggerRateHist, 100);
362 WriteBinary("ftmcontrol-boardrates",
363 vector<float>(brates, brates+40), 50);
364 WriteBinary("ftmcontrol-patchrates",
365 vector<float>(prates, prates+160), 10);
366 }
367
368 void HandleFadControlEventData(const DimData &d)
369 {
370 if (!CheckDataSize(d, "FadControl:EventData", 23040))
371 return;
372
373 if (fFadControlEventCounter++%30)
374 return;
375
376 //const float *avg = d.ptr<float>();
377 //const float *rms = d.ptr<float>(1440*sizeof(float));
378 const float *max = d.ptr<float>(1440*sizeof(float)*2);
379 //const float *pos = d.ptr<float>(1440*sizeof(float)*3);
380
381 vector<float> dat(160, 0);
382 for (int i=0; i<1440; i++)
383 {
384 const int idx = fPixelMap.index(i).hw()/9;
385 if (max[i]>dat[idx])
386 dat[idx]=max[i];
387 //dat[idx] += max[i];
388 }
389
390 WriteBinary("fadcontrol-eventdata", dat, 4000, 2000);
391 }
392
393 // -------------------------------------------------------------------
394
395 void infoHandler()
396 {
397 DimInfo *curr = getInfo(); // get current DimInfo address
398 if (!curr)
399 return;
400
401 if (HandleService(curr, fDimMagicWeatherData, &StateMachineSmartFACT::HandleMagicWeatherData))
402 return;
403 if (HandleService(curr, fDimDriveControlPointing, &StateMachineSmartFACT::HandleDriveControlPointing))
404 return;
405 if (HandleService(curr, fDimDriveControlTracking, &StateMachineSmartFACT::HandleDriveControlTracking))
406 return;
407 if (HandleService(curr, fDimDriveControlSource, &StateMachineSmartFACT::HandleDriveControlSource))
408 return;
409 if (HandleService(curr, fDimFeedbackCalibration, &StateMachineSmartFACT::HandleFeedbackCalibration))
410 return;
411 if (HandleService(curr, fDimBiasControlVoltage, &StateMachineSmartFACT::HandleBiasControlVoltage))
412 return;
413 if (HandleService(curr, fDimBiasControlCurrent, &StateMachineSmartFACT::HandleBiasControlCurrent))
414 return;
415 if (HandleService(curr, fDimFtmControlTriggerRates, &StateMachineSmartFACT::HandleFtmControlTriggerRates))
416 return;
417 if (HandleService(curr, *fDimFadControlEventData, &StateMachineSmartFACT::HandleFadControlEventData))
418 return;
419
420 if (UpdateState(curr, fDimMagicWeather, fStatusMagicWeather))
421 return;
422 if (UpdateState(curr, fDimDriveControl, fStatusDriveControl))
423 return;
424 if (UpdateState(curr, fDimFeedback, fStatusFeedback))
425 return;
426 if (UpdateState(curr, fDimBiasControl, fStatusBiasControl))
427 return;
428 if (UpdateState(curr, fDimFtmControl, fStatusFtmControl))
429 return;
430 if (UpdateState(curr, fDimFadControl, fStatusFadControl))
431 return;
432
433 if (curr==&fDim)
434 {
435 fStatusDim = GetNewState(fDim);
436 fStatusDim.second = curr->getSize()==4 ? curr->getInt() : 0;
437 return;
438 }
439 }
440
441 bool CheckEventSize(size_t has, const char *name, size_t size)
442 {
443 if (has==size)
444 return true;
445
446 ostringstream msg;
447 msg << name << " - Received event has " << has << " bytes, but expected " << size << ".";
448 Fatal(msg);
449 return false;
450 }
451
452 void PrintState(const pair<Time,int> &state, const char *server)
453 {
454 const State rc = fNetwork.GetState(server, state.second);
455
456 Out() << state.first.GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
457 Out() << kBold << server << ": ";
458 if (rc.index==-2)
459 {
460 Out() << kReset << "Offline" << endl;
461 return;
462 }
463 Out() << rc.name << "[" << rc.index << "]";
464 Out() << kReset << " - " << kBlue << rc.comment << endl;
465 }
466
467 int Print()
468 {
469 Out() << fStatusDim.first.GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
470 Out() << kBold << "DIM_DNS: ";
471 if (fStatusDim.second==0)
472 Out() << "Offline" << endl;
473 else
474 Out() << "V" << fStatusDim.second/100 << 'r' << fStatusDim.second%100 << endl;
475
476 PrintState(fStatusMagicWeather, "MAGIC_WEATHER");
477 PrintState(fStatusDriveControl, "DRIVE_CONTROL");
478 PrintState(fStatusFeedback, "FEEDBACK");
479 PrintState(fStatusBiasControl, "BIAS_CONTROL");
480 PrintState(fStatusFadControl, "FAD_CONTROL");
481
482 return GetCurrentState();
483 }
484
485 int Execute()
486 {
487 // Dispatch (execute) at most one handler from the queue. In contrary
488 // to run_one(), it doesn't wait until a handler is available
489 // which can be dispatched, so poll_one() might return with 0
490 // handlers dispatched. The handlers are always dispatched/executed
491 // synchronously, i.e. within the call to poll_one()
492 //poll_one();
493
494 if (fStatusDim.second==0)
495 return kStateDimNetworkNA;
496
497 Time now;
498 if (now-fLastUpdate<boost::posix_time::seconds(1))
499 return kStateRunning;
500
501 fLastUpdate=now;
502
503 ostringstream out;
504 out << uint64_t(nearbyint(now.UnixTime()*1000)) << '\n';
505 out << setprecision(3);
506
507 // -------------- System status --------------
508 out << "n/a\n";
509
510 const static string kWhite = "#ffffff";
511 const static string kYellow = "#fffff0";
512 const static string kRed = "#fff8f0";
513 const static string kGreen = "#f0fff0";
514 const static string kBlue = "#f0f0ff";
515
516 // ------------------ Drive -----------------
517 if (fStatusDriveControl.second>=5) // Armed, Moving, Tracking
518 {
519 const State rc = fNetwork.GetState("DRIVE_CONTROL", fStatusDriveControl.second);
520 out << kWhite << "\t";
521 out << rc.name << '\t';
522 out << fDriveControlPointingZd << '\t';
523 out << fDriveControlPointingAz << '\t';
524 out << fDriveControlTrackingDev << '\t';
525 out << fDriveControlSourceName << '\n';
526 }
527 else
528 out << kWhite << "\n";
529
530 // --------------- MagicWeather -------------
531 if (fStatusMagicWeather.second==3)
532 {
533 const float diff = fMagicWeatherData[kTemp]-fMagicWeatherData[kDew];
534 string col1 = kRed;
535 if (diff>0.3)
536 col1 = kYellow;
537 if (diff>0.7)
538 col1 = kGreen;
539
540 const float wind = fMagicWeatherData[kGusts];
541 string col2 = kGreen;
542 if (wind>35)
543 col2 = kYellow;
544 if (wind>50)
545 col2 = kRed;
546
547 out << col1 << "\t";
548 out << fMagicWeatherData[kTemp] << '\t';
549 out << fMagicWeatherData[kDew] << '\n';
550 out << col2 << "\t";
551 out << fMagicWeatherData[kGusts] << '\n';
552 }
553 else
554 out << kWhite << "\n\n";
555
556 // --------------- FtmControl -------------
557 if (fStatusFtmControl.second>=FTM::kIdle)
558 {
559 string col = kGreen;
560 if (fFtmControlTriggerRateCam<15)
561 col = kYellow;
562 if (fFtmControlTriggerRateCam>100)
563 col = kRed;
564
565 out << col << '\t' << fFtmControlTriggerRateCam << '\n';
566 }
567 else
568 out << kWhite << '\n';
569
570 // --------------- BiasControl -------------
571 if (fStatusBiasControl.second==5 || // Ramping
572 fStatusBiasControl.second==7 || // On
573 fStatusBiasControl.second==9) // Off
574 {
575 string col = fBiasControlVoltageMed>3?kGreen:kWhite;
576 if (fBiasControlCurrentMax>280)
577 col = kYellow;
578 if (fBiasControlCurrentMax>350)
579 col = kRed;
580
581 if (fFeedbackCalibration.size()==0)
582 col = kBlue;
583
584 out << col << "\t";
585 out << fBiasControlCurrentMed << '\t';
586 out << fBiasControlCurrentMax << '\t';
587 out << fBiasControlVoltageMed << '\n';
588 }
589 else
590 out << kWhite << "\n";
591
592
593 // ------------------------------------------
594 ofstream fout("www/fact.txt");
595 fout << out.str();
596
597 return kStateRunning;
598 }
599
600public:
601 StateMachineSmartFACT(ostream &out=cout) : StateMachineDim(out, "SMART_FACT"),
602 fFadControlEventCounter(0),
603 //---
604 fStatusDim (make_pair(Time(), -2)),
605 fStatusDriveControl(make_pair(Time(), -2)),
606 fStatusMagicWeather(make_pair(Time(), -2)),
607 fStatusFeedback (make_pair(Time(), -2)),
608 fStatusBiasControl (make_pair(Time(), -2)),
609 fStatusFtmControl (make_pair(Time(), -2)),
610 fStatusFadControl (make_pair(Time(), -2)),
611 //---
612 fDim ("DIS_DNS/VERSION_NUMBER", (void*)NULL, 0, this),
613 //---
614 fDimDriveControl ("DRIVE_CONTROL/STATE", (void*)NULL, 0, this),
615 fDimDriveControlPointing ("DRIVE_CONTROL/POINTING_POSITION", (void*)NULL, 0, this),
616 fDimDriveControlTracking ("DRIVE_CONTROL/TRACKING_POSITION", (void*)NULL, 0, this),
617 fDimDriveControlSource ("DRIVE_CONTROL/SOURCE_POSITION", (void*)NULL, 0, this),
618 //---
619 fDimMagicWeather ("MAGIC_WEATHER/STATE", (void*)NULL, 0, this),
620 fDimMagicWeatherData ("MAGIC_WEATHER/DATA", (void*)NULL, 0, this),
621 //---
622 fDimFeedback ("FEEDBACK/STATE", (void*)NULL, 0, this),
623 fDimFeedbackCalibration ("FEEDBACK/CALIBRATION", (void*)NULL, 0, this),
624 //---
625 fDimBiasControl ("BIAS_CONTROL/STATE", (void*)NULL, 0, this),
626 fDimBiasControlVoltage ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
627 fDimBiasControlCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
628 //---
629 fDimFtmControl ("FTM_CONTROL/STATE", (void*)NULL, 0, this),
630 fDimFtmControlTriggerRates("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
631 //-
632 fDimFadControl ("FAD_CONTROL/STATE", (void*)NULL, 0, this),
633 fDimFadControlEventData(0)
634 {
635 // State names
636 AddStateName(kStateDimNetworkNA, "DimNetworkNotAvailable",
637 "The Dim DNS is not reachable.");
638
639 AddStateName(kStateRunning, "Running", "");
640
641 // Verbosity commands
642// AddEvent("SET_VERBOSE", "B:1")
643// (bind(&StateMachineMCP::SetVerbosity, this, placeholders::_1))
644// ("set verbosity state"
645// "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
646
647 AddEvent("PRINT")
648 (bind(&StateMachineSmartFACT::Print, this))
649 ("");
650 }
651 ~StateMachineSmartFACT()
652 {
653 delete fDimFadControlEventData;
654 }
655 int EvalOptions(Configuration &conf)
656 {
657 if (!fPixelMap.Read(conf.Get<string>("pixel-map-file")))
658 {
659 Error("Reading mapping table from "+conf.Get<string>("pixel-map-file")+" failed.");
660 return 1;
661 }
662
663 // Pixel map is needed to deal with this service
664 fDimFadControlEventData=new DimStampedInfo("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this);
665
666 return -1;
667 }
668};
669
670// ------------------------------------------------------------------------
671
672#include "Main.h"
673
674template<class T>
675int RunShell(Configuration &conf)
676{
677 return Main::execute<T, StateMachineSmartFACT>(conf);
678}
679
680void SetupConfiguration(Configuration &conf)
681{
682 po::options_description control("Smart FACT");
683 control.add_options()
684 ("pixel-map-file", var<string>("FACTmapV5a.txt"), "Pixel mapping file. Used here to get the default reference voltage.")
685 ;
686
687 conf.AddOptions(control);
688}
689
690/*
691 Extract usage clause(s) [if any] for SYNOPSIS.
692 Translators: "Usage" and "or" here are patterns (regular expressions) which
693 are used to match the usage synopsis in program output. An example from cp
694 (GNU coreutils) which contains both strings:
695 Usage: cp [OPTION]... [-T] SOURCE DEST
696 or: cp [OPTION]... SOURCE... DIRECTORY
697 or: cp [OPTION]... -t DIRECTORY SOURCE...
698 */
699void PrintUsage()
700{
701 cout <<
702 "SmartFACT is a tool writing the files needed for the SmartFACT web interface.\n"
703 "\n"
704 "The default is that the program is started without user intercation. "
705 "All actions are supposed to arrive as DimCommands. Using the -c "
706 "option, a local shell can be initialized. With h or help a short "
707 "help message about the usuage can be brought to the screen.\n"
708 "\n"
709 "Usage: smartfact [-c type] [OPTIONS]\n"
710 " or: smartfact [OPTIONS]\n";
711 cout << endl;
712}
713
714void PrintHelp()
715{
716 Main::PrintHelp<StateMachineSmartFACT>();
717
718 /* Additional help text which is printed after the configuration
719 options goes here */
720
721 /*
722 cout << "bla bla bla" << endl << endl;
723 cout << endl;
724 cout << "Environment:" << endl;
725 cout << "environment" << endl;
726 cout << endl;
727 cout << "Examples:" << endl;
728 cout << "test exam" << endl;
729 cout << endl;
730 cout << "Files:" << endl;
731 cout << "files" << endl;
732 cout << endl;
733 */
734}
735
736int main(int argc, const char* argv[])
737{
738 Configuration conf(argv[0]);
739 conf.SetPrintUsage(PrintUsage);
740 Main::SetupConfiguration(conf);
741 SetupConfiguration(conf);
742
743 if (!conf.DoParse(argc, argv, PrintHelp))
744 return -1;
745
746 //try
747 {
748 // No console access at all
749 if (!conf.Has("console"))
750 {
751// if (conf.Get<bool>("no-dim"))
752// return RunShell<LocalStream, StateMachine, ConnectionFSC>(conf);
753// else
754 return RunShell<LocalStream>(conf);
755 }
756 // Cosole access w/ and w/o Dim
757/* if (conf.Get<bool>("no-dim"))
758 {
759 if (conf.Get<int>("console")==0)
760 return RunShell<LocalShell, StateMachine, ConnectionFSC>(conf);
761 else
762 return RunShell<LocalConsole, StateMachine, ConnectionFSC>(conf);
763 }
764 else
765*/ {
766 if (conf.Get<int>("console")==0)
767 return RunShell<LocalShell>(conf);
768 else
769 return RunShell<LocalConsole>(conf);
770 }
771 }
772 /*catch (std::exception& e)
773 {
774 cerr << "Exception: " << e.what() << endl;
775 return -1;
776 }*/
777
778 return 0;
779}
Note: See TracBrowser for help on using the repository browser.