configurable.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2011 LpzRobots development team                    *
00003  *    Georg Martius  <georg dot martius at web dot de>                     *
00004  *    Frank Guettler <guettler at informatik dot uni-leipzig dot de        *
00005  *    Frank Hesse    <frank at nld dot ds dot mpg dot de>                  *
00006  *    Ralf Der       <ralfder at mis dot mpg dot 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 #ifndef __CONFIGURABLE_H
00025 #define __CONFIGURABLE_H
00026 
00027 #include <iostream>
00028 #include <cstdlib>
00029 
00030 #include <limits>
00031 #include <list>
00032 #include <utility>
00033 #include <string>
00034 #include <map>
00035 #include "stl_adds.h"
00036 #include "backcaller.h"
00037 
00038 /**
00039  Abstact class for configurable objects. Sort of Hashmap interface. Parameters are double, int or boolean values
00040 
00041  The Configurator is a (planned) external tool that can be used for changing the values of configurable objects.
00042 
00043  * Protocoll for Configurator:
00044  \code
00045  To Configurator (BNF notation):
00046  Conf         := <Comp>*
00047  Comp         := <CompName> <Pair>*
00048  CompName     := [<string>][<int>]<newline>
00049  Pair         := <alphanum>=<double><newline>
00050  \endcode
00051  the remaining tags are self explanatory
00052 
00053  Example
00054  \code
00055  [Component name which can contain spaces and digits and .,- ][ID1]
00056  key1 = value1
00057  key2 = value2
00058  .
00059  .
00060  [Other Component name which can contain spaces and digits and .,- ][ID2]
00061  key3 = value3
00062  \endcode
00063 
00064  Answer: (from Communicator to Simulation environment)\n
00065  1. On change of a parameter:
00066  \code
00067  [ID] key=newvalue
00068  \endcode
00069  or
00070  \code
00071  key=newvalue
00072  \endcode
00073  the latter one means that the parameter is changed in all components
00074 
00075  2. Request of the description as defined above.
00076  \code
00077  #Something I don\'t care
00078  \endcode
00079  */
00080 
00081 class Configurable : public BackCaller
00082 {
00083   public:
00084   
00085     typedef std::string paramkey;
00086     typedef std::string paramdescr;
00087     // params of type double
00088     typedef double paramval;
00089     typedef std::list<std::pair<paramkey, paramval> > paramlist;
00090     typedef std::map<paramkey, paramval*> parammap;
00091 
00092     // params of type bool
00093     typedef bool parambool;
00094     typedef std::list<std::pair<paramkey, parambool> > paramboollist;
00095     typedef std::map<paramkey, parambool*> paramboolmap;
00096 
00097     // params of type int
00098     typedef int paramint;
00099     typedef std::list<std::pair<paramkey, paramint> > paramintlist;
00100     typedef std::map<paramkey, paramint*> paramintmap;
00101 
00102     typedef std::map<paramkey, paramdescr> paramdescrmap;
00103 
00104     // stuff for bounds
00105     typedef std::pair<paramval, paramval> paramvalBounds;
00106     typedef std::map<paramkey, paramvalBounds> paramvalBoundsMap;
00107     #define valDefMaxBound 10.0
00108     #define valDefMinBound -10.0
00109 
00110     typedef std::pair<paramint, paramint> paramintBounds;
00111     typedef std::map<paramkey, paramintBounds> paramintBoundsMap;
00112     #define intDefMinBound -10
00113     #define intDefMaxBound 10
00114 
00115     typedef std::pair<paramkey, paramval*> paramvalpair;
00116     typedef std::pair<paramkey, parambool*> paramboolpair;
00117     typedef std::pair<paramkey, paramint*> paramintpair;
00118 
00119     typedef std::vector<Configurable*> configurableList;
00120 
00121     /// nice predicate function for finding by ID
00122     struct matchId : public std::unary_function<Configurable*, bool>
00123     {
00124         matchId(int id) :
00125           id(id)
00126         {
00127         }
00128         int id;
00129         bool operator()(Configurable* c)
00130         {
00131           return c->id == id;
00132         }
00133     };
00134 
00135     Configurable()
00136     {
00137       id = rand();
00138     }
00139     /// intialise with name and revision (use "$ID$")
00140     Configurable(const std::string& name, const std::string& revision) :
00141       name(name), revision(revision)
00142     {
00143       id = rand();
00144     }
00145 
00146 //   Configurable(const Configurable& copy)
00147 //     :id(copy.id), name(copy.name), revision(revision), 
00148 //      mapOfValues(mapOfValues), mapOfBoolean(mapOfBoolean), mapOfInteger(mapOfInteger)
00149 //   {  
00150 //   }
00151   
00152 
00153     virtual ~Configurable()
00154     {
00155     }
00156 
00157     /**
00158        Is called when a parameter was changes via setParam(). Note that
00159        it is not called of parameters of childs are changed, then there notifyOnChange() method
00160        is called. The key and of the changed parameter 
00161        (use getParam() to retrieve its actual value).
00162        Overload this function when special actions have to be taken on parameter changes.
00163     */
00164     virtual void notifyOnChange(const paramkey& key){}
00165 
00166     /**
00167      This is the new style for adding configurable parameters. Just call this function
00168      for each parameter and you are done.
00169      If you need to do some special treatment for setting (or getting) of the parameter
00170      you can handle this by overloading getParam and setParam
00171      */
00172     virtual void addParameter(const paramkey& key, paramval* val, 
00173                               paramval minBound, paramval maxBound,
00174                               const paramdescr& descr = paramdescr() ) {
00175       mapOfValues[key] = val;
00176       if (minBound>*val) minBound = (*val)>0 ? 0 : (*val)*2;
00177       if (maxBound<*val) maxBound = (*val)>0 ? (*val)*2 : 0;
00178       if(!descr.empty()) mapOfDescr[key] = descr;
00179       mapOfValBounds[key]=paramvalBounds(minBound,maxBound);
00180     }
00181 
00182     ///  See addParameter(const paramkey& key, paramval* val, paramval minBound, paramval maxBound, const paramdescr& descr)
00183     virtual void addParameter(const paramkey& key, paramval* val, 
00184                               const paramdescr& descr = paramdescr()){
00185       addParameter(key,val,valDefMinBound, valDefMaxBound, descr);
00186     }
00187 
00188 
00189     /**
00190      See addParameter(const paramkey& key, paramval* val) but for bool values
00191      */
00192     virtual void addParameter(const paramkey& key, parambool* val, 
00193                             const paramdescr& descr = paramdescr()) {
00194       mapOfBoolean[key] = val;
00195       if(!descr.empty()) mapOfDescr[key] = descr;
00196     }
00197 
00198     /**
00199      See addParameter(const paramkey& key, paramval* val) but for int values
00200      */
00201     virtual void addParameter(const paramkey& key, paramint* val, 
00202                               paramint minBound, paramint maxBound,
00203                               const paramdescr& descr = paramdescr()) {
00204       mapOfInteger[key] = val;
00205       if (minBound>*val) minBound = (*val)>0 ? 0 : (*val)*2;
00206       if (maxBound<*val) maxBound = (*val)>0 ? (*val)*2 : 0;
00207       if(!descr.empty()) mapOfDescr[key] = descr;
00208       mapOfIntBounds[key]=paramintBounds(minBound,maxBound);
00209     }
00210 
00211     virtual void addParameter(const paramkey& key, paramint* val, 
00212                               const paramdescr& descr = paramdescr()){
00213       addParameter(key,val,intDefMinBound, intDefMaxBound, descr);
00214     }
00215 
00216     /**
00217      This function is only provided for convenience. It does the same as addParameter but set the
00218      variable to the default value
00219      */
00220     virtual void addParameterDef(const paramkey& key, paramval* val, paramval def, 
00221                                  paramval minBound, paramval maxBound,
00222                                  const paramdescr& descr = paramdescr()){
00223       *val = def;
00224       addParameter(key,val, minBound, maxBound, descr);
00225     }
00226 
00227     virtual void addParameterDef(const paramkey& key, paramval* val, paramval def, 
00228                                  const paramdescr& descr = paramdescr()){
00229       addParameterDef(key,val,def,valDefMinBound, valDefMaxBound, descr);
00230     }
00231 
00232 
00233     /// See addParameterDef(const paramkey&, paramval*, paramval)
00234     virtual void addParameterDef(const paramkey& key, parambool* val, parambool def,
00235                                  const paramdescr& descr = paramdescr()) {
00236       *val = def;
00237       addParameter(key,val,descr);
00238     }
00239 
00240     /// See addParameterDef(const paramkey&, paramval*, paramval)
00241     virtual void addParameterDef(const paramkey& key, paramint* val, paramint def, 
00242                                  paramint minBound, paramint maxBound,
00243                                  const paramdescr& descr = paramdescr()) {
00244       *val = def;
00245       addParameter(key,val, minBound, maxBound, descr);
00246     }
00247 
00248     virtual void addParameterDef(const paramkey& key, paramint* val, paramint def, 
00249                                  const paramdescr& descr = paramdescr()) {
00250       addParameterDef(key,val,def,intDefMinBound, intDefMaxBound, descr);
00251     }
00252 
00253     /// sets a description for the given parameter
00254     virtual void setParamDescr(const paramkey& key, const paramdescr& descr, 
00255                                bool traverseChildren = true);
00256 
00257 
00258     /// return the id of the configurable objects, which is created by random on initialisation
00259     int getId() const {
00260       return id;
00261     }
00262 
00263     /// return the name of the object
00264     virtual paramkey getName() const {
00265       return name;
00266     }
00267 
00268     /// returns the revision of the object
00269     virtual paramkey getRevision() const {
00270       return revision;
00271     }
00272 
00273     /**
00274      *  Sets the name of the configurable.
00275      * @param name the name to set
00276      * @param callSetNameOfInspectable if true and if this instance is also inspectable,
00277      * call automatically setNameOfInspectable(name).
00278      */
00279     virtual void setName(const paramkey& name, bool callSetNameOfInspectable = true);
00280 
00281     /// sets the revision Hint: {  return "$ID$"; }
00282     virtual void setRevision(const paramkey& revision) {
00283       this->revision = revision;
00284     }
00285 
00286     /** returns the value of the requested parameter
00287      or 0 (+ error message to stderr) if unknown.
00288      */
00289     virtual paramval getParam(const paramkey& key, bool traverseChildren = true) const;
00290 
00291     /**
00292      * Returns if the requested parameter is part of the configurable or their children
00293      * @param key to search for
00294      * @return true if key found, otherwise false
00295      */
00296     virtual bool hasParam(const paramkey& key, bool traverseChildren = true) const;
00297 
00298     /** sets the value of the given parameter
00299      or does nothing if unknown.
00300      */
00301     virtual bool setParam(const paramkey& key, paramval val, bool traverseChildren = true);
00302 
00303     /**
00304      * Sets the bounds (minBound and maxBound) of the given parameter.
00305      * Not useful for parambool.
00306      * If minBound=maxBound, it is threated as that no bound is given.
00307      */
00308     virtual void setParamBounds(const paramkey& key, paramval minBound, paramval maxBound, bool traverseChildren = true);
00309 
00310     virtual void setParamBounds(const paramkey& key, paramint minBound, paramint maxBound, bool traverseChildren = true);
00311 
00312     virtual void setParamBounds(const paramkey& key, paramvalBounds bounds, bool traverseChildren = true);
00313 
00314     virtual void setParamBounds(const paramkey& key, paramintBounds bounds, bool traverseChildren = true);
00315 
00316     /** The list of all parameters with there value as allocated lists.
00317         Note that these are only parameters that are managed manually (with setParam, getParam)
00318         @see getAllParamNames() 
00319      @return list of key-value pairs
00320      */
00321     virtual paramlist getParamList() const {
00322       return paramlist(); // return an empty list
00323     }
00324 
00325     /// returns all names that are configureable
00326     virtual std::list<paramkey> getAllParamNames(bool traverseChildren = true);
00327 
00328     virtual parammap getParamValMap() const {
00329       return mapOfValues;
00330     }
00331 
00332     virtual paramintmap getParamIntMap() const {
00333       return mapOfInteger;
00334     }
00335 
00336     virtual paramboolmap getParamBoolMap() const {
00337       return mapOfBoolean;
00338     }
00339 
00340     /// returns the description for the given parameter
00341     virtual paramdescr getParamDescr(const paramkey& key, bool traverseChildren = true) const;
00342 
00343     virtual paramvalBounds getParamvalBounds(const paramkey& key, bool traverseChildren = true) const;
00344 
00345     virtual paramintBounds getParamintBounds(const paramkey& key, bool traverseChildren = true) const;
00346 
00347     virtual bool hasParamDescr(const paramkey& key, bool traverseChildren = true) const;
00348 
00349     virtual bool hasParamvalBounds(const paramkey& key, bool traverseChildren = true) const;
00350 
00351     virtual bool hasParamintBounds(const paramkey& key, bool traverseChildren = true) const;
00352 
00353 
00354 
00355 
00356 
00357     /** This is a utility function for inserting the filename and the revision number
00358      at the beginning of the given string buffer str and terminates it.
00359      @param str buffer (call by reference)
00360      that should have space for file+revision+2 characters
00361      @param file filename given by CVS i.e. $RCSfile$
00362      @param revision revision number given by CVS i.e. $Revision$
00363      */
00364     static void insertCVSInfo(paramkey& str, const char* file, const char* revision);
00365 
00366     /** stores the key values paires into the file : filenamestem.cfg
00367      including the comments given in the list
00368      */
00369     virtual bool storeCfg(const char* filenamestem, const std::list<std::string>& comments = std::list<std::string>());
00370     /** restores the key values paires from the file : filenamestem.cfg */
00371     virtual bool restoreCfg(const char* filenamestem);
00372     /// prints the keys, values and descriptions to the file. Each line is prefixed
00373     void print(FILE* f, const char* prefix, int columns=90, bool traverseChildren = true) const;
00374 
00375     /// parses the configuration from the given file
00376     bool parse(FILE* f, const char* prefix = 0, bool traverseChildren = true);
00377 
00378     /**
00379       * Adds a configurable as a child object.
00380       * @param conf the instance to add
00381       */
00382     virtual void addConfigurable(Configurable* conf);
00383 
00384     /**
00385       * Removes a configurable as a child object.
00386       * @param conf the instance to remove
00387       */
00388     virtual void removeConfigurable(Configurable* conf);
00389 
00390     /**
00391      * Returns the list containing all configurable children.
00392      */
00393     virtual const configurableList& getConfigurables() const;
00394 
00395     /**
00396      * Indicates that the configurable itself or the configurable children
00397      * attached to this configurable have changed.
00398      * This method must be called manually so that the Configurator GUI can react
00399      * at the changes.
00400      * This is done through the callbackable interface
00401      * (using CallbackableType CALLBACK_CONFIGURABLE_CHANGED).
00402      */
00403     virtual void configurableChanged();
00404 
00405     static const CallbackableType CALLBACK_CONFIGURABLE_CHANGED = 11;
00406 
00407   protected:
00408     /// copies the internal params of the given configurable
00409     void copyParameters(const Configurable&, bool traverseChildren = true);
00410 
00411     // internal function to print only description in multiline fasion
00412     void printdescr(FILE* f, const char* prefix, const paramkey& key, 
00413                   int columns, int indent) const;
00414 
00415 
00416   private:
00417     int id;
00418     paramkey name;
00419     paramkey revision;
00420 
00421     parammap mapOfValues;
00422     paramboolmap mapOfBoolean;
00423     paramintmap mapOfInteger;
00424     paramdescrmap mapOfDescr;
00425 
00426     paramvalBoundsMap mapOfValBounds;
00427     paramintBoundsMap mapOfIntBounds;
00428 
00429     void initParamBounds(const paramkey& key);
00430 
00431     configurableList ListOfConfigurableChildren;
00432     Configurable* parent;
00433 };
00434 
00435 #endif // __CONFIGURABLE_H
Generated on Thu Jun 28 14:45:36 2012 for Robot Simulator of the Robotics Group for Self-Organization of Control by  doxygen 1.6.3