Skip to content. | Skip to navigation

Personal tools

ini.cpp

ini.cpp

ini.cpp

/////////////////////////////////////////////////////////////////////////////
// INI.CPP
//
//  Last updated: 4/8/2004
//
//  Part of the source code for the Vane End Actuator Control System
//
//  Contains routines for reading and editing VANE.INI
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// ScanFloat: Reads a float from VANE.INI
int ScanFloat(float *data,FILE* f)
// This procedure reads a floating point value from a line in the VANE.INI
// file. Lines that begin with a ";" are ignored as a comment.
// Characters on regular lines are ignored until an "=" is found, and all
// later characters on the line are read into a float.
// Example of a valid set of lines:
//
//
//              ;Meteors are very interesting!
//              Bacteria per meteor ratio = 34.7
//
// Pass it the file being read in "f", and a pointer to the variable that
// will be set with the read value in "*data".
// Returns a 0 on success, 1 on failure
{
	char line[80];
	int i;

	do
		fgets(line,80,f);
	while (!feof(f) && (line[0] == ';'));
	i = 0;
	while ((i < strlen(line)) && (line[i] != '='))
		i++;
	if (feof(f) || (i == strlen(line))) return(1);
	if (sscanf(&line[i+1],"%f",data) != 1) return(1);
	return(0);
}

/////////////////////////////////////////////////////////////////////////////
// ScanInt: Read a long int from VANE.INI
int ScanInt(int *data,FILE* f)
// This procedure reads a long integer from a line in the VANE.INI
// file. Lines that begin with a ";" are ignored as a comment.
// Characters on regular lines are ignored until an "=" is found, and all
// later characters on the line are read into a long int.
// Example of a valid set of lines:
//
//
//              ;Always obey the speed limit.
//              Speed limit in the desert = 75
//
// Pass it the file being read in "f", and a pointer to the variable that
// will be set with the read value in "*data".
// Returns a 0 on success, 1 on failure
{
	char line[80];
	int i;

	do
		fgets(line,80,f);
	while (!feof(f) && (line[0] == ';'));
	i = 0;
	while ((i < strlen(line)) && (line[i] != '='))
		i++;
	if (feof(f) || (i == strlen(line))) return(1);
	if (sscanf(&line[i+1],"%ld",data) != 1) return(1);
	return(0);
}

/////////////////////////////////////////////////////////////////////////////
// ScanChar: Read a single character form VANE.INI
int ScanChar(char *data,FILE* f)
// This procedure reads a character from a line in the VANE.INI
// file. Lines that begin with a ";" are ignored as a comment.
// Characters on regular lines are ignored until an "=" is found, and the
// character between quotes is read.
// Example of a valid set of lines:
//
//
//              ;What grade did you get
//              Grade = "F"
//
// Pass it the file being read in "f", and a pointer to the variable that
// will be set with the read value in "*data".
// Returns a 0 on success, 1 on failure
{
	char line[80];
	int i;

	do
		fgets(line,80,f);
	while (!feof(f) && (line[0] == ';'));
	i = 0;
	while ((i < strlen(line)) && (line[i] != '='))
		i++;
	while ((i < strlen(line)) && (line[i] != '"'))
		i++;
	i++;
	if (feof(f) || (i == strlen(line))) return(1);
	*data = line[i];
	return(0);
}

/////////////////////////////////////////////////////////////////////////////
// ReadINI: Loads an INI file
int ReadINI(char filename[12])
// Reads the file filename (typically VANE.INI) to initialize global variables */
// Returns a 0 on success, 1 on failure
{
  FILE* f;
  int i,itemp;

  if ((f = fopen(filename,"r")) == NULL) return(1);
  // Read the Telescope id
  if (ScanInt(&Telescope,f)) return(2);
  // Read the serial communication address, prompt, and response characters
	if (ScanChar(&Address,f)) return(3);
	if (ScanChar(&Prompt,f)) return(4);
	if (ScanChar(&Response,f)) return(5);
	// Read the clock adjustment (in ppm)
	if (ScanInt(&ClockPPM,f))	return(6);
	// Read the DumpLogOnFatal flag
	if (ScanInt(&Flags.DumpLogOnFatal,f)) return(7);
  // Read ZS1 and ZS2
  for (i=0;i<=3;i++)
    if (ScanInt(&Cell.ZAE[i],f)) return(8);
  for (i=0;i<=3;i++)
    if (ScanInt(&Cell.ZRE[i],f)) return(9);
  // Read MinS1 and MinS2
	for (i=0;i<=3;i++)
		if (ScanInt(&Cell.MinAE[i],f)) return(10);
	for (i=0;i<=3;i++)
		if (ScanInt(&Cell.MinRE[i],f)) return(11);
	// Read MaxS1 and MaxS2
	for (i=0;i<=3;i++)
		if (ScanInt(&Cell.MaxAE[i],f)) return(12);
	for (i=0;i<=3;i++)
		if (ScanInt(&Cell.MaxRE[i],f)) return(13);
	// Read Load Cell calibration constants
	for (i=0;i<=7;i++)
	{
		if (ScanFloat(&Cell.DGHs[i].Cal0,f)) return(14);
		if (ScanFloat(&Cell.DGHs[i].Cal1,f)) return(15);
		if (ScanFloat(&Cell.DGHs[i].Cal2,f)) return(16);
	}
	// Read soft tension limits
	for (i=0;i<=7;i++)
		if (ScanFloat(&Cell.DGHs[i].MinTension,f)) return(17);
	for (i=0;i<=7;i++)
		if (ScanFloat(&Cell.DGHs[i].MaxTension,f)) return(18);

	// Read the XY positioning correction factor FixXY
	if (ScanFloat(&FixXY,f)) return(19);
	// Read the Z positioning correction factor FixZ
	if (ScanFloat(&FixZ,f)) return(20);
	if (ScanFloat(&FixH,f)) return(21);
	if (ScanFloat(&FixV,f)) return(22);
	// Read the amount to tension the vanes by
	if (ScanInt(&TensionAmount,f)) return(23);

	// Read the maximum axial and radial errors
	if (ScanInt(&AxialError,f)) return(24);
	if (ScanInt(&RadialError,f)) return(25);

	// Read the maximum allowable manual move (by IR,IA,and A commands)
	if (ScanInt(&MaxManualMove,f)) return(26);

	// Read all motion constants
	if (ScanInt(&BacklashMove,f)) return(27);
	if (ScanInt(&BacklashTime,f)) return(28);
	if (ScanInt(&BacklashTimeout,f)) return(29);
	if (ScanInt(&BacklashDelay,f)) return(30);
	if (ScanInt(&MacroMove,f)) return(31);
	if (ScanInt(&MacroTime,f)) return(32);
	if (ScanInt(&MacroTimeout,f)) return(33);
	if (ScanInt(&MacroDelay,f)) return(34);
	if (ScanInt(&MicroTime,f)) return(35);
	if (ScanInt(&MicroTimeout,f)) return(36);
	if (ScanInt(&MicroDelay,f)) return(37);
	// Read thresholds
	if (ScanInt(&BacklashThreshold,f)) return(38);
	if (ScanInt(&MacroThreshold,f)) return(39);
	if (ScanInt(&BacklashTarget,f)) return(40);
	if (ScanFloat(&MacroError,f)) return(41);

  // Instrument rotator values
  for (i=0;i<NumberIRs;i++)
  {
		if (ScanFloat(&IRs[i].P,f)) return(100+i*20);
		if (ScanFloat(&IRs[i].I,f)) return(100+i*20+1);
		if (ScanFloat(&IRs[i].D,f)) return(100+i*20+2);
		if (ScanInt(&IRs[i].Acc,f)) return(100+i*20+3);
		if (ScanInt(&IRs[i].Dec,f)) return(100+i*20+4);
		if (ScanInt(&IRs[i].Spd,f)) return(100+i*20+5);
		if (ScanInt(&IRs[i].ErrorLimit,f)) return(100+i*20+6);
		if (ScanFloat(&IRs[i].VelocProfFilter,f)) return(100+i*20+7);
		if (ScanFloat(&IRs[i].TorqueLimit,f)) return(100+i*20+8);
		if (ScanInt(&IRs[i].Revolution,f)) return(100+i*20+9);
		if (ScanInt(&IRs[i].HomeJogSpeed,f)) return(100+i*20+10);
		if (ScanInt(&IRs[i].CCWHome,f)) return(100+i*20+11);
		if (ScanInt(&IRs[i].MinHomeDistance,f)) return(100+i*20+12);
		if (ScanInt(&IRs[i].MinBackOffLimitDistance,f)) return(100+i*20+13);
		if (ScanFloat(&IRs[i].SpdP,f)) return(100+i*20+14);
		if (ScanFloat(&IRs[i].SpdI,f)) return(100+i*20+15);
		if (ScanFloat(&IRs[i].SpdD,f)) return(100+i*20+16);
		if (ScanFloat(&IRs[i].SpdIL,f)) return(100+i*20+17);
		if (ScanInt(&IRs[i].CWLimit,f)) return(100+i*20+18);
		if (ScanInt(&IRs[i].CCWLimit,f)) return(100+i*20+19);
		if (ScanFloat(&IRs[i].SLDist,f)) return(100+i*20+20);
		if (ScanInt(&itemp,f))
			 return(100+i*20+20);
		else if (itemp)
			IRs[i].Enable();
		else
			IRs[i].Disable();
	}

  // Secondary Pressure-Vacuum control parameters
	for (i = 0; i < 5; i++) {
		if (ScanFloat(&PresVac[i].Kp,f)) return(300);
		if (ScanFloat(&PresVac[i].Ki,f)) return(301);
		if (ScanFloat(&PresVac[i].Kd,f)) return(302);
		if (ScanFloat(&PresVac[i].VIl,f)) return(303);
		if (ScanFloat(&PresVac[i].PIl,f)) return(304);
		if (ScanFloat(&PresVac[i].IntegralThreshold,f)) return(305);
		if (ScanInt(&PresVac[i].VacuumMinPulseWidth,f)) return(306);
		if (ScanInt(&PresVac[i].PressureMinPulseWidth,f)) return(307);
		if (ScanFloat(&PresVac[i].PMfact,f)) return(309);
	}
	if (ScanInt(&itemp,f)) return(308);
	PulseCycle = itemp;

  // MAG2 CASS positioning shortcuts
	if (ScanFloat(&M2Cass.CPNASW,f)) return(400);
	if (ScanInt(&M2Cass.CENASW,f)) return(401);
	if (ScanFloat(&M2Cass.CPNASE,f)) return(402);
	if (ScanInt(&M2Cass.CENASE,f)) return(403);
	if (ScanFloat(&M2Cass.CPAUX1,f)) return(404);
	if (ScanInt(&M2Cass.CEAUX1,f)) return(405);
	if (ScanFloat(&M2Cass.CPAUX2,f)) return(406);
	if (ScanInt(&M2Cass.CEAUX2,f)) return(407);
	if (ScanFloat(&M2Cass.CPAUX3,f)) return(408);
	if (ScanInt(&M2Cass.CEAUX3,f)) return(409);

	// Done; close file
	if (fclose(f)) return(500);
	return(0);
}

