Skip to content. | Skip to navigation

Personal tools

presvac.cpp

presvac.cpp

presvac.cpp

/////////////////////////////////////////////////////////////////////////////
// PRESVAC.CPP
//
//  Last updated: 03/26/2002
//
//  Part of the source code for the Vane End Actuator Control System
//
//  Contains code for the control of the pressure/vacuum support
//	behind the secondary mirror (M2)
/////////////////////////////////////////////////////////////////////////////

// Secondary Mirror Vacuum Test
// Kp 3 Ki 0.5 Kd 1.5 Il 0.1
// 0.3 to -0.3 in 36 seconds -> Leakage = 0.003 (200 ms cycle)
// -0.3 to 0.3 in 14 seconds -> Vacuum Gain = 0.008 (200 ms cycle)
// 0.3 to -0.3 in 17 seconds -> Pressure Gain = 0.007 (200 ms cycle)
// Valve minimum open times
// Vacuum: 11-12 ms
// Pressure: 20-25 ms

///////////////////////////////////////////////////////////////
// PresVacClockInterrupt(): Called on each clock interrupt for pres/vac control
void PresVacClockInterrupt()
// Opens and closes pressure/vacuum valves with millisecond precision
// according to the pulse widths given by the controls variables
// VacuumPulseWidth and PressurePulseWidth.
{
	// User code shoud go here
	static int vwidth[5],pwidth[5];	// Used to store a snapshot of the control variables

	static char PortOut;
	static int i;
	static int pv;
	static int vv;
	if (f11Present & !f5Present) {
		if ((Timer - PulseTime) >= PulseCycle)
		{
			vwidth[0] = PresVac[0].VacuumPulseWidth;
			pwidth[0] = PresVac[0].PressurePulseWidth;
			PulseTime = Timer;
			PresVac[0].vaccom = 0;
			PresVac[0].precom = 0;
			if (vwidth[0] > 0)
			PresVac[0].vaccom = 1;
			if (pwidth[0] > 0)
			PresVac[0].precom = 1;
		}
		if (((Timer - PulseTime) >= vwidth[0]) && (vwidth[0] < PulseCycle))
		PresVac[0].vaccom = 0;		// Turn vacuum off
		if (((Timer - PulseTime) >= pwidth[0]) && (pwidth[0] < PulseCycle))
		PresVac[0].precom = 0;		// Turn air off
	}

	if (f5Present) {
		if (PresVacMode == PVMIdle) return;
		// Open valves
		if ((Timer - PulseTime) >= PulseCycle) {
			PulseTime = Timer;
			PortOut = parport.value;

			for (i = 1; i <= 4; i++) {
				vwidth[i] = PresVac[i].VacuumPulseWidth;
				pwidth[i] = PresVac[i].PressurePulseWidth;
				pv = PresVac[i].presValve;
				vv = PresVac[i].vacValve;
				if ((vwidth[i] > 0) && (PresVac[i].vaccom == 0)) {
					//Open vacuum valve
					PortOut &= ((1 << (vv * 2)) & ValvesToAct) ^ 0xFF;
					PresVac[i].vaccom = ((PortOut ^ 0xFF) & (1 << (vv * 2))) ? 1 : 0;
				}
				if ((pwidth[i] > 0) && (PresVac[i].precom == 0)) {
					// Open pressure valve
					PortOut &= ((2 << (pv * 2)) & ValvesToAct) ^ 0xFF;
					PresVac[i].precom = ((PortOut ^ 0xFF) & (2 << (pv * 2))) ? 1 : 0;
				}
			}

			ParPortOut(&parport, PortOut);
		}

		// Close valves
		for (i = 1; i <= 4; i++) {
			pv = PresVac[i].presValve;
			vv = PresVac[i].vacValve;
			if (((Timer - PulseTime) >= vwidth[i]) && (vwidth[i] < PulseCycle)) {
				// Close vacuum valve
				ParPortOut(&parport,parport.value | (1 << (vv * 2)));
				PresVac[i].vaccom = 0;
			}
			if (((Timer - PulseTime) >= pwidth[i]) && (pwidth[i] < PulseCycle)) {
				// Close pressure valve
				ParPortOut(&parport,parport.value | ((1 << (pv * 2 + 1))));
				PresVac[i].precom = 0;
			}
		}
	}
}

