Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <mvsim/mvsim.h>
00011
00012 #include <chrono>
00013 #include <thread>
00014
00015 #include <mrpt/system/os.h>
00016 #include <mrpt/utils/CTicTac.h>
00017
00018 #include <rapidxml_utils.hpp>
00019 #include <iostream>
00020
00021 using namespace mvsim;
00022
00023 struct TThreadParams
00024 {
00025 World* world;
00026 volatile bool closing;
00027 TThreadParams() : world(NULL), closing(false) {}
00028 };
00029 void usage(const char* argv0);
00030 void thread_update_GUI(TThreadParams& thread_params);
00031 World::TGUIKeyEvent gui_key_events;
00032 std::string msg2gui;
00033
00034 int main(int argc, char** argv)
00035 {
00036 try
00037 {
00038 if (argc != 2)
00039 {
00040 usage(argv[0]);
00041 return -1;
00042 }
00043
00044 World world;
00045
00046
00047 rapidxml::file<> fil_xml(argv[1]);
00048 world.load_from_XML(fil_xml.data(), argv[1]);
00049
00050
00051 TThreadParams thread_params;
00052 thread_params.world = &world;
00053 std::thread thGUI =
00054 std::thread(thread_update_GUI, std::ref(thread_params));
00055
00056
00057 mrpt::utils::CTicTac tictac;
00058 double t_old = tictac.Tac();
00059 double REALTIME_FACTOR = 1.0;
00060 bool do_exit = false;
00061 size_t teleop_idx_veh = 0;
00062
00063 while (!do_exit && !mrpt::system::os::kbhit())
00064 {
00065
00066
00067
00068 double t_new = tictac.Tac();
00069 double incr_time = REALTIME_FACTOR * (t_new - t_old);
00070
00071 if (incr_time >= world.get_simul_timestep())
00072
00073
00074 {
00075
00076 world.run_simulation(incr_time);
00077
00078
00079 t_old = t_new;
00080 }
00081
00082
00083 std::this_thread::sleep_for(std::chrono::milliseconds(10));
00084
00085
00086
00087
00088 std::string txt2gui_tmp;
00089 World::TGUIKeyEvent keyevent = gui_key_events;
00090
00091
00092 switch (keyevent.keycode)
00093 {
00094 case 27:
00095 do_exit = true;
00096 break;
00097 case '1':
00098 case '2':
00099 case '3':
00100 case '4':
00101 case '5':
00102 case '6':
00103 teleop_idx_veh = keyevent.keycode - '1';
00104 break;
00105 };
00106
00107 {
00108 const World::TListVehicles& vehs = world.getListOfVehicles();
00109 txt2gui_tmp += mrpt::format(
00110 "Selected vehicle: %u/%u\n",
00111 static_cast<unsigned>(teleop_idx_veh + 1),
00112 static_cast<unsigned>(vehs.size()));
00113 if (vehs.size() > teleop_idx_veh)
00114 {
00115
00116 World::TListVehicles::const_iterator it_veh = vehs.begin();
00117 std::advance(it_veh, teleop_idx_veh);
00118
00119
00120 {
00121 const vec3& vel = it_veh->second->getVelocityLocal();
00122 txt2gui_tmp += mrpt::format(
00123 "gt. vel: lx=%7.03f, ly=%7.03f, w= %7.03fdeg/s\n",
00124 vel.vals[0], vel.vals[1],
00125 mrpt::utils::RAD2DEG(vel.vals[2]));
00126 }
00127
00128 {
00129 const vec3& vel =
00130 it_veh->second->getVelocityLocalOdoEstimate();
00131 txt2gui_tmp += mrpt::format(
00132 "odo vel: lx=%7.03f, ly=%7.03f, w= %7.03fdeg/s\n",
00133 vel.vals[0], vel.vals[1],
00134 mrpt::utils::RAD2DEG(vel.vals[2]));
00135 }
00136
00137
00138
00139 {
00140 ControllerBaseInterface* controller =
00141 it_veh->second->getControllerInterface();
00142 ControllerBaseInterface::TeleopInput teleop_in;
00143 ControllerBaseInterface::TeleopOutput teleop_out;
00144 teleop_in.keycode = keyevent.keycode;
00145 controller->teleop_interface(teleop_in, teleop_out);
00146 txt2gui_tmp += teleop_out.append_gui_lines;
00147 }
00148 }
00149 }
00150
00151
00152 if (keyevent.keycode != 0) gui_key_events = World::TGUIKeyEvent();
00153
00154 msg2gui = txt2gui_tmp;
00155
00156 }
00157
00158 thread_params.closing = true;
00159 thGUI.join();
00160 }
00161 catch (const std::exception& e)
00162 {
00163 std::cerr << "ERROR: " << e.what() << std::endl;
00164 return 1;
00165 }
00166 return 0;
00167 }
00168
00169 void thread_update_GUI(TThreadParams& thread_params)
00170 {
00171 while (!thread_params.closing)
00172 {
00173 World::TUpdateGUIParams guiparams;
00174 guiparams.msg_lines = msg2gui;
00175
00176 thread_params.world->update_GUI(&guiparams);
00177
00178
00179 if (guiparams.keyevent.keycode != 0)
00180 gui_key_events = guiparams.keyevent;
00181
00182 std::this_thread::sleep_for(std::chrono::milliseconds(25));
00183 }
00184 }
00185
00186 void usage(const char* argv0)
00187 {
00188 std::cerr << "Usage:\n"
00189 " "
00190 << argv0 << " [WORLD_MODEL.xml]\n";
00191 }