/////////////////////////////////////////////////////////////////////////////
// UpdateEditDisplay: Update the VANE.INI editing screen
void UpdateEditDisplay(int top,int y,int VaneCount)
{
	int i;
	int max;

	if (VaneCount > top+26)
		max = top+26;
	else
		max = VaneCount;
	for (i=top;i < max;i++)
		if (i == y)
			PutString16(VaneText[i],7,632,(i-top)*16+10,SHECWHITE,BLUE);
		else
			PutString16(VaneText[i],7,632,(i-top)*16+10,BLACK,SHECMEDGRAY);
	return;
}

/////////////////////////////////////////////////////////////////////////////
// EditINILine: Edit a line in VANE.INI
void EditINILine(int y)
{
	char s[80];
	char c = 0;
	int Done = 0;

	strcpy(s,VaneText[y]);
	PutString16(s,12,632,453,BLACK,SHECMEDGRAY);
	do
	{
		Watchdog();
		// Make the cursor blink every CursorBlinkRate milliseconds
		if ((Timer - CursorTimer) > CursorBlinkRate)
		{
			if (Cursor)
			{
				PutChar16('_',strlen(s)*8+12,453,BLACK,SHECMEDGRAY);
				Cursor = 0;
			}
			else
			{
				PutChar16(' ',strlen(s)*8+12,453,BLACK,SHECMEDGRAY);
				Cursor = 1;
			}
			CursorTimer = Timer;
		}
		if (kbhit())
		{
			c = getch();
			if (c == 13)
			{
				strcpy(VaneText[y],s);
				Done = 1;
			}
			else if (c == 27)
				Done = 1;
			// Process a backspace
			else if (c == '\b')
			{
				if (strlen(s) > 0)
				{
					s[strlen(s) - 1] = 0;
					PutString16(s,12,632,453,BLACK,SHECMEDGRAY);
				}
			}
			else if ((strlen(s) < 80) && (c >= 32))
			{
				// Otherwise, add the new character to the current buffer
				s[strlen(s)+1] = 0;
				s[strlen(s)] = c;
				PutString16(s,12,632,453,BLACK,SHECMEDGRAY);
			}
		}
	}
	while (!Done);
	return;
}

/////////////////////////////////////////////////////////////////////////////
// EditVane: Edit VANE.INI on the fly
void EditVane()
{
	FILE* f;
	int VaneCount = 0;
	int x = 0;
	int y = 0;
	int top = 0;
	int i,e;
	int Done = 0;
	int UseINI = 0;
	char c = 0;
	char s[255];
	int INIDisplayLines = 26;

	if (UseEditedINI)
	{
		// User has already edited VANE.INI, so keep using the edited version
		if ((f = fopen("VANEINI.NEW","r")) == NULL) return;
	}
	else
		// Read VANE.INI into memory for editing if no editing has been done
		if ((f = fopen("VANE.INI","r")) == NULL) return;
	while (!feof(f))
	{
		fgets(VaneText[VaneCount],80,f);
		// Get rid of linefeeds
		VaneText[VaneCount][strlen(VaneText[VaneCount])-1] = 0;
		VaneCount++;
		Watchdog();
	}
	fclose(f);
	ShadowBox(0,0,639,479,SHECLIGHTGRAY,SHECDARKGRAY,SHECMEDGRAY);
	HLine(10,629,446,SHECDARKGRAY);
	HLine(10,629,447,SHECLIGHTGRAY);
	UpdateEditDisplay(top,y,VaneCount);
	do
	{
		Watchdog();
		if (kbhit())
		{
			c = toupper(getch());
			switch(c)
			{
				case 0:
				{
					c = toupper(getch());
					switch(c)
					{
						// Up arrow
						case 72:
						{
							if (y > 0)
								y--;
							if (y < top)
								top = y;
							UpdateEditDisplay(top,y,VaneCount);
						} break;
						// Down arrow
						case 80:
						{
							if (y < VaneCount - 1)
								y++;
							if (y - top >= INIDisplayLines)
								top++;
							UpdateEditDisplay(top,y,VaneCount);
						} break;
						// Page up
						case 73:
						{
							y -= INIDisplayLines;
							top -= INIDisplayLines;
							if (y < 0)
							{
								y = 0;
								top = 0;
							}
							if (top < 0)
								top = 0;
							UpdateEditDisplay(top,y,VaneCount);
						} break;
						// Page down
						case 81:
						{
							y += INIDisplayLines;
							top += INIDisplayLines;
							if (y >= VaneCount - 1)
							{
								y = VaneCount - 1;
								top = y - INIDisplayLines + 1;
								if (top < 0)
									top = 0;
							}
							if (top > VaneCount - INIDisplayLines)
								top = VaneCount - INIDisplayLines;
							UpdateEditDisplay(top,y,VaneCount);
						} break;
						// Home
						case 71:
						{
							y = 0;
							top = 0;
							UpdateEditDisplay(top,y,VaneCount);
						} break;
						// End
						case 79:
						{
							y = VaneCount - 1;
							top = y - INIDisplayLines + 1;
							if (top < 0)
								top = 0;
							UpdateEditDisplay(top,y,VaneCount);
						} break;
					}
				} break;
				case 13:
				{
					EditINILine(y);
					PutString16("",12,632,453,BLACK,SHECMEDGRAY);
					UpdateEditDisplay(top,y,VaneCount);
				} break;
				case 27:
				{
					Done = 1;
				} break;
				case 'S':
				{
					Done = 1;
					// Write the edited VANE.INI to VANEINI.NEW
					f = fopen("VANEINI.NEW","w");
					for (i = 0;i < VaneCount;i++)
					fprintf(f,"%s\n",VaneText[i]);
					fclose(f);
					UseINI = 1;
				} break;
			}
		}
	}
	while (!Done);
	// Restore screen
	InitDisplay();
	Cell.DisplayAll();
	if (UseINI)
	{
		Log.AddX("Edited VANE.INI written to VANEINI.NEW",997,SHECGREEN,BRIEF);
		Log.AddX("To use permanently, copy VANEINI.NEW to VANE.INI",997,SHECGREEN,BRIEF);
		if (ReadINI("VANEINI.NEW"))
		{
			Log.AddX("Error reading VANENEW.INI, reading in old VANE.INI",2,SHECRED,BRIEF);
			if (e = ReadINI("VANE.INI"))
			{
				Log.AddX("VANE.INI Read error %d",2,SHECRED,BRIEF,e);
				Flags.SetFatal(FFINIFile);
			}
		}
		else
		{
			Log.AddX("Edited VANE.INI in use",997,SHECGREEN,BRIEF);
			UseEditedINI = 1;
		}
	}
	return;
}