///////////////////////////////////////////////////////////////
// CPresVac::Init - Initialize pressure/vacuum control
void CPresVac::Init(int pv, int vv)
{
/* These variables are initialized from VANE.INI
	PulseCycle = 200;
  IntegralThreshold = 0.05;
	PressureMinPulseWidth = 21;
  VacuumMinPulseWidth = 12;
  VIl = 0.1;
  PIl = 0.03;
  Kp = 2.5;
  Ki = 0.3;
  Kd = 0.5;
*/
	PulseUpdateTime = Timer;
	wgt = 0.0;
  wgtlbs = 0.0;
	olderr = 0.0;
	target = 0.0;
	P = 0.0;
	I = 0.0;
	D = 0.0;
	UserClockInterrupt = &PresVacClockInterrupt;
  PresVacStep = 0;
  vaccom = 0;
  precom = 0;
	PressurePulseWidth = 0;
	VacuumPulseWidth = 0;
	OrigMinPresPulse = PressureMinPulseWidth;
	OrigMinVacPulse = VacuumMinPulseWidth;
	atLimit = 0;
	presValve = pv;
	vacValve = vv;
	disabled = 0;

	// 3 DGH (i,j,k) modules were initialized in Cell with all the other 8.
}

///////////////////////////////////////////////////////////////
// CPresVacComm(): Executes pres/vac control sending the command to rad DMC
int CPresVac::PresVacComm()
// This routine gets called in Cell.Update() to keep the order in which the
// DMC Galil cards are polled.
{
	char line[80];	/*buffer*/
  int e;

  if (PresVacMode == PVMAuto)
  {
	  if (PresVacStep == 0)
		{
		  if (vaccom)
	    {
		    // Turn vacuum on
        e = DMCCommand(Radial,"SB4\r",line,DMCFastCommand);
        vflag = 1;
        if (e == -1) return(-1);
	      PresVacStep = 1;
      	return(0);
	    }
      else
			{
		    // Turn vacuum off
			  e = DMCCommand(Radial,"CB4\r",line,DMCFastCommand);
        vflag = 0;
        if (e == -1) return(-1);
	      PresVacStep = 1;
      	return(0);
      }
    }
    else if (PresVacStep == 1)
	  {
		  if (precom)
      {
		    // Turn air on
			  e = DMCCommand(Radial,"SB3\r",line,DMCFastCommand);
        pflag = 1;
        if (e == -1) return(-1);
	      PresVacStep = 0;
      	return(0);
    	}
		  else
	    {
		    // Turn air off
				e = DMCCommand(Radial,"CB3\r",line,DMCFastCommand);
        pflag = 0;
        if (e == -1) return(-1);
	      PresVacStep = 0;
      	return(0);
      }
    }
	}
 	return(0);
}

///////////////////////////////////////////////////////////////
// CPresVac::Update - Update pressure/vacuum control variables
void CPresVac::Update(float weight, int chart)
{
	char s[255];
  int e;

	if ((Timer - PulseUpdateTime) > PulseCycle)
	{
		PulseUpdateTime = Timer;
		wgt = weight;
		wgtlbs = wgt * PMfact;
		err = target - wgt;

		PresVacCharts[chart].Add(wgt);

		// Calc derivative term
		D = Kd * (err - olderr);
		olderr = err;

		// Calc proportional term
		P = Kp * err;

		// Calc integral term
		I = I + Ki * err;

		if (fabs(err) > IntegralThreshold)
			I = 0.0;

		// Limit I to within +/- VIl/PIl
		if (I > VIl)
			I = VIl;
		if (I < -PIl)
			I = -PIl;

		// Calculate pulse width
		if (PresVacMode == PVMAuto)
		{
		  disable();
		  if ((P + I + D) > 0.0)
		  {
			  VacuumPulseWidth = PulseCycle * (P + I + D) + VacuumMinPulseWidth;

			if (VacuumPulseWidth >= 200 && atLimit == 0) {
				atLimit = 1;
				PressureMinPulseWidth = 0;
			}
			else if (atLimit == 1 && VacuumPulseWidth <= 100) {
				atLimit= 0;
				PressureMinPulseWidth = OrigMinPresPulse;
			}

			  PressurePulseWidth = PressureMinPulseWidth;
		  }
		  else if ((P + I + D) < 0.0)
		  {
			  PressurePulseWidth = -PulseCycle * (P + I + D) + PressureMinPulseWidth;
			  VacuumPulseWidth = VacuumMinPulseWidth;
		  }
		  else
		  {
			  VacuumPulseWidth = VacuumMinPulseWidth;
			  PressurePulseWidth = PressureMinPulseWidth;
		  }

		  // Limit pulse width to 0..PulseCycle
		  if (VacuumPulseWidth > PulseCycle) VacuumPulseWidth = PulseCycle;
		  if (PressurePulseWidth > PulseCycle) PressurePulseWidth = PulseCycle;
		  enable();
    }

		// Force pulse width
		if (PresVacMode == PVMBurnin)
		{
			disable();
			VacuumPulseWidth = VacuumMinPulseWidth;
			PressurePulseWidth = PressureMinPulseWidth;
			enable();
		}
		Display();
	}
}

