#!/usr/bin/perl
use strict;

#############################################################################
#  FILENAME:        vco_tracker.pl
#
#  PURPOSE:         Servo the VCO setting on a TASS Mk III Camera so as to
#                   keep the scan period at a constat specified value
#                   
#  AUTHOR:          Chris Albertson
#
#  DATE WRITTEN:    Thu Jan 21 1999
#
#  RCS Version Info
#  $Id: vco_tracker.pl,v 1.2 1999/01/21 08:18:57 chris Exp chris $
#
#
# Copyright (C) 1998 Chris Albertson <chrisja@jps.net>
#  
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#############################################################################


# This is the desired Scan Period in seconds.  Set this based on
# your image scale and declination aim point.
my $Scan_Period_SetPoint = 0.9222;

# This is the directory that holds the cclient executable.  Normally
# this is /usr/local/bin or /usr/local/tass/bin.
# Set this as required.
my $ClientBinDir         = "/home/chris/TASS/Software/Mk3_Driver/";

# A change of +1 in the VCO setting changes period by $slope seconds.
# This value to be determined by experiment.
my $slope                = -0.0001;

# Set this to "1" if you want to see lots of output, otherwise set
# this to "0"
my $verbose              = 1;

# The name of the computer that runs the Mk III driver software
my $Mk3_Host             = "gopher";


my $telemetry;
my $JD;
my $TEC_Set;
my $VCO_Set;
my $CCD_Temp;
my $Water_Temp;
my $TEC_Current;
my $PlusVDC;
my $MinusVDC;
my $Scan_Period;
my $Scan_Period_Error;
my $NewVCO;
my $command;
my $EstimatedVCO;


print "VCO Tracker version 0.0\n";

while (1)
{
    # Ask the driver for the current telemetry data
    $telemetry = `$ClientBinDir/cclient -h $Mk3_Host -c telem`;

    ($JD, 
     $TEC_Set,
     $VCO_Set,
     $CCD_Temp,
     $Water_Temp,
     $TEC_Current, 
     $PlusVDC,
     $MinusVDC, 
     $Scan_Period)  =  split(/\s+/, $telemetry);

    # If no data is being collected the driver reports a zero scan period
    # If we are doing a "clear" then the period is (on my 486) about 0.1 sec 
    if ($Scan_Period > 0.2)
    { 
        # Compute the NEW VCO setting from the current setting and the error.
        # We don't set the VCO to this.  We will only go half way to this setting
        # so as to avoid "hunting".        
        $Scan_Period_Error = $Scan_Period - $Scan_Period_SetPoint;
        $EstimatedVCO      = $VCO_Set - ($Scan_Period_Error/$slope);
        $NewVCO            = ($VCO_Set + $EstimatedVCO) / 2.0;

        # If the new setting is close to the old don't bother changing it
        if ( abs($NewVCO - $VCO_Set) >= 1.0 )
        {
            # Round the VCO setting to nearest integer (add .5 and truncate)
            $NewVCO  = int($NewVCO + 0.5);
            
            $command = "$ClientBinDir/cclient -h $Mk3_Host -c't3_vco $NewVCO'";

            if ($verbose)
            {
                print "RUNNING: $command \n";
                print "VCO=$VCO_Set Period=$Scan_Period Error=$Scan_Period_Error NewVCO=$NewVCO \n";
            }

            # Send a command to the driver to change the VCO
            system $command;
        }
        else
        {
            if ($verbose)
            {
                print "VCO is correct, no change required\n";
            }
        }
    }    
    else
    {
        print "Waiting for data...\n";
    }

    sleep(10);
}

