source: trunk/FACT++/scripts/Main.js@ 14770

Last change on this file since 14770 was 14769, checked in by neise, 12 years ago
moved the schedule out of Main.js so it is easier for the shifter to edit it
File size: 24.7 KB
Line 
1/**
2 * @fileOverview This file has functions related to documenting JavaScript.
3 * @author <a href="mailto:thomas.bretz@epfl.ch">Thomas Bretz</a>
4 */
5'use strict';
6
7//this is just the class implementation of 'Observation'
8include('scripts/Observation_class.js');
9
10dimctrl.defineState(37, "TimeOutBeforeTakingData", "MCP took more than 5minutes to start TakingData");
11
12
13// error handline : http://www.sitepoint.com/exceptional-exception-handling-in-javascript/
14// clases: http://www.phpied.com/3-ways-to-define-a-javascript-class/
15//
16// Arguments: TakeFirstDrsCalib
17// To be determined: How to stop the script without foreceful interruption?
18
19// adapt states of drivectrl
20
21//
22// SCRIPTS:
23//
24// - Startup, e.g. do not open LID
25//
26// - Bring telescop to state 'operational', e.g. open lid,
27// when first run != START is detected in the loop
28//
29// - Take data
30//
31// - Shutdown
32//
33// ----> Does smartfact display alarm messages already?
34// ----> How to display errors in smartfact? Is that necessary at all?
35// (red output? maybe just <red>...</red>?
36//
37// ----------------------------------------------------------------
38
39function currentEst(source)
40{
41 var moon = new Moon();
42 if (!moon.isUp)
43 return 7.7;
44
45 var dist = Sky.dist(moon, source);
46
47 var alt = 90-moon.toLocal().zd;
48
49 var lc = dist*alt*pow(Moon.disk(), 6)/360/360;
50
51 var cur = 7.7+4942*lc;
52
53 return cur;
54}
55
56function thresholdEst(source) // relative threshold (ratio)
57{
58 // Assumption:
59 // atmosphere is 70km, shower taks place after 60km, earth radius 6400km
60 // just using the cosine law
61 // This fits very well with MC results: See Roger Firpo, p.45
62 // "Study of the MAGIC telescope sensitivity for Large Zenith Angle observations"
63
64 var c = Math.cos(Math.Pi-source.zd);
65 var ratio = (10*sqrt(409600*c*c+9009) + 6400*c - 60)/10;
66
67 // assumption: Energy threshold increases linearily with current
68 // assumption: Energy threshold increases linearily with distance
69
70 return ratio*currentEst(source)/7.7;
71}
72
73// Ratio in rate would be (estimate, not precise calculation)
74// pow(ratio, -0.7)
75
76// ----------------------------------------------------------------
77
78//DN: the name of the Subscription object 'service_con' is not really
79// telling that its a subscription to FAD_CONTROL/CONNECTIONS
80// fad_connections sound ok for be, since
81// fad_connections.onchange() is pretty clear
82// fad_connections.reconnect() is not really good, but at least it has FAD in it.
83var service_con = new Subscription("FAD_CONTROL/CONNECTIONS");
84/**
85 * call-back function of FAD_CONTROL/CONNECTIONS
86 * store IDs of problematic FADs
87 *
88 */
89service_con.onchange = function(evt)
90{
91 this.reset = [ ];
92
93 for (var x=0; x<40; x++)
94 if (evt.obj['status'][x]!=66 && evt.obj['status'][x]!=67)
95 this.reset.push(x);
96
97 if (this.reset.length==0)
98 return;
99
100 dim.alarm("FAD board loss detected...");
101 dim.send("MCP/RESET");
102 dim.send("FAD_CONTROL/CLOSE_OPEN_FILES");
103}
104
105/**
106 * reconnect to problematic FADs
107 *
108 * Dis- and Reconnects to FADs, found to be problematic by call-back function
109 * onchange() to have a different CONNECTION value than 66 or 67.
110 *
111 * @returns
112 * a boolean is returned.
113 * reconnect returns true if:
114 * * nothing needed to be reset --> no problems found by onchange()
115 * * the reconnection went fine.
116 *
117 * reconnect *never returns false* so far.
118 *
119 * @example
120 * if (!service_con.reconnect())
121 * exit();
122 */
123service_con.reconnect = function()
124{
125 // this.reset is a list containing the IDs of FADs,
126 // which have neither CONNECTION==66 nor ==67, whatever this means :-)
127 if (this.reset.length==0)
128 return true;
129
130 console.out(" Reconnect: start ["+this.reset.length+"]");
131
132 for (var i=0; i<this.reset.length; i++)
133 dim.send("FAD_CONTROL/DISCONNECT", this.reset[i]);
134
135 v8.sleep(3000);
136
137 while (this.reset.length)
138 dim.send("FAD_CONTROL/CONNECT", this.reset.pop());
139
140 v8.sleep(1000);
141 dim.wait("FAD_CONTROL", "Connected", 3000);
142
143 console.out(" Reconnect: end");
144
145 return true;
146}
147
148function takeRun(type, count, time)
149{
150 if (!count)
151 count = -1;
152 if (!time)
153 time = -1;
154
155 console.out(" Take run N="+count+" T="+time+"s ["+type+"]");
156 // change rats for cal runs1!!!
157
158 dim.send("MCP/START", time?time:-1, count?count:-1, type);
159
160
161
162 // What could be a reasonable timeout here?
163 // FIXME: Replace by callback?
164 //
165 // DN: I believe instead of waiting for 'TakingData' one could split this
166 // up into two checks with an extra condition:
167 // if type == 'data':
168 // wait until ThresholdCalibration starts:
169 // --> this time should be pretty identical for each run
170 // if this takes longer than say 3s:
171 // there might be a problem with one/more FADs
172 //
173 // wait until "TakingData":
174 // --> this seems to take even some minutes sometimes...
175 // (might be optimized rather soon, but still in the moment...)
176 // if this takes way too long:
177 // there might be something broken,
178 // so maybe a very high time limit is ok here.
179 // I think there is not much that can go wrong,
180 // when the Thr-Calib has already started. Still it might be nice
181 // If in the future RateControl is written so to find out that
182 // in case the threshold finding algorithm does
183 // *not converge as usual*
184 // it can complain, and in this way give a hint, that the weather
185 // might be a little bit too bad.
186 // else:
187 // wait until "TakingData":
188 // --> in a non-data run this time should be pretty short again
189 // if this takes longer than say 3s:
190 // there might be a problem with one/more FADs
191 //
192
193 if (!dim.wait("MCP", "TakingData", -300000) )
194 {
195 console.out("MCP took longer than 5 minutes to start TakingData");
196 console.out("maybe this idicates a problem with one of the FADs?");
197 dimctrl.setState(37);
198 dim.wait("MCP", "TakingData", 500);
199 }
200 dim.wait("MCP", "Idle");
201
202 console.out(" Take run: end");
203
204 // DN: currently reconnect() never returns false
205 // .. but it can fail of course.
206 if (!service_con.reconnect())
207 exit();
208
209 return true;//service_con.reconnect();
210}
211
212// ----------------------------------------------------------------
213
214function doDrsCalibration()
215{
216 console.out(" DRS cal: start");
217 service_feedback.voltageOff();
218
219 while (1)
220 {
221 dim.send("FAD_CONTROL/START_DRS_CALIBRATION");
222 if (!takeRun("drs-pedestal", 1000)) // 40 / 20s (50Hz)
223 continue;
224 if (!takeRun("drs-gain", 1000)) // 40 / 20s (50Hz)
225 continue;
226 if (!takeRun("drs-pedestal", 1000)) // 40 / 20s (50Hz)
227 continue;
228
229 dim.send("FAD_CONTROL/SET_FILE_FORMAT", 2);
230 if (!takeRun("drs-pedestal", 1000)) // 40 / 20s (50Hz)
231 continue;
232 if (!takeRun("drs-time", 1000)) // 40 / 20s (50Hz)
233 continue;
234
235 dim.send("FAD_CONTROL/RESET_SECONDARY_DRS_BASELINE");
236 if (!takeRun("pedestal", 1000)) // 40 / 10s (80Hz)
237 continue;
238
239 dim.send("FAD_CONTROL/SET_FILE_FORMAT", 2);
240 if (!takeRun("pedestal", 1000)) // 40 / 10s (80Hz)
241 continue;
242 // -----------
243 // 4'40 / 2'00
244
245 break;
246 }
247
248 console.out(" DRS cal: end");
249}
250
251// ----------------------------------------------------------------
252
253function OpenLid()
254{
255 var horizon_parameter = "nautical"
256 if (Sun.horizon( horizon_parameter ).isUp)
257 {
258 console.out(JSON.stringify(Sun.horizon( horizon_parameter )));
259 throw new Error("Sun is above FACT-horizon, lid cannot be opened.");
260 }
261
262 console.out("Open lid: start");
263
264 // Wait for lid to be open
265 if (dim.state("LID_CONTROL").name=="Closed")
266 dim.send("LID_CONTROL/OPEN");
267 dim.wait("LID_CONTROL", "Open", 30000);
268 console.out("Open lid: done");
269}
270
271function CloseLid()
272{
273 console.out("Close lid: start");
274
275 // Wait for lid to be open
276 if (dim.state("LID_CONTROL").name=="Open")
277 dim.send("LID_CONTROL/CLOSE");
278 dim.wait("LID_CONTROL", "Closed", 30000);
279
280 console.out("Open lid: end");
281}
282
283// ----------------------------------------------------------------
284
285var service_feedback = new Subscription("FEEDBACK/DEVIATION");
286
287// DN: Why is voltageOff() implemented as
288// a method of a Subscription to a specific Service
289// I naively would think of voltageOff() as an unbound function.
290// I seems to me it has to be a method of a Subscription object, in order
291// to use the update counting method. But does it have to be
292// a Subscription to FEEDBACK/DEVIATION, or could it work with other services as well?
293service_feedback.voltageOff = function()
294{
295 console.out(" Voltage off: start");
296
297 var isOn = dim.state("BIAS_CONTROL").name=="VoltageOn";
298
299 if (isOn)
300 {
301 console.out(" Voltage on: switch off");
302 dim.send("BIAS_CONTROL/SET_ZERO_VOLTAGE");
303 }
304
305 dim.wait("BIAS_CONTROL", "VoltageOff", 5000);
306
307 // FEEDBACK stays in CurrentCtrl when Voltage is off but output enabled
308 // dim.wait("FEEDBACK", "CurrentCtrlIdle", 1000);
309
310 console.out(" Voltage off: end");
311}
312
313// DN: The name of the method voltageOn() in the context of the method
314// voltageOff() is a little bit misleading, since when voltageOff() returns
315// the caller can be sure the voltage is off, but when voltageOn() return
316// this is not the case, in the sense, that the caller can now take data.
317// instead the caller of voltageOn() *must* call waitForVoltageOn() afterwards
318// in order to safely take good-quality data.
319// This could lead to nasty bugs in the sense, that the second call might
320// be forgotten by somebody
321//
322// so I suggest to rename voltageOn() --> prepareVoltageOn()
323// waitForVoltageOn() stays as it is
324// and one creates a third method called:voltageOn() like this
325/* service_feedback.voltageOn = function()
326 * {
327 * this.prepareVoltageOn();
328 * this.waitForVoltageOn();
329 * }
330 *
331 * */
332// For convenience.
333
334service_feedback.voltageOn = function()
335{
336 //if (Sun.horizon("FACT").isUp)
337 // throw new Error("Sun is above FACT-horizon, voltage cannot be switched on.");
338
339 console.out(" Voltage on: start");
340
341 var isOff = dim.state("BIAS_CONTROL").name=="VoltageOff";
342
343 if (isOff)
344 {
345 console.out(" Voltage on: switch on");
346 console.out(JSON.stringify(dim.state("BIAS_CONTROL")));
347
348 dim.send("BIAS_CONTROL/SET_GLOBAL_DAC", 1);
349 }
350
351 // Wait until voltage on
352 dim.wait("BIAS_CONTROL", "VoltageOn", 5000);
353
354 // From now on the feedback waits for a valid report from the FSC
355 // and than switchs to CurrentControl
356 dim.wait("FEEDBACK", "CurrentControl", 60000);
357
358 if (isOff)
359 {
360 this.cnt = this.get().counter;
361 console.out(" Voltage on: cnt="+this.cnt);
362 }
363
364 console.out(" Voltage on: end");
365}
366
367
368
369service_feedback.waitForVoltageOn = function()
370{
371 // waiting 45sec for the current control to stabilize...
372 // v8.sleep(45000);
373
374 // ----- Wait for at least three updates -----
375 // The feedback is started as if the camera where at 0deg
376 // Then after the first temp update, the temperature will be set to the
377 // correct value (this has already happened)
378 // So we only have to wait for the current to get stable.
379 // This should happen after three to five current updates.
380 // So we want one recent temperature update
381 // and three recent current updates
382 console.out(" Voltage wait: start");
383 while (this.cnt==undefined || this.get().counter<=this.cnt+2)
384 v8.sleep();
385 console.out(" Voltage wait: end [cnt="+this.get().counter+"]");
386}
387
388// ================================================================
389// Crosscheck all states
390// ================================================================
391
392include('scripts/Startup.js');//Startup();
393
394/*
395include('scripts/CheckStates.js');
396
397var table =
398[
399 [ "TNG_WEATHER" ],
400 [ "MAGIC_WEATHER" ],
401 [ "CHAT" ],
402 [ "SMART_FACT" ],
403 [ "FSC_CONTROL", [ "Connected" ] ],
404 [ "MCP", [ "Idle" ] ],
405 [ "TIME_CHECK", [ "Valid" ] ],
406 [ "PWR_CONTROL", [ "SystemOn" ] ],
407 [ "AGILENT_CONTROL", [ "VoltageOn" ] ],
408 [ "BIAS_CONTROL", [ "VoltageOff" ] ],
409 [ "FEEDBACK", [ "CurrentControl", "CurrentCtrlIdle", "Connected" ] ],
410 [ "RATE_SCAN", [ "Connected" ] ],
411 [ "RATE_CONTROL", [ "Connected" ] ],
412 [ "LID_CONTROL", [ "Open", "Closed" ] ],
413 [ "DRIVE_CONTROL", [ "Armed", "Tracking", "OnTrack" ] ],
414 [ "FTM_CONTROL", [ "Idle", "TriggerOn" ] ],
415 [ "FAD_CONTROL", [ "Connected", "WritingData" ] ],
416 [ "DATA_LOGGER", [ "NightlyFileOpen", "WaitForRun", "Logging" ] ],
417];
418
419console.out("Checking states.");
420if (!checkStates(table, 10000))
421{
422 console.out("Something unexpected has happened. Although the startup-",
423 "procedure has finished, not all servers are in the state",
424 "in which they ought to be. Please, try to find out what",
425 "happened...");
426 exit();
427}
428
429console.out("Checking states: done.");
430*/
431// ----------------------------------------------------------------
432
433console.out("Checking send.");
434checkSend(["MCP", "DRIVE_CONTROL", "LID_CONTROL", "FAD_CONTROL", "FEEDBACK"]);
435console.out("Checking send: done");
436
437// ----------------------------------------------------------------
438
439console.out("Feedback init: start.");
440service_feedback.get(5000);
441
442dim.send("FEEDBACK/ENABLE_OUTPUT", true);
443dim.send("FEEDBACK/START_CURRENT_CONTROL", 0.);
444
445console.out("Feedback init: end.");
446
447// ----------------------------------------------------------------
448// ================================================================
449// ----------------------------------------------------------------
450
451// this file just contains the definition of
452// the variable observations, which builds our nightly schedule, hence the filename
453include('scripts/schedule.js');
454
455// make Observation objects from user input and check if 'date' is increasing.
456for (var i=0; i<observations.length; i++)
457{
458 observations[i] = new Observation(observations[i]);
459
460 // check if the start date given by the user is increasing.
461 if (i>0 && observations[i].utc <= observations[i-1].utc)
462 {
463 throw new Error("Start time '"+utc.toUTCString()+
464 "' in row "+i+" exceeds start time in row "+(i-1));
465 }
466}
467
468
469
470// ----------------------------------------------------------------
471// Bring the system into a well defined state
472// ----------------------------------------------------------------
473
474console.out("Drs runs init: start.");
475
476// FIMXE: Double subscription is not allowed!
477// also Startup needs DRS_RUNS
478var service_drs = new Subscription("FAD_CONTROL/DRS_RUNS");
479service_drs.get(5000, false);
480
481console.out("Drs runs init: end.");
482
483// FIXME: Check if the last DRS calibration was complete?
484// ----------------------------------------------------------------
485
486// We have to stup a few things here which might not by set by Startup.js
487dim.send("FAD_CONTROL/SET_FILE_FORMAT", 2);
488
489// ----------------------------------------------------------------
490
491console.out("Start main loop.");
492
493function Startup()
494{
495 /**** dummy ****/
496 console.out(" => [STARTUP] called.");
497}
498
499function Shutdown()
500{
501 /**** dummy ****/
502 console.out(" => [SHUTDOWN] called.");
503}
504
505// Get the observation scheduled for 'now' from the table and
506// return its index
507function getObservation(now)
508{
509 if (now==undefined)
510 now = new Date();
511
512 if (isNaN(now.valueOf()))
513 throw new Error("Date argument in getObservation invalid.");
514
515 for (var i=0; i<observations.length; i++)
516 if ( now<observations[i].start )
517 return i-1;
518
519 return observations.length-1;
520}
521
522
523// DN: using so called magic numbers to encode certain
524// states of the logic is considered pretty bad coding as far as I understand.
525// the reader at this point has no idea why run is -2 ... this is the first time she
526// reads about this variable and there is not a word of explanation found.
527var run = -2;
528var lastObs;
529
530while (1)
531{
532 // Check if observation position is still valid
533 // If source position has changed, set run=0
534 var idxObs = getObservation();
535 if (idxObs===undefined)
536 exit();
537
538 if (idxObs==-1)
539 {
540 v8.sleep(1000);
541 continue;
542 }
543
544 var obs = observations[idxObs];
545 var nextObs = observations[idxObs+1];
546
547 // Check if observation target has changed
548 if (lastObs!=idxObs)
549 {
550 console.out("--- "+idxObs+" ---");
551 console.out("Current time: "+new Date());
552 console.out("Current observation: "+obs);
553 console.out("Next observation: "+nextObs);
554 console.out("");
555
556 // This is the first source, but we do not come from
557 // a scheduled 'START', so we have to check if the
558 // telescop is operational already
559 if (run==-2)
560 {
561 Startup(); // -> Bias On/Off?, Lid open/closed?
562 CloseLid();
563 }
564
565 run = 0;
566 }
567 lastObs = idxObs;
568
569 // We have performed startup or shutdown... wait for next observation
570 if (run==-1)
571 {
572 v8.sleep(1000);
573 continue;
574 }
575
576 // Check if obs.task is one of the one-time-tasks
577 switch (obs.task)
578 {
579 case "STARTUP":
580 console.out(" STARTUP", "");
581 Startup(); // BiasOn/Off?, Lid open/close?
582 CloseLid();
583
584 console.out(" Take DRS calibration.");
585 doDrsCalibration(); // -> VoltageOff
586
587 service_feedback.voltageOn();
588 service_feedback.waitForVoltageOn();
589
590 // Before we can switch to 3000 we have to make the right DRS calibration
591 console.out(" Take single p.e. run.");
592 while (!takeRun("pedestal", 5000));
593
594 service_feedback.voltageOff();
595
596 console.out(" Waiting for first scheduled observation.","");
597 run = -1;
598 continue;
599
600 case "SHUTDOWN":
601 console.out(" SHUTDOWN","");
602 Shutdown();
603
604 console.out(" Waiting for next startup.", "");
605 run = -1;
606 continue;
607
608 case "RATESCAN":
609 console.out(" RATESCAN ");
610
611 dim.send("DRIVE_CONTROL/STOP");
612 dim.wait("DRIVE_CONTROL", "Armed", 3000);
613
614 if (obs.source != undefined)
615 dim.send("DRIVE_CONTROL/TRACK_ON", obs.source);
616 else
617 dim.send("DRIVE_CONTROL/TRACK", obs.ra, obs.dec);
618
619 //OpenLid();
620 dim.wait("DRIVE_CONTROL", "OnTrack", 300000);
621
622 // Checking if system is Ready for Data Taking, which is in this case
623 // the same as Ready for RateScan.
624 //
625 // this part might be simply wrong here, since I should be able to expect
626 // the system to be able for data taking. And if not, then it is not here,
627 // to bring the system into a better state, correct?
628 dim.wait("FEEDBACK", "CurrentControl", -100);
629 dim.wait("BIAS_CONTROL", "VoltageOn", -100);
630 dim.wait("FAD_CONTROL", "Connected", -100);
631
632 dim.wait("RATE_SCAN","Connected", 5000);
633 dim.send("RATE_SCAN/START_THRESHOLD_SCAN", 50, 1000, -10);
634
635 // lets wait if the Ratescan really starts .. it should be started after 10sec max.
636 dim.wait("RATE_SCAN", "InProgress", 10000);
637 dim.wait("RATE_SCAN", "Connected", 2700000);
638
639 console.out("Ratescan done.");
640 run = -1;
641 continue;
642 }
643/*
644 if (Sun.horizon("FACT").isUp)
645 {
646 console.out(" SHUTDOWN","");
647 Shutdown();
648 console.out(" Exit forced due to broken schedule", "");
649 exit();
650 }
651*/
652 // Calculate remaining time for this observation in minutes
653 var remaining = (nextObs.start-new Date())/60000;
654
655 // ------------------------------------------------------------
656
657 console.out(" Checking states [mainloop]");
658 var table =
659 [
660 [ "TNG_WEATHER" ],
661 [ "MAGIC_WEATHER" ],
662 [ "CHAT" ],
663 [ "SMART_FACT" ],
664 [ "DATA_LOGGER", [ "NightlyFileOpen", "WaitForRun", "Logging" ] ],
665 [ "FSC_CONTROL", [ "Connected" ] ],
666 [ "MCP", [ "Idle" ] ],
667 [ "TIME_CHECK", [ "Valid" ] ],
668 [ "PWR_CONTROL", [ "SystemOn" ] ],
669 [ "AGILENT_CONTROL", [ "VoltageOn" ] ],
670 [ "BIAS_CONTROL", [ "VoltageOff", "VoltageOn" ] ],
671 [ "FEEDBACK", [ "CurrentCtrlIdle", "CurrentControl" ] ],
672 [ "RATE_SCAN", [ "Connected" ] ],
673 [ "RATE_CONTROL", [ "Connected", "InProgress" ] ],
674 [ "LID_CONTROL", [ "Open", "Closed" ] ],
675 [ "DRIVE_CONTROL", [ "Armed", "Tracking", "OnTrack" ] ],
676 [ "FTM_CONTROL", [ "Idle", "TriggerOn" ] ],
677 [ "FAD_CONTROL", [ "Connected", "WritingData" ] ],
678 ];
679
680 if (!checkStates(table))
681 {
682 throw new Error("Something unexpected has happened. One of the servers"+
683 "is in a state in which it should not be. Please,"+
684 "try to find out what happened...");
685 }
686
687 console.out(" Checking states: end.");
688
689 // ------------------------------------------------------------
690
691 console.out(" Run #"+run+" ("+parseInt(remaining)+"min)");
692
693 // ----- Time since last DRS Calibration [min] ------
694 var runs = service_drs.get(0, false);
695 var diff = (new Date()-runs.time)/60000;
696
697 // Warning: 'roi=300' is a number which is not intrisically fixed
698 // but can change depending on the taste of the observers
699 var valid = runs.data[1][2]>0 && runs.data[0]==300;
700
701 if (valid)
702 console.out(" Last DRS calib: "+diff+"min ago");
703 else
704 console.out(" No valid drs calibration");
705
706 // Changine pointing position and take calibration...
707 // ...every four runs (every ~20min)
708 // ...if at least ten minutes of observation time are left
709 // ...if this is the first run on the source
710 var point = (run%4==0 && remaining>10) || run==0;
711
712 // Take DRS Calib...
713 // ...every four runs (every ~20min)
714 // ...at last every two hours
715 // ...when DRS temperature has changed by more than 2deg (?)
716 // ...when more than 15min of observation are left
717 // ...no drs calibration was done yet
718 var drscal = (run%4==0 && (remaining>15 && diff>70)) || !valid;
719
720 if (point)
721 {
722 var wobble = parseInt(run/4)%2;
723
724 //console.out(" Move telescope to '"+source+"' "+offset+" "+wobble);
725 console.out(" Move telescope to '"+obs.source+"' ["+wobble+"]");
726
727 //var offset = observations[obs][2];
728 //var wobble = observations[obs][3 + parseInt(run/4)%2];
729
730 //dim.send("DRIVE_CONTROL/TRACK_SOURCE", offset, wobble, source);
731
732 dim.send("DRIVE_CONTROL/TRACK_WOBBLE", wobble+1, obs.source);
733
734 // Do we have to check if the telescope is really moving?
735 // We can cross-check the SOURCE service later
736 }
737
738 if (drscal)
739 {
740 console.out(" Take DRS calibration.");
741 doDrsCalibration(); // -> VoltageOff
742 }
743
744 OpenLid();
745
746 // voltage must be switched on after the lid is open for the
747 // feedback to adapt the voltage properly to the night-sky
748 // background light level.
749 service_feedback.voltageOn();
750
751 // This is now th right time to wait for th drive to be stable
752 dim.wait("DRIVE_CONTROL", "OnTrack", 150000); // 110s for turning and 30s for stabilizing
753
754 // Now we have to be prepared for data-taking:
755 // make sure voltage is on
756 service_feedback.waitForVoltageOn();
757
758 // If pointing had changed, do calibration
759 if (point)
760 {
761 console.out(" Calibration.");
762
763 // Calibration (2% of 20')
764 while (1)
765 {
766 if (!takeRun("pedestal", 1000)) // 80 Hz -> 10s
767 continue;
768 if (!takeRun("light-pulser-ext", 1000)) // 80 Hz -> 10s
769 continue;
770 break;
771 }
772 }
773
774 console.out(" Taking data: start [5min]");
775
776 var len = 300;
777 while (len>0)
778 {
779 var time = new Date();
780 if (!takeRun("data", -1, len)) // Take data (5min)
781 len -= parseInt((new Date()-time)/1000);
782 else
783 break;
784 }
785
786 //v8.sleep(360000);
787 console.out(" Taking data: done");
788
789 run++;
790}
791
792service_drs.close();
Note: See TracBrowser for help on using the repository browser.