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 * * 00007 * This program is free software; you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation; either version 2 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License * 00018 * along with this program; if not, write to the * 00019 * Free Software Foundation, Inc., * 00020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00021 * * 00022 * The Idea of this class is a controller wrapped in the wiring * 00023 * with all the plotoptions and so on, just without robot. It * 00024 * seams to be a much better architecture for connecting the controller * 00025 * to a hardware robot or other platforms. * 00026 * * 00027 * * 00028 * $Log: wiredcontroller.h,v $ 00029 * Revision 1.6 2008/08/12 11:50:00 guettler 00030 * plug and play update, added some features for the ECBRobotGUI 00031 * 00032 * Revision 1.5 2008/08/01 14:42:04 guettler 00033 * we try the trip to hell! make selforg AVR compatible...good luck (first changes) 00034 * 00035 * Revision 1.4 2008/05/07 16:45:52 martius 00036 * code cosmetics and documentation 00037 * 00038 * Revision 1.3 2008/05/02 17:20:04 martius 00039 * *** empty log message *** 00040 * 00041 * Revision 1.2 2008/04/17 14:54:35 martius 00042 * randomGen added, which is a random generator with long period and an 00043 * internal state. Each Agent has an instance and passed it to the controller 00044 * and the wiring. This is good for 00045 * a) repeatability on agent basis, 00046 * b) parallel execution as done in ode_robots 00047 * 00048 * Revision 1.1 2007/11/06 15:14:41 martius 00049 * new class that composes controller and wiring 00050 * 00051 * * 00052 ***************************************************************************/ 00053 /* 00054 ** Started on Mon Oct 22 10:50:47 2007 Georg Martius 00055 ** Last update Mon Oct 22 10:50:47 2007 Georg Martius 00056 */ 00057 #ifndef WIREDCONTROLLER_H_ 00058 # define WIREDCONTROLLER_H_ 00059 00060 00061 #ifndef AVR 00062 00063 #include <stdio.h> 00064 #include <list> 00065 #include <utility> 00066 #include <string> 00067 00068 #include "types.h" 00069 #include "randomgenerator.h" 00070 00071 class AbstractController; 00072 class AbstractWiring; 00073 class Configurable; 00074 class Inspectable; 00075 class Callbackable; 00076 class WiredController; 00077 00078 /** Output mode for agent. 00079 */ 00080 enum PlotMode { 00081 /// dummy (does nothing) is there for compatibility, might be removed later 00082 NoPlot, 00083 /// write into file 00084 File, 00085 /// plotting with guilogger (gnuplot) 00086 GuiLogger, 00087 /// plotting with guiscreen (gnuplot) in file logging mode 00088 GuiLogger_File, 00089 /// net visualiser 00090 NeuronViz, 00091 00092 /// Acustic output of robotic values via external SoundMan 00093 SoundMan, 00094 00095 /// gui for ECBRobots (see lpzrobots/ecbrobots), should be usable with OdeRobots, too 00096 ECBRobotGUI, 00097 00098 /// dummy used for upper bound of plotmode type 00099 LastPlot 00100 }; 00101 00102 /** Output either sensors from robot or from controller 00103 (there can be a difference depending on the used wiring) 00104 */ 00105 enum PlotSensors {Robot, Controller}; 00106 00107 /** This class contains options for the use of an external plot utility like guilogger or neuronviz 00108 or just simply file output 00109 */ 00110 class PlotOption { 00111 public: 00112 friend class WiredController; 00113 00114 PlotOption(){ mode=NoPlot; whichSensors=Controller; interval=1; pipe=0; parameter="";} 00115 PlotOption( PlotMode mode, PlotSensors whichSensors = Controller, 00116 int interval = 1, 00117 std::list<const Configurable*> confs = std::list<const Configurable*>(), 00118 std::string parameter="") 00119 : interval(interval), mode(mode), whichSensors(whichSensors), 00120 configureables(confs), parameter(parameter) 00121 { pipe=0; } 00122 00123 virtual ~PlotOption(){} 00124 00125 /// nice predicate function for finding by mode 00126 struct matchMode : public std::unary_function<const PlotOption&, bool> { 00127 matchMode(PlotMode mode) : mode(mode) {} 00128 int mode; 00129 bool operator()(const PlotOption& m) { return m.mode == mode; } 00130 }; 00131 00132 void addConfigurable(const Configurable*); 00133 void setName(const std::string& name) { this->name = name;} 00134 00135 bool open(); ///< opens the connections to the plot tool 00136 void close();///< closes the connections to the plot tool 00137 00138 FILE* pipe; 00139 long t; 00140 int interval; 00141 std::string name; 00142 00143 private: 00144 00145 PlotMode mode; 00146 PlotSensors whichSensors; 00147 std::list< const Configurable* > configureables; 00148 std::string parameter; ///< additional parameter for external command 00149 }; 00150 00151 00152 /** The WiredController contains a controller and a wiring, which 00153 connects the controller with the robot. 00154 Additionally there are some ways to keep track of internal information. 00155 You have the possibility to keep track of sensor values, 00156 motor values and internal parameters of the controller with PlotOptions. 00157 The name PlotOptions is a bit missleaded, it should be "OutputOptions", 00158 however you can write the data into a file or send it to 00159 visualisation tools like guilogger or neuronviz. 00160 */ 00161 class WiredController { 00162 public: 00163 /** constructor. PlotOption as output setting. 00164 noisefactor is used to set the relative noise strength of this agent 00165 */ 00166 WiredController(const PlotOption& plotOption = PlotOption(NoPlot), double noisefactor = 1); 00167 /** constructor. A list of PlotOption can given. 00168 noisefactor is used to set the relative noise strength of this agent 00169 */ 00170 WiredController(const std::list<PlotOption>& plotOptions, double noisefactor = 1); 00171 00172 /** destructor 00173 */ 00174 virtual ~WiredController(); 00175 00176 /** initializes the object with the given controller and wiring 00177 and initializes the output options 00178 It is also possible to provide a random seed, 00179 if not given (0) rand() is used to create one 00180 */ 00181 bool init(AbstractController* controller, AbstractWiring* wiring, 00182 int robotsensornumber, int robotmotornumber, RandGen* randGen=0); 00183 00184 /** Performs an step of the controller, which includes 00185 pushing sensor values through the wiring, 00186 controller step, 00187 pushing controller outputs (= motorcommands) back through the wiring 00188 @param sensors sensors inputs scaled to [-1,1] 00189 @param sensornumber length of the sensor array 00190 @param motors motors outputs. MUST have enough space for motor values! 00191 @param motornumber length of the provided motor array 00192 00193 @param noise Noise strength. 00194 @param time (optional) current simulation time (used for logging) 00195 */ 00196 void step(const sensor* sensors, int sensornumber, 00197 motor* motors, int motornumber, 00198 double noise, double time=-1); 00199 00200 /** Returns a pointer to the controller. 00201 */ 00202 virtual AbstractController* getController() { return controller;} 00203 00204 /** Returns a pointer to the wiring. 00205 */ 00206 virtual AbstractWiring* getWiring() { return wiring;} 00207 00208 /** adds the PlotOptions to the list of plotoptions 00209 If a plotoption with the same Mode exists, then the old one is deleted first 00210 */ 00211 virtual void addPlotOption(const PlotOption& plotoption); 00212 00213 /** removes the PlotOptions with the given type 00214 @return true if sucessful, false otherwise 00215 */ 00216 virtual bool removePlotOption(PlotMode mode); 00217 00218 /** 00219 write comment to output streams (PlotOptions). For instance changes in parameters. 00220 */ 00221 virtual void writePlotComment(const char* cmt); 00222 00223 /** adds an inspectable object for logging. Must be called before addPlotOption and before init! 00224 */ 00225 virtual void addInspectable(const Inspectable* inspectable); 00226 00227 /** adds an Callbackable object for getting a callback every step. 00228 */ 00229 virtual void addCallbackable(Callbackable* callbackable); 00230 00231 protected: 00232 /** 00233 * Plots controller sensor- and motorvalues and internal controller parameters. 00234 * @param rx actual sensorvalues from robot (used for generation of motorcommand in actual timestep) 00235 * @param rsensornumber length of rx 00236 * @param cx actual sensorvalues which are passed to controller (used for generation of motorcommand in actual timestep) 00237 * @param csensornumber length of cx 00238 * @param y actual motorcommand (generated in the actual timestep) 00239 * @param motornumber length of y 00240 * @param time simulation time 00241 */ 00242 virtual void plot(const sensor* rx, int rsensornumber, const sensor* cx, int csensornumber, 00243 const motor* y, int motornumber, double time); 00244 00245 00246 AbstractController* controller; 00247 AbstractWiring* wiring; 00248 00249 /// number of sensors of robot 00250 int rsensornumber; 00251 /// number of motors of robot 00252 int rmotornumber; 00253 /// number of sensors of comntroller 00254 int csensornumber; 00255 /// number of motors of comntroller 00256 int cmotornumber; 00257 00258 /// factor that is muliplied with noise stength 00259 double noisefactor; 00260 00261 motor *cmotors; 00262 sensor *csensors; 00263 00264 void internInit(); 00265 00266 protected: 00267 long int t; 00268 00269 std::list<PlotOption> plotOptions; 00270 std::list<const Inspectable* > inspectables; 00271 bool initialised; 00272 00273 std::list<Callbackable* > callbackables; 00274 00275 }; 00276 00277 #else /* AVR */ 00278 00279 #include "types.h" 00280 #include "randomgenerator.h" 00281 #include "avrtypes.h" 00282 00283 class AbstractController; 00284 class AbstractWiring; 00285 class Configurable; 00286 class Inspectable; 00287 class Callbackable; 00288 class WiredController; 00289 00290 /** Output mode for agent. 00291 */ 00292 enum PlotMode { 00293 /// dummy (does nothing) is there for compatibility, might be removed later 00294 NoPlot, 00295 /// write into file 00296 File, 00297 /// plotting with guilogger (gnuplot) 00298 GuiLogger, 00299 /// plotting with guiscreen (gnuplot) in file logging mode 00300 GuiLogger_File, 00301 /// net visualiser 00302 NeuronViz, 00303 00304 /// Acustic output of robotic values via external SoundMan 00305 SoundMan, 00306 00307 /// dummy used for upper bound of plotmode type 00308 LastPlot 00309 }; 00310 00311 /** Output either sensors from robot or from controller 00312 (there can be a difference depending on the used wiring) 00313 */ 00314 enum PlotSensors {Robot, Controller}; 00315 00316 /** This class contains options for the use of an external plot utility like guilogger or neuronviz 00317 or just simply file output 00318 */ 00319 class PlotOption { 00320 public: 00321 friend class WiredController; 00322 00323 PlotOption(){ mode=NoPlot; whichSensors=Controller; interval=1; pipe=0; parameter="";} 00324 PlotOption( PlotMode mode, PlotSensors whichSensors = Controller, 00325 int interval = 1, 00326 const Configurable*[maxNumberEntries] confs, 00327 charArray parameter="") 00328 : interval(interval), mode(mode), whichSensors(whichSensors), 00329 configureables(confs), parameter(parameter) 00330 { pipe=0; } 00331 00332 virtual ~PlotOption(){} 00333 00334 void addConfigurable(const Configurable*); 00335 void setName(const charArray& name) { this->name = name;} 00336 00337 bool open(); ///< opens the connections to the plot tool 00338 void close();///< closes the connections to the plot tool 00339 00340 FILE* pipe; 00341 long t; 00342 int interval; 00343 charArray name; 00344 00345 private: 00346 00347 PlotMode mode; 00348 PlotSensors whichSensors; 00349 Configurable*[maxNumberEntries] configureables; 00350 charArray parameter; ///< additional parameter for external command 00351 }; 00352 00353 00354 /** The WiredController contains a controller and a wiring, which 00355 connects the controller with the robot. 00356 Additionally there are some ways to keep track of internal information. 00357 You have the possibility to keep track of sensor values, 00358 motor values and internal parameters of the controller with PlotOptions. 00359 The name PlotOptions is a bit missleaded, it should be "OutputOptions", 00360 however you can write the data into a file or send it to 00361 visualisation tools like guilogger or neuronviz. 00362 */ 00363 class WiredController { 00364 public: 00365 /** constructor. PlotOption as output setting. 00366 noisefactor is used to set the relative noise strength of this agent 00367 */ 00368 WiredController(const PlotOption& plotOption = PlotOption(NoPlot), double noisefactor = 1); 00369 /** constructor. A list of PlotOption can given. 00370 noisefactor is used to set the relative noise strength of this agent 00371 */ 00372 WiredController(const PlotOption[maxNumberEntries]& plotOptions, double noisefactor = 1); 00373 00374 /** destructor 00375 */ 00376 virtual ~WiredController(); 00377 00378 /** initializes the object with the given controller and wiring 00379 and initializes the output options 00380 It is also possible to provide a random seed, 00381 if not given (0) rand() is used to create one 00382 */ 00383 bool init(AbstractController* controller, AbstractWiring* wiring, 00384 int robotsensornumber, int robotmotornumber, RandGen* randGen=0); 00385 00386 /** Performs an step of the controller, which includes 00387 pushing sensor values through the wiring, 00388 controller step, 00389 pushing controller outputs (= motorcommands) back through the wiring 00390 @param sensors sensors inputs scaled to [-1,1] 00391 @param sensornumber length of the sensor array 00392 @param motors motors outputs. MUST have enough space for motor values! 00393 @param motornumber length of the provided motor array 00394 00395 @param noise Noise strength. 00396 @param time (optional) current simulation time (used for logging) 00397 */ 00398 void step(const sensor* sensors, int sensornumber, 00399 motor* motors, int motornumber, 00400 double noise, double time=-1); 00401 00402 /** Returns a pointer to the controller. 00403 */ 00404 virtual AbstractController* getController() { return controller;} 00405 00406 /** Returns a pointer to the wiring. 00407 */ 00408 virtual AbstractWiring* getWiring() { return wiring;} 00409 00410 /** adds the PlotOptions to the list of plotoptions 00411 If a plotoption with the same Mode exists, then the old one is deleted first 00412 */ 00413 virtual void addPlotOption(const PlotOption& plotoption); 00414 00415 /** removes the PlotOptions with the given type 00416 @return true if sucessful, false otherwise 00417 */ 00418 virtual bool removePlotOption(PlotMode mode); 00419 00420 /** 00421 write comment to output streams (PlotOptions). For instance changes in parameters. 00422 */ 00423 virtual void writePlotComment(const char* cmt); 00424 00425 /** adds an inspectable object for logging. Must be called before addPlotOption and before init! 00426 */ 00427 virtual void addInspectable(const Inspectable* inspectable); 00428 00429 /** adds an Callbackable object for getting a callback every step. 00430 */ 00431 virtual void addCallbackable(Callbackable* callbackable); 00432 00433 protected: 00434 /** 00435 * Plots controller sensor- and motorvalues and internal controller parameters. 00436 * @param rx actual sensorvalues from robot (used for generation of motorcommand in actual timestep) 00437 * @param rsensornumber length of rx 00438 * @param cx actual sensorvalues which are passed to controller (used for generation of motorcommand in actual timestep) 00439 * @param csensornumber length of cx 00440 * @param y actual motorcommand (generated in the actual timestep) 00441 * @param motornumber length of y 00442 * @param time simulation time 00443 */ 00444 virtual void plot(const sensor* rx, int rsensornumber, const sensor* cx, int csensornumber, 00445 const motor* y, int motornumber, double time); 00446 00447 00448 AbstractController* controller; 00449 AbstractWiring* wiring; 00450 00451 /// number of sensors of robot 00452 int rsensornumber; 00453 /// number of motors of robot 00454 int rmotornumber; 00455 /// number of sensors of comntroller 00456 int csensornumber; 00457 /// number of motors of comntroller 00458 int cmotornumber; 00459 00460 /// factor that is muliplied with noise stength 00461 double noisefactor; 00462 00463 motor *cmotors; 00464 sensor *csensors; 00465 00466 void internInit(); 00467 00468 protected: 00469 long int t; 00470 00471 PlotOption[maxNumberEntries] plotOptions; 00472 Inspectable*[maxNumberEntries] inspectables; 00473 bool initialised; 00474 00475 Callbackable*[maxNumberEntries] callbackables; 00476 00477 }; 00478 00479 #endif /* !AVR */ 00480 00481 #endif /* !WIREDCONTROLLER_H_ */