/////////////////////////////////////////////////////////////////////////////
// WriteZero: Write current encoders as zero point to VANE.INI
void WriteZero()
{
	FILE* f;
	int VaneCount = 0;
	int i,line,index,corner,e;
	char s[255];

	if (UseEditedINI)
	{
		// User has already edited VANE.INI, so keep using the edited version
		if ((f = fopen("VANEINI.NEW","r")) == NULL) return;
	}
	else
		// Read VANE.INI into memory for editing if no editing has been done
		if ((f = fopen("VANE.INI","r")) == NULL) return;
	while (!feof(f))
	{
		fgets(VaneText[VaneCount],80,f);
		// Get rid of linefeeds
		VaneText[VaneCount][strlen(VaneText[VaneCount])-1] = 0;
		VaneCount++;
		Watchdog();
	}
	fclose(f);

	// Find the lines that need to be edited
	line = 0;
	while (VaneText[line][0] == ';') line++;
	line++;
	while (VaneText[line][0] == ';') line++;
	line++;
	while (VaneText[line][0] == ';') line++;
	line++;
	while (VaneText[line][0] == ';') line++;

	// Now write the new zero point to these lines
	// Write zeroed axial encoders
	for (corner=0;corner <= 3;corner++)
	{
		index = 0;
		while (VaneText[line][index] != '=')
		{
			s[index] = VaneText[line][index];
			index++;
		}
		sprintf(&s[index],"= %d",Cell.AE[corner]);
		strcpy(VaneText[line],s);
		line++;
		while (VaneText[line][0] == ';') line++;
	}
	// Write zeroed radial encoders
	for (corner=0;corner <= 3;corner++)
	{
		index = 0;
		while (VaneText[line][index] != '=')
		{
			s[index] = VaneText[line][index];
			index++;
		}
		sprintf(&s[index],"= %d",Cell.RE[corner] - TensionAmount*1.678);
		strcpy(VaneText[line],s);
		line++;
		while (VaneText[line][0] == ';') line++;
	}

	// Write the edited VANE.INI to VANEINI.NEW
	f = fopen("VANEINI.NEW","w");
	for (i = 0;i < VaneCount;i++)
	fprintf(f,"%s\n",VaneText[i]);
	fclose(f);

	// Restore screen
	InitDisplay();
	Cell.DisplayAll();

	// Inform user that the updated file is now in use
	Log.AddX("Edited VANE.INI written to VANEINI.NEW",997,SHECGREEN,BRIEF);
	Log.AddX("To use permanently, copy VANEINI.NEW to VANE.INI",997,SHECGREEN,BRIEF);
	if (ReadINI("VANEINI.NEW"))
	{
		Log.AddX("Error reading VANENEW.INI, reading in old VANE.INI",2,SHECRED,BRIEF);
		if (e = ReadINI("VANE.INI"))
		{
			Log.AddX("VANE.INI Read error %d",2,SHECRED,BRIEF,e);
			Flags.SetFatal(FFINIFile);
		}
	}
	else
	{
		Log.AddX("Edited VANE.INI in use",997,SHECGREEN,BRIEF);
		UseEditedINI = 1;
	}
	return;
}

