AREXPORT void ArActionLimiterRot::addToConfig(ArConfig *config, 
						       const char *section, 
						       const char *prefix)
{
  std::string strPrefix;
  std::string name;
  if (prefix == NULL || prefix[0] == '\0')
    strPrefix = "";
  else
    strPrefix = prefix;

  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section, ArPriority::NORMAL);  

  name = strPrefix;
  name += "CheckRadius";
  config->addParam(
	  ArConfigArg(name.c_str(), &myCheckRadius, 
		      "True to check the robot's radius and apply InRadiusSpeed, false not to"), 
	  section, ArPriority::NORMAL);

  name = strPrefix;
  name += "InRadiusSpeed";
  config->addParam(
	  ArConfigArg(name.c_str(), &myInRadiusSpeed, 
		      "Maximum speed to allow if CheckRadius is true and there are sensor readings in the robot's radius, 0 or less means allow no rotation (deg/sec)"), 
	  section, ArPriority::NORMAL);

  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section, ArPriority::NORMAL);
}
Beispiel #2
0
  ConfigExample():
    myIntParam(0),
    myDoubleParam(0.5),
    myBoolParam(false),
    myProcessConfigCB(this, &ConfigExample::processConfigFile)
  {
    // The global Aria class contains an ArConfig object.  You can create
    // other instances of ArConfig, but this is how you can share one ArConfig
    // among various program modules.
    // If you want to store a config parameter in ArConfig, first you must add 
    // it to the ArConfig object.  Parameters are stored in sections, and
    // they affect a variable via a pointer provided in an ArConfigArg
    // object:
    ArConfig* config = Aria::getConfig();
    config->setSectionComment("Example Section", "Contains parameters created by the configExample");

    // Add an integer which ranges from -10 to 10:
    config->addParam( ArConfigArg("ExampleIntegerParameter", &myIntParam, "Example parameter integer.", -10, 10), "Example Section", ArPriority::NORMAL);
    
    // Add a floating point number which ranges from 0.0 to 1.0:
    config->addParam( ArConfigArg("ExampleDoubleParameter", &myDoubleParam, "Example double precision floating point number.", 0.0, 1.0), "Example Section", ArPriority::NORMAL);

    // Essential parameters can be placed in the "Important" priority level:
    config->addParam( ArConfigArg("ExampleBoolParameter", &myBoolParam, "Example boolean parameter."), "Example Section", ArPriority::IMPORTANT);

    // Unimportant parameters can be placed in the "Trivial" priority level:
    myStringParam[0] = '\0';  // make string empty
    config->addParam( ArConfigArg("ExampleStringParameter", myStringParam, "Example string parameter.", 256), "Example Section", ArPriority::TRIVIAL);

    // You can set a callback to be invoked when the configuration changes, in
    // case you need to respond to any changes in the parameter values:
    config->addProcessFileCB(&myProcessConfigCB, 0);
  }
Beispiel #3
0
AREXPORT void ArLog::addToConfig(ArConfig *config)
{
  std::string section = "LogConfig";
  config->addParam(
	  ArConfigArg("LogType", (int *)&ourConfigLogType,
		      "The type of log we'll be using, 0 for StdOut, 1 for StdErr, 2 for File (and give it a file name), 3 for colbert (don't use that), and 4 for None", 
		      ArLog::StdOut, ArLog::None), 
	  section.c_str(), ArPriority::TRIVIAL);
  config->addParam(
	  ArConfigArg("LogLevel", (int *)&ourConfigLogLevel,
		      "The level of logging to do, 0 for Terse, 1 for Normal, and 2 for Verbose", 
		      ArLog::Terse, ArLog::Verbose), 
	  section.c_str(), ArPriority::TRIVIAL);
  config->addParam(
	  ArConfigArg("LogFileName", ourConfigFileName,
		      "File to log to", sizeof(ourConfigFileName)),
	  section.c_str(), ArPriority::TRIVIAL);
  config->addParam(
	  ArConfigArg("LogTime", &ourConfigLogTime,
		      "True to prefix log messages with time and date, false not to"),
	  section.c_str(), ArPriority::TRIVIAL);
  config->addParam(
	  ArConfigArg("LogAlsoPrint", &ourConfigAlsoPrint,
		      "True to also printf the message, false not to"),	  
	  section.c_str(), ArPriority::TRIVIAL);
  ourConfigProcessFileCB.setName("ArLog");
  config->addProcessFileCB(&ourConfigProcessFileCB, 200);
}
AREXPORT void ArLineFinder::addToConfig(ArConfig *config,
					const char *section)
{
  
  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section,
		     ArPriority::NORMAL);
  config->addParam(
	  ArConfigArg("CreatingMinLineLength", &myMakingMinLen,
		      "The minimum possible line length for creating lines", 0),
	  section, ArPriority::TRIVIAL);
  config->addParam(
	  ArConfigArg("CreatingMinLinePoints", &myMakingMinPoints,
		      "The minimum number of points in a line for creating lines", 0),
	  section, ArPriority::TRIVIAL);

  config->addParam(
	  ArConfigArg("CreatingMaxDistBetweenPoints", 
		      &myMaxDistBetweenPoints,
		      "The max dist between points for creating lines", 
		      0),
	  section, ArPriority::TRIVIAL);


  config->addParam(
	  ArConfigArg("CombiningAngleTol", &myCombiningAngleTol,
		      "The angle tolerance when combining lines", 0),
	  section, ArPriority::TRIVIAL);

  config->addParam(
	  ArConfigArg("CombiningCloseEnough", &myCombiningLinesCloseEnough,
		      "How far apart lines can be when combining lines", 0),
	  section, ArPriority::TRIVIAL);

  config->addParam(
	  ArConfigArg("FilteringMinPointsInLine", &myFilteringMinPointsInLine,
		      "How many points need to be in a line when filtering", 
		      0),
	  section, ArPriority::TRIVIAL);

  config->addParam(
	  ArConfigArg("FilteringMinLineLength", &myFilteringMinLineLength,
		      "How many points are needed in a line when filtering", 
		      0),
	  section, ArPriority::TRIVIAL);

  config->addParam(
	  ArConfigArg("ValidMaxDistFromLine", &myValidMaxDistFromLine,
		      "For the validation phase, the max dist from line", 
		      0),
	  section, ArPriority::TRIVIAL);

  config->addParam(
	  ArConfigArg("ValidMaxAveDistFromLine", &myValidMaxAveFromLine,
		      "For the validation phase, the max ave dist from line", 
		      0),
	  section, ArPriority::TRIVIAL);

}
  ArnlASyncTaskExample(ArPathPlanningTask *pp, ArRobot *robot, ArServerModeGoto *servermode, ArArgumentParser *argParser) : 
    ArnlAsyncTask(pp, robot, "Example ARNL Goal Task", argParser),
    myServerMode(servermode), myCurrentGoal(1), myNumGoals(4), myApproachDist(250)
	{	
    // Add some parameters to ArConfig so they can be changed in MobileEyes.
		addConfigParam(ArConfigArg("ApproachDist", &myApproachDist, "distance to approach drop point"));
		addConfigParam(ArConfigArg("NumGoals", &myNumGoals, "number of goals in chain"));

    ArLog::log(ArLog::Normal, "ArArnlASyncTaskExample created:  will perform tasks at each goal, and then send ARNL to another. ");
	}
