Robot Simulator of the Robotics Group for Self-Organization of Control: configurable.h Source File

# 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