Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Config.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_Config_h
00003 #define INCLUDED_Config_h
00004 
00005 #include "Shared/plist.h"
00006 #include "Shared/RobotInfo.h"
00007 extern "C" {
00008 #include <jpeglib.h>
00009 }
00010 #ifdef PLATFORM_APERIOS
00011 #  include <OPENR/OPrimitiveControl.h>
00012 #else
00013 typedef unsigned int OSpeakerVolume; //!< provides an OPEN-R type of the same name for compatability, see Config::sound_config::volume
00014 const OSpeakerVolume ospkvolinfdB = 0x8000; //!< 'muted' volume level, see Config::sound_config::volume
00015 const OSpeakerVolume ospkvol25dB  = 0xe700; //!< low volume, see Config::sound_config::volume
00016 const OSpeakerVolume ospkvol18dB  = 0xee00; //!< mid volume, see Config::sound_config::volume
00017 const OSpeakerVolume ospkvol10dB  = 0xf600; //!< high volume, see Config::sound_config::volume
00018 #endif
00019 #include <vector>
00020 #include <string>
00021 
00022 //! a subclass of plist::Dictionary which adds support for filtering settings by robot model, each configuration section is based on this
00023 /*! As a slight extension to standard plists, you can specify
00024  *  model-specific settings by prepending a key with:
00025  *     Model:MODEL_PATTERN:KEY_NAME
00026  *  For example, to use different 'thresh' settings on the ERS-2xx
00027  *  series vs. the ERS-7 model, you would use the keys:
00028  *   - Model:ERS-2*:thresh
00029  *   - Model:ERS-7:thresh
00030  *  You can filter several items as a group by leaving off the second
00031  *  ':' and name, and providing a dictionary as the value.  If the
00032  *  model matches, all entries from the dictionary are imported into
00033  *  the parent dictionary.
00034  */
00035 class ConfigDictionary : public plist::Dictionary {
00036 public:
00037   ConfigDictionary() : plist::Dictionary(false)
00038   {
00039     if(curModel.size()==0)
00040       curModel=RobotName;
00041   }
00042   
00043 protected:
00044   
00045   virtual bool loadXMLNode(const std::string& key, xmlNode* val, const std::string& comment);
00046   virtual bool saveOverXMLNode(xmlNode* k, xmlNode* val, const std::string& key, std::string comment, const std::string& indentStr, std::set<std::string>& seen) const;
00047 
00048   //! returns true if pattern matches model - pattern may have up to 1 '*', case insensitive
00049   static bool matchNoCase(const std::string& model, const std::string& pattern);
00050   
00051   static const std::string msPrefix; //!< the prefix indicating a model-specific key
00052   static const std::string msSep; //!< the separator string which splits the key into the prefix, model pattern, and (optionally) a single key name
00053   //static const std::string msNum;
00054   static std::string curModel; //!< will be set to the model identifier of the currently running hardware
00055   static void initCurModel(); //!< function to initialize #curModel
00056 };
00057 
00058 //! Stores an item for each joint, can be accessed via joint name or array offset
00059 /*! Two main reasons for this class are to keep outputs in offset order (not alphabetic by name),
00060  *  and to strip '~' from output names for backward compatability (used to pad output names
00061  *  to ensure constant string length. */
00062 template<typename T>
00063 class OutputConfig : public ConfigDictionary {
00064 public:
00065   //! constructor
00066   OutputConfig(unsigned int firstOffset, unsigned int numOutputsToStore, const T& defValue)
00067   : ConfigDictionary(), offset(firstOffset), outputs(numOutputsToStore,defValue)
00068   {
00069     for(unsigned int i=0; i<numOutputsToStore; ++i)
00070       addEntry(outputNames[i+firstOffset],outputs[i]);
00071   }
00072   //! strips trailing '~' characters from name before doing usual lookup
00073   virtual ObjectBase& getEntry(const std::string& name) {
00074     std::string::size_type n = name.find_last_not_of('~')+1;
00075     return ConfigDictionary::getEntry((n==name.size()) ? name : name.substr(0,n));
00076   }
00077   //! return the value at position @a index, which must exist (no range checking)
00078   T& getEntry(size_t index) { return outputs[index]; }
00079   //! return the value at position @a index, which must exist (no range checking, equivalent to getEntry(index))
00080   T& operator[](size_t index) { return outputs[index]; }
00081   using ConfigDictionary::operator[];
00082   
00083   //! small trick -- override to save outputs in indexed order instead of alphabetical order
00084   void saveXML(xmlNode* node, bool onlyOverwrite, std::set<std::string>& seen) const;
00085   using ConfigDictionary::saveXML;
00086   
00087 protected:
00088   //! strips trailing '~' characters from name before doing usual lookup
00089   bool loadXMLNode(const std::string& key, xmlNode* val, const std::string& comment) {
00090     std::string::size_type n = key.find_last_not_of('~')+1;
00091     return ConfigDictionary::loadXMLNode((n==key.size()) ? key : key.substr(0,n), val, comment);
00092   }
00093   
00094   unsigned int offset; //!< the index offset of the first entry in #outputs
00095   std::vector<T> outputs; //!< storage of data for each output
00096 };
00097 
00098 //! the root configuration object, provides some global functionality like porting pathnames (portPath())
00099 class Config : public ConfigDictionary {
00100 public:
00101   Config(const std::string& filename="") : ConfigDictionary(),
00102     behaviors(), wireless(), main(), controller(), vision(), motion(this), sound(this), fsRoot()
00103   {
00104     addEntry("wireless",wireless);
00105     addEntry("vision",vision);
00106     addEntry("main",main);
00107     addEntry("behaviors",behaviors);
00108     addEntry("controller",controller);
00109     addEntry("motion",motion);
00110     addEntry("sound",sound);
00111     if(filename.size()!=0)
00112       loadFile(filename.c_str());
00113   }
00114   
00115   enum transports { UDP, TCP }; //!< types of network transport protocols supported
00116   static const unsigned int NUM_TRANSPORTS=2; //!< number of #transports available
00117   static const char * transport_names[NUM_TRANSPORTS+1]; //!< string names for #transports
00118   
00119   void setFileSystemRoot(const std::string& fsr); //!< sets #fsRoot
00120   const std::string& getFileSystemRoot() const { return fsRoot; } //!< returns #fsRoot
00121   std::string portPath(const std::string& path) const; //!< returns a portable version of @a path which should be usable on either the simulator or the robot
00122   
00123   
00124   
00125   // **************************************** //
00126   //! place for users to put their own configuration
00127   // **************************************** //
00128   /*! you can dynamically "link in" external configuration settings by passing them to the addEntry() of the
00129    *  plist::Dictionary superclass.  You may want to call writeParseTree() first to flush current settings,
00130    *  and then readParseTree() afterward to pull any pre-existing values from the configuration
00131    *  file into the instances you've just registered.
00132    *
00133    *  Of course, you could also just write your values into the configuration file first, and just rely
00134    *  on getEntry/setEntry to read/write the value.  This may be more convenient if you use the
00135    *  value infrequently and don't need an instance of it sitting around. */
00136   class behaviors_config : public ConfigDictionary {
00137   public:
00138     //! constructor
00139     behaviors_config() : ConfigDictionary(), flash_bytes(4), flash_on_start(true)
00140     {
00141       //users may want to dynamically link in their own settings when running, so don't warn if there are
00142       // unused items in this section
00143       setUnusedWarning(false);
00144       
00145       addEntry("flash_bytes",flash_bytes,"how many bytes of the address to flash\n"
00146                "You probably already know the first 3 bytes for your network,\n"
00147                "so you might only want the last byte for brevity.\n"
00148                "(valid values are 1 through 4) ");
00149       addEntry("flash_on_start",flash_on_start,"whether or not to automatically trigger on boot\n"
00150                "Will use a priority of kEmergencyPriority+1 in order to override\n"
00151                "the emergency stop's status animation ");
00152     }
00153     plist::Primitive<unsigned int> flash_bytes; //!< how many bytes of the IP to flash
00154     plist::Primitive<bool> flash_on_start;      //!< whether or not to trigger flashing when initially started
00155   } behaviors;
00156 
00157   
00158   
00159   // **************************************** //
00160   //! wireless configuration options
00161   // **************************************** //
00162   class wireless_config : public ConfigDictionary {
00163   public:
00164     //! constructor
00165     wireless_config () : ConfigDictionary(), id(1) {
00166       addEntry("id",id,"id number (in case you have more than one AIBO)");
00167     }
00168     plist::Primitive<int> id; //!< id number (in case you have more than one AIBO)
00169   } wireless;
00170   
00171   
00172   
00173   // **************************************** //
00174   //! general configuration options
00175   // **************************************** //
00176   class main_config : public ConfigDictionary {
00177   public:
00178     //!constructor
00179     main_config()
00180       : ConfigDictionary(), seed_rng(true), console_port(10001), consoleMode(CONTROLLER,consoleModeNames), stderr_port(10002),
00181       wsjoints_port(10031),wspids_port(10032),headControl_port(10052),
00182       walkControl_port(10050),estopControl_port(10053),stewart_port(10055),aibo3d_port(10051),
00183       wmmonitor_port(10061), use_VT100(true), worldState_interval(0)
00184     {
00185       addEntry("seed_rng",seed_rng,"if true, will call srand with timestamp data, mangled by current sensor data");
00186       addEntry("console_port",console_port,"port to send/receive \"console\" information on (separate from system console)");
00187       addEntry("consoleMode",consoleMode,"determines how input on console_port is interpreted\n"+consoleMode.getDescription()+"\n"
00188                "  'controller' will pass it as input to the Controller (assumes same syntax as ControllerGUI)\n"
00189                "  'textmsg' will broadcast it as a TextMsgEvent (textmsgEGID)\n"
00190                "  'auto' is the original mode, which uses 'textmsg' if the ControllerGUI is connected, and 'controller' otherwise ");
00191       addEntry("stderr_port",stderr_port,"port to send error information to");
00192       addEntry("wsjoints_port",wsjoints_port,"port to send joint positions on");
00193       addEntry("wspids_port",wspids_port,"port to send pid info on");
00194       addEntry("headControl_port",headControl_port,"port for receiving head commands");
00195       addEntry("walkControl_port",walkControl_port,"port for receiving walk commands");
00196       addEntry("estopControl_port",estopControl_port,"port for receiving walk commands");
00197       addEntry("stewart_port",stewart_port,"port for running a stewart platform style of control");
00198       addEntry("aibo3d_port",aibo3d_port,"port for send/receive of joint positions from Aibo 3D GUI");
00199       addEntry("wmmonitor_port",wmmonitor_port,"port for monitoring Watchable Memory");
00200       addEntry("use_VT100",use_VT100,"if true, enables VT100 console codes (currently only in Controller menus - 1.3)");
00201       addEntry("worldState_interval",worldState_interval,"time (in milliseconds) to wait between sending WorldState updates over wireless");
00202     }
00203     plist::Primitive<bool> seed_rng;     //!< if true, will call srand with timestamp data, mangled by current sensor data
00204     plist::Primitive<int> console_port;  //!< port to send/receive "console" information on (separate from system console)
00205     //! types that #consoleMode can take on
00206     enum consoleMode_t {
00207       CONTROLLER, //!< all input is interpreted as Controller commands, using same syntax as the GUI sends
00208       TEXTMSG, //!< all input is broadcast as a text message event
00209       AUTO //!< if the GUI is connected, interpret as text messages, otherwise as controller commands.  This was the historical behavior, but seems to be more confusing than helpful.
00210     };
00211     static const unsigned int NUM_CONSOLE_MODES=3; //!< the number of consoleMode_t values available
00212     static const char* consoleModeNames[NUM_CONSOLE_MODES+1]; //!< string names for #consoleMode_t
00213     //! determines how input on #console_port is interpreted
00214     plist::NamedEnumeration<consoleMode_t> consoleMode; 
00215     plist::Primitive<int> stderr_port;   //!< port to send error information to
00216     plist::Primitive<int> wsjoints_port; //!< port to send joint positions on
00217     plist::Primitive<int> wspids_port;   //!< port to send pid info on
00218     plist::Primitive<int> headControl_port;    //!< port for receiving head commands
00219     plist::Primitive<int> walkControl_port;    //!< port for receiving walk commands
00220     plist::Primitive<int> estopControl_port;     //!< port for receiving walk commands
00221     plist::Primitive<int> stewart_port;  //!< port for running a stewart platform style of control
00222     plist::Primitive<int> aibo3d_port;   //!< port for send/receive of joint positions from Aibo 3D GUI
00223     plist::Primitive<int> wmmonitor_port; //!< port for monitoring Watchable Memory
00224     plist::Primitive<bool> use_VT100;    //!< if true, enables VT100 console codes (currently only in Controller menus - 1.3)
00225     plist::Primitive<unsigned int> worldState_interval; //!< time (in milliseconds) to wait between sending WorldState updates over wireless
00226   } main;
00227 
00228   
00229   
00230   // **************************************** //
00231   //! controller information
00232   // **************************************** //
00233   class controller_config : public ConfigDictionary {
00234   public:
00235     //!constructor
00236     controller_config() : ConfigDictionary(), gui_port(10020), select_snd(), next_snd(), prev_snd(), read_snd(), cancel_snd(), error_snd()
00237     {
00238       addEntry("gui_port",gui_port,"port to listen for the GUI to connect to aibo on");
00239       addEntry("select_snd",select_snd,"sound file to use for \"select\" action");
00240       addEntry("next_snd",next_snd,"sound file to use for \"next\" action");
00241       addEntry("prev_snd",prev_snd,"sound file to use for \"prev\" action");
00242       addEntry("read_snd",read_snd,"sound file to use for \"read from std-in\" action");
00243       addEntry("cancel_snd",cancel_snd,"sound file to use for \"cancel\" action");
00244       addEntry("error_snd",error_snd,"sound file to use to signal errors");
00245     }
00246   
00247     plist::Primitive<int> gui_port;        //!< port to listen for the GUI to connect to aibo on
00248     plist::Primitive<std::string> select_snd; //!< sound file to use for "select" action
00249     plist::Primitive<std::string> next_snd;   //!< sound file to use for "next" action
00250     plist::Primitive<std::string> prev_snd;   //!< sound file to use for "prev" action
00251     plist::Primitive<std::string> read_snd;   //!< sound file to use for "read from std-in" action
00252     plist::Primitive<std::string> cancel_snd; //!< sound file to use for "cancel" action
00253     plist::Primitive<std::string> error_snd; //!< sound file to use to signal errors
00254   } controller;
00255 
00256   
00257   
00258   // **************************************** //
00259   //! vision configuration options (this is a *big* section, with sub-sections)
00260   // **************************************** //
00261   class vision_config : public ConfigDictionary {
00262   public:
00263     //!constructor
00264     vision_config() : ConfigDictionary(), 
00265       white_balance(WB_FLUORESCENT), gain(GAIN_MID), shutter_speed(SHUTTER_MID),
00266       resolution(1),
00267       thresh(), colors("config/default.col"), restore_image(true), region_calc_total(true),
00268       jpeg_dct_method(JDCT_IFAST,dct_method_names), aspectRatio(CameraResolutionX/(float)CameraResolutionY),
00269       x_range(aspectRatio>1?1:*aspectRatio), y_range(aspectRatio>1?1/aspectRatio:1),
00270       rawcam(), segcam(), regioncam(), calibration()
00271     {
00272       white_balance.addNameForVal("indoor",WB_INDOOR);
00273       white_balance.addNameForVal("outdoor",WB_OUTDOOR);
00274       white_balance.addNameForVal("fluorescent",WB_FLUORESCENT);
00275       white_balance.addNameForVal("flourescent",WB_FLUORESCENT); //catch common typo
00276       addEntry("white_balance",white_balance,"white balance shifts color spectrum in the image\n"+white_balance.getDescription());
00277       
00278       gain.addNameForVal("low",GAIN_LOW);
00279       gain.addNameForVal("mid",GAIN_MID);
00280       gain.addNameForVal("med",GAIN_MID);
00281       gain.addNameForVal("medium",GAIN_MID);
00282       gain.addNameForVal("high",GAIN_HIGH);
00283       addEntry("gain",gain,"Increasing gain will brighten the image, at the expense of more graininess/noise\n"+gain.getDescription());
00284       
00285       shutter_speed.addNameForVal("slow",SHUTTER_SLOW);
00286       shutter_speed.addNameForVal("low",SHUTTER_SLOW);
00287       shutter_speed.addNameForVal("mid",SHUTTER_MID);
00288       shutter_speed.addNameForVal("med",SHUTTER_MID);
00289       shutter_speed.addNameForVal("medium",SHUTTER_MID);
00290       shutter_speed.addNameForVal("fast",SHUTTER_FAST);
00291       shutter_speed.addNameForVal("high",SHUTTER_FAST);
00292       addEntry("shutter_speed",shutter_speed,"slower shutter will brighten image, but increases motion blur\n"+shutter_speed.getDescription());
00293       
00294       addEntry("resolution",resolution,"the resolution that object recognition system will run at.\nThis counts down from the maximum resolution layer, so higher numbers mean lower resolution. ");
00295       addEntry("thresh",thresh,"Threshold (.tm) files define the mapping from full color to indexed color.\n"
00296                "You can uncomment more than one of these - they will be loaded into separate\n"
00297                "channels of the segmenter.  The only cost of loading multiple threshold files is\n"
00298                "memory - the CPU cost of performing segmentation is only incurred if/when\n"
00299                "the channel is actually accessed for the first time for a given frame. ");
00300       addEntry("colors",colors,"The colors definition (.col) file gives names and a \"typical\" color for display.\n"
00301                "The indexes numbers it contains correspond to indexes in the .tm file\n"
00302                "This file is common to all .tm files; when doing new color segmentations,\n"
00303                "make sure you define colors in the same order as listed here! ");
00304       addEntry("restore_image",restore_image,"Apparently someone at Sony thought it would be a good idea to replace some\n"
00305                "pixels in each camera image with information like the frame number and CDT count.\n"
00306                "If non-zero, will replace those pixels with the actual image pixel value in RawCamGenerator ");
00307       addEntry("region_calc_total",region_calc_total,"When true, this will fill in the CMVision::color_class_state::total_area\n"
00308                "field for each color following region labeling.  If false, the total_area\n"
00309                "will stay 0 (or whatever the last value was), but you save a little CPU. ");
00310       addEntry("jpeg_dct_method",jpeg_dct_method,"pick between dct methods for jpeg compression\n"+jpeg_dct_method.getDescription());
00311       //addEntry("aspectRatio",aspectRatio,"ratio of width to height (x_res/y_res); this is *not* read from configuration file, but set from most recent camera image (or RobotInfo namespace values if no camera image has been received)");
00312       //addEntry("x_range",x_range,"range of values for the x axis when using generalized coordinates; this is *not* read from configuration file, but set from most recent camera image (or RobotInfo namespace values if no camera image has been received)");
00313       //addEntry("y_range",y_range,"range of values for the x axis when using generalized coordinates; this is *not* read from configuration file, but set from most recent camera image (or RobotInfo namespace values if no camera image has been received)");
00314       
00315       addEntry("calibration",calibration,"Lens distortion correction parameters\nComputated by 'Camera Calibration Toolbox for Matlab', by Jean-Yves Bouguet");
00316       addEntry("rawcam",rawcam);
00317       addEntry("segcam",segcam);
00318       addEntry("regioncam",regioncam);
00319     }
00320     
00321 #ifdef PLATFORM_APERIOS
00322     //! white balance levels supported by the Aibo's camera
00323     enum white_balance_levels {
00324       WB_INDOOR=ocamparamWB_INDOOR_MODE,
00325       WB_OUTDOOR=ocamparamWB_OUTDOOR_MODE,
00326       WB_FLUORESCENT=ocamparamWB_FL_MODE
00327     };
00328 #else
00329     //! white balance levels supported by the Aibo's camera
00330     enum white_balance_levels { WB_INDOOR=1, WB_OUTDOOR, WB_FLUORESCENT };
00331 #endif
00332     plist::NamedEnumeration<white_balance_levels> white_balance; //!< white balance shifts color spectrum in the image
00333     
00334 #ifdef PLATFORM_APERIOS
00335     //! gain levels supported by the Aibo's camera
00336     enum gain_levels {
00337       GAIN_LOW=ocamparamGAIN_LOW,
00338       GAIN_MID=ocamparamGAIN_MID,
00339       GAIN_HIGH=ocamparamGAIN_HIGH
00340     };
00341 #else
00342     //! gain levels supported by the Aibo's camera
00343     enum gain_levels { GAIN_LOW=1, GAIN_MID, GAIN_HIGH };
00344 #endif
00345     plist::NamedEnumeration<gain_levels> gain; //!< Increasing gain will brighten the image, at the expense of more graininess/noise
00346 
00347 #ifdef PLATFORM_APERIOS
00348     //! shutter speeds supported by the Aibo's camera
00349     enum shutter_speeds {
00350       SHUTTER_SLOW=ocamparamSHUTTER_SLOW,
00351       SHUTTER_MID=ocamparamSHUTTER_MID,
00352       SHUTTER_FAST=ocamparamSHUTTER_FAST
00353     };
00354 #else
00355     //! shutter speeds supported by the Aibo's camera
00356     enum shutter_speeds { SHUTTER_SLOW=1, SHUTTER_MID, SHUTTER_FAST };
00357 #endif
00358     plist::NamedEnumeration<shutter_speeds> shutter_speed; //!< slower shutter will brighten image, but increases motion blur
00359     
00360     plist::Primitive<int> resolution;       //!< the resolution that object recognition system will run at -- this counts down from the maximum resolution layer, so higher numbers mean lower resolution
00361     plist::ArrayOf<plist::Primitive<std::string> > thresh;      //!< threshold file names
00362     plist::Primitive<std::string> colors;      //!< colors definition (.col) file
00363     plist::Primitive<bool> restore_image;   //!< if true, replaces pixels holding image info with actual image pixels (as much as possible anyway)
00364     plist::Primitive<bool> region_calc_total; //!< if true, RegionGenerator will calculate total area for each color (has to run through the region list for each color)
00365     static const char * dct_method_names[]; //!< string names for #J_DCT_METHOD
00366     plist::NamedEnumeration<J_DCT_METHOD> jpeg_dct_method;  //!< pick between dct methods for jpeg compression
00367     plist::Primitive<float> aspectRatio;    //!< ratio of width to height (x_res/y_res); this is *not* read from configuration file, but set from most recent camera image (or RobotInfo namespace values if no camera image has been received)
00368     plist::Primitive<float> x_range;        //!< range of values for the x axis when using generalized coordinates; this is *not* read from configuration file, but set from most recent camera image (or RobotInfo namespace values if no camera image has been received)
00369     plist::Primitive<float> y_range;        //!< range of values for the x axis when using generalized coordinates; this is *not* read from configuration file, but set from most recent camera image (or RobotInfo namespace values if no camera image has been received)
00370     
00371     //! contains settings related to streaming video over the network
00372     class StreamingConfig : public ConfigDictionary {
00373     public:
00374       explicit StreamingConfig(int portNum) : ConfigDictionary(), port(portNum), transport(Config::UDP,transport_names), interval(0)
00375       {
00376         addEntry("port",port,"the port number to open for sending data over");
00377         addEntry("transport",transport,"the IP protocol to use when sending data");
00378         addEntry("interval",interval,"minimum amount of time (in milliseconds) which must pass between frames\nE.g. 200 yields just under 5 frames per second, 0 is as fast as possible");
00379       }
00380       plist::Primitive<int> port;
00381       plist::NamedEnumeration<Config::transports> transport;
00382       plist::Primitive<unsigned int> interval;
00383     };
00384     
00385     //! contains settings specific to the "RawCam" (original camera images) for streaming video over the network
00386     class RawCamConfig : public StreamingConfig {
00387     public:
00388       RawCamConfig() : StreamingConfig(10011),
00389         encoding(ENCODE_COLOR,encoding_names), channel(0), compression(COMPRESS_JPEG,compression_names), compress_quality(85), y_skip(2), uv_skip(3)
00390       {
00391         addEntry("encoding",encoding,"holds whether to send color or single channel\n"+encoding.getDescription());
00392         addEntry("channel",channel,"if encoding is single channel, this indicates the channel to send");
00393         addEntry("compression",compression,"the type of compression to apply the image\n"+compression.getDescription());
00394         addEntry("compress_quality",compress_quality,"0-100, compression quality (currently only used by jpeg)");
00395         addEntry("y_skip",y_skip,"resolution level to transmit y channel\nAlso used as the resolution level when in single-channel encoding mode ");
00396         addEntry("uv_skip",uv_skip,"resolution level to transmit uv channel at when using 'color' encoding mode");
00397       }
00398       //! type of information to send, stored in #encoding
00399       enum encoding_t {
00400         ENCODE_COLOR, //!< send Y, U, and V channels
00401         ENCODE_SINGLE_CHANNEL, //!< send only a single channel (which channel to send is stored in #channel) This is also used for all seg cam images
00402       };
00403       static const unsigned int NUM_ENCODINGS=2; //!< number of encodings available
00404       static const char * encoding_names[NUM_ENCODINGS+1]; //!< string names for #encoding_t
00405       plist::NamedEnumeration<encoding_t> encoding; //!< holds whether to send color or single channel
00406       plist::Primitive<int> channel;    //!< RawCameraGenerator::channel_id_t, if #encoding is single channel, this indicates the channel to send
00407 
00408       //! compression format to use, stored in Config::vision_config::RawCamConfig::compression
00409       enum compression_t {
00410         COMPRESS_NONE, //!< no compression (other than subsampling)
00411         COMPRESS_JPEG, //!< JPEG compression
00412         COMPRESS_PNG, //!< PNG compression
00413       };
00414       static const unsigned int NUM_COMPRESSIONS=4; //!< number of compression algorithms available
00415       static const char * compression_names[NUM_COMPRESSIONS+1]; //!< string names for #compression_t
00416       plist::NamedEnumeration<compression_t> compression;//!< holds whether to send jpeg compression
00417 
00418       plist::Primitive<int> compress_quality;//!< 0-100, compression quality (currently only used by jpeg)
00419       plist::Primitive<int> y_skip;     //!< resolution level to transmit y channel at
00420       plist::Primitive<int> uv_skip;    //!< resolution level to transmit uv channel at
00421     } rawcam;
00422     
00423     //! contains settings specific to the "SegCam" (segmented color images) for streaming video over the network
00424     class SegCamConfig : public StreamingConfig {
00425     public:
00426       SegCamConfig() : StreamingConfig(10012), skip(1), channel(0), compression(COMPRESS_RLE, compression_names)
00427       {
00428         addEntry("skip",skip,"resolution level to transmit segmented images at");
00429         addEntry("channel",channel,"channel of RLEGenerator to send (i.e. which threshold map to use");
00430         addEntry("compression",compression,"what compression to use on the segmented image"+compression.getDescription());
00431       }
00432       plist::Primitive<int> skip;       //!< resolution level to transmit segmented images at
00433       plist::Primitive<int> channel;    //!< channel of RLEGenerator to send (i.e. which threshold map to use)
00434       
00435       //! compression format to use, stored in Config::vision_config::RawCamConfig::compression
00436       enum compression_t {
00437         COMPRESS_NONE, //!< no compression (other than subsampling)
00438         COMPRESS_RLE   //!< RLE compression
00439       };
00440       static const unsigned int NUM_COMPRESSIONS=4; //!< number of compression algorithms available
00441       static const char * compression_names[NUM_COMPRESSIONS+1]; //!< string names for #compression_t
00442       plist::NamedEnumeration<compression_t> compression;//!< what compression to use on the segmented image
00443     } segcam;
00444     
00445     //! contains settings specific to the "RegionCam" (only display a box for each blob of color) for streaming over the network
00446     class RegionCamConfig : public StreamingConfig {
00447     public: