Skip to content. | Skip to navigation

Personal tools

vane.cpp

vane.cpp

vane.cpp

/////////////////////////////////////////////////////////////////////////////
// VANE-END ACTUATOR CONTROL PROGRAM
//
//  Last updated: 09 / 07 / 2006
//  by Jose M. Soto (original source by Greg Bredthauer)
//     The Observatories of the Carnegie Institution of Washington
//
//  Compile using Open Watcom C/C++32 ver 1.5 using CauseWay
//    Compile command:
//                    see bat file MAKEOP.BAT
//
//  Note: This program also uses the general-purpose source code files
//        SERCLOCK.CPP, and one of the video driver files such as
//        VIDEO.CPP (for VESA 2.0 cards) or ET4000.CPP.
//
/////////////////////////////////////////////////////////////////////////////

// Notes:
//  Get rid of WriteZero command?
//  Change DGH readings to ints (float * 100) for precision with remote
//  Add remote commands

#define Version "3.33RC1"

/////////////////////////////////////////////////////////////////////////////
// LOG OF CHANGES FOR VANE PROG AT MAG1 & MAG2
//
//  09/07/06: Recompiled source code with new release of Open Watcom ver. 1.5
//            Vane End program version is ver. 3.25
//  08/28/04: Added hardware flow control (handshaking) to the serial line
//            communications, using RTS/CTS pins.
//
/////////////////////////////////////////////////////////////////////////////
// LOG OF CHANGES FOR VANE PROG AT MAG1
//
//  01/24/04: Added two signals into Galil's inputs:
//            1. One analog that measures the Set-Up signal coming from Renishaw
//            encoder and tells how good is the reading (ranges between 0-5)
//            2. One digital which detects the power amplifier status
//            Glentek off is 0, on is 1.
//  06/07/03: Optimize Galils commands in IR.CPP.
//  03/26/02: New parameter in INI file, 'PMfact'.
//                                              Is the lbs/mV conversion factor for M2 weight load cells.
//      03/17/02: Added SPDERR IR command to toggle display of speed servo error
//  03/16/02: Added PROG IR command to Vane to download IRSERVO.DMC to
//            a Galil, usage is PROG n, n = 0-5.
//                                        Added SPDP,SPDI,SPDD,SPDIL IR commands to tune speed servo.
//  03/15/02: Improved GoS command... position/speed servo is now done
//            by a program running on the Galil.
//      07/07/00:       Presvac control complete. Original strategy splitted in 2.
//                                              Part with the logic updates every clock interrupt,
//                                              piece with the Galil cards comm. updates every program cycle.
//                                              This make the control's response slower, but it
//                                              is the only way to keep communication controlled.
//  07/04/00: 3 new DGHs where added in top's ring daisy chain (8 previously)
//            New files (DGHPV.H/CPP) discarded since only exisitng DGH.H/CPP
//                                              were modified.
//  06/11/00:   Make the speed of GOA/GOR commands independent of a JOG command
//                                              previously issued. This 'cause the speed in Galils is changed
//                                              when a Jog is issued and this affects subsequent Go moves
//  06/06/00: Added command GOR to move any IR n degrees relative to the
//                                              the current position. Previous comm GO was modified to GOA,
//                                              or move (absolute) the IR to a target angle.
//      05/26/00: Started to add code for the control of pres/vac.
//                                              files created: DGHPV.H/CPP, PRESVAC.H/CPP
//
//      05/24/00:       Start making room on the screen
//                                              for vaccuum/air support system of secondary mirror.
//                                              Files modified: display.cpp/.h,flags.cpp,cell.cpp,ir.cpp
//
//      05/11/00:       Changed displayed position of input log and messages log.
//                                              First is now at left side of the screen, latter at right
//                                              (opposite as it was)
//
//  3/16: Added EDS log, DumpLogOnFatal flag
// 11/20: Allow each corner to be homed individually and clear fatal
// 11/16: Removed remote and local program modes
//         Removed S command, added TE (toggle DGH enabled) command
//         Took ResetEmergency out of Home.
// 11/13: Adding instrument rotator control
//  6/23: Operations continue during help screen
//  12/3: Modified GetXYZHVFromEncoders, GetDestination, and VaneCalc
//         to use more accurate geometry.
// 11/18: Altered the AdjustTension routine to modify VANE.INI
//         Added Tension Limits check to CheckFatal
//                               Home now waits 60 seconds for a retry, then continues without input
//         Added F4 for pausing and resuming log entries
// 11/13: Added DGH limit display, movement display
// 11/5:  Removed backlash flags, backlash removal always done now
// 10/23: Pipelining complete, though untested in field
//                               Added serial status request commands P,E,T
// 10/14: Began pipelining I/O
//  9/21: Added DGHFormat routine to put leading 0's on DGH alarm settings
//  9/20: Modifying display to match Shectman's
//  9/17: Fixed the "sign-of-zero" problem with DMC motion
//                               Added "TC1" DMC command following a "?" DMC response
//         Added "TP" and "TV" commands for testing pressure/vacuum
//         Added "F" command to toggle forced update of tensions/encoders
//         Added FixZ into the calculation code in CELL.CPP
//                               Added "W" command to write current location as zero point
//  9/2:  Added display of limit switches
//                               Added motor movement constants to VANE.INI
//  8/25: Added the 'CA' (clear alarm) command to DGH initialization
//                               Added a prompt to retry the homing of each corner
//  8/21: VIDEO.CPP routines switched to assembly language for speed
//  8/14: Cleaning up comments, etc
//                               Improved serial/clock routines (reentry safe)
//         Added left/right scrolling in log display
//  6/4:  Continuing revisions, optimizations
//         Added faster character drawing to Video
//                               Added header files to each CPP file for better inter-unit calls
//                         Added onscreen movement stage display
//  4/23: Revising source code, switching to classes for many functions
//      4/22:   Added 'A' command for adjusting tensions
//                               Changed function keys: F1=Help,F2=Dump log,F3=Dump Screen
//      4/20: Added 'E' command for on-the-fly editing of VANE.INI
//                               Added 'P' command to toggle tension view mV/Pounds
//      4/8:  Added Home and End log keys, changes error messages in parse routine,
//                         changed the dumped log file name to include date, added command mode
//                         display
//      3/17: Added 5Hz cursor, encoder/tension readings that turn red
//                               when they're out of bounds, and yellow when they're near
//                               the soft limits. Added F2 Screen Dump.
//
/////////////////////////////////////////////////////////////////////////////
// LOG OF CHANGES FOR VANE PROG AT MAG2
//
//  01/10/04: Brakes were all removed from rotators. Updated code accordingly
//            Cass has now a clamping system to hold tertiary in place.
//            Adapted old brake logic in CASS for this new clapms.
//  05/10/03: Get rid of Heidenhain and Sony index system.
//            Now Renishaw encoder/index system is used in all rotators.
//  09/03/02: Adapted IRs home routine to handle CASS IR Sony magnet sensor.
//                                              All the other IRs use Renishaw index system.
//  08/30/02: Added extra serial port (COM4) to talk with Folded Port IRs.
//                                              Adapted serial communication routines to talk with Galils at COM4.
//  03/26/02: New parameter in INI file, 'PMfact'.
//                                              Is the lbs/mV conversion factor for M2 weight load cells.
//      03/17/02: Added SPDERR IR command to toggle display of speed servo error
//  03/16/02: Added PROG IR command to Vane to download IRSERVO.DMC to
//            a Galil, usage is PROG n, n = 0-5.
//                                        Added SPDP,SPDI,SPDD,SPDIL IR commands to tune speed servo.
//  03/15/02: Improved GoS command... position/speed servo is now done
//            by a program running on the Galil.
//      07/07/00:       Presvac control complete. Original strategy splitted in 2.
//                                              Part with the logic updates every clock interrupt,
//                                              piece with the Galil cards comm. updates every program cycle.
//                                              This make the control's response slower, but it
//                                              is the only way to keep communication controlled.
//  07/04/00: 3 new DGHs where added in top's ring daisy chain (8 previously)
//            New files (DGHPV.H/CPP) discarded since only exisitng DGH.H/CPP
//                                              were modified.
//  06/11/00:   Make the speed of GOA/GOR commands independent of a JOG command
//                                              previously issued. This 'cause the speed in Galils is changed
//                                              when a Jog is issued and this affects subsequent Go moves
//  06/06/00: Added command GOR to move any IR n degrees relative to the
//                                              the current position. Previous comm GO was modified to GOA,
//                                              or move (absolute) the IR to a target angle.
//      05/26/00: Started to add code for the control of pres/vac.
//                                              files created: DGHPV.H/CPP, PRESVAC.H/CPP
//
//      05/24/00:       Start making room on the screen
//                                              for vaccuum/air support system of secondary mirror.
//                                              Files modified: display.cpp/.h,flags.cpp,cell.cpp,ir.cpp
//
//      05/11/00:       Changed displayed position of input log and messages log.
//                                              First is now at left side of the screen, latter at right
//                                              (opposite as it was)
//
//  3/16: Added EDS log, DumpLogOnFatal flag
// 11/20: Allow each corner to be homed individually and clear fatal
// 11/16: Removed remote and local program modes
//         Removed S command, added TE (toggle DGH enabled) command
//         Took ResetEmergency out of Home.
// 11/13: Adding instrument rotator control
//  6/23: Operations continue during help screen
//  12/3: Modified GetXYZHVFromEncoders, GetDestination, and VaneCalc
//         to use more accurate geometry.
// 11/18: Altered the AdjustTension routine to modify VANE.INI
//         Added Tension Limits check to CheckFatal
//                               Home now waits 60 seconds for a retry, then continues without input
//         Added F4 for pausing and resuming log entries
// 11/13: Added DGH limit display, movement display
// 11/5:  Removed backlash flags, backlash removal always done now
// 10/23: Pipelining complete, though untested in field
//                               Added serial status request commands P,E,T
// 10/14: Began pipelining I/O
//  9/21: Added DGHFormat routine to put leading 0's on DGH alarm settings
//  9/20: Modifying display to match Shectman's
//  9/17: Fixed the "sign-of-zero" problem with DMC motion
//                               Added "TC1" DMC command following a "?" DMC response
//         Added "TP" and "TV" commands for testing pressure/vacuum
//         Added "F" command to toggle forced update of tensions/encoders
//         Added FixZ into the calculation code in CELL.CPP
//                               Added "W" command to write current location as zero point
//  9/2:  Added display of limit switches
//                               Added motor movement constants to VANE.INI
//  8/25: Added the 'CA' (clear alarm) command to DGH initialization
//                               Added a prompt to retry the homing of each corner
//  8/21: VIDEO.CPP routines switched to assembly language for speed
//  8/14: Cleaning up comments, etc
//                               Improved serial/clock routines (reentry safe)
//         Added left/right scrolling in log display
//  6/4:  Continuing revisions, optimizations
//         Added faster character drawing to Video
//                               Added header files to each CPP file for better inter-unit calls
//                         Added onscreen movement stage display
//  4/23: Revising source code, switching to classes for many functions
//      4/22:   Added 'A' command for adjusting tensions
//                               Changed function keys: F1=Help,F2=Dump log,F3=Dump Screen
//      4/20: Added 'E' command for on-the-fly editing of VANE.INI
//                               Added 'P' command to toggle tension view mV/Pounds
//      4/8:  Added Home and End log keys, changes error messages in parse routine,
//                         changed the dumped log file name to include date, added command mode
//                         display
//      3/17: Added 5Hz cursor, encoder/tension readings that turn red
//                               when they're out of bounds, and yellow when they're near
//                               the soft limits. Added F2 Screen Dump.
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// Force Byte-alignment: necessary for properly aligned structures
#pragma pack(1)
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// PORT COMMUNICATION CONTROL
//
//  Uncomment the "#define ENABLEIO" line to enable reading/writing
//  to all ports.  Comment it out to test the software on a computer without
//  the hardware.
//
#define ENABLEIO
//
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// Video graphics driver usage
//
//  Select from one of the following video drivers
//#include "..\libmag\slovideo.cpp" // Compatible (slow) graphics
//#include "..\libmag\video.cpp"    // Fast VESA graphics routines
#include "..\libmag\et4000.cpp"     // Tseng ET-4000 graphics routines
/////////////////////////////////////////////////////////////////////////////

