Beispiel #1
0
int
main (int argc, char *argv[])
{
  int i, Sense;
  long lj;
  char s[513];

  GetParameters (ControllerNumber);
  Roll.CurrentAdjustedReading = 0;
  Roll.LastRawReading = 0;
  Pitch.CurrentAdjustedReading = 0;
  Pitch.LastRawReading = 0;
  Yaw.CurrentAdjustedReading = 0;
  Yaw.LastRawReading = 0;

  fprintf (stdout, "yaACA3 Apollo ACA simulation, ver " VER(NVER) ", built " __DATE__ " " __TIME__ "\n");
  fprintf (stdout, "Copyright 2009 by Ronald S. Burkey\n");
  fprintf (stdout, "Refer to http://www.ibiblio.org/apollo/index.html for more information.\n");
	
  Portnum = 19803;  
  for (i = 1; i < argc; i++)
  {
    
    if (1 == sscanf (argv[i], "--ip=%s", s))
      {
	strcpy (NonDefaultHostname, s);
	Hostname = NonDefaultHostname;
      }
    else if (1 == sscanf (argv[i], "--port=%ld", &lj))
      {
	Portnum = lj;
	if (Portnum <= 0 || Portnum >= 0x10000)
	  {
	    fprintf (stdout, "The --port switch is out of range.  Must be 1-64K.\n");
	    goto Help;
	  }
      }
    else if (1 == sscanf (argv[i], "--delay=%ld", &lj))
      {
	StartupDelay = lj;
      }
    else if (1 == sscanf (argv[i], "--controller=%ld", &lj))
      {
	if (lj < 0 || lj > 1)
	  {
	    fprintf (stdout, "Only --controller=0 and --controller=1 are allowed.\n");
	    goto Help;
	  }
	else
	  ControllerNumber = lj;
      }
    else if (1 == sscanf (argv[i], "--pitch=-%ld", &lj))
      {
         Pitch.PositiveSense = 0;
         Pitch.Axis = lj;
	 CfgExisted = 0;
      }
    else if (1 == sscanf (argv[i], "--pitch=+%ld", &lj) ||
    	     1 == sscanf (argv[i], "--pitch=%ld", &lj))
      {
         Pitch.PositiveSense = 1;
         Pitch.Axis = lj;
	 CfgExisted = 0;
      }
    else if (1 == sscanf (argv[i], "--roll=-%ld", &lj))
      {
         Roll.PositiveSense = 0;
         Roll.Axis = lj;
	 CfgExisted = 0;
      }
    else if (1 == sscanf (argv[i], "--roll=+%ld", &lj) ||
    	     1 == sscanf (argv[i], "--roll=%ld", &lj))
      {
         Roll.PositiveSense = 1;
         Roll.Axis = lj;
	 CfgExisted = 0;
      }
    else if (1 == sscanf (argv[i], "--yaw=-%ld", &lj))
      {
         Yaw.PositiveSense = 0;
         Yaw.Axis = lj;
	 CfgExisted = 0;
      }
    else if (1 == sscanf (argv[i], "--yaw=+%ld", &lj) ||
    	     1 == sscanf (argv[i], "--yaw=%ld", &lj))
      {
         Yaw.PositiveSense = 1;
         Yaw.Axis = lj;
	 CfgExisted = 0;
      }
    else
      {
      Help:
	fprintf (stdout, "USAGE:\n");
	fprintf (stdout, "\tyaACA3 [OPTIONS]\n");
	fprintf (stdout, "The available options are:\n");
	fprintf (stdout, "--ip=Hostname\n");
	fprintf (stdout, "\tThe yaACA2 program and the yaAGC Apollo Guidance Computer simulation\n");
	fprintf (stdout, "\texist in a \"client/server\" relationship, in which the yaACA2 program\n");
	fprintf (stdout, "\tneeds to be aware of the IP address or symbolic name of the host \n");
	fprintf (stdout, "\tcomputer running the yaAGC program.  By default, this is \"localhost\",\n");
	fprintf (stdout, "\tmeaning that both yaACA2 and yaAGC are running on the same computer.\n");
	fprintf (stdout, "--port=Portnumber\n");
	fprintf (stdout, "\tBy default, yaACA2 attempts to connect to the yaAGC program using port\n");
	fprintf (stdout, "\tnumber %d.  However, if more than one instance of yaACA2 is being\n",
		Portnum);
	fprintf (stdout, "\trun, or if yaAGC has been configured to listen on different ports, then\n");
	fprintf (stdout, "\tdifferent port settings for yaACA2 are needed.  Note that by default,\n");
	fprintf (stdout, "\tyaAGC listens for new connections on ports %d-%d.\n",
		19697, 19697 + 10 - 1);
	fprintf (stdout, "--delay=N\n");
	fprintf (stdout, "\t\"Start-up delay\", in ms.  Defaults to %d.  What the start-up\n", StartupDelay);
	fprintf (stdout, "\tdelay does is to prevent yaACA2 from attempting to communicate with\n");
	fprintf (stdout, "\tyaAGC for a brief time after power-up.  This option is really only\n");
	fprintf (stdout, "\tuseful in Win32, to work around a problem with race-conditions at\n");
	fprintf (stdout, "\tstart-up.\n");
	fprintf (stdout, "--roll=N\n");
	fprintf (stdout, "--pitch=N\n");
	fprintf (stdout, "--yaw=N\n");
	fprintf (stdout, "\tThese options allow you to relate the axis numbers (0, 1, ...) by\n");
	fprintf (stdout, "\twhich the joystick controller works to physical axes (pitch, roll,\n");
	fprintf (stdout, "\tyaw) by which the spacecraft works.  In almost all cases --roll=0\n");
	fprintf (stdout, "\tand --pitch=1 (the defaultswill be correct, but the --yaw=N setting\n");
	fprintf (stdout, "\tvaries from target platform to target platform, and joystick model\n");
	fprintf (stdout, "\tto joystick model.  Once you use these command-line switches once,\n");
	fprintf (stdout, "\tthe settings are saved to a configuration file and you don't have\n");
	fprintf (stdout, "\tto use them again.  The axis-number N can optionally be preceded by\n");
	fprintf (stdout, "\ta \'-\' to indicate that the sense of the axis is reversed from the\n");
	fprintf (stdout, "\tdefault expectation.  For example, if axis 5 was used for yaw, but\n");
	fprintf (stdout, "\tyou found you were getting yaw left where you expected yaw-right, you\n");
	fprintf (stdout, "\tshould use--yaw=-5 rather than --yaw=5.\n");
	fprintf (stdout, "--controller=N\n");
	fprintf (stdout, "\tIn case there are two joystick controllers attached, this allows\n");
	fprintf (stdout, "\tselection of just one of them.  The default is N=0, but N=1 is also\n");
	fprintf (stdout, "\tallowed.  If there are more than two attached, only the first two can\n");
	fprintf (stdout, "\tbe accessed.\n");
	return (1);
      }	
  }
  if (!CfgExisted)
    WriteParameters (ControllerNumber);

  // Now we start polling the joystick from time to time.  The way Allegro works is to 
  // maintain an array containing info on each joystick.  This array is updated only when
  // poll_joystick is called (which you have to do explicitly).  To see what has changed,
  // we maintain a copy of the joy[] array.
  while (1)
    {
      // Sleep for a while so that this job won't monopolize CPU cycles.
#ifdef WIN32
      Sleep (UPDATE_INTERVAL);	    
#else // WIN32
      struct timespec req, rem;
      req.tv_sec = 0;
      req.tv_nsec = 1000000 * UPDATE_INTERVAL;
      nanosleep (&req, &rem);
#endif // WIN32

      ServiceJoystick_sdl ();			// Get joystick physical values.
      if (Initialization >= 2)
        {
	  UpdateJoystick ();			// Translate physical to logical values.
	  PrintJoy ();				// Display them locally.
        }
      PulseACA ();				// Manage server connection.
    }

#ifndef SOLARIS
  return (0);
#endif
}
void DriverstationMessages::DisplayMessage()
{
	// Instead of updating the screen at 50 hz (or whatever period the periodic service runs,
	/// do it every 20 times (where 20 is configurable).
	if (numverOfCallsToDisplayMessage % ourPeriod != 0) return;
	
	
	//the joystick should be coming in from the command.
	bool pressed = CommandBase::oi->GetDriveStick()->GetRawButton(DRIVER_STATION_TOGGLE);
	static bool wasPressed = false;
	
	switch(index)
	{
	case 0 :
		PrintDefaultDiags();
		break;		
	case 1 : 
		PrintJag(CommandBase::leftBackJag, "Left Back");
		break;
	case 2 :
		PrintJag(CommandBase::leftFrontJag, "Left Front");
		break;
	case 3 :
		PrintJag(CommandBase::rightBackJag, "Right Back");
		break;
	case 4 :
		PrintJag(CommandBase::rightFrontJag, "Right Front");
		break;
	case 5 :
		PrintJag(CommandBase::turretJag, "Turret");
		break;
	case 6 :
		PrintJag(CommandBase::upperWheelJag, "Upper");
		break;
	case 7 :
		PrintJag(CommandBase::lowerWheelJag, "Shooter");
		break;
	case 8 :
		if(IsLibraKraken())
		{ PrintVictor(CommandBase::armMotor, "Arm"); }
		break;
	case 9 :
		if(IsLibraKraken())
		{ PrintVictor(CommandBase::collectorVictor1, "Collector 1"); }
		break;
	case 10 :
		if(IsLibraKraken())
		{ PrintVictor(CommandBase::collectorVictor2, "Collector 2");}
		break; //etc...
	case 11:
		PrintVictor(CommandBase::collectorVictor3, "Collector 3");
		break;
	case 12:
		if(IsLibraKraken())
		{
			PrintDigitalIO(CommandBase::collectorSensorLower,
						   CommandBase::collectorSensorMiddle,
					       CommandBase::collectorSensorUpper, "sensor" );
		}
		break;
	case 13:
		if(IsLibraKraken())
		{ PrintLimits(CommandBase::armLimitUp, CommandBase::armLimitDown, "arm limit"); }
		break;
	case 14:
	{
		static unsigned int i = 0;
		if(0 == (i % 50))
		{
			PrintGyro(CommandBase::gyro, "Gyro");
		}
		i++;
	}
		break;
	case 15: 
		PrintMagEncoder(CommandBase::armMagneticEncoder, "arm encoder");
		break;
	case 16:
		PrintBallSpeedSensor(CommandBase::ballSpeedSensor, "Ball Speed Sensor");
		break;
	case 17:
		PrintJoy(CommandBase::oi->GetDriveStick(), "Drive");
		break;
	case 18:
		PrintJoy(CommandBase::oi->GetOperatorStick(), "Operator");
		break;
	case 19:
		PrintFeetPosition();
		break;
	default :
		PrintFeetPosition();
		index = 0;
	}

	if (pressed && !wasPressed)
		index++;
	wasPressed = pressed;
	
	SendTextLines();
}
Beispiel #3
0
int
main (int argc, char *argv[]) 
{
  int DesiredJoystick = 0, i, j, Joystick, Stick, Axis, Offset, Changed = 0;
  float Factor;
  char *s;

#ifdef WIN32
  Out = stdout; // fopen ("yaACA.txt", "w");
#else
  Out = stdout;
#endif

  fprintf (Out, "Apollo Attitude Controller Assembly (ACA) emulation, version " NVER 
  	  ", built " __DATE__ "\n");
  fprintf (Out, "(c)2005,2009 Ronald S. Burkey\n");
  fprintf (Out, "Refer to http://www.ibiblio.org/apollo/index.html for more information.\n");
  fflush (Out);
  
  // Initialize Allegro.
Retry:
  allegro_init ();
  if (install_joystick (JOY_TYPE_AUTODETECT) || num_joysticks <= 0)
    {
      fprintf (Out, "Couldn\'t find any joysticks. Retrying ...\n");
      fflush (Out);
      //return (1);
#ifdef WIN32
      Sleep (5000);	    
#else // WIN32
      {
	struct timespec req, rem;
	req.tv_sec = 5;
	req.tv_nsec = 0;
	nanosleep (&req, &rem);
      }
#endif // WIN32
      allegro_exit ();
      goto Retry;
    }
    
    {
      GetParameters (Controller);
           
      //fprintf (Out, "%d joysticks found:\n", num_joysticks);
      for (i = 0; i < num_joysticks; i++)
        {
	  int k;
	  fprintf (Out, "Joystick device #%d:\n", i);
	  if (joy[i].flags & JOYFLAG_DIGITAL)
	    fprintf (Out, "\tThis control provides a digital input.\n");
	  else if (joy[i].flags & JOYFLAG_ANALOGUE)
	    fprintf (Out, "\tThis control provides an analog input.\n");
	  else if (joy[i].flags & JOYFLAG_CALIB_DIGITAL)
	    fprintf (Out, "\tThis control will provide a digital input after calibration.\n");
	  else if (joy[i].flags & JOYFLAG_CALIB_ANALOGUE)
	    fprintf (Out, "\tThis control will provide an analog input after calibration.\n"); 
	  else if (joy[i].flags & JOYFLAG_CALIBRATE)
	    fprintf (Out, "\tThis control needs calibration.\n");
	  else if (joy[i].flags & JOYFLAG_SIGNED)
	    fprintf (Out, "\tThis control provides signed data (i.e., -127 to 127).\n");
	  else if (joy[i].flags & JOYFLAG_UNSIGNED)
	    fprintf (Out, "\tThis control provides unsigned data (i.e., 0 to 255).\n");
	  for (j = 0; j < joy[i].num_sticks; j++)
	    {
	      fprintf (Out, "\tStick #%d of joystick device #%d:\n", j, i);
	      if (joy[i].stick[j].flags & JOYFLAG_DIGITAL)
		fprintf (Out, "\t\tThis control provides a digital input.\n");
	      else if (joy[i].stick[j].flags & JOYFLAG_ANALOGUE)
		fprintf (Out, "\t\tThis control provides an analog input.\n");
	      else if (joy[i].stick[j].flags & JOYFLAG_CALIB_DIGITAL)
		fprintf (Out, "\t\tThis control will provide a digital input after calibration.\n");
	      else if (joy[i].stick[j].flags & JOYFLAG_CALIB_ANALOGUE)
		fprintf (Out, "\t\tThis control will provide an analog input after calibration.\n"); 
	      else if (joy[i].stick[j].flags & JOYFLAG_CALIBRATE)
		fprintf (Out, "\t\tThis control needs calibration.\n");
	      else if (joy[i].stick[j].flags & JOYFLAG_SIGNED)
		fprintf (Out, "\t\tThis control provides signed data (i.e., -127 to 127).\n");
	      else if (joy[i].stick[j].flags & JOYFLAG_UNSIGNED)
		fprintf (Out, "\t\tThis control provides unsigned data (i.e., 0 to 255).\n");
	      fprintf (Out, "\t\tDescription = %s\n", joy[i].stick[j].name);
	      for (k = 0; k < joy[i].stick[j].num_axis; k++)
	        fprintf (Out, "\t\tAxis #%d description = %s\n", k, joy[i].stick[j].axis[k].name);
	    }
	  for (j = 0; j < joy[i].num_buttons; j++)
	    {
	      fprintf (Out, "\tButton %d = %s\n", j, joy[i].button[j].name);
	    }
	}
      fprintf (Out, "\n");
      fprintf (Out, "Note that only 3 degrees of freedom and no buttons are used by yaACA.\n");
      fprintf (Out, "Right roll, upward pitch, and clockwise yaw are positive values.\n");
      fprintf (Out, "Left roll, downward pitch, and counter-clockwise yaw are negative values.\n");
    }
    
  // Parse the command-line arguments.
  for (i = 1; i < argc; i++)
    {
      if (!strcmp (argv[i], "--help"))
        {
	  fprintf (Out, 
	    "\n"
	    "USAGE:\n"
	    "\tyaACA [OPTIONS]\n"
	    "The recognized options are:\n"
	    "--help\n"
	    "\tDisplays this message.\n"
	    "--roll=J,S,A,F,O  or  --pitch=J,S,A,F,O  or  --yaw=J,S,A,F,O\n"
	    "\tThese options allow you to configure how the roll/pitch/yaw degrees\n"
	    "\tof freedom map to the characteristics of the joystick as recognized\n"
	    "\tby the computer's operating system.  J is the joystick number (in \n"
	    "\tcase multiple joysticks are installed), S is the stick number within\n"
	    "\tthe joystick, and A is the axis within the stick.  F is a factor which\n"
	    "\tthe joystick reading is multiplied by, and O is an offset added to the\n"
	    "\tjoystick reading (after multiplication is completed).  The factor is \n"
	    "\tuseful (for example) in swapping right-to-left, back-to-front, or \n"
	    "\tclockwise-to-counter-clockwise.  The offset would be useful when the\n"
	    "\tthe joystick provides unsigned readings (0-255) rather than the desired\n"
	    "\tsigned readings (-127 to 127).  The defaults are:\n"
	    "\t\t\tRoll\t\t0,0,0,+1.0,0\n"
	    "\t\t\tPitch\t\t0,0,1,+1.0,0\n"
#ifdef __APPLE__
	    "\t\t\tYaw\t\t0,2,0,+1.0,%d\n"
#else	    
	    "\t\t\tYaw\t\t0,1,0,+1.0,%d\n"
#endif
	    "\t(By the way, the defaults work with a Logitech Extreme 3D Pro.)\n"
	    "\tAlthough it would appear that you can select a different joystick\n"
	    "\tcontroller (the first field) for each of the pitch/roll/yaw axes,\n"
	    "\tyou really cannot, so please do not do so.  For versions 20090406\n"
	    "\tand later, your selections are automatically stored in a configuration\n"
	    "\tfile called yaACA-N.cfg, where N is the joystick controller number,\n"
	    "\tand become the new defaults the next time the program is run.  In\n"
	    "\tother words, once you've determined the appropriate command-line\n"
	    "\tsettings for --roll, --pitch, and --yaw, you don't need to use the\n"
	    "\tcommand-line parameters again.  An exception is if the joystick\n"
	    "\tcontroller-number is non-zero.  If so, you will need to use at least\n"
	    "\tone of these command-line switches every time, or else the saved\n"
	    "\tsettings for controller 0 will be used.\n"
	    "--ip=Hostname\n"
	    "\tThe yaACA program and the yaAGC Apollo Guidance Computer simulation\n"
	    "\texist in a \"client/server\" relationship, in which the yaACA program\n"
	    "\tneeds to be aware of the IP address or symbolic name of the host\n"
	    "\tcomputer running the yaAGC program.  By default, this is \"localhost\",\n"
	    "\tmeaning that both yaACA and yaAGC are running on the same computer.\n"
            "--port=Portnumber\n"
	    "\tBy default, yaACA attempts to connect to the yaAGC program using port\n"
	    "\tnumber %d.  However, if more than one instance of yaACA is being\n"
	    "\trun, or if yaAGC has been configured to listen on different ports, then\n"
	    "\tdifferent port settings for yaACA are needed.  Note that by default,\n"
	    "\tyaAGC listens for new connections on ports 19697-19706, but that the\n"
	    "\trecommended port range when using yaAGC in the LM is 19797-19806.\n",
	    YawOffset, sPortnum
	  );
	  fprintf (Out, "--delay=N\n");
	  fprintf (Out, "\t\"Start-up delay\", in ms.  Defaults to %d.  What the start-up\n", StartupDelay);
	  fprintf (Out, "\tdelay does is to prevent yaACA from attempting to communicate with\n");
	  fprintf (Out, "\tyaAGC for a brief time after power-up.  This option is really only\n");
	  fprintf (Out, "\tuseful in Win32, to work around a problem with race-conditions in\n");
	  fprintf (Out, "\tat start-up time.\n");
	  return (0);
	}
      else if (5 == sscanf (argv[i], "--roll=%d,%d,%d,%f,%d", &Joystick, &Stick, &Axis, &Factor, &Offset) ||
               5 == sscanf (argv[i], "--pitch=%d,%d,%d,%f,%d", &Joystick, &Stick, &Axis, &Factor, &Offset) ||
	       5 == sscanf (argv[i], "--yaw=%d,%d,%d,%f,%d", &Joystick, &Stick, &Axis, &Factor, &Offset) )
        {
	  if (Joystick >= 0 && Joystick < num_joysticks)
	    {
	      DesiredJoystick = Joystick;
	      if (Stick < 0 || Stick >= joy[Joystick].num_sticks)
	        {
		  fprintf (Out, "\nJoystick #%d stick numbers must be >=0 and < %d.  Sorry!\n",
		          Joystick, joy[Joystick].num_sticks);
		  return (1);
		}
	      if (Axis < 0 || Axis >= joy[Joystick].stick[Stick].num_axis)
	        {
		  fprintf (Out, "\nJoystick #%d, stick #%d axis numbers must be >=0 and < %d.  Sorry!\n",
		          Joystick, Stick, joy[Joystick].stick[Stick].num_axis);
		  return (1);
		}
	      if (0 == (JOYFLAG_ANALOGUE & joy[Joystick].stick[Stick].flags))
	        {
		  fprintf (Out, "\nJoystick #%d, stick #%d is not analog.  Sorry!\n",
		          Joystick, Stick);
		  return (1);
		}
	      if ('r' == argv[i][2])
	        {
	          Roll = &joy[Joystick].stick[Stick].axis[Axis].pos;
		  RollFactor = Factor;
		  RollOffset = Offset;
		  Controller = Joystick;
		  RollStick = Stick;
		  RollAxis = Axis;
		  Changed = 1;
		}
	      else if ('p' == argv[i][2])
	        {
	          Pitch = &joy[Joystick].stick[Stick].axis[Axis].pos;
		  PitchFactor = Factor;
		  PitchOffset = Offset;
		  Controller = Joystick;
		  PitchStick = Stick;
		  PitchAxis = Axis;
		  Changed = 1;
		}
	      else
	        {
	          Yaw = &joy[Joystick].stick[Stick].axis[Axis].pos;
		  YawFactor = Factor;
		  YawOffset = Offset;
		  Controller = Joystick;
		  YawStick = Stick;
		  YawAxis = Axis;
		  Changed = 1;
		}
	    }
	  else
	    {
	      fprintf (Out, "\nJoystick numbers must be >= 0 and < %d.  Sorry!\n", num_joysticks);
	      return (1);
	    }  
	}
      else if (1 == sscanf (argv[i], "--delay=%d", &j))
        StartupDelay = j;
      else 
        {
	  fprintf (Out, "Unknown command-line switch \"%s\".\n", argv[i]);
	  fprintf (Out, "Try \"yaACA --help\".\n");
	  return (1);
	}	
    }
  if (Changed || !CfgExisted)
    WriteParameters (Controller);
    
  // Set up variables for quick access to just the desired joystick, and check for minimum
  // requirements.  Note that the ACA requires no pushbuttons (there are associated toggle
  // switches, but they're not physically on the hand-control, and they are toggle switches
  // anyhow).  
  s = (char *) calibrate_joystick_name (DesiredJoystick);
  if (s != NULL)
    {
      fprintf (Out, "%s\n", calibrate_joystick_name (DesiredJoystick));
      if (calibrate_joystick (DesiredJoystick))
	{
	  fprintf (Out, "Joystick calibration problem.\n");
	  return (1);
	}
    }
  PrintJoy ();
    
  // Now we start polling the joystick from time to time.  The way Allegro works is to 
  // maintain an array containing info on each joystick.  This array is updated only when
  // poll_joystick is called (which you have to do explicitly).  To see what has changed,
  // we maintain a copy of the joy[] array.
  while (1)
    {
      // Sleep for a while so that this job won't monopolize CPU cycles.
#ifdef WIN32
      Sleep (UPDATE_INTERVAL);	    
#else // WIN32
      struct timespec req, rem;
      req.tv_sec = 0;
      req.tv_nsec = 1000000 * UPDATE_INTERVAL;
      nanosleep (&req, &rem);
#endif // WIN32
      poll_joystick ();				// Get joystick values.
      PrintJoy ();				// Display them locally.
      PulseACA ();				// Manage server connection.
#if 0      
      {
        static int Count = 0;
        fprintf (Out, "*");
	Count++;
	if (Count >= 32)
	  {
	    Count = 0;
	    fflush (Out);
	  }
      }
#endif      
    }

  return (0);
}