configurable.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Robot Group Leipzig                             *
00003  *    martius@informatik.uni-leipzig.de                                    *
00004  *    fhesse@informatik.uni-leipzig.de                                     *
00005  *    der@informatik.uni-leipzig.de                                        *
00006  *    guettler@informatik.uni-leipzig.de                                   *
00007  *                                                                         *
00008  *   This program is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   (at your option) any later version.                                   *
00012  *                                                                         *
00013  *   This program is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this program; if not, write to the                         *
00020  *   Free Software Foundation, Inc.,                                       *
00021  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00022  ***************************************************************************
00023  *                                                                         *
00024  *  DESCRIPTION                                                            *
00025  *                                                                         *
00026  *   $Log: configurable.h,v $
00027  *   Revision 1.9  2010/03/03 14:56:30  martius
00028  *   improved printing of parameterdescription
00029  *
00030  *   Revision 1.8  2009/08/05 22:47:10  martius
00031  *   added support for integer variables and
00032  *    proper display for bool and int
00033  *
00034  *   Revision 1.7  2009/08/05 08:36:22  guettler
00035  *   added support for boolean variables
00036  *
00037  *   Revision 1.6  2009/03/27 06:16:57  guettler
00038  *   support for gcc 4.3 compatibility (has to be checked), StatisticTools moves from utils to statistictools
00039  *
00040  *   Revision 1.5  2008/11/14 09:16:15  martius
00041  *   small things
00042  *
00043  *   Revision 1.4  2008/08/14 08:06:02  robot1
00044  *   fixed compile bug
00045  *
00046  *   Revision 1.3  2008/08/01 14:42:03  guettler
00047  *   we try the trip to hell! make selforg AVR compatible...good luck (first changes)
00048  *
00049  *   Revision 1.2  2008/04/29 07:41:40  guettler
00050  *   added GPL and revision tag
00051  *
00052  *   Revision 1.1  2008/04/29 07:39:54  guettler
00053  *   interfaces moved to selforg/utils directory
00054  *
00055  *   Revision 1.7  2008/04/11 14:12:30  martius
00056  *   comments paramter in storeCfg
00057  *
00058  *   Revision 1.6  2007/06/08 15:44:32  martius
00059  *   termination string -> more robust parsing
00060  *
00061  *   Revision 1.5  2007/03/26 13:13:47  martius
00062  *   store and restore with params
00063  *
00064  *   Revision 1.4  2007/01/24 14:38:35  martius
00065  *   new implementation with a map from key to reference.
00066  *   addParameter and addParameterDef are used for registration of a parameter
00067  *   the old style is still supported
00068  *
00069  *   Revision 1.3  2006/07/14 12:23:57  martius
00070  *   selforg becomes HEAD
00071  *
00072  *   Revision 1.1.2.7  2006/06/25 21:56:07  martius
00073  *   configureable has name and revision
00074  *
00075  *   Revision 1.1.2.6  2006/02/08 16:17:40  martius
00076  *   no namespace using
00077  *
00078  *   Revision 1.1.2.5  2006/01/18 16:48:10  martius
00079  *   configurables can be stored and reloaded
00080  *
00081  *   Revision 1.1.2.4  2006/01/18 10:45:32  martius
00082  *   *** empty log message ***
00083  *
00084  *   Revision 1.1.2.3  2006/01/18 10:44:49  martius
00085  *   (re)storeCfg
00086  *
00087  *   Revision 1.1.2.2  2006/01/16 17:40:13  martius
00088  *   parsing works
00089  *
00090  *   Revision 1.1.2.1  2006/01/16 17:27:17  martius
00091  *   *** empty log message ***
00092  *
00093  *                                                                 *
00094  ***************************************************************************/
00095 #ifndef __CONFIGURABLE_H
00096 #define __CONFIGURABLE_H
00097 
00098 #include <iostream>
00099 #include <cstdlib>
00100 
00101 #include <list>
00102 #include <utility>
00103 #include <string>
00104 #include <map>
00105 #include "stl_adds.h"
00106 
00107 /**
00108  Abstact class for configurable objects. Sort of Hashmap interface. Parameters are double, int or boolean values
00109 
00110  The Configurator is a (planned) external tool that can be used for changing the values of configurable objects.
00111 
00112  * Protocoll for Configurator:
00113  \code
00114  To Configurator (BNF notation):
00115  Conf         := <Comp>*
00116  Comp         := <CompName> <Pair>*
00117  CompName     := [<string>][<int>]<newline>
00118  Pair         := <alphanum>=<double><newline>
00119  \endcode
00120  the remaining tags are self explanatory
00121 
00122  Example
00123  \code
00124  [Component name which can contain spaces and digits and .,- ][ID1]
00125  key1 = value1
00126  key2 = value2
00127  .
00128  .
00129  [Other Component name which can contain spaces and digits and .,- ][ID2]
00130  key3 = value3
00131  \endcode
00132 
00133  Answer: (from Communicator to Simulation environment)\n
00134  1. On change of a parameter:
00135  \code
00136  [ID] key=newvalue
00137  \endcode
00138  or
00139  \code
00140  key=newvalue
00141  \endcode
00142  the latter one means that the parameter is changed in all components
00143 
00144  2. Request of the description as defined above.
00145  \code
00146  #Something I don\'t care
00147  \endcode
00148  */
00149 
00150 class Configurable
00151 {
00152   public:
00153   
00154     typedef std::string paramkey;
00155     typedef std::string paramdescr;
00156     // params of type double
00157     typedef double paramval;
00158     typedef std::list<std::pair<paramkey, paramval> > paramlist;
00159     typedef std::map<paramkey, paramval*> parammap;
00160 
00161     // params of type bool
00162     typedef bool parambool;
00163     typedef std::list<std::pair<paramkey, parambool> > paramboollist;
00164     typedef std::map<paramkey, parambool*> paramboolmap;
00165 
00166     // params of type int
00167     typedef int paramint;
00168     typedef std::list<std::pair<paramkey, paramint> > paramintlist;
00169     typedef std::map<paramkey, paramint*> paramintmap;
00170 
00171     typedef std::map<paramkey, paramdescr> paramdescrmap;
00172 
00173     /// nice predicate function for finding by ID
00174     struct matchId : public std::unary_function<Configurable*, bool>
00175     {
00176         matchId(int id) :
00177           id(id)
00178         {
00179         }
00180         int id;
00181         bool operator()(Configurable* c)
00182         {
00183           return c->id == id;
00184         }
00185     };
00186 
00187     Configurable()
00188     {
00189       id = rand();
00190     }
00191     /// intialise with name and revision (use "$ID$")
00192     Configurable(const std::string& name, const std::string& revision) :
00193       name(name), revision(revision)
00194     {
00195       id = rand();
00196     }
00197 
00198 //   Configurable(const Configurable& copy)
00199 //     :id(copy.id), name(copy.name), revision(revision), 
00200 //      mapOfValues(mapOfValues), mapOfBoolean(mapOfBoolean), mapOfInteger(mapOfInteger)
00201 //   {  
00202 //   }
00203   
00204 
00205     virtual ~Configurable()
00206     {
00207     }
00208 
00209     /// return the id of the configurable objects, which is created by random on initialisation
00210     int getId() const {
00211       return id;
00212     }
00213 
00214     /// return the name of the object
00215     virtual paramkey getName() const {
00216       return name;
00217     }
00218 
00219     /// returns the revision of the object
00220     virtual paramkey getRevision() const {
00221       return revision;
00222     }
00223 
00224     /// stes the name of the object
00225     virtual void setName(const paramkey& name){
00226       this->name = name;
00227     }
00228     /// sets the revision Hint: {  return "$ID$"; }
00229     virtual void setRevision(const paramkey& revision) {
00230       this->revision = revision;
00231     }
00232 
00233     /** returns the value of the requested parameter
00234      or 0 (+ error message to stderr) if unknown.
00235      */
00236     virtual paramval getParam(const paramkey& key) const;
00237 
00238     /** sets the value of the given parameter
00239      or does nothing if unknown.
00240      */
00241     virtual bool setParam(const paramkey& key, paramval val);
00242 
00243     /** The list of all parameters with there value as allocated lists.
00244         Note that these are only parameters that are managed manually (with setParam, getParam)
00245         @see getAllParamNames() 
00246      @return list of key-value pairs
00247      */
00248     virtual paramlist getParamList() const {
00249       return paramlist(); // return an empty list
00250     }
00251 
00252     /// returns all names that are configureable
00253     virtual std::list<paramkey> getAllParamNames();
00254 
00255     /// returns the description for the given parameter
00256     virtual paramdescr getParamDescr(const paramkey& key) const;
00257 
00258     /// sets a description for the given parameter
00259     virtual void setParamDescr(const paramkey& key, const paramdescr& descr) {
00260       if(!descr.empty()) mapOfDescr[key] = descr;
00261     }
00262 
00263     /**
00264      This is the new style for adding configurable parameters. Just call this function
00265      for each parameter and you are done.
00266      If you need to do some special treatment for setting (or getting) of the parameter
00267      you can handle this by overloading getParam and setParam
00268      */
00269     virtual void addParameter(const paramkey& key, paramval* val, 
00270                               const paramdescr& descr = paramdescr()) {
00271       mapOfValues[key] = val;
00272       if(!descr.empty()) mapOfDescr[key] = descr;
00273     }
00274 
00275     /**
00276      See addParameter(const paramkey& key, paramval* val) but for bool values
00277      */
00278     virtual void addParameter(const paramkey& key, parambool* val, 
00279                             const paramdescr& descr = paramdescr()) {
00280       mapOfBoolean[key] = val;
00281       if(!descr.empty()) mapOfDescr[key] = descr;
00282     }
00283 
00284     /**
00285      See addParameter(const paramkey& key, paramval* val) but for int values
00286      */
00287     virtual void addParameter(const paramkey& key, paramint* val,
00288                               const paramdescr& descr = paramdescr()) {
00289       mapOfInteger[key] = val;
00290       if(!descr.empty()) mapOfDescr[key] = descr;
00291     }
00292 
00293     /**
00294      This function is only provided for convenience. It does the same as addParameter but set the
00295      variable to the default value
00296      */
00297     virtual void addParameterDef(const paramkey& key, paramval* val, paramval def,
00298                                  const paramdescr& descr = paramdescr()){
00299       *val = def;
00300       addParameter(key,val,descr);
00301     }
00302 
00303     /// See addParameterDef(const paramkey&, paramval*, paramval)
00304     virtual void addParameterDef(const paramkey& key, parambool* val, parambool def,
00305                                  const paramdescr& descr = paramdescr()) {
00306       *val = def;
00307       addParameter(key,val,descr);
00308     }
00309 
00310     /// See addParameterDef(const paramkey&, paramval*, paramval)
00311     virtual void addParameterDef(const paramkey& key, paramint* val, paramint def,
00312                                  const paramdescr& descr = paramdescr()) {
00313       *val = def;
00314       addParameter(key,val,descr);
00315     }
00316 
00317 
00318     /** This is a utility function for inserting the filename and the revision number
00319      at the beginning of the given string buffer str and terminates it.
00320      @param str buffer (call by reference)
00321      that should have space for file+revision+2 characters
00322      @param file filename given by CVS i.e. $RCSfile: configurable.h,v $
00323      @param revision revision number given by CVS i.e. $Revision: 1.9 $
00324      */
00325     static void insertCVSInfo(paramkey& str, const char* file, const char* revision);
00326 
00327     /** stores the key values paires into the file : filenamestem.cfg
00328      including the comments given in the list
00329      */
00330     virtual bool storeCfg(const char* filenamestem, const std::list<std::string>& comments = std::list<std::string>());
00331     /** restores the key values paires from the file : filenamestem.cfg */
00332     virtual bool restoreCfg(const char* filenamestem);
00333     /// prints the keys, values and descriptions to the file. Each line is prefixed
00334     void print(FILE* f, const char* prefix, int columns=90) const;
00335     // internal function to print only description in multiline fasion
00336   void printdescr(FILE* f, const char* prefix, const paramkey& key, 
00337                   int columns, int indent) const;
00338 
00339     void parse(FILE* f);
00340 
00341   private:
00342     int id;
00343     paramkey name;
00344     paramkey revision;
00345 
00346     parammap mapOfValues;
00347     paramboolmap mapOfBoolean;
00348     paramintmap mapOfInteger;
00349     paramdescrmap mapOfDescr;
00350 };
00351 
00352 #endif // __CONFIGURABLE_H
Generated on Fri Nov 4 10:59:38 2011 for Robot Simulator of the Robotics Group for Self-Organization of Control by  doxygen 1.6.3