// Macros for easier-to-read source code
#define setvect _dos_setvect
#define getvect _dos_getvect
#define enable _enable
#define disable _disable
#define getdate _dos_getdate
#define time dostime_t
#define date dosdate_t
#define PI 3.14159265359
#define BRIEF 0
#define EXTRA 1
#define VERBOSE 2

// Globals

// These step variables are used in their associated functions to keep
// track of an operation in progress between calls.
// For example, DMCStep is used by the DMC communication routines to keep
// track of whether a command has been sent yet or a response received.
int DMCStep = 0,MoveStep = 0,GetEncodersStep = 0,UpdateStep = 0;
int CheckFatalStep = 0,GetSwitchesStep = 0,UpdateEncodersStep = 0;
int MoveAllMotorsStep = 0,BacklashStep = 0;
int PauseOK = 0;        // Flag set when stopping Cell.Update() is OK
unsigned DMCTime; // Used to watch for DMC timeouts.
int ClockPPM = 0;       // Speed up or slow down clock in PPM (for accuracy)
// Number that identifies the Magellan telescope the program is running at:
// MAG1(Baade)=1, MAG2(Clay)=2
int Telescope = 0;

// Flags that indicates if a secondary mirror is installed and
// available. They are used to be able to choose which secondary to
// control.
int f11Present = 1;
int f5Present = 1;


// Includes
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <i86.h>
#include <graph.h>

#include "..\libmag\math.cpp"     // General math routines
//#include "..\libmag\serclock.cpp" // Serial/Clock interrupt routines
// New serial routines with RTS-CTS handshaking
#include "..\libmag\sercloc2.cpp" // Serial/Clock interrupt routines
#include "..\libmag\log.cpp"      // Multipurpose logging routines
#include "..\libmag\chart.cpp"    // Data logging/display routines
#include "parport.h"	// parallel port driver


// Globals
CLog Log,InputLog;                      // The two running logs
struct ParPort parport;

#include "io.h"                                 // Low-level I/O routines
#include "flags.h"                      // All global status flags
#include "display.h"    // Functions that update the display
#include "dmc.h"        // DMC (motor controller) communications
#include "dgh.h"                                // DGH (load cell) communications
#include "cell.h"                               // All mirror cell functions (homing,moving)
#include "ini.h"                                // Functions dealing with VANE.INI
#include "parse.h"      // Functions that parse serial and keyboard input
#include "edslog.h"                     // Engineering Data Stream log routines
#include "ir.h"                                 // Instrument Rotator routines
#include "presvac.h"            // Secondary mirror pressure/vacuum support routines

#include "io.cpp"
#include "flags.cpp"
#include "display.cpp"
#include "parport.cpp"
#include "dmc.cpp"
#include "dgh.cpp"
#include "cell.cpp"
#include "ini.cpp"
#include "parse.cpp"
#include "edslog.cpp"
#include "ir.cpp"
#include "presvac.cpp"

void main(int _argc,const char * _argv[])
{
  int i,e;
  char s[255]; // This type of string is used all over for log entries

/////////////////////////////////////////////////////////////////////////////
// INITIALIZATION
/////////////////////////////////////////////////////////////////////////////

	// Initialize parellel port
	ParPortInit(&parport);

  // Initialize the running logs
  Log.Init(1000,212,630,392,5,1,1,340,376);
  InputLog.Init(100,12,192,392,4,0,0,0,0);
  EDSLog.Init(100);
  if (_argc > 1)
    Log.VerboseLevel = 3;

  EDSLog.Add(999,"Program startup (v%s)",Version);

  // Initialize instrument rotator charts
  i = ibty+26+6*16;
  IRErr2Chart.Init( 12+ 7*8,i,11+20*8,i+47,SHECRED,SHECMEDGRAY,BLACK,WHITE,0,1.0,4);
  IRErrChart.Init ( 12+ 7*8,i,11+20*8,i+47,YELLOW,SHECMEDGRAY,BLACK,WHITE,0,1.0,4);
  IRVel2Chart.Init( 12+28*8,i,11+41*8,i+47,SHECRED,SHECMEDGRAY,BLACK,WHITE,0,3.0,4);
  IRVelChart.Init( 12+28*8,i,11+41*8,i+47,YELLOW,SHECMEDGRAY,BLACK,WHITE,0,3.0,4);
        IRVoltChart.Init(12+49*8,i,11+62*8,i+47,YELLOW,SHECMEDGRAY,BLACK,WHITE,0,10.0,4);

  // Initialize all status flags
  Flags.Init();

  // Switch to 640x480x256 video mode
  // First set Shec colors for this machine (colors vary with
  // monitor and video card
  ShecDARKGRAY = 16;    // 16 by default
  ShecMEDGRAY = 38;             // 28 by default
  ShecLIGHTGRAY = 50;   // 40 by default
  ShecWHITE = 62;     // 52 by default
  ShecRED = 79;       // 78 by default
  ShecYELLOW = 95;    // 94 by default
  ShecGREEN = 109;    // 109 by default

  if (e = InitVideo(0))
  {
    CloseVideo();
    printf("Error initializing graphics mode! (Error %d)\n",e);
    return;
  }

  // Initialize clock interrupt, which occurs at 1000Hz
  InitClock(1000); // Enable clock interrupt control

  // Initialize serial interrupt control, and all port parameters
  InitPorts(); // Enable serial interrupt control

  // Initialize instrument rotators
  for (i=0;i<=5;i++)
    IRs[i].Init(i);

  // Read the mirror's zeroed encoder values and tension limits
  if (e = ReadINI("VANE.INI"))
  {
    Flags.SetFatal(FFINIFile);
    EDSLog.Add(2,"VANE.INI read error %d",e);
  }
  else
    EDSLog.Add(997,"VANE.INI read success");

  // Force logs to display every log entry during startup
  Log.ForceDisplay = 1;
  InputLog.ForceDisplay = 1;

  // Reset DMCs and check outputs
  if (e = CheckDMCs())
  {
    Flags.SetFatal(FFCheckFatal);
    EDSLog.Add(1,"DMC check error %d",e);
  }
  else
    EDSLog.Add(998,"DMC check success");

  // Speed up or slow down clock, based on INI file
  SetNewClockPPM(ClockPPM);

  // Initialize the mirror cell variables, initialize DGH modules
  Cell.Init();

  // Initialize DGH Average charts for sec mirrors
	// Chart for F11
	if (f11Present)  {
		PresVacCharts[0].Init(
			296,
			sbty+22,
			296+13*8,
			sbty+22+47,
			YELLOW,BLACK,LIGHTGREEN,WHITE,
			0,1.5,4);
	}
	// Charts for F5
	if (f5Present) {
		// Upper
		PresVacCharts[1].Init(
			48,
			sbty+22,
			48+75,
			sbty+22+47,
			YELLOW,BLACK,LIGHTGREEN,WHITE,
			0,10.0,4);

		// Lower right
		PresVacCharts[2].Init(
			48+75+48,
			sbty+22,
			48+75+48+75,
			sbty+22+47,
			YELLOW,BLACK,LIGHTGREEN,WHITE,
			0,10.0,4);

		// Lower left
		PresVacCharts[3].Init(
			48+75+48+75+48,
			sbty+22,
			48+75+48+75+48+75,
			sbty+22+47,
			YELLOW,BLACK,LIGHTGREEN,WHITE,
			0,10.0,4);

		// Lateral
		PresVacCharts[4].Init(
			48+75+48+75+48+75+48,
			sbty+22,
			48+75+48+75+48+75+48+75,
			sbty+22+47,
			YELLOW,BLACK,LIGHTGREEN,WHITE,
			0,10.0,4);
	}

	// Display all unchanging information on the screen
	// It is done here because only after initializing the cell we know if
	// the F5 mirror is present.
	InitDisplay();

  // Initialize Pressure/Vaccum control and charts
	if (f11Present && !f5Present) {
		PresVac[0].Init(0,0);

	}
	else if (f5Present) {
		PresVac[1].Init(0,0);
		PresVac[2].Init(1,1);
		PresVac[3].Init(2,2);
		PresVac[4].Init(3,3);
	}

  // Home encoders and initialize the DMCs
  if (e = Cell.Home())
  {
    EDSLog.Add(3,"Encoder homing error %d",e);
    Log.AddX("Use HOME command to retry",3,SHECRED,BRIEF);
    // Home operation failed, so set fatal flag
    Flags.SetFatal(FFHome);
  }
  else
    EDSLog.Add(996,"Encoder homing success");

  // Reset emergency stop card
  if (e = ResetEmergency())
    EDSLog.Add(9,"Emerg stop reset error x",e);

  EDSLog.Add(995,"Main loop started");
  Log.AddX("Hit Q to quit, F1 for help",995,SHECGREEN,BRIEF);

  // Let logs update asynchronously
  Log.ForceDisplay = 0;
  InputLog.ForceDisplay = 0;

  // Clear serial buffer from host before main loop begins
  HostTimer = Timer;
  ClearSerialBuffer(0);

/////////////////////////////////////////////////////////////////////////////
// MAIN LOOP
/////////////////////////////////////////////////////////////////////////////

  do
  {
    // Keep the watchdog happy
    Watchdog();

    // Update onscreen timers (clock, et, cycle av/mx)
    UpdateTime(0);

    // Keep the cursor blinking
    UpdateCursor(kbline);

    // Check for fatal errors, read encoders/tensions, perform moves
    Cell.Update();

    // Update instrument rotators
    UpdateIRs();

    // Update pressure/vaccum control

	// For F11 just sum the three load cells reading
	if (f11Present && !f5Present) {
		PresVac[0].Update(
			Cell.DGHs[8].Reading +
			Cell.DGHs[9].Reading +
			Cell.DGHs[10].Reading, 0);
	}

	// F5
	if (f5Present) {

		// For axial actuators, just read the correspondign load cell
		// reading
		PresVac[1].Update(Cell.DGHs[11].Reading, 1);
		PresVac[2].Update(Cell.DGHs[12].Reading, 2);
		PresVac[3].Update(Cell.DGHs[13].Reading, 3);

		// For lateral actuator, DGHs 16 and 15 reads two load cells
		// meassuring simmetrical gravity components, at 30 deg angle and
		// in opposite directions of each other. DGH 14 reads a load cell
		// perpendicular to gravity, so it doesn't matter.
		PresVac[4].Update(cos(2 * PI * (30.0 / 360.0)) *
			(Cell.DGHs[16].Reading - Cell.DGHs[15].Reading), 4);

		F5PresVacDisplay();
	}

    // Keep the log displays up-to-date
    Log.Update();
    InputLog.Update();

    // EDS periodic updates
    UpdateEDS();

    // Parse all keyboard and serial commands
    Parse();

  } while (!Quit);

/////////////////////////////////////////////////////////////////////////////
// CLOSE PROGRAM
/////////////////////////////////////////////////////////////////////////////

  // Restore all interrupt vectors, and return to text mode
  CloseComPorts();
  CloseClock();
  CloseVideo();
  printf("Clock Overruns: %d\n", Overruns);
}

Generated by GNU Enscript 1.6.5.2.
Document Actions