10 #include <mrpt/core/exceptions.h>
11 #include <mrpt/core/round.h>
12 #include <mrpt/system/os.h>
21 MRPT_TODO(
"win32: add SetConsoleCtrlHandler");
66 std::optional<LaunchData>
app;
70 app->thread_params.closing(
true);
72 if (
app->thGUI.joinable())
app->thGUI.join();
75 if (
app->world.getTimeLogger().isEnabledKeepWholeHistory())
77 const std::string sFil =
"mvsim_profiler.m";
78 std::cout <<
"\n***SAVING PROFILER DATA TO***: " << sFil << std::endl;
79 app->world.getTimeLogger().saveToMFile(sFil);
82 app->world.free_opengl_resources();
88 std::cerr <<
"Caught signal " <<
s <<
". Shutting down..." << std::endl;
95 struct sigaction sigIntHandler;
98 sigemptyset(&sigIntHandler.sa_mask);
99 sigIntHandler.sa_flags = 0;
101 sigaction(SIGINT, &sigIntHandler,
nullptr);
108 using namespace mvsim;
110 std::string txt2gui_tmp;
113 txt2gui_tmp += mrpt::format(
114 "Selected vehicle: %u/%u",
static_cast<unsigned>(
app->teleopIdxVeh + 1),
115 static_cast<unsigned>(vehs.size()));
117 if (
app->teleopIdxVeh >= vehs.size())
return txt2gui_tmp;
120 World::VehicleList::const_iterator it_veh = vehs.begin();
121 std::advance(it_veh,
app->teleopIdxVeh);
123 auto& veh = *it_veh->second;
127 txt2gui_tmp +=
" (LOGGING)\n";
133 const mrpt::math::TTwist2D& vel = veh.getVelocityLocal();
134 txt2gui_tmp += mrpt::format(
135 "gt. vel: lx=%7.03f, ly=%7.03f, w= %7.03fdeg/s\n", vel.vx, vel.vy,
136 mrpt::RAD2DEG(vel.omega));
140 const mrpt::math::TTwist2D& vel = veh.getVelocityLocalOdoEstimate();
141 txt2gui_tmp += mrpt::format(
142 "odo vel: lx=%7.03f, ly=%7.03f, w= %7.03fdeg/s\n", vel.vx, vel.vy,
143 mrpt::RAD2DEG(vel.omega));
163 using namespace mvsim;
166 bool badArgs =
false;
167 const auto& unlabeledArgs =
cli->argCmd.getValue();
168 if (unlabeledArgs.size() != 2) badArgs =
true;
170 if (
cli->argHelp.isSet() || badArgs)
174 R
"XXX(Usage: mvsim launch <WORLD_MODEL.xml> [options]
177 --headless Launch without GUI (e.g. suitable for dockerized envs.)
178 --full-profiler Enable full profiling (generates file with all timings)
179 --realtime-factor <1.0> Run slower (<1) or faster (>1) than real time if !=1.0
180 -v, --verbosity Set verbosity level: DEBUG, INFO (default), WARN, ERROR
188 const auto verbosityLevel = mrpt::typemeta::TEnumType<mrpt::system::VerbosityLevel>::name2value(
189 cli->argVerbosity.getValue());
191 if (verbosityLevel <= mrpt::system::LVL_INFO)
193 mrpt::system::consoleColorAndStyle(mrpt::system::ConsoleForegroundColor::BRIGHT_YELLOW);
196 <<
"====================================================\n"
197 <<
" MVSIM simulator running. Press CTRL+C to end. \n"
198 <<
"====================================================\n"
200 mrpt::system::consoleColorAndStyle(mrpt::system::ConsoleForegroundColor::DEFAULT);
203 const auto sXMLfilename = unlabeledArgs.at(1);
207 app->world.setMinLoggingLevel(verbosityLevel);
210 if (
cli->argFullProfiler.isSet())
app->world.getTimeLogger().enableKeepWholeHistory();
212 if (
cli->argHeadless.isSet())
app->world.headless(
true);
218 app->world.load_from_XML(fil_xml.
data(), sXMLfilename.c_str());
220 catch (
const std::exception& e)
222 std::cerr <<
"Error: " << e.what() << std::endl;
231 app->world.connectToServer();
234 app->thread_params.world = &
app->world;
236 if (!
cli->argHeadless.isSet())
248 const double tAbsInit = mrpt::Clock::nowDouble();
249 const double rtFactor =
cli->argRealTimeFactor.getValue();
255 if (
app->world.simulator_must_close())
break;
260 double tNew = mrpt::Clock::nowDouble();
261 double incrTime = rtFactor * (tNew - tAbsInit) -
app->world.get_simul_time();
263 static_cast<int>(std::floor(incrTime /
app->world.get_simul_timestep()));
266 if (incrTimeSteps > 0)
268 app->world.run_simulation(incrTimeSteps *
app->world.get_simul_timestep());
271 std::this_thread::sleep_for(std::chrono::milliseconds(10));
298 const auto js =
app->world.getJoystickState();
309 if (
app->thread_params.isClosing()) doExit =
true;
322 ASSERT_(thread_params.
world);
338 std::this_thread::sleep_for(std::chrono::milliseconds(25));
341 catch (
const std::exception& e)
343 std::cerr <<
"[mvsim_server_thread_update_GUI] Exception: " << e.what() << std::endl;
351 ASSERT_(thread_params.
world);
356 std::this_thread::sleep_for(std::chrono::microseconds(
363 catch (
const std::exception& e)
365 std::cerr <<
"[mvsim_server_thread_update_GUI] Exception: " << e.what() << std::endl;