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