Skip to content. | Skip to navigation

Personal tools

lcu/parse.cpp

lcu/parse.cpp

lcu/parse.cpp

/////////////////////////////////////////////////////////////////////////////
// PARSE.CPP
//
//  Last updated: 3/15/2005
//
//  Part of the source code for the Remote M3 Program
//
// This file contains the functions that parse serial and keyboard input,
// and execute the appropriate functions to carry out the commands.
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// ParseKB: Parse a keyboard command line
int ParseKB(char *line,char *errmsg)
// This routine parses a keyboard command-line, and executes the
// appropriate code to accomplish the command.
// Returns a 0 if OK, >= 1 on a parse error
// errmsg is filled with an error message to send to upstream computers.
{
  int CmdError = 0;

  // Temporary parsing variables
  float ftemp,ftemp2,ftemp3;
  int itemp;
  char Cmds[10][30];  // Tokenized command line
  int CmdCount = 0;   // Number of command tokens

  EDSLog.Add(830,"ParseKB(%d): Parsing \"%s\"",__LINE__,line);

  // Blank input line
  if (strlen(line) == 0)
    return(0);

  // Break the line up into command tokens
  strncpy(Cmds[0],strtok(line," "),29);

  do {
    CmdCount++;
    strncpy(Cmds[CmdCount],strtok(NULL," "),29);
  } while ( (strcmp(Cmds[CmdCount],NULL)) && (CmdCount < 9) );

  // Identify the command and execute

  // Quit
  if ((!strcmp(Cmds[0],"Q") || !strcmp(Cmds[0],"EXIT")) && (CmdCount == 1))
    Quit = 1;
  // Toggle stepper power (Tilts)
  else if (!strcmp(Cmds[0],"SP") && (CmdCount == 1))
  {
    if (StepperPowerFlag)
      StepperPowerOffNow();
    else
      StepperPowerOn();
  }
  // Toggle tilt brakes
  else if (!strcmp(Cmds[0],"TBRK") && (CmdCount == 1))
  {
    if (GetDigBit(5))
      ClrDigBit(5);
    else
      SetDigBit(5);
  }
  /*
    // Terminal on COM1: (Host)
    else if (!strcmp(Cmds[0],"T1") && (CmdCount == 1) && !SerialCommand)
      COMTerminal(0);
    // Terminal on COM2: (DGHs)
    else if (!strcmp(Cmds[0],"T2") && (CmdCount == 1) && !SerialCommand)
      COMTerminal(1);
    // Terminal on COM2: at 300 baud (DGH Setup)
    else if (!strcmp(Cmds[0],"T3") && (CmdCount == 1) && !SerialCommand)
    {
      SetComPortSpeed(1,300);
      COMTerminal(1);
      RestoreComPortSpeed(1);
    }
  */
  // Tilt A Commands
  else if (!strcmp(Cmds[0],"TA") && (CmdCount == 2))
  {
    // Move tilt A
    if (sscanf(Cmds[1],"%d",&itemp) == 1)
    {
      EDSLog.Add(930,"Move in progress");
      Tilt.MoveSteps(-itemp,0,0);
    }
    else
      CmdError = 1;
  }
  // Tilt B Commands
  else if (!strcmp(Cmds[0],"TB") && (CmdCount == 2))
  {
    // Move tilt B
    if (sscanf(Cmds[1],"%d",&itemp) == 1)
    {
      EDSLog.Add(930,"Move in progress");
      Tilt.MoveSteps(-itemp,1,0);
    }
    else
      CmdError = 1;
  }
  // Tilt C Commands
  else if (!strcmp(Cmds[0],"TC") && (CmdCount == 2))
  {
    // Move tilt C
    if (sscanf(Cmds[1],"%d",&itemp) == 1)
    {
      EDSLog.Add(930,"Move in progress");
      Tilt.MoveSteps(-itemp,2,0);
    }
    else
      CmdError = 1;
  }
  // Compound Tilt Commands
  // PISTON type
  else if (!strcmp(Cmds[0],"PISTON") && (CmdCount == 2))
  {
    // Move tilt A-B-C = millimeters
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
    {
      if (fabs(ftemp) > 1.0)
        EDSLog.Add(31,"Piston move aborted, max 1 mm allowed");
      else
      {
        EDSLog.Add(931,"Move in progress");
        itemp = round(Tilt.Kstepmm * ftemp);
        Tilt.MoveSteps(-itemp,0,0);  // Move actuator A
        Tilt.MoveSteps(-itemp,1,0);  // Move actuator B
        Tilt.MoveSteps(-itemp,2,0);  // Move actuator C
      }
    }
    else
      CmdError = 1;
  }
  // Tilt around a horizontal line crossing the middle of M3
  else if (!strcmp(Cmds[0],"TH") && (CmdCount == 2))
  {
    //Tilt A=arcsec & B-C=-arcsec
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
    {
      EDSLog.Add(932,"Move in progress");
      itemp = round(Tilt.Kstepmm * ftemp * Tilt.KKA / (3437.75*60));
      Tilt.MoveSteps(-itemp,0,0);  // Move actuator A
      itemp = -round(Tilt.Kstepmm * ftemp * Tilt.KKB / (3437.75*60));
      Tilt.MoveSteps(-itemp,1,0);  // Move actuator B
      itemp = -round(Tilt.Kstepmm * ftemp * Tilt.KKC / (3437.75*60));
      Tilt.MoveSteps(-itemp,2,0);  // Move actuator C
    }
    else
      CmdError = 1;
  }
  // Tilt around a vertical line crossing the middle of M3
  else if (!strcmp(Cmds[0],"TV") && (CmdCount == 2))
  {
    //Tilt B=arcsec & C=-arcsec
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
    {
      EDSLog.Add(933,"Move in progress");
      itemp = round(Tilt.Kstepmm * ftemp * Tilt.KKB / (3437.75*60));
      Tilt.MoveSteps(-itemp,1,0);  // Move actuator B
      itemp = -round(Tilt.Kstepmm * ftemp * Tilt.KKC / (3437.75*60));
      Tilt.MoveSteps(-itemp,2,0); // Move actuator C
    }
    else
      CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"TAS") && (CmdCount == 2))
  {
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
    {
      EDSLog.Add(934,"Move in progress");
      Tilt.Servo(0,ftemp);
    }
    else
      CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"TBS") && (CmdCount == 2))
  {
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
    {
      EDSLog.Add(935,"Move in progress");
      Tilt.Servo(1,ftemp);
    }
    else
      CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"TCS") && (CmdCount == 2))
  {
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
    {
      EDSLog.Add(936,"Move in progress");
      Tilt.Servo(2,ftemp);
    }
    else
      CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"TILTS") && (CmdCount == 4))
  {
    if ((sscanf(Cmds[1],"%f",&ftemp) == 1) &&
        (sscanf(Cmds[2],"%f",&ftemp2) == 1) &&
        (sscanf(Cmds[3],"%f",&ftemp3) == 1))
    {
      EDSLog.Add(937,"Move in progress");
      Tilt.ServoAll(ftemp,ftemp2,ftemp3);
    }
    else
      CmdError = 1;
  }

  // Pressure/vacuum control commands
  // Toggle pressure
  else if (!strcmp(Cmds[0],"PRES") && (CmdCount == 1))
    if (GetDigBit(19))
      ClrDigBit(19);
    else
      SetDigBit(19);
  // Toggle vacuum
  else if (!strcmp(Cmds[0],"VAC") && (CmdCount == 1))
    if (GetDigBit(20))
      ClrDigBit(20);
    else
      SetDigBit(20);
  // Toggle pressure/vacuum control mode
  else if (!strcmp(Cmds[0],"PVM") && (CmdCount == 1))
  {
    if (PresVacMode == PVMAuto)
    {
      PresVacMode = PVMOff;
      ClrDigBit(20); // Turn off vacuum
      ClrDigBit(19); // Turn off pressure
    }
    else
      PresVacMode = PVMAuto;
  }
  else if (!strcmp(Cmds[0],"KP") && (CmdCount == 2))
  {
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      PresVac.Kp = ftemp;
    else
      CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"KI") && (CmdCount == 2))
  {
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      PresVac.Ki = ftemp;
    else
      CmdError = 1;
  }
  else if (!strcmp(Cmds[0],"KD") && (CmdCount == 2))
  {
    if (sscanf(Cmds[1],"%f",&ftemp) == 1)
      PresVac.Kd = ftemp;
    else
      CmdError = 1;
  }

  else
    CmdError = 1;

  if (CmdError == 1)
    strcpy(errmsg,"Command decode error");
  // Send error message if necessary
  if (CmdError >= 1)
    EDSLog.Add(34,"%s",errmsg);
  return(CmdError);
}

