Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <mvsim/World.h>
00010
00011 #include <mrpt/system/filesystem.h>
00012
00013 #include <iostream>
00014 #include <algorithm>
00015 #include <stdexcept>
00016 #include <map>
00017
00018 using namespace mvsim;
00019 using namespace std;
00020
00021
00022 World::World()
00023 : m_gravity(9.81),
00024 m_simul_time(0.0),
00025 m_simul_timestep(0.010),
00026 m_b2d_vel_iters(6),
00027 m_b2d_pos_iters(3),
00028 m_base_path("."),
00029 m_box2d_world(NULL)
00030 {
00031 this->clear_all();
00032 }
00033
00034
00035 World::~World()
00036 {
00037 this->clear_all();
00038 delete m_box2d_world;
00039 m_box2d_world = NULL;
00040 }
00041
00042
00043 void World::clear_all(bool acquire_mt_lock)
00044 {
00045 try
00046 {
00047 if (acquire_mt_lock) m_world_cs.lock();
00048
00049
00050 m_simul_time = 0.0;
00051
00052
00053
00054 delete m_box2d_world;
00055 m_box2d_world = new b2World(b2Vec2_zero);
00056
00057
00058 b2BodyDef groundBodyDef;
00059 m_b2_ground_body = m_box2d_world->CreateBody(&groundBodyDef);
00060
00061
00062
00063 for (TListVehicles::iterator it = m_vehicles.begin();
00064 it != m_vehicles.end(); ++it)
00065 delete it->second;
00066 m_vehicles.clear();
00067
00068 for (std::list<WorldElementBase*>::iterator it =
00069 m_world_elements.begin();
00070 it != m_world_elements.end(); ++it)
00071 delete *it;
00072 m_world_elements.clear();
00073
00074 for (TListBlocks::iterator it = m_blocks.begin(); it != m_blocks.end();
00075 ++it)
00076 delete it->second;
00077 m_blocks.clear();
00078
00079 if (acquire_mt_lock) m_world_cs.unlock();
00080 }
00081 catch (std::exception&)
00082 {
00083 if (acquire_mt_lock) m_world_cs.unlock();
00084 throw;
00085 }
00086 }
00087
00089 void World::run_simulation(double dt)
00090 {
00091 m_timlogger.registerUserMeasure("run_simulation.dt", dt);
00092
00093
00094 ASSERT_(dt > 0);
00095 ASSERT_(m_simul_timestep > 0);
00096
00097
00098 const double end_time = m_simul_time + dt;
00099 const double timetol =
00100 1e-6;
00101 while (m_simul_time < (end_time - timetol))
00102 {
00103
00104 internal_one_timestep(m_simul_timestep);
00105 }
00106 }
00107
00109 void World::internal_one_timestep(double dt)
00110 {
00111 m_timer_iteration.Tic();
00112
00113 TSimulContext context;
00114 context.b2_world = m_box2d_world;
00115 context.simul_time = m_simul_time;
00116 context.dt = dt;
00117
00118
00119 {
00120 CTimeLoggerEntry tle(m_timlogger, "timestep.0.prestep");
00121 for (TListVehicles::iterator it = m_vehicles.begin();
00122 it != m_vehicles.end(); ++it)
00123 it->second->simul_pre_timestep(context);
00124
00125 for (TListVehicles::iterator it = m_vehicles.begin();
00126 it != m_vehicles.end(); ++it)
00127 {
00128 VehicleBase::TListSensors& sensors = it->second->getSensors();
00129 for (VehicleBase::TListSensors::iterator itSen = sensors.begin();
00130 itSen != sensors.end(); ++itSen)
00131 {
00132 (*itSen)->simul_pre_timestep(context);
00133 }
00134 }
00135
00136 for (TListBlocks::iterator it = m_blocks.begin(); it != m_blocks.end();
00137 ++it)
00138 it->second->simul_pre_timestep(context);
00139
00140 for (std::list<WorldElementBase*>::iterator it =
00141 m_world_elements.begin();
00142 it != m_world_elements.end(); ++it)
00143 (*it)->simul_pre_timestep(context);
00144 }
00145
00146
00147 {
00148 CTimeLoggerEntry tle(
00149 m_timlogger, "timestep.1.dynamics_integrator");
00150
00151 m_box2d_world->Step(dt, m_b2d_vel_iters, m_b2d_pos_iters);
00152 m_simul_time += dt;
00153 }
00154
00155
00156 {
00157 CTimeLoggerEntry tle(
00158 m_timlogger, "timestep.3.save_dynstate");
00159
00160 context.simul_time = m_simul_time;
00161 for (TListVehicles::iterator it = m_vehicles.begin();
00162 it != m_vehicles.end(); ++it)
00163 {
00164 it->second->simul_post_timestep_common(context);
00165 it->second->simul_post_timestep(context);
00166 }
00167 for (TListBlocks::iterator it = m_blocks.begin(); it != m_blocks.end();
00168 ++it)
00169 {
00170 it->second->simul_post_timestep_common(context);
00171 it->second->simul_post_timestep(context);
00172 }
00173 }
00174
00175
00176 {
00177 CTimeLoggerEntry tle(m_timlogger, "timestep.4.poststep");
00178 for (TListVehicles::iterator it = m_vehicles.begin();
00179 it != m_vehicles.end(); ++it)
00180 it->second->simul_post_timestep(context);
00181
00182 for (TListVehicles::iterator it = m_vehicles.begin();
00183 it != m_vehicles.end(); ++it)
00184 {
00185 VehicleBase::TListSensors& sensors = it->second->getSensors();
00186 for (VehicleBase::TListSensors::iterator itSen = sensors.begin();
00187 itSen != sensors.end(); ++itSen)
00188 {
00189 (*itSen)->simul_post_timestep(context);
00190 }
00191 }
00192
00193 for (TListBlocks::iterator it = m_blocks.begin(); it != m_blocks.end();
00194 ++it)
00195 it->second->simul_post_timestep(context);
00196
00197 for (std::list<WorldElementBase*>::iterator it =
00198 m_world_elements.begin();
00199 it != m_world_elements.end(); ++it)
00200 (*it)->simul_post_timestep(context);
00201 }
00202
00203 const double ts = m_timer_iteration.Tac();
00204 m_timlogger.registerUserMeasure(
00205 (ts > dt ? "timestep_too_slow_alert" : "timestep"), ts);
00206 }
00207
00210 std::string World::resolvePath(const std::string& s_in) const
00211 {
00212 std::string ret;
00213 const std::string s = mrpt::system::trim(s_in);
00214
00215
00216
00217
00218 bool is_relative = true;
00219 if (s.size() > 2 && s[1] == ':' && (s[2] == '/' || s[2] == '\\'))
00220 is_relative = false;
00221 if (s.size() > 0 && (s[0] == '/' || s[0] == '\\')) is_relative = false;
00222 if (is_relative)
00223 {
00224 ret = m_base_path;
00225 if (!ret.empty() && ret[ret.size() - 1] != '/' &&
00226 ret[ret.size() - 1] != '\\')
00227 ret += string("/");
00228 ret += s;
00229 }
00230 else
00231 ret = s;
00232
00233
00234
00235
00236 return mrpt::system::filePathSeparatorsToNative(ret);
00237 }
00238
00240 void World::runVisitorOnVehicles(VehicleVisitorBase& v)
00241 {
00242 for (TListVehicles::iterator it = m_vehicles.begin();
00243 it != m_vehicles.end(); ++it)
00244 v.visit(it->second);
00245 }
00246
00248 void World::runVisitorOnWorldElements(WorldElementVisitorBase& v)
00249 {
00250 for (std::list<WorldElementBase*>::iterator it = m_world_elements.begin();
00251 it != m_world_elements.end(); ++it)
00252 v.visit(*it);
00253 }