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