/////////////////////////////////////////////////////////////////////////////
// CPresVac::Display - Display changed information
void CPresVac::Display()
{
  char s[80];	// buffer

  // Update screen
	// Display PID control variables
	if (f11Present && !f5Present) {
		sprintf(s,"%7.3f",P);
		PutString16(s,436,436+7*8,sbty+8+16,BLACK,SHECMEDGRAY);
		sprintf(s,"%7.3f",I);
		PutString16(s,436,436+7*8,sbty+8+32,BLACK,SHECMEDGRAY);
		sprintf(s,"%7.3f",D);
		PutString16(s,436,436+7*8,sbty+8+48,BLACK,SHECMEDGRAY);

	  // Display weight in pounds
		sprintf(s,"%7.3f",wgtlbs);
		PutString16(s,52,52+7*8,sbty+8+48,BLACK,SHECMEDGRAY);

		// Display Pulse widhts
		sprintf(s,"%4d",PressurePulseWidth);	//msec
		PutString16(s,108,108+4*8,sbty+8+16,BLACK,SHECMEDGRAY);
		sprintf(s,"%4d",VacuumPulseWidth);		//msec
		PutString16(s,108,108+4*8,sbty+8+32,BLACK,SHECMEDGRAY);

		// Display pressure/vacuum valve status
		if (vflag)			// Vacuum
			PutChar16('þ',92,sbty+8+32,SHECGREEN,SHECMEDGRAY);
		else
			PutChar16('þ',92,sbty+8+32,BLACK,SHECMEDGRAY);
		if (pflag)			// Pressure
			PutChar16('þ',92,sbty+8+16,SHECGREEN,SHECMEDGRAY);
		else
			PutChar16('þ',92,sbty+8+16,BLACK,SHECMEDGRAY);

		//sprintf(s,"           VIl: %10.4f",VIl);
		//PutString16(s,330,630,300,BLACK,SHECMEDGRAY);
		//sprintf(s,"           PIl: %10.4f",PIl);
		//PutString16(s,330,630,316,BLACK,SHECMEDGRAY);
		//sprintf(s," Int Threshold: %10.4f",IntegralThreshold);
		//PutString16(s,330,630,332,BLACK,SHECMEDGRAY);
		//sprintf(s," Vac Min Pulse: %10d ms",VacuumMinPulseWidth);
		//PutString16(s,330,630,348,BLACK,SHECMEDGRAY);
		//sprintf(s,"Pres Min Pulse: %10d ms",PressureMinPulseWidth);
		//PutString16(s,330,630,364,BLACK,SHECMEDGRAY);
		//sprintf(s,"   Pulse Cycle: %10d ms",PulseCycle);
		//PutString16(s,330,630,380,BLACK,SHECMEDGRAY);

		// Display PID control variables
		//sprintf(s,"%7.3f",Kp);
		//PutString16(s,12+3*8,36+7*8,sbty+8+16,BLACK,SHECMEDGRAY);
		//sprintf(s,"%7.3f",Ki);
		//PutString16(s,12+3*8,36+7*8,sbty+8+32,BLACK,SHECMEDGRAY);
		//sprintf(s,"%7.3f",Kd);
		//PutString16(s,12+3*8,36+7*8,sbty+8+48,BLACK,SHECMEDGRAY);
	}

	// Display Mode
	if (PresVacMode == PVMAuto)
    sprintf(s,"AUTO");
	else if (PresVacMode == PVMBurnin)
    sprintf(s,"BURN");
	else
		sprintf(s,"IDLE");
	PutString16(s,252,252+4*8,sbty+6,BLACK,SHECMEDGRAY);
}