Beispiel #6
0
ConfigTester::ConfigTester() : 
  mySetFunctor(this, &ConfigTester::listAdder),
  myGetFunctor(this, &ConfigTester::getList)
{
  myInt = 32;
  myDouble = 239.394;
  myBool = true;
  myPose.setPose(42, -42.3, 21.21);
  strcpy(myString, "happy fun string will begin to smoke");

  addParam(ArConfigArg("int", &myInt, "fun things!"), "fuah");//, 0, 300));
  addParam(ArConfigArg("double", &myDouble, "fun things double!"));//, 0, 2300));
  addParam(ArConfigArg("bool", &myBool, "fun things bool!"));
  addParam(ArConfigArg("string", myString, "fun things string!", sizeof(myString)));
  addParam(ArConfigArg("functor", &mySetFunctor, &myGetFunctor, "fun functor thing!"));
}
Beispiel #7
0
void ArSpeechSynth::addVoiceConfigParam(ArConfig *config)
{
  const char *current = getCurrentVoiceName();
  if(current)
  {
    strncpy(myConfigVoice, current, sizeof(myConfigVoice));
  }
  else
  {
    myConfigVoice[0] = 0;
  }
  std::string displayHint;
  std::list<std::string> voices = getVoiceNames();
  for(std::list<std::string>::const_iterator i = voices.begin(); i != voices.end(); i++)
  {
    if(i == voices.begin())
      displayHint = "Choices:";
    else
      displayHint += ";;";
    displayHint += *i;
  }
  config->addParam(
    ArConfigArg("Voice", myConfigVoice, "Name of voice to use for speech synthesis", sizeof(myConfigVoice)), 
    "Speech Synthesis",
    ArPriority::NORMAL,
    displayHint.c_str()
  );
}
AREXPORT void ArLaserReflectorDevice::addToConfig(ArConfig *config, 
						  const char *section)
{
  config->addParam(
	  ArConfigArg("ReflectanceThreshold", &myReflectanceThreshold,
		      "The threshold to start showing reflector readings at (normalized from 0 to 255, 31 is the default)", 
		      0, 255),
	  section, ArPriority::DETAILED);
		      
}
AREXPORT void ArLaserFilter::addToConfig(ArConfig *config, 
					       const char *sectionName,
					       const char *prefix)
{
  std::string name;
  
  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), sectionName,
		     ArPriority::TRIVIAL);
  name = prefix;
  name += "AngleSpread";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAngleToCheck,
	      "The angle spread to check on either side of each reading",
		      0),
	  sectionName, ArPriority::TRIVIAL);

  name = prefix;
  name += "AnyNeighborFactor";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAnyFactor,
	      "If a reading (decided by the anglespread) is further than any of its neighbor reading times this factor, it is ignored... so a value between 0 and 1 will check if they're all closer, a value greater than 1 will see if they're all further, negative values means this factor won't be used",
		      -1),
	  sectionName, ArPriority::TRIVIAL);

  name = prefix;
  name += "AllNeighborFactor";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAllFactor,
	      "If a reading (decided by the anglespread) is further than all of its neighbor reading times this factor, it is ignored... so a value between 0 and 1 will check if they're all closer, a value greater than 1 will see if they're all further, negative values means this factor won't be used",
		      -1),
	  sectionName, ArPriority::TRIVIAL);

  name = prefix;
  name += "MaxRange";
  config->addParam(
	  ArConfigArg(name.c_str(), &myMaxRange,
		      "If a reading is further than this max range it will be ignored, -1 will use the base range device's max range",
		      -1),
	  sectionName, ArPriority::TRIVIAL);

  name = prefix;
  name += "CumulativeKeepDist";
  config->addParam(
	  ArConfigArg(name.c_str(), &myMaxDistToKeepCumulative,
		      "Distance cumulative readings can be from current pose",
		      -1),
	  sectionName, ArPriority::TRIVIAL);

  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), sectionName,
		   ArPriority::TRIVIAL);
}
AREXPORT void ArLaserReflectorDevice::addToConfig(ArConfig *config, 
						  const char *section)
{

  config->addSection(ArConfig::CATEGORY_ROBOT_PHYSICAL,
                     section,
                     "Settings for using the reflector readings from this laser");

  config->addParam(
	  ArConfigArg("ReflectanceThreshold", &myReflectanceThreshold,
		      "The threshold to start showing reflector readings at (normalized from 0 to 255, 31 is the default)", 
		      0, 255),
	  section, ArPriority::DETAILED);
		      
}
Beispiel #11
0
AREXPORT void ArDataLogger::addToConfig(ArConfig *config)
{
  if (config == NULL || myAddedToConfig)
    return;
  myConfig = config;
  if (!myRobot->isConnected())
  {
    myAddToConfigAtConnect = true;
    myRobot->addConnectCB(&myConnectCB);
    return;
  }
  else
  {
    connectCallback();
  }

  myAddedToConfig = true;
  ArLog::log(ArLog::Verbose, "ArDataLogger::addToConfig");
  std::string section;
  char name[512];
  char desc[512];
  int i;
  section = "Data logging";
  // add everything to the config
  myConfig->addParam(
	  ArConfigArg("DataLog", &myConfigLogging, "True to log data, false not to"),
	  section.c_str(), ArPriority::NORMAL);

  myConfig->addParam(
	  ArConfigArg("DataLogInterval", &myConfigLogInterval, "Seconds between logs", 0),
	  section.c_str(), ArPriority::NORMAL);

  if (myPermanentFileName.size() == 0)
    myConfig->addParam(
	    ArConfigArg("DataLogFileName", myConfigFileName, 
			"File to log data into", sizeof(myConfigFileName)),
	    section.c_str(), ArPriority::NORMAL);
  
  for (i = 0; i < myStringsCount; i++)
  {
    snprintf(name, sizeof(name), "DataLog%s", myStrings[i]->getName());
    snprintf(desc, sizeof(desc), "Logs %s", myStrings[i]->getName());
    myConfig->addParam(
	    ArConfigArg(name, myStringsEnabled[i], desc),
	    "Custom data logging", ArPriority::NORMAL);
  }

  myConfig->addParam(
	  ArConfigArg("DataLogBatteryVoltage", &myLogVoltage, "True to log battery voltage"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogChargeState", &myLogChargeState, 
		      "True to log charge state"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogPose", &myLogPose, "True to log robot's pose"),
	  section.c_str(), ArPriority::NORMAL);
  myConfig->addParam(
	  ArConfigArg("DataLogEncoderPose", &myLogEncoderPose, "True to log robot's raw encoder pose"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogCorrectedEncoderPose", &myLogCorrectedEncoderPose, "True to log robot's corrected (by gyro, etc) encoder pose"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogEncoders", &myLogEncoders, "True to log the raw encoder readings"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogLeftVel", &myLogLeftVel, "True to log left wheel velocity"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogRightVel", &myLogRightVel, "True to log right wheel velocity"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogTransVel", &myLogTransVel, "True to log translational wheel velocity"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogRotVel", &myLogRotVel, "True to log rotational wheel velocity"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogLeftStalled", &myLogLeftStalled, "True to log if the left wheel is stalled"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogRightStalled", &myLogRightStalled, "True to log if the right wheel is stalled"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogStallBits", &myLogStallBits, "True to log all the stall bits is stalled"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogFlags", &myLogFlags, "True to log all the flags"),
	  section.c_str(), ArPriority::DETAILED);
  myConfig->addParam(
	  ArConfigArg("DataLogFaultFlags", &myLogFaultFlags, "True to log all the fault flags"),
	  section.c_str(), ArPriority::DETAILED);

  for (i = 0; i < myAnalogCount; i++)
  {
    snprintf(name, sizeof(name), "DataLogAnalog%d", i);
    snprintf(desc, sizeof(desc), 
	     "Logs the value of analog %d as a 10 bit (0-1024) value",
	     i);
    myConfig->addParam(
	    ArConfigArg(name, &myAnalogEnabled[i], desc),
	    section.c_str(), ArPriority::DETAILED);
  }
  for (i = 0; i < myAnalogVoltageCount; i++)
  {
    snprintf(name, sizeof(name), "DataLogAnalogVoltage%d", i);
    snprintf(desc, sizeof(desc), 
	     "Logs the value of analog %d as voltage from 0 to 5",
	     i);
    myConfig->addParam(
	    ArConfigArg(name, &myAnalogVoltageEnabled[i], desc),
	    section.c_str(), ArPriority::DETAILED);
  }
  for (i = 0; i < myDigInCount; i++)
  {
    snprintf(name, sizeof(name), "DataLogDigIn%d", i);
    snprintf(desc, sizeof(desc), "Logs digital in %d", i);
    myConfig->addParam(
	    ArConfigArg(name, &myDigInEnabled[i], desc),
	    section.c_str(), ArPriority::DETAILED);
  }
  for (i = 0; i < myDigOutCount; i++)
  {
    snprintf(name, sizeof(name), "DataLogDigOut%d", i);
    snprintf(desc, sizeof(desc), "Logs digital out %d", i);
    myConfig->addParam(
	    ArConfigArg(name, &myDigOutEnabled[i], desc),
	    section.c_str(), ArPriority::DETAILED);
  }
  myProcessFileCB.setName("ArDataLogger");
  myConfig->addProcessFileWithErrorCB(&myProcessFileCB, 100);
}
Beispiel #12
0
AREXPORT void ArLog::aramInit(const char *prefix, ArLog::LogLevel defaultLevel,
			      double defaultSize, bool daemonized)
{
  if (prefix == NULL || prefix[0] == '\0')
    ourAramPrefix = "";
  else
  {
    ourAramPrefix = prefix;
    if (prefix[strlen(prefix) - 1] != '/')
      ourAramPrefix += "/";
  }
  
  std::string section = "Log Config";
  Aria::getConfig()->addParam(
	  ArConfigArg("Level", ourAramConfigLogLevel,
		      "The level of logging type of log we'll be using", sizeof(ourAramConfigLogLevel)),
	  section.c_str(), ArPriority::TRIVIAL, 
	  "Choices:Terse;;Normal;;Verbose");
  Aria::getConfig()->addParam(
	  ArConfigArg("LogFileSize", &ourAramConfigLogSize,
		      "The maximum size of the log files (6 files are rotated through), 0 means no maximum", 0, 20000),
	  section.c_str(), ArPriority::TRIVIAL);

  ourUseAramBehavior = true;
  ourAramConfigProcessFileCB.setName("ArLogAram");
  Aria::getConfig()->addProcessFileCB(&ourAramConfigProcessFileCB, 210);

  if (defaultLevel == ArLog::Terse)
    sprintf(ourAramConfigLogLevel, "Terse");
  else if (defaultLevel == ArLog::Normal)
    sprintf(ourAramConfigLogLevel, "Normal");
  if (defaultLevel == ArLog::Verbose)
    sprintf(ourAramConfigLogLevel, "Verbose");

  ourAramDaemonized = daemonized;

  char buf[2048];
  snprintf(buf, sizeof(buf), "%slog1.txt", ourAramPrefix.c_str());
  ArLog::init(ArLog::File, defaultLevel, buf, true, !daemonized, true);

  if (ourAramDaemonized)
  {

    if (dup2(fileno(ourFP), fileno(stderr)) < 0)
      ArLog::logErrorFromOSNoLock(
	      ArLog::Normal, "ArLog: Error redirecting stderr to log file.");
    
    // this is is taken out since if you set this flag, the file gets
    //closed twice, then really weird stuff happens after the exec
    //ArUtil::setFileCloseOnExec(fileno(stderr), true);

    fprintf(stderr, "Stderr...\n");

    /* stdout is taken out since we don't necessarily need it and it
     * wound up at the end of the file, which got really strange

    if (dup2(fileno(ourFP), fileno(stdout)) < 0)

      ArLog::logErrorFromOSNoLock(
	      ArLog::Normal, "ArLog: Error redirecting stdout to log file.");

    // this is is taken out since if you set this flag, the file gets
    //closed twice, then really weird stuff happens after the exec
    ArUtil::setFileCloseOnExec(fileno(stdout), true);

    fprintf(stdout, "Stdout...\n");
    */
  }

  ourAramConfigLogSize  = defaultSize;  // even megabytes
  ourAramLogSize = ArMath::roundInt(ourAramConfigLogSize * 1000000);  // even megabytes
}
ArCentralManager::ArCentralManager(ArServerBase *robotServer, 
			       ArServerBase *clientServer) :
  myNetSwitchCB(this, &ArCentralManager::netServerSwitch),
  myNetClientListCB(this, &ArCentralManager::netClientList),
  myAriaExitCB(this, &ArCentralManager::close),
  myProcessFileCB(this, &ArCentralManager::processFile),
  myForwarderServerClientRemovedCB(
	  this, &ArCentralManager::forwarderServerClientRemovedCallback),
  myMainServerClientRemovedCB(
	  this, &ArCentralManager::mainServerClientRemovedCallback)
{
  myMutex.setLogName("ArCentralManager::myCallbackMutex");
  myDataMutex.setLogName("ArCentralManager::myDataMutex");
  setThreadName("ArCentralManager");

  myRobotServer = robotServer;
  myClientServer = clientServer;
  
  myAriaExitCB.setName("ArCentralManager");
  Aria::addExitCallback(&myAriaExitCB, 25);

  myEnforceType = ArServerCommands::TYPE_UNSPECIFIED;

  myClientBackupTimeout = 2;
  Aria::getConfig()->addParam(
	  ArConfigArg("CentralServerToClientTimeoutInMins", 
		      &myClientBackupTimeout,
		      "The amount of time the central server can go without sending a packet to the robot successfully (when there are packets to send).  A number less than 0 means this won't happen.  The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1),
	  "Connection timeouts", ArPriority::DETAILED);

  myRobotBackupTimeout = 2;
  Aria::getConfig()->addParam(
	  ArConfigArg("CentralServerToRobotTimeoutInMins", 
		      &myRobotBackupTimeout,
		      "The amount of time the central server can go without sending a packet to the robot successfully (when there are packets to send).  A number less than 0 means this won't happen.  The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1),
	  "Connection timeouts", ArPriority::DETAILED);
  
  myHeartbeatTimeout = 2;
  Aria::getConfig()->addParam(
	  ArConfigArg("CentralServerFromRobotTimeoutInMins", 
		      &myHeartbeatTimeout,
		      "The amount of time the central server can go without hearing a robot's heartbeat without disconnecting it.  A number less than 0 means that the robots will never timeout.  The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1),
	  "Connection timeouts", ArPriority::DETAILED);

  myUdpHeartbeatTimeout = 2;
  Aria::getConfig()->addParam(
	  ArConfigArg("CentralServerFromRobotUdpTimeoutInMins", 
		      &myUdpHeartbeatTimeout,
		      "The amount of time the central server can go without hearing a robot's udp heartbeat without disconnecting it (this fails it over to tcp only).  A number less than 0 means that the robots will never timeout.  The time is in minutes but takes doubles (ie .5) (5 seconds is used if the value is positive, but less than that amount)", -1),
	  "Connection timeouts", ArPriority::DETAILED);


  myProcessFileCB.setName("ArCentralManager");
  Aria::getConfig()->addProcessFileCB(&myProcessFileCB, -999);

  myRobotServer->addData("switch", "switches the direction of the connection, after this is requested it sends an empty packet denoting acceptance of the switch, then switches this to a client connection",
			 &myNetSwitchCB, "string: robotName", "empty packet", "RobotInfo", 
			 "RETURN_SINGLE");

  myRobotServer->addData("centralServerHeartbeat", "Just a data to let the robot's know that this server has the centralServerHeartbeat feature (nothing is actually done with this command)",
			 NULL, "none", "none", "RobotInfo", 
			 "RETURN_NONE");

  myClientServer->addData("clientList", "Lists the clients that are connected",
			  &myNetClientListCB, "none", 
			  "ubyte2: numClients; repeating for <numClients> [string: hostname (empty means this host); ubyte2: port; string: robot name; string: flags; string: robot ip address]",
			  "RobotInfo", "RETURN_SINGLE");
  myClientServer->addData("clientAdded", "Broadcast when a client is added",
			  NULL, "none", 
			  "string: hostname (empty means this host); ubyte2: port; string: robot name; string: flags; string: robot ip address",
			  "RobotInfo", "RETURN_SINGLE");
  myClientServer->addData("clientRemoved", "Broadcast when a client is removed",
			  NULL, "none", 
			  "string: hostname (empty means this host); ubyte2: port; string: robot name; string: flags; string: robot ip address",
			  "RobotInfo", "RETURN_SINGLE");

  myClientServer = clientServer;

  myClosingConnectionID = 0;

  myMostForwarders = 0;
  myMostClients = 0;

  myForwarderServerClientRemovedCB.setName("ArCentralManager");


  myMainServerClientRemovedCB.setName("ArCentralManager");
  myClientServer->addClientRemovedCallback(&myMainServerClientRemovedCB);

  runAsync();
}
AREXPORT void ArActionMovementParameters::addToConfig(ArConfig *config, 
						      const char *section, 
						      const char *prefix)
{
  std::string strPrefix;
  std::string name;
  if (prefix == NULL || prefix[0] == '\0')
    strPrefix = "";
  else
    strPrefix = prefix;

  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section, ArPriority::DETAILED);
  name = strPrefix;
  name += "TransVelMax";
  config->addParam(
	  ArConfigArg(name.c_str(), &myMaxVel, 
		      "Maximum forward translational velocity (0 means use default)", 
		      0),
		      //myRobot->getAbsoluteMaxTransVel()),
	  section, ArPriority::DETAILED);


  name = strPrefix;
  name += "TransNegVelMax";
  config->addParam(
	  ArConfigArg(name.c_str(), &myMaxNegVel, 
		      "Maximum backwards translational velocity (0 means use default)", 
		      0),
	  //myRobot->getAbsoluteMaxTransVel()),
	  section, ArPriority::DETAILED);

  name = strPrefix;
  name += "TransAccel";
  config->addParam(
	  ArConfigArg(name.c_str(), &myTransAccel, 
		      "Translational acceleration (0 means use default)", 0),
		      //myRobot->getAbsoluteMaxTransAccel()),		      
	  section, ArPriority::DETAILED);

  name = strPrefix;
  name += "TransDecel";
  config->addParam(
	  ArConfigArg(name.c_str(), &myTransDecel, 
		      "Translational deceleration (0 means use default)", 0),
		      //myRobot->getAbsoluteMaxTransDecel()),		      
	  section, ArPriority::DETAILED);

  name = strPrefix;
  name += "RotVelMax";
  config->addParam(
	  ArConfigArg(name.c_str(), &myMaxRotVel, 
		      "Maximum rotational velocity (0 means use default)", 
		      0), // myRobot->getAbsoluteMaxRotVel()),
	  section, ArPriority::DETAILED);

  name = strPrefix;
  name += "RotAccel";
  config->addParam(
	  ArConfigArg(name.c_str(), &myRotAccel, 
		      "Rotational acceleration (0 means use default)", 0),
	  //myRobot->getAbsoluteMaxRotAccel()),
	  section, ArPriority::DETAILED);

  name = strPrefix;
  name += "RotDecel";
  config->addParam(
	  ArConfigArg(name.c_str(), &myRotDecel, 
		      "Rotational deceleration (0 means use default)", 0),
		      //myRobot->getAbsoluteMaxRotDecel()),
	  section, ArPriority::DETAILED);

  if (myAddLatVelIfAvailable && myRobot != NULL && myRobot->hasLatVel())
  {
    name = strPrefix;
    name += "LatVelMax";
    config->addParam(
	    ArConfigArg(name.c_str(), &myMaxLatVel, 
			"Maximum lateral velocity (0 means use default)", 
			0), // myRobot->getAbsoluteMaxLatVel()),
	    section, ArPriority::DETAILED);
    
    name = strPrefix;
    name += "LatAccel";
    config->addParam(
	    ArConfigArg(name.c_str(), &myLatAccel, 
			"Lateral acceleration (0 means use default)", 0),
	    //myRobot->getAbsoluteMaxLatAccel()),
	    section, ArPriority::DETAILED);
    
    name = strPrefix;
    name += "LatDecel";
    config->addParam(
	    ArConfigArg(name.c_str(), &myLatDecel, 
			"Lateral deceleration (0 means use default)", 0),
	    //myRobot->getAbsoluteMaxLatDecel()),
	    section, ArPriority::DETAILED);
  }

  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section, ArPriority::DETAILED);


}
/**
   @param server the server to add our data too

   @param arMap If this points to a map file then this will simply
   serve up that map file and add in a map changed cb for that map,
   otherwise it'll operate via the Aria::getConfig.

   @param dataToSend Which data to send, just the lines, the points,
   or both
 **/
AREXPORT ArServerHandlerMap::ArServerHandlerMap(ArServerBase *server, 
						                                    ArMapInterface *arMap,
						                                    DataToSend dataToSend) :
  myGetMapIdCB(this, &ArServerHandlerMap::serverGetMapId),
  myGetMapNameCB(this, &ArServerHandlerMap::serverGetMapName),
  myGetMapCB(this, &ArServerHandlerMap::serverGetMap),
  myGetMapBinaryCB(this, &ArServerHandlerMap::serverGetMapBinary),
  myGetMapMultiScansCB(this, &ArServerHandlerMap::serverGetMapMultiScans),
  myGetMapMaxCategoryCB(this, &ArServerHandlerMap::serverGetMapWithMaxCategory),
  myGetGoalsCB(this, &ArServerHandlerMap::serverGetGoals),
  myCheckMapCB(this, &ArServerHandlerMap::handleCheckMap),
  myProcessFileCB(this, &ArServerHandlerMap::processFile),
  myMapChangedCB(this, &ArServerHandlerMap::mapChanged)
{
  myServer = server;
  myOwnMap = false;
  myMap = arMap;
  setDataToSend(dataToSend);
  myMapChangedCB.setName("ArServerHandlerMap");
  myProcessFileCB.setName("ArServerHandlerMap");
  if (myMap != NULL)
  {
    strcpy(myMapFileName, myMap->getFileName());
    myAlreadyLoaded = false;
    myOwnMap = false;
    myMap->addMapChangedCB(&myMapChangedCB, ArListPos::FIRST);
  }
  else
  {
    myMapFileName[0] = '\0';
    Aria::getConfig()->addParam(ArConfigArg("Map", myMapFileName, 
					    "map file to load", 
					    sizeof(myMapFileName)),
              "Files", 
              ArPriority::IMPORTANT);
    Aria::getConfig()->setSectionComment("Files", 
					 "The files where important data is stored");
    Aria::getConfig()->addProcessFileCB(&myProcessFileCB, 95);
  }


  if (myServer != NULL)
  {
    myServer->addData("getMapId", "Gets the ID of the map being used",
		                  &myGetMapIdCB, 
                      "none", 
                      "string: map name (empty string if no maps)",  // TODO! 
                      "Map", 
                      "RETURN_SINGLE");
    
    myServer->addData("getMapName", "gets the name of the map being used",
		      &myGetMapNameCB, "none", "string: map name (empty string if no maps)", "Map", "RETURN_SINGLE");

    // The "getMapBinary" request replaces the old text-based "getMap" request.
    myServer->addData("getMapBinary", "gets the map objects as ascii and the data points as binary", 
		      &myGetMapBinaryCB, 
		      "none", 
		      "packets of '<string>: line' for header, followed by packets of '<byte4>: numPtsInPacket, (<double>:x, <double>:y)*' until numPtsInPacket == 0",
		      "Map", "RETURN_UNTIL_EMPTY");

    // 
    myServer->addData("getMapMultiScans", 
                      "Deprecated; getMapWithMaxCategory is preferred", 
		                  &myGetMapMultiScansCB, 
		                  "none", 
		                  "packets of '<string>: line' for header, followed by packets of '<byte4>: numPtsInPacket, (<double>:x, <double>:y)*' until numPtsInPacket == 0",
		                  "Map", "RETURN_UNTIL_EMPTY");
	  
    myServer->addData("getMapWithMaxCategory", 
                      "Requests the map with the specified maximum features; header and info are ascii, data points and lines are binary", 
                      &myGetMapMaxCategoryCB,
                      "string: category (one of the constants defined in ArMapInterface)", 
		                  "packets of '<string>: line' for header, followed by packets of '<byte4>: numPtsInPacket, (<double>:x, <double>:y)*' until numPtsInPacket == 0",
		                  "Map", "RETURN_UNTIL_EMPTY");
  
    
    
    myServer->addData("getMap", "gets the map as a set of ascii lines", 
		            &myGetMapCB, "none", 
			  "packets of '<string>: line' followed by a packet with an empty string to denote end (if only empty string then no map)",
			  "Map", "RETURN_UNTIL_EMPTY");
    myServer->addData("mapUpdated", "a single packet is sent to this when the map is updated and this denotes a new getMap and getMapName should be requested", 
		      NULL, "none", "none", 
		      "Map", "RETURN_SINGLE");
    myServer->addData("getGoals", "gets the list of goals", 
		      &myGetGoalsCB, "none", 
		      "<repeat> string: goal", "Map", "RETURN_SINGLE");
    myServer->addData("goalsUpdated", "a single packet is sent to this when the goals are updated and this denotes a new getGoals should be requested", 
		      NULL, "none", "none", 
		      "Map", "RETURN_SINGLE");

    myServer->addData("checkMap", 
                      "Requests that the server check whether the map needs to be read",
		                  &myCheckMapCB, 
                      "none", 
                      "none",
                      "Map", 
                      "RETURN_NONE|IDLE_PACKET");


  }
}
AREXPORT bool ArClientArg::createArg(ArNetPacket *packet, 
							                       ArConfigArg &argOut,
                                     std::string *parentPathNameOut) 
{
	if (packet == NULL) {
    ArLog::log(ArLog::Verbose, "ArClientArg::createArg() cannot unpack NULL packet");
		return false;
	}

	bool isSuccess = true;

	char name[32000];
	char description[32000];
  myDisplayBuffer[0] = '\0';

	packet->bufToStr(name, sizeof(name));
	packet->bufToStr(description, sizeof(description));


	char priorityVal = packet->bufToByte();
 
	ArPriority::Priority priority = myLastPriority;
  if ((priorityVal >= 0) && (priorityVal <= myLastPriority)) {
    priority = (ArPriority::Priority) priorityVal;
  }

	char argType = packet->bufToByte();

 switch (argType) {
	
 case 'B':
 case 'b': // Lower case indicates display information contained in packet...
	  {
      if ((argType == 'B') || (myIsDisplayHintParsed)) {

		    bool boolVal = false;
		    if (packet->bufToByte()) {
			    boolVal = true;
		    }
		    //packet->bufToStr(myDisplayBuffer, BUFFER_LENGTH);
		    argOut = ArConfigArg(name, boolVal, description);
      }
      else {
        isSuccess = false;
      }
	  }
    break;

  case 'I':
  case 'i':  // Lower case indicates display information contained in packet...
	  {
      if ((argType == 'I') || (myIsDisplayHintParsed)) {
  
		    int intVal = packet->bufToByte4();
		    int intMin = packet->bufToByte4();
		    int intMax = packet->bufToByte4();

		    argOut = ArConfigArg(name, intVal, description, intMin, intMax);
      }
      else {
        isSuccess = false;
      }
  
	  }
    break;

  case 'D':
	case 'd': // Lower case indicates display information contained in packet...
  {
    if ((argType == 'D') || (myIsDisplayHintParsed)) {
 		  double doubleVal = packet->bufToDouble();
		  double doubleMin = packet->bufToDouble();
		  double doubleMax = packet->bufToDouble();
      
      if (myVersion >= 2) {
        int precision = packet->bufToByte4();
        argOut = ArConfigArg(name, doubleVal, description, doubleMin, doubleMax, precision);
      }
      else {
		    argOut = ArConfigArg(name, doubleVal, description, doubleMin, doubleMax, -1);
      }
	  }
    else {
      isSuccess = false;
    }
  }
  break;

  case 'S':
  case 's': // Lower case indicates display information contained in packet...
	  {
      if ((argType == 'S') || (myIsDisplayHintParsed)) {

		    packet->bufToStr(myBuffer, BUFFER_LENGTH);
				
        //packet->bufToStr(myDisplayBuffer, BUFFER_LENGTH);
  	    argOut = ArConfigArg(name, myBuffer, description, 0);
      }
      else {
        isSuccess = false;
      }
	  }  
    break;

  case 'L':
  case 'l': // Lower case indicates display information contained in packet...
	  {

      if ((argType == 'L') || (myIsDisplayHintParsed)) {
		 
        int childCount = packet->bufToByte4();

        ArConfigArg listArg(ArConfigArg::LIST, name, description);
        ArConfigArg childArg;

        for (int i = 0; ((i < childCount) && (isSuccess)); i++) {
          isSuccess = createArg(packet, 
							                  childArg);
          if (isSuccess) {
            listArg.addArg(childArg);
          }
        }

        if (isSuccess) {
          argOut = listArg;
        }
      }
      else {
        isSuccess = false;
      }
	  }  
    break;

  case '.':
    {
       //if (myIsDisplayHintParsed) {
			 //packet->bufToStr(myDisplayBuffer, BUFFER_LENGTH);
       //}
       argOut = ArConfigArg(ArConfigArg::SEPARATOR);
    }
    break;

  default:

		isSuccess = false;
    ArLog::log(ArLog::Terse, 
               "ArClientArg::createArg() unsupported param type '%c'",
               argType);
	}

  argOut.setConfigPriority(priority);
  if (myIsDisplayHintParsed) {

    if (isSuccess) {
		  packet->bufToStr(myDisplayBuffer, BUFFER_LENGTH);
    }

    IFDEBUG(
      if (strlen(myDisplayBuffer) > 0) {
        ArLog::log(ArLog::Verbose, "ArClientArg::createArg() arg %s has displayHint = %s",
                  argOut.getName(), myDisplayBuffer);
      }
    );

    argOut.setDisplayHint(myDisplayBuffer);
  }
/** 
    @internal

    doesn't delete the old one, do that if you're going to call this
    yourself and make sure you lock around all that (okay, it deletes
    it now, but the stuff that calls it should still take care of it)
**/
void ArServerHandlerConfig::createDefaultConfig(const char *defaultFileBaseDir)
{
  if (myDefault != NULL)
  {
    delete myDefault;
    myDefault = NULL;
  }
  // copy that config (basedir will be NULL if we're not loading from
  // a file)... don't have the default save unknown values
  myDefault = new ArConfig(defaultFileBaseDir, false, false, false, false);

  std::list<ArConfigSection *>::iterator sectionIt;
  std::list<ArConfigArg>::iterator paramIt;
  ArConfigSection *section = NULL;
  std::list<ArConfigArg> *params = NULL;
  ArConfigArg param;
  for (sectionIt = myConfig->getSections()->begin(); 
       sectionIt != myConfig->getSections()->end(); 
       sectionIt++)
  {
    section = (*sectionIt);
    params = section->getParams();
    for (paramIt = params->begin(); paramIt != params->end(); paramIt++)
    {
      param = (*paramIt);
      switch (param.getType()) {
      case ArConfigArg::INT:
	myDefault->addParam(
		ArConfigArg(param.getName(), param.getInt(), 
			    param.getDescription(), 
			    param.getMinInt(), param.getMaxInt()), 
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
      case ArConfigArg::DOUBLE:
	myDefault->addParam(
		ArConfigArg(param.getName(), param.getDouble(), 
			    param.getDescription(),
			    param.getMinDouble(), param.getMaxDouble()), 
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
	
      case ArConfigArg::BOOL:
	myDefault->addParam(
		ArConfigArg(param.getName(), param.getBool(), 
			    param.getDescription()),
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
	
      case ArConfigArg::STRING:
	myDefault->addParam(
		ArConfigArg(param.getName(), (char *)param.getString(), 
			    param.getDescription(), 0),
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
	
      case ArConfigArg::SEPARATOR:
	myDefault->addParam(
		ArConfigArg(ArConfigArg::SEPARATOR),
		section->getName(), 
		param.getConfigPriority(),
		param.getDisplayHint());
	break;
      default:
	break;
      } // end switch param type
    } // end for each param
  } // end for each section
}
AREXPORT void ArRobotConfig::connectCallback(void)
{
  std::string section;
  section = "Robot config";

  if (!mySavedOriginalMovementParameters)
  {
    mySavedOriginalMovementParameters = true;
    myOriginalTransVelMax = ArMath::roundInt(myRobot->getTransVelMax());
    myOriginalTransAccel = ArMath::roundInt(myRobot->getTransAccel());
    myOriginalTransDecel = ArMath::roundInt(myRobot->getTransDecel());
    myOriginalRotVelMax = ArMath::roundInt(myRobot->getRotVelMax());
    myOriginalRotAccel = ArMath::roundInt(myRobot->getRotAccel());
    myOriginalRotDecel = ArMath::roundInt(myRobot->getRotDecel());
  }

  if (!myAddedMovementParams)
  {
    myAddedMovementParams = true;
    Aria::getConfig()->addParam(
	    ArConfigArg("TransVelMax", &myTransVelMax, 
			"maximum translational speed (mm/sec) (0 means use original value)",
			0, (int)myRobot->getAbsoluteMaxTransVel()), 
	    section.c_str(), ArPriority::TRIVIAL);
    Aria::getConfig()->addParam(
	    ArConfigArg("TransAccel", &myTransAccel, 
			"translational acceleration (mm/sec/sec) (0 means use original value)",
			0, (int)myRobot->getAbsoluteMaxTransAccel()), 
	    section.c_str(), ArPriority::TRIVIAL);
    Aria::getConfig()->addParam(
	    ArConfigArg("TransDecel", &myTransDecel, 
			"translational deceleration (mm/sec/sec) (0 means use original value)",
			0, (int)myRobot->getAbsoluteMaxTransDecel()), 
	    section.c_str(), ArPriority::TRIVIAL);
    Aria::getConfig()->addParam(
	    ArConfigArg("RotVelMax", &myRotVelMax, 
			"maximum rotational speed (deg/sec) (0 means use original value)",
			0, (int)myRobot->getAbsoluteMaxRotVel()), 
	    section.c_str(), ArPriority::TRIVIAL);
    Aria::getConfig()->addParam(
	    ArConfigArg("RotAccel", &myRotAccel, 
			"rotational acceleration (deg/sec/sec) (0 means use original value)",
			0, (int)myRobot->getAbsoluteMaxRotAccel()), 
	    section.c_str(), ArPriority::TRIVIAL);
    Aria::getConfig()->addParam(
	    ArConfigArg("RotDecel", &myRotDecel, 
			"rotational deceleration (deg/sec/sec) (0 means use original value)",
			0, (int)myRobot->getAbsoluteMaxRotDecel()), 
	    section.c_str(), ArPriority::TRIVIAL);
  }

  if (myAnalogGyro != NULL && !myAddedGyro && 
      myAnalogGyro->haveGottenData())
  {
    myAddedGyro = true;
    Aria::getConfig()->addParam(
	    ArConfigArg("UseGyro", &myUseGyro, 
			"True to use the gyro, false not to"),
	    section.c_str(), ArPriority::TRIVIAL);

  }

}
Beispiel #19
0
AREXPORT ArRobotParams::ArRobotParams() :
  ArConfig(NULL, true),
  myIRUnitGetFunctor(this, &ArRobotParams::getIRUnits),
  myIRUnitSetFunctor(this, &ArRobotParams::parseIRUnit),
  mySonarUnitGetFunctor(this, &ArRobotParams::getSonarUnits),
  mySonarUnitSetFunctor(this, &ArRobotParams::parseSonarUnit)
{
  sprintf(myClass, "Pioneer");
  mySubClass[0] = '\0';
  myRobotRadius = 250;
  myRobotDiagonal = 120;
  myRobotWidth = 400;
  myRobotLength = 500; 
  myRobotLengthFront = 0; 
  myRobotLengthRear = 0; 
  myHolonomic = true;
  myAbsoluteMaxVelocity = 0;
  myAbsoluteMaxRVelocity = 0;
  myHaveMoveCommand = true;
  myAngleConvFactor = 0.001534;
  myDistConvFactor = 0;
  myVelConvFactor = 1.0;
  myRangeConvFactor = 0;
  myVel2Divisor = 20;
  myGyroScaler = 1.626;
  myNumSonar = 0;
  myTableSensingIR = false;
  myNewTableSensingIR = false;
  myFrontBumpers = false;
  myNumFrontBumpers = 5;
  myRearBumpers = false;
  myNumRearBumpers = 5;
  myNumSonar = 0;
  myNumIR = 0;
  mySonarMap.clear();
  myIRMap.clear();
  myLaserPossessed = false;
  sprintf(myLaserPort, "COM3");
  myLaserFlipped = false;
  myLaserPowerControlled = true;
  myLaserX = 0;
  myLaserY = 0;
  myLaserTh = 0.0;
  myLaserIgnore[0] = '\0';
  
  myRequestIOPackets = false;
  myRequestEncoderPackets = false;
  mySwitchToBaudRate = 38400;

  mySettableVelMaxes = true;
  myTransVelMax = 0;
  myRotVelMax = 0;

  mySettableAccsDecs = true;
  myTransAccel = 0;
  myTransDecel = 0;
  myRotAccel = 0;
  myRotDecel = 0;

  addComment("Robot parameter file");
//  addComment("");
  //addComment("General settings");
  std::string section;
  section = "General settings";
  addParam(ArConfigArg("Class", myClass, "general type of robot", 
		 sizeof(myClass)), section.c_str(), ArPriority::TRIVIAL);
  addParam(ArConfigArg("Subclass", mySubClass, "specific type of robot", 
		       sizeof(mySubClass)), section.c_str(), 
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("RobotRadius", &myRobotRadius, "radius in mm"), 
	   section.c_str(), ArPriority::NORMAL);
  addParam(ArConfigArg("RobotDiagonal", &myRobotDiagonal, 
		 "half-height to diagonal of octagon"), "General settings",
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("RobotWidth", &myRobotWidth, "width in mm"), 
	   section.c_str(), ArPriority::NORMAL);
  addParam(ArConfigArg("RobotLength", &myRobotLength, "length in mm of the whole robot"),
	   section.c_str(), ArPriority::NORMAL);
  addParam(ArConfigArg("RobotLengthFront", &myRobotLengthFront, "length in mm to the front of the robot (if this is 0 (or non existant) this value will be set to half of RobotLength)"),
	   section.c_str(), ArPriority::NORMAL);
  addParam(ArConfigArg("RobotLengthRear", &myRobotLengthRear, "length in mm to the rear of the robot (if this is 0 (or non existant) this value will be set to half of RobotLength)"), 
	   section.c_str(), ArPriority::NORMAL);
  addParam(ArConfigArg("Holonomic", &myHolonomic, "turns in own radius"), 
	   section.c_str(), ArPriority::TRIVIAL);
  addParam(ArConfigArg("MaxRVelocity", &myAbsoluteMaxRVelocity, 
		       "absolute maximum degrees / sec"), section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("MaxVelocity", &myAbsoluteMaxVelocity, 
		 "absolute maximum mm / sec"), section.c_str(), 
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("HasMoveCommand", &myHaveMoveCommand, 
		 "has built in move command"), section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("RequestIOPackets", &myRequestIOPackets,
		 "automatically request IO packets"), section.c_str(),
	   ArPriority::NORMAL);
  addParam(ArConfigArg("RequestEncoderPackets", &myRequestEncoderPackets,
		       "automatically request encoder packets"), 
	   section.c_str(), ArPriority::NORMAL);
  addParam(ArConfigArg("SwitchToBaudRate", &mySwitchToBaudRate, 
		 "switch to this baud if non-0 and supported on robot"), 
	   section.c_str(), ArPriority::IMPORTANT);
  
  section = "Conversion factors";
  addParam(ArConfigArg("AngleConvFactor", &myAngleConvFactor,
		     "radians per angular unit (2PI/4096)"), section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("DistConvFactor", &myDistConvFactor,
		       "multiplier to mm from robot units"), section.c_str(),
	   ArPriority::IMPORTANT);
  addParam(ArConfigArg("VelConvFactor", &myVelConvFactor,
		     "multiplier to mm/sec from robot units"), 
	   section.c_str(),
	   ArPriority::NORMAL);
  addParam(ArConfigArg("RangeConvFactor", &myRangeConvFactor, 
		       "multiplier to mm from sonar units"), section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("DiffConvFactor", &myDiffConvFactor, 
		     "ratio of angular velocity to wheel velocity (unused in newer firmware that calculates and returns this)"), 
	   section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("Vel2Divisor", &myVel2Divisor, 
		       "divisor for VEL2 commands"), section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("GyroScaler", &myGyroScaler, 
		     "Scaling factor for gyro readings"), section.c_str(),
	   ArPriority::IMPORTANT);

  section = "Accessories the robot has";
  addParam(ArConfigArg("TableSensingIR", &myTableSensingIR,
		       "if robot has upwards facing table sensing IR"), 
	   section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("NewTableSensingIR", &myNewTableSensingIR,
		 "if table sensing IR are sent in IO packet"), 
	   section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("FrontBumpers", &myFrontBumpers, 
		 "if robot has a front bump ring"), section.c_str(),
	   ArPriority::IMPORTANT);
  addParam(ArConfigArg("NumFrontBumpers", &myNumFrontBumpers,
		     "number of front bumpers on the robot"), 
	   section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("RearBumpers", &myRearBumpers,
		       "if the robot has a rear bump ring"), section.c_str(),
	   ArPriority::IMPORTANT);
  addParam(ArConfigArg("NumRearBumpers", &myNumRearBumpers,
		       "number of rear bumpers on the robot"), section.c_str(),
	   ArPriority::TRIVIAL);

  section = "IR parameters";
  addParam(ArConfigArg("IRNum", &myNumIR, "number of IRs on the robot"), section.c_str(), ArPriority::NORMAL);
   addParam(ArConfigArg("IRUnit", &myIRUnitSetFunctor, &myIRUnitGetFunctor,
			"IRUnit <IR Number> <IR Type> <Persistance, cycles> <x position, mm> <y position, mm>"), 
	    section.c_str(), ArPriority::TRIVIAL);


  section = "Sonar parameters";
  addParam(ArConfigArg("SonarNum", &myNumSonar, 
		     "number of sonar on the robot"), section.c_str(),
	   ArPriority::NORMAL);
  addParam(ArConfigArg("SonarUnit", &mySonarUnitSetFunctor, 
		     &mySonarUnitGetFunctor,
		     "SonarUnit <sonarNumber> <x position, mm> <y position, mm> <heading of disc, degrees>"), section.c_str(), ArPriority::TRIVIAL);


  section = "Laser parameters";
  addParam(ArConfigArg("LaserPossessed", &myLaserPossessed, 
		     "if there is a laser on the robot"), section.c_str(),
	   ArPriority::IMPORTANT);
  addParam(ArConfigArg("LaserPort", myLaserPort, "port the laser is on", 
		     sizeof(myLaserPort)), section.c_str(),
	   ArPriority::NORMAL);
  addParam(ArConfigArg("LaserFlipped", &myLaserFlipped,
		     "if the laser is upside-down or not"), section.c_str(),
	   ArPriority::NORMAL);
  addParam(ArConfigArg("LaserPowerControlled", &myLaserPowerControlled,
		     "if the power to the laser is controlled by serial"), 
	   section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("LaserX", &myLaserX, "x location of laser, mm"), 
	   section.c_str(),
	   ArPriority::NORMAL);
  addParam(ArConfigArg("LaserY", &myLaserY, "y location of laser, mm"), 
	   section.c_str(),
	   ArPriority::NORMAL);
  addParam(ArConfigArg("LaserTh", &myLaserTh, "rotation of laser, deg"), 
	   section.c_str(),
	   ArPriority::NORMAL);
  addParam(ArConfigArg("LaserIgnore", myLaserIgnore, "Readings within a degree of the listed degrees (separated by a space) will be ignored", sizeof(myLaserIgnore)), 
	   section.c_str(),
	   ArPriority::NORMAL);

  section = "Movement control parameters";
  setSectionComment(section.c_str(), "if these are 0 the parameters from robot flash will be used, otherwise these values will be used");
  addParam(ArConfigArg("SettableVelMaxes", &mySettableVelMaxes, "if TransVelMax and RotVelMax can be set"), section.c_str(),
	   ArPriority::TRIVIAL);
  addParam(ArConfigArg("TransVelMax", &myTransVelMax, "maximum desired translational velocity for the robot"), section.c_str(), 
	   ArPriority::IMPORTANT);
  addParam(ArConfigArg("RotVelMax", &myRotVelMax, "maximum desired rotational velocity for the robot"), section.c_str(),
	   ArPriority::IMPORTANT);
  addParam(ArConfigArg("SettableAccsDecs", &mySettableAccsDecs, "if the accel and decel parameters can be set"), section.c_str(), ArPriority::TRIVIAL);
  addParam(ArConfigArg("TransAccel", &myTransAccel, "translational acceleration"), 
	   section.c_str(), ArPriority::IMPORTANT);
  addParam(ArConfigArg("TransDecel", &myTransDecel, "translational deceleration"), 

	   section.c_str(), ArPriority::IMPORTANT);
  addParam(ArConfigArg("RotAccel", &myRotAccel, "rotational acceleration"), 
	   section.c_str());
  addParam(ArConfigArg("RotDecel", &myRotDecel, "rotational deceleration"),
	   section.c_str(), ArPriority::IMPORTANT);

}
AREXPORT void ArActionDeceleratingLimiter::addToConfig(ArConfig *config,
        const char *section,
        const char *prefix)
{
    std::string strPrefix;
    std::string name;
    if (prefix == NULL || prefix[0] == '\0')
        strPrefix = "";
    else
        strPrefix = prefix;

    config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section, ArPriority::NORMAL);

    name = strPrefix;
    name += "Clearance";
    config->addParam(
        ArConfigArg(name.c_str(), &myClearance,
                    "Don't get closer than this to something in front or back. (mm)"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "SlowSpeed";
    config->addParam(
        ArConfigArg(name.c_str(),
                    &mySlowSpeed,
                    "Consider this speed slow (mm/sec)"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "SideClearanceAtSlowSpeed";
    config->addParam(
        ArConfigArg(name.c_str(),
                    &mySideClearanceAtSlowSpeed,
                    "Don't get closer than this to something on the side if we're going at slow speed or below. (mm)"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "PaddingAtSlowSpeed";
    config->addParam(
        ArConfigArg(name.c_str(), &myPaddingAtSlowSpeed,
                    "Try to stop this far away from clearance at slow speed or below. (mm)"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "FastSpeed";
    config->addParam(
        ArConfigArg(name.c_str(),
                    &myFastSpeed,
                    "Consider this speed fast (mm/sec)"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "SideClearanceAtFastSpeed";
    config->addParam(
        ArConfigArg(name.c_str(),
                    &mySideClearanceAtFastSpeed,
                    "Don't get closer than this to something on the side if we're going at fast speed or above. (mm)"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "PaddingAtFastSpeed";
    config->addParam(
        ArConfigArg(name.c_str(), &myPaddingAtFastSpeed,
                    "Try to stop this far away from clearance at fast speed or below. (mm)"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "PreferredDecel";
    config->addParam(
        ArConfigArg(name.c_str(),
                    &myPreferredDecel,
                    "The maximum decel we'll use until something might infringe on clearance and sideClearanceAtSlowSpeed (mm/sec/sec"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "MaxEmergencyDecel";
    config->addParam(
        ArConfigArg(name.c_str(),
                    &myMaxEmergencyDecel,
                    "The maximum decel we'll ever use, 0 means use the robot's maximum (mm/sec/sec"),
        section, ArPriority::NORMAL);

    name = strPrefix;
    name += "UseEStop";
    config->addParam(
        ArConfigArg(name.c_str(),
                    &myUseEStop,
                    "Whether to use an EStop to stop if something will intrude on our clearance"),
        section, ArPriority::NORMAL);

    config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section, ArPriority::NORMAL);
}
int main(int argc, char **argv)
{
  Aria::init();
  ArServerBase server;
  
  ArConfig *config;
  config = Aria::getConfig();
  std::string section;
  char joy[512];
  sprintf(joy, "Joy");
  section = "section1";
  config->addParam(ArConfigArg("int", new int, "fun int", 0), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("double", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("bool", new bool, "fun bool"), section.c_str(), ArPriority::IMPORTANT);
  config->addParam(ArConfigArg("string", joy, "fun string", sizeof(joy)), section.c_str(), ArPriority::TRIVIAL);
  section = "section8";
  config->addParam(ArConfigArg("int", new int, "fun int", 0), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("double", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("doubleFOUR", (double).4, "fun double", 0.0, 1.0), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("double three", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("double two", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("double one", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("double", new double, "fun double", 0, 1), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("bool", new bool, "fun bool"), section.c_str(), ArPriority::IMPORTANT);
  config->addParam(ArConfigArg("string", joy, "fun string", sizeof(joy)), section.c_str(), ArPriority::TRIVIAL);
  section = "some section";
  config->setSectionComment("some section", "this is a random section with 4 ints");
  config->addParam(ArConfigArg("int1", new int, "fun int"), section.c_str(), ArPriority::TRIVIAL);
  config->addParam(ArConfigArg("int2", new int, "fun int", -1, 1200), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("int3", new int, "fun int"), section.c_str(), ArPriority::IMPORTANT);
  config->addParam(ArConfigArg("int4", new int, "fun int"), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("int4", new int, "fun int"), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("int1", new int, "fun int"), section.c_str(), ArPriority::TRIVIAL);
  section = "another section";
  config->setSectionComment("another section", "this is another section with 1 of each type");
  config->addParam(ArConfigArg("inta", new int, "fun int"), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("doublea", new double, "fun double"), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("boola", new bool, "fun bool"), section.c_str(), ArPriority::NORMAL);
  config->addParam(ArConfigArg("stringa", new char[512], "fun string", 512), section.c_str(), ArPriority::NORMAL);

  if (!server.open(7272))
  {
    printf("Could not open server port\n");
    exit(1);
  }
  config->setBaseDirectory("./");
  config->writeFile("default.txt");
  config->parseFile("modified.txt");
  config->writeFile("modifiedModified.txt");
  ArServerHandlerConfig configHandler(&server, Aria::getConfig(), 
				      "default.txt");
  
  server.run();
  
  Aria::shutdown();

  return 0;
}
AREXPORT void ArLaserFilter::addToConfig(ArConfig *config, 
					       const char *sectionName,
					       const char *prefix)
{
  std::string name;
  
  config->addSection(ArConfig::CATEGORY_ROBOT_OPERATION,
                     sectionName,
                     "");

  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), sectionName,
		     ArPriority::FACTORY);
  name = prefix;
  name += "AngleSpread";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAngleToCheck,
	      "Filter settings.  The angle spread to check on either side of each reading",
		      0),
	  sectionName, ArPriority::FACTORY);

  name = prefix;
  name += "AnyNeighborFactor";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAnyFactor,
	      "Filter settings.  If a reading (decided by the anglespread) is further than any of its neighbor reading times this factor, it is ignored... so a value between 0 and 1 will check if they're all closer, a value greater than 1 will see if they're all further, negative values means this factor won't be used",
		      -1),
	  sectionName, ArPriority::FACTORY);

  name = prefix;
  name += "AllNeighborFactor";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAllFactor,
	      "Filter settings.  If a reading (decided by the anglespread) is further than all of its neighbor reading times this factor, it is ignored... so a value between 0 and 1 will check if they're all closer, a value greater than 1 will see if they're all further, negative values means this factor won't be used",
		      -1),
	  sectionName, ArPriority::FACTORY);

  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), sectionName,
		   ArPriority::FACTORY);

  name = prefix;
  name += "AnyNeighborMinRange";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAnyMinRange,
	      "Filter settings.  If a reading itself, or if it has a neighbor (decided by the anglespread) that is closer than this value (in mm) it is ignored... negative values means this factor won't be used",
		      -1),
	  sectionName, ArPriority::FACTORY);

  name = prefix;
  name += "AnyNeighborMinRangeLessThanAngle";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAnyMinRangeLessThanAngle,
	      "Filter settings.  The AnyNeighborMinRange will only be applied to angles LESS than this (so the AnyNeighborMinRange filter will only apply angles below this, or above GreatestAngle)"),
	  sectionName, ArPriority::FACTORY);

  name = prefix;
  name += "AnyNeighborMinRangeGreaterThanAngle";
  config->addParam(
	  ArConfigArg(name.c_str(), &myAnyMinRangeGreaterThanAngle,
	      "Filter settings.  The AnyNeighborMinRange will only be applied to angles GREATER than this (so the AnyNeighborMinRange filter will only apply above this, or below LeastAngle)"),
	  sectionName, ArPriority::FACTORY);

  config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), sectionName,
		   ArPriority::FACTORY);

}