Changeset 15270 for trunk/FACT++


Ignore:
Timestamp:
04/06/13 16:47:58 (12 years ago)
Author:
tbretz
Message:
Restructured the code.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/scripts/Main.js

    r15252 r15270  
    55'use strict';
    66
     7//dimctrl.defineState(37, "TimeOutBeforeTakingData", "MCP took more than 5minutes to start TakingData");
     8
     9// ================================================================
     10//  Code related to the schedule
     11// ================================================================
     12
    713//this is just the class implementation of 'Observation'
    814include('scripts/Observation_class.js');
     
    2531}
    2632
    27 // ----------------------------------------------------------------
    28 // ================================================================
    29 // ----------------------------------------------------------------
    30 
    31 //dimctrl.defineState(37, "TimeOutBeforeTakingData", "MCP took more than 5minutes to start TakingData");
    32 
    33 
    34 // error handline : http://www.sitepoint.com/exceptional-exception-handling-in-javascript/
    35 // classes: http://www.phpied.com/3-ways-to-define-a-javascript-class/
    36 //
    37 // Arguments: TakeFirstDrsCalib
    38 // To be determined: How to stop the script without foreceful interruption?
    39 
    40 //
    41 // SCRIPTS:
    42 //
    43 //  - Startup, e.g. do not open LID
    44 //
    45 //  - Bring telescop to state 'operational', e.g. open lid,
    46 //    when first run != START is detected in the loop
    47 //
    48 //  - Take data
    49 //
    50 //  - Shutdown
    51 //
    52 // ----> Does smartfact display alarm messages already?
    53 // ----> How to display errors in smartfact? Is that necessary at all?
    54 //       (red output? maybe just <red>...</red>?
    55 //
    56 // ----------------------------------------------------------------
    57 
     33// Get the observation scheduled for 'now' from the table and
     34// return its index
     35function getObservation(now)
     36{
     37    if (now==undefined)
     38        now = new Date();
     39
     40    if (isNaN(now.valueOf()))
     41        throw new Error("Date argument in getObservation invalid.");
     42
     43    for (var i=0; i<observations.length; i++)
     44        if (now<observations[i].start)
     45            return i-1;
     46
     47    return observations.length-1;
     48}
     49
     50// ================================================================
     51//  Code to check whether observation is allowed
     52// ================================================================
     53/*
    5854function currentEst(source)
    5955{
     
    8985    return ratio*currentEst(source)/7.7;
    9086}
    91 
    92 // Ratio in rate would be (estimate, not precise calculation)
    93 // pow(ratio, -0.7)
    94 
    95 // ----------------------------------------------------------------
    96 
    97 //DN: the name of the Subscription object 'service_con' is not really
    98 // telling that its a subscription to FAD_CONTROL/CONNECTIONS
    99 // fad_connections sound ok for be, since
    100 // fad_connections.onchange() is pretty clear
    101 // fad_connections.reconnect() is not really good, but at least it has FAD in it.
    102 var service_con = new Subscription("FAD_CONTROL/CONNECTIONS");
     87*/
     88
     89// ----------------------------------------------------------------
     90
     91// ================================================================
     92//  Code related to monitoring the fad system
     93// ================================================================
     94
     95var sub_connections = new Subscription("FAD_CONTROL/CONNECTIONS");
    10396
    10497/**
     
    107100 *
    108101 */
    109 service_con.onchange = function(evt)
     102sub_connections.onchange = function(evt)
    110103{
    111104    return;
     
    144137 *
    145138 * @example
    146  *      if (!service_con.reconnect())
     139 *      if (!sub_connections.reconnect())
    147140 *          exit();
    148141 */
    149 service_con.reconnect = function()
     142sub_connections.reconnect = function()
    150143{
    151144    // this.reset is a list containing the IDs of FADs,
     
    171164    return true;
    172165}
     166
     167// ================================================================
     168//  Code related to taking data
     169// ================================================================
    173170
    174171var startrun = new Subscription("FAD_CONTROL/START_RUN");
     
    244241            console.out("");
    245242
    246             var con  = service_con.get();
     243            var con  = sub_connections.get();
    247244            var stat = con.obj['status'];
    248245
     
    280277    // DN: currently reconnect() never returns false
    281278    //     .. but it can fail of course.
    282     if (!service_con.reconnect())
    283         exit();
    284 
    285     return true;//service_con.reconnect();
     279    //if (!sub_connections.reconnect())
     280    //    exit();
     281
     282    return true;//sub_connections.reconnect();
    286283}
    287284
     
    328325}
    329326
    330 // ----------------------------------------------------------------
     327// ================================================================
     328//  Code related to the lid
     329// ================================================================
    331330
    332331function OpenLid()
     
    375374}
    376375
    377 // ----------------------------------------------------------------
     376// ================================================================
     377//  Code related to switching bias voltage on and off
     378// ================================================================
    378379
    379380var service_feedback = new Subscription("FEEDBACK/DEVIATION");
     
    541542
    542543// ================================================================
    543 // Crosscheck all states
    544 // ================================================================
    545 
    546 include('scripts/Startup.js');//Startup();
    547 
    548 // ----------------------------------------------------------------
    549 
    550 console.out("Checking send.");
    551 checkSend(["MCP", "DRIVE_CONTROL", "LID_CONTROL", "FAD_CONTROL", "FEEDBACK"]);
    552 console.out("Checking send: done");
    553 
    554 // ----------------------------------------------------------------
    555 
    556 console.out("Feedback init: start.");
    557 service_feedback.get(5000);
    558 
    559 dim.send("FEEDBACK/ENABLE_OUTPUT", true);
    560 dim.send("FEEDBACK/START_CURRENT_CONTROL", 0.);
    561 
    562 console.out("Feedback init: end.");
    563 
    564 // ----------------------------------------------------------------
    565 // Bring the system into a well defined state
    566 // ----------------------------------------------------------------
    567 
    568 console.out("Drs runs init: start.");
    569 
    570 // FIMXE: Double subscription is not allowed!
    571 //        also Startup needs DRS_RUNS
    572 var service_drs = new Subscription("FAD_CONTROL/DRS_RUNS");
    573 service_drs.get(5000);
    574 
    575 console.out("Drs runs init: end.");
    576 
    577 // FIXME: Check if the last DRS calibration was complete?
    578 // ----------------------------------------------------------------
    579 
    580 // We have to stup a few things here which might not by set by Startup.js
    581 dim.send("FAD_CONTROL/SET_FILE_FORMAT", 2);
    582 
    583 // ----------------------------------------------------------------
    584 
    585 console.out("Start main loop.");
    586 
    587 function Startup()
    588 {
    589     /**** dummy ****/
    590     console.out("  => [STARTUP] called.");
    591 }
     544//  Function to shutdown the system
     545// ================================================================
    592546
    593547function Shutdown()
     
    644598}
    645599
    646 // Get the observation scheduled for 'now' from the table and
    647 // return its index
    648 function getObservation(now)
    649 {
    650     if (now==undefined)
    651         now = new Date();
    652 
    653     if (isNaN(now.valueOf()))
    654         throw new Error("Date argument in getObservation invalid.");
    655 
    656     for (var i=0; i<observations.length; i++)
    657         if (now<observations[i].start)
    658             return i-1;
    659 
    660     return observations.length-1;
    661 }
    662 
    663 
    664 // DN: using so called magic numbers to encode certain
    665 //      states of the logic is considered pretty bad coding as far as I understand.
    666 //      the reader at this point has no idea why run is -2 ... this is the first time she
    667 //      reads about this variable and there is not a word of explanation found.
    668 var run = -2; // getObservation never called
    669 var sub;
    670 var lastObs;
    671 
     600// ================================================================
     601// Crosscheck all states
     602// ================================================================
     603
     604// ----------------------------------------------------------------
     605// Do a standard startup to bring the system in into a well
     606// defined state
     607// ----------------------------------------------------------------
     608include('scripts/Startup.js');
     609
     610// ----------------------------------------------------------------
     611// Check that everything we need is availabel to receive commands
     612// (FIXME: Should that go to the general CheckState?)
     613// ----------------------------------------------------------------
     614console.out("Checking send.");
     615checkSend(["MCP", "DRIVE_CONTROL", "LID_CONTROL", "FAD_CONTROL", "FEEDBACK"]);
     616console.out("Checking send: done");
     617
     618// ----------------------------------------------------------------
     619// Bring feedback into the correct operational state
     620// ----------------------------------------------------------------
     621console.out("Feedback init: start.");
     622service_feedback.get(5000);
     623
     624dim.send("FEEDBACK/ENABLE_OUTPUT", true);
     625dim.send("FEEDBACK/START_CURRENT_CONTROL", 0.);
     626
     627// ----------------------------------------------------------------
     628// Connect to the DRS_RUNS service
     629// ----------------------------------------------------------------
     630console.out("Drs runs init: start.");
     631
     632var sub_drsruns = new Subscription("FAD_CONTROL/DRS_RUNS");
     633sub_drsruns.get(5000);
     634
     635// FIXME: Check if the last DRS calibration was complete?
     636
     637// ----------------------------------------------------------------
     638// Make sure we will write files
     639// ----------------------------------------------------------------
     640dim.send("FAD_CONTROL/SET_FILE_FORMAT", 2);
     641
     642// ----------------------------------------------------------------
     643// Print some information for the user about the
     644// expected first oberservation
     645// ----------------------------------------------------------------
    672646var test = getObservation();
    673647if (test!=undefined)
     
    682656}
    683657
     658// ----------------------------------------------------------------
     659// Start main loop
     660// ----------------------------------------------------------------
     661console.out("Start main loop.");
     662
     663var run = -2; // getObservation never called
     664var sub;
     665var lastObs;
     666
    684667while (1)
    685668{
     
    688671    var idxObs = getObservation();
    689672    if (idxObs===undefined)
    690         exit();
     673        break;
    691674
    692675    // FIXME: Check missing whether a shutdown is needed...
     
    785768    case "STARTUP":
    786769        console.out("  STARTUP", "");
    787         Startup();  // BiasOn/Off?, Lid open/close?
    788770        CloseLid();
    789771
     
    797779        while (!takeRun("pedestal", 5000));
    798780
     781        // It is unclear what comes next, so we better switch off the voltage
    799782        service_feedback.voltageOff();
    800 
    801         //dim.send("RATE_CONTROL/STOP"); // get out of GlobalThresholdSet
    802         //dim.wait("RATE_CONTROL", "Connected", 3000);
    803 
    804         if (nextObs!=undefined && sub==obs.length-1)
    805             console.out("  Waiting for next observation scheduled for "+nextObs.start.toUTCString(),"");
    806         sub++;
    807         continue;
     783        break;
    808784
    809785    case "SHUTDOWN":
     
    811787        Shutdown();
    812788
     789        // FIXME: Avoid new observations after a shutdown until
     790        //        the next startup (set run back to -2?)
    813791        console.out("  Waiting for next startup.", "");
    814792        sub++;
     
    821799    case "DRSCALIB":
    822800        console.out("  DRSCALIB", "");
    823 
    824801        doDrsCalibration("drscalib");  // will switch the voltage off
    825 
    826         if (nextObs!=undefined && sub==obs.length-1)
    827             console.out("  Waiting for next observation scheduled for "+nextObs.start.toUTCString(),"");
    828 
    829         sub++;
    830         continue;
     802        break;
    831803
    832804    case "SINGLEPE":
     
    847819
    848820        // It is unclear what comes next, so we better switch off the voltage
    849         // service_feedback.voltageOff();
    850 
    851         if (nextObs!=undefined && sub==obs.length-1)
    852             console.out("  Waiting for next observation scheduled for "+nextObs.start.toUTCString(),"");
    853 
    854         sub++;
    855         continue;
     821        service_feedback.voltageOff();
     822        break;
    856823
    857824    case "RATESCAN":
     
    897864
    898865        console.out("  Ratescan done [%.1fs, %.1fs]".$((tm2-tm1)/1000, (new Date()-tm2)/1000));
    899 
    900         if (nextObs!=undefined && sub==obs.length-1)
    901             console.out("  Waiting for next observation scheduled for "+nextObs.start.toUTCString(),"");
    902 
    903         sub++;
    904         continue;
    905     }
    906 
    907     // ========================== case "DATA" ============================
    908 /*
    909     if (Sun.horizon("FACT").isUp)
    910     {
    911         console.out("  SHUTDOWN","");
    912         Shutdown();
    913         console.out("  Exit forced due to broken schedule", "");
    914         exit();
    915     }
    916 */
    917     // Calculate remaining time for this observation in minutes
    918     var remaining = nextObs==undefined ? 0 : (nextObs.start-new Date())/60000;
    919 
    920     // ------------------------------------------------------------
    921 
    922     // Checking for 'Ramping' in the BIAS_CONTROL is not ideal, but at the moment
    923     // it is not possible to distinguish between a real ramping and the short
    924     // ramping which takes place whenever the feedback updated the voltages.
    925 
    926     // ------------------------------------------------------------
    927 
    928     console.out("  Run #"+run+"  (remaining "+parseInt(remaining)+"min)");
    929 
    930     // ----- Time since last DRS Calibration [min] ------
    931     var runs = service_drs.get(0);
    932     var diff = (new Date()-runs.time)/60000;
    933 
    934     // Warning: 'roi=300' is a number which is not intrisically fixed
    935     //          but can change depending on the taste of the observers
    936     var valid = runs.obj['run'][2]>0 && runs.obj['roi']==300;
    937 
    938     if (valid)
    939         console.out("  Last DRS calib: %.1fmin ago".$(diff));
    940     else
    941         console.out("  No valid drs calibration available");
    942 
    943     // Changine pointing position and take calibration...
    944     //  ...every four runs (every ~20min)
    945     //  ...if at least ten minutes of observation time are left
    946     //  ...if this is the first run on the source
    947     var point  = (run%4==0 && remaining>10) || run==0;
    948 
    949     // Take DRS Calib...
    950     //  ...every four runs (every ~20min)
    951     //  ...at last  every two hours
    952     //  ...when DRS temperature has changed by more than 2deg (?)
    953     //  ...when more than 15min of observation are left
    954     //  ...no drs calibration was done yet
    955     var drscal = (run%4==0 && (remaining>15 && diff>70)) || !valid;
    956 
    957     if (point)
    958     {
    959         // Change wobble position every four runs,
    960         // start with alternating wobble positions each day
    961         var wobble = (parseInt(run/4) + parseInt(new Date()/1000/3600/24-0.5))%2+1;
    962 
    963         //console.out("  Move telescope to '"+source+"' "+offset+" "+wobble);
    964         console.out("  Move telescope to '"+obs[sub].source+"' ["+wobble+"]");
    965 
    966         //var offset = observations[obs][2];
    967         //var wobble = observations[obs][3 + parseInt(run/4)%2];
    968 
    969         //dim.send("DRIVE_CONTROL/TRACK_SOURCE", offset, wobble, source);
    970 
    971         dim.send("DRIVE_CONTROL/TRACK_WOBBLE", wobble, obs[sub].source);
    972 
    973         // Do we have to check if the telescope is really moving?
    974         // We can cross-check the SOURCE service later
    975     }
    976 
    977     if (drscal)
    978         doDrsCalibration("data");  // will turn voltage off
    979 
    980     OpenLid();
    981 
    982     // voltage must be switched on after the lid is open for the
    983     // feedback to adapt the voltage properly to the night-sky
    984     // background light level.
    985     service_feedback.voltageOn();
    986 
    987     // This is now th right time to wait for th drive to be stable
    988     dim.wait("DRIVE_CONTROL", "OnTrack", 150000); // 110s for turning and 30s for stabilizing
    989 
    990     // Now we have to be prepared for data-taking:
    991     // make sure voltage is on
    992     service_feedback.waitForVoltageOn();
    993 
    994     // If pointing had changed, do calibration
    995     if (point)
    996     {
    997         console.out("  Calibration.");
    998 
    999         // Calibration (2% of 20')
    1000         while (1)
     866        break; // case "RATESCAN"
     867
     868    case "DATA":
     869
     870        // ========================== case "DATA" ============================
     871    /*
     872        if (Sun.horizon("FACT").isUp)
    1001873        {
    1002             if (!takeRun("pedestal",         1000))  // 80 Hz  -> 10s
    1003                 continue;
    1004             if (!takeRun("light-pulser-ext", 1000))  // 80 Hz  -> 10s
    1005                 continue;
    1006             break;
     874            console.out("  SHUTDOWN","");
     875            Shutdown();
     876            console.out("  Exit forced due to broken schedule", "");
     877            exit();
    1007878        }
    1008     }
    1009 
    1010     console.out("  Taking data: start [5min]");
    1011 
    1012     var len = 300;
    1013     while (len>0)
    1014     {
    1015         var time = new Date();
    1016         if (takeRun("data", -1, len)) // Take data (5min)
    1017             break;
    1018 
    1019         len -= parseInt((new Date()-time)/1000);
    1020     }
    1021 
    1022     console.out("  Taking data: done");
    1023     run++;
    1024 }
    1025 
    1026 service_drs.close();
     879    */
     880        // Calculate remaining time for this observation in minutes
     881        var remaining = nextObs==undefined ? 0 : (nextObs.start-new Date())/60000;
     882
     883        // ------------------------------------------------------------
     884
     885        console.out("  Run #"+run+"  (remaining "+parseInt(remaining)+"min)");
     886
     887        // ----- Time since last DRS Calibration [min] ------
     888        var runs = sub_drsruns.get(0);
     889        var diff = (new Date()-runs.time)/60000;
     890
     891        // Warning: 'roi=300' is a number which is not intrisically fixed
     892        //          but can change depending on the taste of the observers
     893        var valid = runs.obj['run'][2]>0 && runs.obj['roi']==300;
     894
     895        if (valid)
     896            console.out("  Last DRS calib: %.1fmin ago".$(diff));
     897        else
     898            console.out("  No valid drs calibration available");
     899
     900        // Changine pointing position and take calibration...
     901        //  ...every four runs (every ~20min)
     902        //  ...if at least ten minutes of observation time are left
     903        //  ...if this is the first run on the source
     904        var point  = (run%4==0 && remaining>10) || run==0;
     905
     906        // Take DRS Calib...
     907        //  ...every four runs (every ~20min)
     908        //  ...at last  every two hours
     909        //  ...when DRS temperature has changed by more than 2deg (?)
     910        //  ...when more than 15min of observation are left
     911        //  ...no drs calibration was done yet
     912        var drscal = (run%4==0 && (remaining>15 && diff>70)) || !valid;
     913
     914        if (point)
     915        {
     916            // Change wobble position every four runs,
     917            // start with alternating wobble positions each day
     918            var wobble = (parseInt(run/4) + parseInt(new Date()/1000/3600/24-0.5))%2+1;
     919
     920            //console.out("  Move telescope to '"+source+"' "+offset+" "+wobble);
     921            console.out("  Move telescope to '"+obs[sub].source+"' ["+wobble+"]");
     922
     923            //var offset = observations[obs][2];
     924            //var wobble = observations[obs][3 + parseInt(run/4)%2];
     925
     926            //dim.send("DRIVE_CONTROL/TRACK_SOURCE", offset, wobble, source);
     927
     928            dim.send("DRIVE_CONTROL/TRACK_WOBBLE", wobble, obs[sub].source);
     929
     930            // Do we have to check if the telescope is really moving?
     931            // We can cross-check the SOURCE service later
     932        }
     933
     934        if (drscal)
     935            doDrsCalibration("data");  // will turn voltage off
     936
     937        OpenLid();
     938
     939        // voltage must be switched on after the lid is open for the
     940        // feedback to adapt the voltage properly to the night-sky
     941        // background light level.
     942        service_feedback.voltageOn();
     943
     944        // This is now th right time to wait for th drive to be stable
     945        dim.wait("DRIVE_CONTROL", "OnTrack", 150000); // 110s for turning and 30s for stabilizing
     946
     947        // Now we have to be prepared for data-taking:
     948        // make sure voltage is on
     949        service_feedback.waitForVoltageOn();
     950
     951        // If pointing had changed, do calibration
     952        if (point)
     953        {
     954            console.out("  Calibration.");
     955
     956            // Calibration (2% of 20')
     957            while (1)
     958            {
     959                if (!takeRun("pedestal",         1000))  // 80 Hz  -> 10s
     960                    continue;
     961                if (!takeRun("light-pulser-ext", 1000))  // 80 Hz  -> 10s
     962                    continue;
     963                break;
     964            }
     965        }
     966
     967        console.out("  Taking data: start [5min]");
     968
     969        var len = 300;
     970        while (len>0)
     971        {
     972            var time = new Date();
     973            if (takeRun("data", -1, len)) // Take data (5min)
     974                break;
     975
     976            len -= parseInt((new Date()-time)/1000);
     977        }
     978
     979        console.out("  Taking data: done");
     980        run++;
     981
     982        continue; // case "DATA"
     983    }
     984
     985    if (nextObs!=undefined && sub==obs.length-1)
     986        console.out("  Waiting for next observation scheduled for "+nextObs.start.toUTCString(),"");
     987
     988    sub++;
     989}
     990
     991sub_drsruns.close();
     992
     993// ================================================================
     994// Comments and ToDo goes here
     995// ================================================================
     996
     997// error handline : http://www.sitepoint.com/exceptional-exception-handling-in-javascript/
     998// classes: http://www.phpied.com/3-ways-to-define-a-javascript-class/
     999//
     1000// Arguments: TakeFirstDrsCalib
     1001// To be determined: How to stop the script without foreceful interruption?
Note: See TracChangeset for help on using the changeset viewer.