/////////////////////////////////////////////////////////////////////////////
// WriteTension: Write a new tension value to VANE.INI
void WriteTension(int Dist)
{
	FILE* f;
	int VaneCount = 0;
	int i,line,index,e;
	char s[255];

	if (UseEditedINI)
	{
		// User has already edited VANE.INI, so keep using the edited version
		if ((f = fopen("VANEINI.NEW","r")) == NULL) return;
	}
	else
		// Read VANE.INI into memory for editing if no editing has been done
		if ((f = fopen("VANE.INI","r")) == NULL) return;
	while (!feof(f))
	{
		fgets(VaneText[VaneCount],80,f);
		// Get rid of linefeeds
		VaneText[VaneCount][strlen(VaneText[VaneCount])-1] = 0;
		VaneCount++;
		Watchdog();
	}
	fclose(f);

	// Find the line that needs to be edited (TensionAmount = )
	line = 0;
	for (i=0;i<=72;i++)
	{
		while (VaneText[line][0] == ';') line++;
		line++;
	}
	while (VaneText[line][0] == ';') line++;

	// Now write the new tension amount to this line
	index = 0;
	while (VaneText[line][index] != '=')
	{
		s[index] = VaneText[line][index];
		index++;
	}
	sprintf(&s[index],"= %d",Dist);
	strcpy(VaneText[line],s);

	// Write the edited VANE.INI to VANEINI.NEW
	f = fopen("VANEINI.NEW","w");
	for (i = 0;i < VaneCount;i++)
	fprintf(f,"%s\n",VaneText[i]);
	fclose(f);

	// Restore screen
	InitDisplay();
	Cell.DisplayAll();

	// Inform user that the updated file is now in use
	Log.AddX("Edited VANE.INI written to VANEINI.NEW",997,SHECGREEN,BRIEF);
	Log.AddX("To use permanently, copy VANEINI.NEW to VANE.INI",997,SHECGREEN,BRIEF);
	if (ReadINI("VANEINI.NEW"))
	{
		Log.AddX("Error reading VANENEW.INI, reading in old VANE.INI",2,SHECRED,BRIEF);
		if (e = ReadINI("VANE.INI"))
		{
			Log.AddX("VANE.INI Read error %d",2,SHECRED,BRIEF,e);
			Flags.SetFatal(FFINIFile);
		}
	}
	else
	{
		Log.AddX("Edited VANE.INI in use",997,SHECGREEN,BRIEF);
		UseEditedINI = 1;
	}
	return;
}

Generated by GNU Enscript 1.6.5.2.
Document Actions