void F5PresVacDisplay()
{
	char s[80];
	int x,y;

	// Axial north
	x = 8;
	// Label
	y = sbty + 6;
	PutString16("AxN",x+48+21,x+48+21+8*3,y,BLACK,SHECMEDGRAY);
	// Error
	y = sbty + 22 + 16;
	sprintf(s,"%05.2f",Cell.DGHs[11].Reading);
	PutString16(s,x,x+5*8,y,BLACK,SHECMEDGRAY);
	// Pres valve status
	y = sbty + 22;
	if (PresVac[1].precom) PutChar16('þ', x, y, SHECGREEN, SHECMEDGRAY);
	else PutChar16('þ', x, y, BLACK, SHECMEDGRAY);
	// Pres pulse width
	sprintf(s,"%4d",PresVac[1].PressurePulseWidth);
	PutString16(s, x+8, x+8+4*8, y, BLACK, SHECMEDGRAY);
	// Vac valve status
	y = sbty + 22 + 32;
	if (PresVac[1].vaccom) PutChar16('þ', x, y, SHECGREEN, SHECMEDGRAY);
	else PutChar16('þ', x, y, BLACK, SHECMEDGRAY);
	// Vac pulse width
	sprintf(s,"%4d",PresVac[1].VacuumPulseWidth);
	PutString16(s, x+8, x+8+4*8, y, BLACK, SHECMEDGRAY);

	// Axial SE
	x = 48 + 75 + 8;
	// Label
	y = sbty + 6;
	PutString16("AxSE",x+48+21,x+48+21+8*4,y,BLACK,SHECMEDGRAY);
	// Error
	y = sbty + 22 + 16;
	sprintf(s,"%05.2f",Cell.DGHs[12].Reading);
	PutString16(s,x,x+5*8,y,BLACK,SHECMEDGRAY);
	// Pres valve status
	y = sbty + 22;
	if (PresVac[2].precom) PutChar16('þ', x, y, SHECGREEN, SHECMEDGRAY);
	else PutChar16('þ', x, y, BLACK, SHECMEDGRAY);
	// Pres pulse width
	sprintf(s,"%4d",PresVac[2].PressurePulseWidth);
	PutString16(s, x+8, x+8+4*8, y, BLACK, SHECMEDGRAY);
	// Vac valve status
	y = sbty + 22 + 32;
	if (PresVac[2].vaccom) PutChar16('þ', x, y, SHECGREEN, SHECMEDGRAY);
	else PutChar16('þ', x, y, BLACK, SHECMEDGRAY);
	// Vac pulse width
	sprintf(s,"%4d",PresVac[2].VacuumPulseWidth);
	PutString16(s, x+8, x+8+4*8, y, BLACK, SHECMEDGRAY);

	// Axial SW
	x = 48 + 75 + 48 + 75 + 8;
	// Label
	y = sbty + 6;
	PutString16("AxSW",x+48+21,x+48+21+8*4,y,BLACK,SHECMEDGRAY);
	// Error
	y = sbty + 22 + 16;
	sprintf(s,"%05.2f",Cell.DGHs[13].Reading);
	PutString16(s,x,x+5*8,y,BLACK,SHECMEDGRAY);
	// Pres valve status
	y = sbty + 22;
	if (PresVac[3].precom) PutChar16('þ', x, y, SHECGREEN, SHECMEDGRAY);
	else PutChar16('þ', x, y, BLACK, SHECMEDGRAY);
	// Pres pulse width
	sprintf(s,"%4d",PresVac[3].PressurePulseWidth);
	PutString16(s, x+8, x+8+4*8, y, BLACK, SHECMEDGRAY);
	// Vac valve status
	y = sbty + 22 + 32;
	if (PresVac[3].vaccom) PutChar16('þ', x, y, SHECGREEN, SHECMEDGRAY);
	else PutChar16('þ', x, y, BLACK, SHECMEDGRAY);
	// Vac pulse width
	sprintf(s,"%4d",PresVac[3].VacuumPulseWidth);
	PutString16(s, x+8, x+8+4*8, y, BLACK, SHECMEDGRAY);

	// Lateral
	x = 48 + 75 + 48 + 75 + 48 + 75 + 8;
	// Label
	y = sbty + 6;
	PutString16("Lat",x+48+21,x+48+21+8*3,y,BLACK,SHECMEDGRAY);
	// Error
	y = sbty + 22 + 16;
	sprintf(s,"%05.2f",cos(2 * PI * (30.0 / 360.0)) *
		(Cell.DGHs[16].Reading - Cell.DGHs[15].Reading), 4);
	PutString16(s,x,x+5*8,y,BLACK,SHECMEDGRAY);
	// Pres valve status
	y = sbty + 22;
	if (PresVac[4].precom) PutChar16('þ', x, y, SHECGREEN, SHECMEDGRAY);
	else PutChar16('þ', x, y, BLACK, SHECMEDGRAY);
	// Pres pulse width
	sprintf(s,"%4d",PresVac[4].PressurePulseWidth);
	PutString16(s, x+8, x+8+4*8, y, BLACK, SHECMEDGRAY);
	// Vac valve status
	y = sbty + 22 + 32;
	if (PresVac[4].vaccom) PutChar16('þ', x, y, SHECGREEN, SHECMEDGRAY);
	else PutChar16('þ', x, y, BLACK, SHECMEDGRAY);
	// Vac pulse width
	sprintf(s,"%4d",PresVac[4].VacuumPulseWidth);
	PutString16(s, x+8, x+8+4*8, y, BLACK, SHECMEDGRAY);
}

Generated by GNU Enscript 1.6.5.2.
Document Actions