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 * frankguettler@gmx.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 * simulation.h and simulation.cpp provide a generic ode-robot simulation * 00025 * framework. It implements the initialisation, the simulation loop, * 00026 * and a basic command line interface. * 00027 * Usage: call simulation_init(), simulation_start(), simulation_close() * 00028 * see template_onerobot/main.cpp for an example * 00029 * * 00030 * $Log: simulation.h,v $ 00031 * Revision 1.41 2009/08/21 09:49:08 robot12 00032 * (guettler) support for tasked simulations. 00033 * - use the simulation template_taskedSimulations. 00034 * - merged (not completely) from lpzrobots_tasked. 00035 * - graphics is supported, but only for one simulation of a pool 00036 * 00037 * Revision 1.110.2.1 2009/08/11 16:00:44 guettler 00038 * - support for tasked simulations, does not yet work with graphics 00039 * - in development state 00040 * 00041 * Revision 1.40 2009/08/11 12:16:08 robot12 00042 * BUGFIX: sim_step is no longer relevant, disable it to avoid wrong use (guettler) 00043 * 00044 * Revision 1.39 2009/08/07 09:26:32 martius 00045 * plotoptions and globalconfigurables are now in globaldata 00046 * 00047 * Revision 1.38 2009/07/30 12:27:34 jhoffmann 00048 * support for new CameraHandle 00049 * 00050 * Revision 1.37 2009/07/29 14:19:49 jhoffmann 00051 * Various bugfixing, remove memory leaks (with valgrind->memcheck / alleyoop) 00052 * 00053 * Revision 1.36 2009/04/23 14:32:35 guettler 00054 * cosmetic 00055 * 00056 * Revision 1.35 2009/04/23 14:17:34 guettler 00057 * new: simulation cycles, first simple implementation, 00058 * use the additional method bool restart() for starting new cycles, 00059 * template simulation can be found in template_cycledSimulation 00060 * (originally taken from template_onerobot) 00061 * 00062 * Revision 1.34 2009/03/12 08:43:40 martius 00063 * fixed video recording 00064 * 00065 * Revision 1.33 2008/09/16 14:46:41 martius 00066 * use cmath instead of math.h 00067 * 00068 * Revision 1.32 2008/05/05 06:07:26 guettler 00069 * wrong prototype storeODERobotsCFG() 00070 * 00071 * Revision 1.31 2008/04/23 07:17:16 martius 00072 * makefiles cleaned 00073 * new also true realtime factor displayed, 00074 * warning if out of sync 00075 * drawinterval in full speed is 10 frames, independent of the speed 00076 * 00077 * Revision 1.30 2008/04/17 15:59:00 martius 00078 * OSG2 port finished 00079 * 00080 * Revision 1.29.2.7 2008/04/15 16:21:52 martius 00081 * Profiling 00082 * Multithreading also for OSG and ODE but disables because of instabilities 00083 * 00084 * Revision 1.29.2.6 2008/04/14 11:25:30 guettler 00085 * The OSG step (Viewer) runs now in a seperate thread! A Sideeffect is that 00086 * the simulation runs one step out of sync with the ode, don't worry about 00087 * that. This increases the simulation speed up to 30% on a test pc. 00088 * Together with the parallelisation of the ODE we have an total speed up of 00089 * 94% with the shadowtype 5 on an dual Pentium3 1Ghz and NVidia5250! 00090 * 00091 * Revision 1.29.2.5 2008/04/14 10:49:23 guettler 00092 * The ODE simstep runs now in a parallel thread! A Sideeffect is that 00093 * the simulation runs one step out of sync with the ode, don't worry about 00094 * that. This increases the simulation speed up to 50% on a test pc. 00095 * 00096 * Revision 1.29.2.4 2008/04/11 10:41:35 martius 00097 * config file added 00098 * 00099 * Revision 1.29.2.3 2008/04/09 13:57:59 guettler 00100 * New ShadowTechnique added. 00101 * 00102 * Revision 1.29.2.2 2008/04/09 10:18:41 martius 00103 * fullscreen and window options done 00104 * fonts on hud changed 00105 * 00106 * Revision 1.29.2.1 2008/04/08 14:09:23 martius 00107 * compiles and runs with OSG2.2. Juhu 00108 * 00109 * Revision 1.29 2007/08/24 11:52:42 martius 00110 * resetsynctimer is protected 00111 * 00112 * Revision 1.28 2007/06/21 16:19:48 martius 00113 * -nopgraphics option which disables graphics rendering 00114 * 00115 * Revision 1.27 2007/03/26 13:06:30 martius 00116 * use new commandline interface 00117 * 00118 * Revision 1.26 2007/03/16 10:53:18 martius 00119 * new nearcallback structure 00120 * 00121 * Revision 1.25 2007/02/12 13:29:48 martius 00122 * addCallback has flag about controllstep 00123 * 00124 * Revision 1.24 2006/12/13 09:13:03 martius 00125 * agents get comments about changed parameter for logfile 00126 * 00127 * Revision 1.23 2006/12/11 18:31:34 martius 00128 * list of configurables for agents 00129 * reference counting and memleaks fixed 00130 * onlycontrol used in steps where controller is not used 00131 * 00132 * Revision 1.22 2006/09/20 15:30:40 martius 00133 * shadowsize 00134 * 00135 * Revision 1.21 2006/08/04 15:07:46 martius 00136 * documentation 00137 * 00138 * Revision 1.20 2006/07/14 15:17:33 fhesse 00139 * start option for intended simulation time added 00140 * -simtime [min] 00141 * 00142 * Revision 1.18.4.19 2006/06/29 16:31:47 robot3 00143 * includes cleared up 00144 * 00145 * Revision 1.18.4.18 2006/06/25 16:52:23 martius 00146 * filelogging is done with a plotoption 00147 * 00148 * Revision 1.18.4.17 2006/05/28 22:12:03 martius 00149 * - noshadow cmdline flag 00150 * 00151 * Revision 1.18.4.16 2006/05/15 13:07:48 robot3 00152 * -handling of starting guilogger moved to simulation.cpp 00153 * -CTRL-F now toggles logging to the file (controller stuff) on/off 00154 * -CTRL-G now restarts the GuiLogger 00155 * 00156 * Revision 1.18.4.15 2006/03/30 12:34:47 martius 00157 * documentation updated 00158 * 00159 * Revision 1.18.4.14 2006/03/06 16:54:05 robot3 00160 * now ExtendedViewer is used because of the new getCurrentCameraManipulator(), 00161 * code optimizations 00162 * 00163 * Revision 1.18.4.13 2006/02/22 15:26:32 martius 00164 * frame grabbing with osg works again 00165 * 00166 * Revision 1.18.4.12 2006/02/20 10:50:20 martius 00167 * pause, random, windowsize, Ctrl-keys 00168 * 00169 * Revision 1.18.4.11 2006/02/14 17:36:14 martius 00170 * much better time syncronisation 00171 * 00172 * Revision 1.18.4.10 2006/01/17 17:01:53 martius 00173 * *** empty log message *** 00174 * 00175 * Revision 1.18.4.9 2006/01/12 22:33:23 martius 00176 * key eventhandler integrated 00177 * 00178 * Revision 1.18.4.8 2005/12/29 16:49:48 martius 00179 * end is obsolete 00180 * tidyUp is used for deletion 00181 * 00182 * Revision 1.18.4.7 2005/12/29 12:54:09 martius 00183 * multiple Tesselhints 00184 * 00185 * Revision 1.18.4.6 2005/12/15 17:02:04 martius 00186 * light is in sky and standart cams removed 00187 * config has a default implentation now 00188 * 00189 * Revision 1.18.4.5 2005/12/11 23:35:07 martius 00190 * *** empty log message *** 00191 * 00192 * Revision 1.18.4.4 2005/12/09 16:53:17 martius 00193 * camera is working now 00194 * 00195 * Revision 1.18.4.3 2005/12/06 17:38:13 martius 00196 * *** empty log message *** 00197 * 00198 * Revision 1.18.4.2 2005/12/06 10:13:23 martius 00199 * openscenegraph integration started 00200 * 00201 * Revision 1.18.4.1 2005/11/14 17:37:01 martius 00202 * changed makefile structure to have and include directory 00203 * mode to selforg 00204 * 00205 * Revision 1.18 2005/10/06 17:11:26 martius 00206 * switched to stl lists 00207 * 00208 * Revision 1.17 2005/09/27 13:58:48 martius 00209 * added drawLine 00210 * 00211 * Revision 1.16 2005/09/22 13:17:11 martius 00212 * OdeHandle and GlobalData finished 00213 * doInternalStuff included 00214 * 00215 * Revision 1.15 2005/09/22 11:21:57 martius 00216 * removed global variables 00217 * OdeHandle and GlobalData are used instead 00218 * sensor prepared 00219 * 00220 * Revision 1.14 2005/08/12 11:55:01 robot1 00221 * camera module integrated 00222 * 00223 * Revision 1.13 2005/08/03 20:33:30 martius 00224 * changed signature of contains (but it stays compatible) 00225 * 00226 * Revision 1.12 2005/07/27 13:23:16 martius 00227 * new color and position construction 00228 * 00229 * Revision 1.11 2005/07/18 08:35:27 martius 00230 * drawcallback is additionalcallback now 00231 * 00232 * Revision 1.10 2005/07/13 08:39:21 robot8 00233 * added the possibility to use an additional command function, which handels special Inputs if the ODE simulation window has the focus 00234 * 00235 * Revision 1.9 2005/07/08 10:14:05 martius 00236 * added contains (helper for stringlist search) 00237 * 00238 * Revision 1.8 2005/07/07 10:23:44 martius 00239 * added user draw callback 00240 * 00241 * Revision 1.7 2005/06/30 13:23:38 robot8 00242 * completing the call of the dynamic collisionCallback-function for standard collisions 00243 * 00244 * Revision 1.6 2005/06/29 09:27:11 martius 00245 * *** empty log message *** 00246 * 00247 * Revision 1.5 2005/06/29 09:25:06 martius 00248 * customized callback for collision 00249 * 00250 * Revision 1.4 2005/06/17 08:42:01 martius 00251 * documentation 00252 * 00253 * Revision 1.3 2005/06/15 14:01:31 martius 00254 * moved all general code from main to simulation 00255 * * 00256 ***************************************************************************/ 00257 #ifndef __SIMULATION_H 00258 #define __SIMULATION_H 00259 00260 // include base classes of class Simulation 00261 #include "base.h" 00262 00263 #include <osgViewer/Viewer> 00264 #include <osgViewer/ViewerEventHandlers> 00265 #include <osgGA/KeySwitchMatrixManipulator> 00266 #include <osg/Camera> 00267 00268 00269 #include <cmath> 00270 #define PI M_PI // (3.14159265358979323846) 00271 #include <vector> 00272 #include <iterator> 00273 #include <string> 00274 00275 #include "globaldata.h" 00276 #include "grabframe.h" 00277 #include "pos.h" 00278 #include "camerahandle.h" 00279 00280 /*** some forward declarations ***/ 00281 class PlotOption; // selforg 00282 00283 namespace lpzrobots { 00284 class ExtendedViewer; 00285 } 00286 /*** end of forward declarations ***/ 00287 00288 00289 namespace lpzrobots { 00290 00291 class Simulation : public Base, public osgGA::GUIEventHandler, public Configurable 00292 { 00293 public: 00294 00295 /* typedef */ enum SimulationState { none, initialised, running, closed }; 00296 00297 Simulation(); 00298 virtual ~Simulation(); 00299 00300 /** starts the Simulation. Do not overload it. 00301 This function returns of the simulation is terminated. 00302 @return: true if closed regulary, false on error 00303 */ 00304 bool run(int argc, char** argv); 00305 00306 // the following function have to be overloaded. 00307 00308 /// start() is called at the first start of the cycles and should create all the object (obstacles, agents...). 00309 virtual void start(const OdeHandle&, const OsgHandle&, GlobalData& globalData) = 0; 00310 00311 // the following functions have dummy default implementations 00312 00313 /** 00314 * restart() is called at the second and all following starts of the cylce 00315 * The end of a cycle is determined by (simulation_time_reached==true) 00316 * @param the odeHandle 00317 * @param the osgHandle 00318 * @param globalData 00319 * @return if the simulation should be restarted; this is false by default 00320 */ 00321 virtual bool restart(const OdeHandle&, const OsgHandle&, GlobalData& globalData); 00322 00323 /// end() is called at the end and should tidy up 00324 virtual void end(GlobalData& globalData); 00325 /** config() is called when the user presses Ctrl-C 00326 @return false to exit program, true otherwiese 00327 */ 00328 virtual bool config(GlobalData& globalData); 00329 /** is called if a key was pressed. 00330 For keycodes see: osgGA::GUIEventAdapter 00331 @return true if the key was handled 00332 */ 00333 virtual bool command(const OdeHandle&, const OsgHandle&, GlobalData& globalData, 00334 int key, bool down) { return false; }; 00335 00336 /** this can be used to describe the key bindings used by command() 00337 */ 00338 virtual void bindingDescription(osg::ApplicationUsage & au) const {}; 00339 00340 /** collCallback() can be used to overload the standart collision handling. 00341 However it is called after the robots collision handling. 00342 @return true if collision is treated, false otherwise 00343 */ 00344 virtual bool collCallback(const OdeHandle&, void* data, dGeomID o1, dGeomID o2) { return false;}; 00345 00346 /** optional additional callback function which is called every simulation step. 00347 Called between physical simulation step and drawing. 00348 @param draw indicates that objects are drawn in this timestep 00349 @param pause always false (only called of simulation is running) 00350 @param control indicates that robots have been controlled this timestep 00351 */ 00352 virtual void addCallback(GlobalData& globalData, bool draw, bool pause, bool control) {}; 00353 00354 virtual void odeStep(); 00355 00356 virtual void osgStep(); 00357 00358 protected: 00359 // GUIEventHandler 00360 virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&); 00361 virtual void getUsage (osg::ApplicationUsage & au) const; 00362 virtual void accept(osgGA::GUIEventHandlerVisitor& v); 00363 00364 virtual bool init(int argc, char** argv); 00365 00366 /** define the home position and view orientation of the camera. 00367 view.x is the heading angle in degree. view.y is the tilt angle in degree (nick), 00368 view.z is ignored 00369 */ 00370 void setCameraHomePos(const osg::Vec3& eye, const osg::Vec3& view); 00371 00372 static void nearCallback_TopLevel(void *data, dGeomID o1, dGeomID o2); 00373 static void nearCallback(void *data, dGeomID o1, dGeomID o2); 00374 bool control_c_pressed(); 00375 00376 // plotoptions is a list of possible online output, 00377 // if the list is empty no online gnuplot windows and no logging to file occurs. 00378 // The list is modified with commandline options, see run() in simulation.cpp 00379 std::list<PlotOption>& plotoptions; // points now to globaldata.plotoptions 00380 /// this list contains by default only the odeconfig. This list should be added to new agents 00381 std::list<Configurable*>& globalconfigurables; // points now to globaldata.globalconfigurables 00382 00383 00384 private: 00385 void insertCmdLineOption(int& argc,char**& argv); 00386 bool loop(); 00387 /// clears obstacle and agents lists and delete entries 00388 void tidyUp(GlobalData& globalData); 00389 00390 protected: 00391 virtual void processCmdLine(int argc, char** argv); 00392 void resetSyncTimer(); 00393 long timeOfDayinMS(); 00394 00395 private: 00396 static void control_c(int i); 00397 static void cmd_handler_exit(); 00398 static void cmd_handler_init(); 00399 static void cmd_begin_input(); 00400 static void cmd_end_input(); 00401 00402 // Commandline interface stuff 00403 static void usage(const char* progname); 00404 00405 bool storeOdeRobotsCFG(); 00406 00407 00408 protected: 00409 GlobalData globalData; 00410 osg::ref_ptr<VideoStream> videostream; 00411 00412 int nextLeakAnnounce; 00413 int leakAnnCounter; 00414 long realtimeoffset; 00415 long simtimeoffset; 00416 double truerealtimefactor; // calculated true speed 00417 bool justresettimes; // true if we just reset sync times 00418 00419 paramint windowWidth; 00420 paramint windowHeight; 00421 00422 bool pause; 00423 bool simulation_time_reached; 00424 long int simulation_time; 00425 bool noGraphics; 00426 00427 // use globalData.sim_step instead 00428 //long sim_step; 00429 00430 int guiloggerinterval; 00431 int filelogginginterval; 00432 int neuronvizinterval; 00433 00434 char odeRobotsCfg[256]; /// < filename of config file 00435 00436 // CameraType camType; // default is a non-moving and non-rotating camera 00437 // OdeRobot* viewedRobot; // the robot who is viewed from the camera 00438 00439 /// the current cycle; the simulation restarts if restart() returns true 00440 int currentCycle; 00441 00442 CameraHandle cameraHandle; 00443 00444 parambool useOdeThread; 00445 parambool useOsgThread; 00446 parambool useQMPThreads; // decides if quick mp is used in this simulation 00447 parambool inTaskedMode; 00448 00449 std::string windowName; 00450 00451 private: 00452 SimulationState state; 00453 osg::ArgumentParser* arguments; 00454 osgViewer::Viewer* viewer; 00455 osgGA::KeySwitchMatrixManipulator* keyswitchManipulator; 00456 00457 static int ctrl_C; 00458 00459 // multiprocessoring stuff 00460 pthread_t odeThread; 00461 pthread_t osgThread; 00462 bool odeThreadCreated; 00463 bool osgThreadCreated; 00464 00465 }; 00466 00467 // /// initializes or resets the camera per user, if wanted 00468 // void camera_init(CameraType type, OdeRobot* robot); 00469 00470 // /// starts the simulation. 00471 // void simulation_start(int argc, char** argv); 00472 // /// call this after the @simulation_start()@ has returned to tidy up. 00473 // void simulation_close(); 00474 00475 00476 // Commandline interface stuff 00477 /// shows all parameters of all given configurable objects 00478 void showParams(const ConfigList& configs); 00479 00480 /// creates a new directory with the stem base, which is not yet there (using subsequent numbers) 00481 void createNewDir(const char* base, char *newdir); 00482 } 00483 00484 #endif