10 #include <mrpt/opengl/COpenGLScene.h> 11 #include <mrpt/opengl/CPointCloud.h> 12 #include <mrpt/tfest.h> 13 #include <mrpt/version.h> 24 using namespace mvsim;
39 std::string sElevationImgFile;
40 params[
"elevation_image"] =
TParamEntry(
"%s", &sElevationImgFile);
41 std::string sTextureImgFile;
42 params[
"texture_image"] =
TParamEntry(
"%s", &sTextureImgFile);
44 double img_min_z = 0.0, img_max_z = 5.0;
45 params[
"elevation_image_min_z"] =
TParamEntry(
"%lf", &img_min_z);
46 params[
"elevation_image_max_z"] =
TParamEntry(
"%lf", &img_max_z);
48 double corner_min_x = std::numeric_limits<double>::max();
49 double corner_min_y = std::numeric_limits<double>::max();
51 params[
"corner_min_x"] =
TParamEntry(
"%lf", &corner_min_x);
52 params[
"corner_min_y"] =
TParamEntry(
"%lf", &corner_min_y);
54 mrpt::img::TColor mesh_color(0xa0, 0xe0, 0xa0);
55 params[
"mesh_color"] =
TParamEntry(
"%color", &mesh_color);
61 params[
"debug_show_contact_points"] =
68 mrpt::math::CMatrixFloat elevation_data;
69 if (!sElevationImgFile.empty())
73 mrpt::img::CImage imgElev;
74 if (!imgElev.loadFromFile(
75 sElevationImgFile, 0 ))
76 throw std::runtime_error(mrpt::format(
77 "[ElevationMap] ERROR: Cannot read elevation image '%s'",
78 sElevationImgFile.c_str()));
82 imgElev.getAsMatrix(elevation_data);
83 ASSERT_(img_min_z != img_max_z);
85 const double vmin = elevation_data.minCoeff();
86 const double vmax = elevation_data.maxCoeff();
87 mrpt::math::CMatrixFloat
f = elevation_data;
89 f *= (img_max_z - img_min_z) / (vmax - vmin);
90 mrpt::math::CMatrixFloat m(
91 elevation_data.rows(), elevation_data.cols());
92 m.setConstant(img_min_z);
94 elevation_data = std::move(f);
98 MRPT_TODO(
"Imgs or txt matrix")
102 mrpt::img::CImage mesh_image;
103 bool has_mesh_image =
false;
104 if (!sTextureImgFile.empty())
108 if (!mesh_image.loadFromFile(sTextureImgFile))
109 throw std::runtime_error(mrpt::format(
110 "[ElevationMap] ERROR: Cannot read texture image '%s'",
111 sTextureImgFile.c_str()));
112 has_mesh_image =
true;
116 gl_mesh_ = mrpt::opengl::CMesh::Create();
118 gl_mesh_->enableTransparency(
false);
122 gl_mesh_->assignImageAndZ(mesh_image, elevation_data);
124 #if MRPT_VERSION >= 0x270 139 const double LX = (elevation_data.rows() - 1) *
resolution_;
140 const double LY = (elevation_data.cols() - 1) *
resolution_;
142 if (corner_min_x == std::numeric_limits<double>::max())
143 corner_min_x = -0.5 * LX;
145 if (corner_min_y == std::numeric_limits<double>::max())
146 corner_min_y = -0.5 * LY;
152 corner_min_x, corner_min_x + LX, corner_min_y, corner_min_y + LY);
160 const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& viz,
161 const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& physical,
162 [[maybe_unused]]
bool childrenOnly)
168 "ERROR: Can't render Mesh before loading it! Have you called " 169 "loadConfigFrom() first?");
193 for (
auto& nameVeh : lstVehs)
197 auto& veh = nameVeh.second;
199 const size_t nWheels = veh->getNumWheels();
209 mrpt::math::TPoint3D dir_down;
210 for (
int iter = 0; iter < 2; iter++)
212 const mrpt::math::TPose3D& cur_pose = veh->getPose();
214 const mrpt::poses::CPose3D cur_cpose(cur_pose);
216 mrpt::math::TPose3D new_pose = cur_pose;
219 bool out_of_area =
false;
220 for (
size_t iW = 0; !out_of_area && iW < nWheels; iW++)
222 const Wheel& wheel = veh->getWheelInfo(iW);
225 mrpt::tfest::TMatchingPair corr;
227 #if MRPT_VERSION >= 0x240 229 corr.local = mrpt::math::TPoint3D(wheel.
x, wheel.
y, 0);
232 corr.other_x = wheel.
x;
233 corr.other_y = wheel.
y;
237 const mrpt::math::TPoint3D gPt =
238 cur_cpose.composePoint({wheel.
x, wheel.
y, 0.0});
246 #if MRPT_VERSION >= 0x240 248 corr.global = mrpt::math::TPoint3D(gPt.x, gPt.y, z);
258 if (out_of_area)
continue;
262 mrpt::poses::CPose3DQuat tmpl;
265 corrs_, tmpl, transf_scale,
true );
270 std::cout <<
"iter: " << iter <<
" poseErr:" 271 << std::sqrt(corrs.overallSquareError(optimal_transf_))
272 <<
" p:" << optimal_transf_ <<
"\n";
280 veh->setPose(new_pose);
288 for (
const auto& c :
corrs_)
293 for (
float x = -60; x < 60; x += 0.5)
294 for (
float y = -60; y < 60; y += 0.5)
307 mrpt::poses::CPose3D rot_only;
308 rot_only.setRotationMatrix(
optimalTf_.getRotationMatrix());
309 rot_only.inverseComposePoint(
310 .0, .0, -1.0, dir_down.x, dir_down.y, dir_down.z);
317 const double chassis_weight = veh->getChassisMass() * gravity;
318 const mrpt::math::TPoint2D chassis_com =
319 veh->getChassisCenterOfMass();
321 {dir_down.x * chassis_weight, dir_down.y * chassis_weight},
325 for (
size_t iW = 0; iW < nWheels; iW++)
327 const Wheel& wheel = veh->getWheelInfo(iW);
328 const double wheel_weight = wheel.
mass * gravity;
330 {dir_down.x * wheel_weight, dir_down.y * wheel_weight},
349 const mrpt::math::TPoint3Df& p1,
const mrpt::math::TPoint3Df& p2,
350 const mrpt::math::TPoint3Df& p3,
float x,
float y)
352 const float det = (p2.x - p3.x) * (p1.y - p3.y) +
353 (p3.y - p2.y) * (p1.x - p3.x);
354 ASSERT_(det != 0.0
f);
357 ((p2.x - p3.x) * (y - p3.y) + (p3.y - p2.y) * (x - p3.x)) / det;
359 ((p3.x - p1.x) * (y - p3.y) + (p1.y - p3.y) * (x - p3.x)) / det;
360 const float l3 = 1.0f - l1 - l2;
362 return l1 * p1.z + l2 * p2.z + l3 * p3.z;
367 const mrpt::opengl::CMesh* mesh =
gl_mesh_.get();
369 const float x0 = mesh->getxMin();
370 const float y0 = mesh->getyMin();
371 const float x1 = mesh->getxMax();
372 const float y1 = mesh->getyMax();
377 const float sCellX = (x1 - x0) / (nCellsX - 1);
378 const float sCellY = (y1 - y0) / (nCellsY - 1);
381 const int cx00 = ::floor((x - x0) / sCellX);
382 const int cy00 = ::floor((y - y0) / sCellY);
384 if (cx00 < 1 || cx00 >=
int(nCellsX - 1) || cy00 < 1 ||
385 cy00 >=
int(nCellsY - 1))
399 const mrpt::math::TPoint3Df p00(.0
f, .0
f, z00);
400 const mrpt::math::TPoint3Df p01(.0
f, sCellY, z01);
401 const mrpt::math::TPoint3Df p10(sCellX, .0
f, z10);
402 const mrpt::math::TPoint3Df p11(sCellX, sCellY, z11);
404 const float lx = x - (x0 + cx00 * sCellX);
405 const float ly = y - (y0 + cy00 * sCellY);
408 z =
calcz(p00, p01, p11, lx, ly);
410 z =
calcz(p00, p10, p11, lx, ly);
This file contains rapidxml parser and DOM implementation.
float textureExtensionX_
0=auto
mrpt::opengl::CMesh::Ptr gl_mesh_
std::map< std::string, TParamEntry > TParameterDefinitions
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions ¶ms, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="", mrpt::system::COutputLogger *logger=nullptr)
virtual void loadConfigFrom(const rapidxml::xml_node< char > *root) override
virtual void simul_pre_timestep(const TSimulContext &context) override
virtual void internalGuiUpdate(const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &viz, const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &physical, bool childrenOnly) override
bool debugShowContactPoints_
std::multimap< std::string, VehicleBase::Ptr > VehicleList
const VehicleList & getListOfVehicles() const
std::shared_ptr< mrpt::opengl::CPointCloud > gl_debugWheelsContactPoints_
mrpt::math::CMatrixFloat meshCacheZ_
bool firstSceneRendering_
const std::map< std::string, std::string > & user_defined_variables() const
float textureExtensionY_
0=auto
virtual void simul_post_timestep(const TSimulContext &context)
static float calcz(const mrpt::math::TPoint3Df &p1, const mrpt::math::TPoint3Df &p2, const mrpt::math::TPoint3Df &p3, float x, float y)
mrpt::system::CTimeLogger & getTimeLogger()
mrpt::poses::CPose3D optimalTf_
std::string local_to_abs_path(const std::string &in_path) const
bool getElevationAt(double x, double y, float &z) const
return false if out of bounds
std::string xmlPathToActualPath(const std::string &modelURI) const
double get_gravity() const
mrpt::tfest::TMatchingPairList corrs_
virtual void simul_post_timestep(const TSimulContext &context) override