/////////////////////////////////////////////////////////////////////////////
// ParseSer: Parse a serial command line
void ParseSer(char line[80])
// This routine parses a command line from the serial port, and executes the
// appropriate code to accomplish the command.
{
  int i,e;
  char s[255];
  char temp[80];
  struct dostime_t t;

  //EDSLog.Add(831,"ParseSer(%d): Parsing \"%s\"",__LINE__,line);

  // Is message for us?
  if ((line[0] == Prompt) && (line[1] == Address))
  {
    switch (line[2])
    {
      // Send next EDS message
      case '2':
        EDSLog.SendNextMessage();break;
      // Repeat last EDS message
      case '3':
        EDSLog.RepeatLastMessage();break;
      // Set UT
      case '4':
      {
        if (VerifyChecksum(line) ||
                        (sscanf(&line[3],"%2d%2d%2d%2d",&t.hour,&t.minute,&t.second,
                         &t.hsecond) != 4))
        {
          RespondToHost("40\r");
          EDSLog.Add(35,"Incorrectly formatted UT message from TCS");
        }
        else
        {
          EDSLog.Add(935,"UT set by TCS to %02d %02d %02d.%02d",
                         t.hour,t.minute,t.second,t.hsecond);
          settime(&t);
          RespondToHost("41\r");
        }
      } break;
      // Free-form command
      case '9':
      {
        if (VerifyChecksum(line) ||
            (line[3] < '0') || (line[3] > '9') ||
            (line[4] < '0') || (line[4] > '9'))
          RespondToHost("?\r");
        else
        {
          i = (line[3] - '0') * 10 + line[4] - '0';
          if (strlen(line) != i + 7)
            RespondToHost("?\r");
          else
          {
            strncpy(s,&line[5],i);
            s[i] = 0;
            if (e = ParseKB(s,temp))
            {
              sprintf(s,"9%d%02d%s",e,strlen(temp),temp);
              RespondToHostWithChecksum(s);
            }
            else
              RespondToHostWithChecksum("9000");
          }
        }
      } break;
      default:
        RespondToHost("?\r");
    }
  }
}

/////////////////////////////////////////////////////////////////////////////
// Parse: Checks for keyboard and serial input
void Parse()
{
  int c;

  // Check for a command from the serial port
  if (SerialBufCharReady(Host))
  {
    c = toupper(SerialBufGetChar(Host));
    // On a carriage return, parse the serial command line
    if (c == 13)
    {
      ParseSer(serline);
      serline[0] = 0;
      ClearSerialBuffer(Host);
    }
    // On receiving our prompt character, flush the serial receive line
    else if (c == Prompt)
    {
      serline[0] = Prompt;
      serline[1] = 0;
    }
    // Otherwise, add the character to the buffer
    else if (strlen(serline) < 79)
    {
      serline[strlen(serline)+1] = 0;
      serline[strlen(serline)] = c;
    }
    else
    {
      serline[0] = 0;
    }
  }
}

Generated by GNU Enscript 1.6.5.2.
Document Actions