|
38 | 38 | #include <string> |
39 | 39 | #include <vector> |
40 | 40 |
|
| 41 | +#include <Eigen/Eigenvalues> |
| 42 | +#include <Eigen/Geometry> |
| 43 | + |
41 | 44 | #include <OgreEntity.h> |
42 | 45 | #include <OgreMaterial.h> |
43 | 46 | #include <OgreMaterialManager.h> |
|
52 | 55 | #include <QFileInfo> // NOLINT cpplint cannot handle include order here |
53 | 56 | #include <QString> // NOLINT: cpplint is unable to handle the include order here |
54 | 57 |
|
55 | | -#include <gz/math/Inertial.hh> |
56 | | -#include <gz/math/MassMatrix3.hh> |
57 | | -#include <gz/math/Pose3.hh> |
58 | | -#include <gz/math/Quaternion.hh> |
59 | | -#include <gz/math/Vector3.hh> |
60 | | - |
61 | 58 | #include "resource_retriever/retriever.hpp" |
62 | 59 |
|
63 | 60 | #include "rviz_default_plugins/robot/robot_joint.hpp" |
@@ -880,46 +877,54 @@ void RobotLink::createMass(const urdf::LinkConstSharedPtr & link) |
880 | 877 |
|
881 | 878 | void RobotLink::createInertia(const urdf::LinkConstSharedPtr & link) |
882 | 879 | { |
883 | | - if (link->inertial) { |
884 | | - const gz::math::Vector3d i_xx_yy_zz( |
885 | | - link->inertial->ixx, |
886 | | - link->inertial->iyy, |
887 | | - link->inertial->izz); |
888 | | - const gz::math::Vector3d Ixyxzyz( |
889 | | - link->inertial->ixy, |
| 880 | + if (!link->inertial) { |
| 881 | + return; |
| 882 | + } |
| 883 | + |
| 884 | + const Eigen::Matrix3d inertia{(Eigen::Matrix3d{} << link->inertial->ixx, link->inertial->ixy, |
890 | 885 | link->inertial->ixz, |
891 | | - link->inertial->iyz); |
892 | | - gz::math::MassMatrix3d mass_matrix(link->inertial->mass, i_xx_yy_zz, Ixyxzyz); |
893 | | - |
894 | | - gz::math::Vector3d box_scale; |
895 | | - gz::math::Quaterniond box_rot; |
896 | | - if (!mass_matrix.EquivalentBox(box_scale, box_rot)) { |
897 | | - // Invalid inertia, load with default scale |
898 | | - if (link->parent_joint && link->parent_joint->type != urdf::Joint::FIXED) { |
899 | | - // Do not show error message for base link or static links |
900 | | - RVIZ_COMMON_LOG_ERROR_STREAM( |
901 | | - "The link " << link->name << " has unrealistic " |
902 | | - "inertia, so the equivalent inertia box will not be shown.\n"); |
903 | | - } |
904 | | - return; |
| 886 | + link->inertial->ixy, link->inertial->iyy, link->inertial->iyz, |
| 887 | + link->inertial->ixz, link->inertial->iyz, link->inertial->izz).finished()}; |
| 888 | + const Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver{inertia}; |
| 889 | + if (link->inertial->mass <= 0 || link->inertial->ixx <= 0 || |
| 890 | + link->inertial->ixx * link->inertial->iyy - std::pow(link->inertial->ixy, 2) <= 0 || |
| 891 | + inertia.determinant() <= 0 || eigen_solver.info() != Eigen::ComputationInfo::Success) |
| 892 | + { |
| 893 | + // Invalid inertia, load with default scale |
| 894 | + if (link->parent_joint && link->parent_joint->type != urdf::Joint::FIXED) { |
| 895 | + // Do not show error message for base link or static links |
| 896 | + RVIZ_COMMON_LOG_ERROR_STREAM( |
| 897 | + "The link " << link->name << " has unrealistic " |
| 898 | + "inertia, so the equivalent inertia box will not be shown.\n"); |
905 | 899 | } |
906 | | - Ogre::Vector3 translate( |
907 | | - link->inertial->origin.position.x, |
908 | | - link->inertial->origin.position.y, |
909 | | - link->inertial->origin.position.z); |
910 | | - |
911 | | - double x, y, z, w; |
912 | | - link->inertial->origin.rotation.getQuaternion(x, y, z, w); |
913 | | - Ogre::Quaternion originRotate(w, x, y, z); |
914 | | - |
915 | | - Ogre::Quaternion rotate(box_rot.W(), box_rot.X(), box_rot.Y(), box_rot.Z()); |
916 | | - Ogre::SceneNode * offset_node = inertia_node_->createChildSceneNode( |
917 | | - translate, originRotate * rotate); |
918 | | - inertia_shape_ = new Shape(Shape::Cube, scene_manager_, offset_node); |
919 | | - |
920 | | - inertia_shape_->setColor(1, 0, 0, 1); |
921 | | - inertia_shape_->setScale(Ogre::Vector3(box_scale.X(), box_scale.Y(), box_scale.Z())); |
922 | | - } |
| 900 | + return; |
| 901 | + } |
| 902 | + |
| 903 | + const Eigen::Vector3d & eigen_values{eigen_solver.eigenvalues()}; |
| 904 | + Eigen::Vector3d box_size{(eigen_values.y() + eigen_values.z() - eigen_values.x()), |
| 905 | + (eigen_values.x() + eigen_values.z() - eigen_values.y()), |
| 906 | + (eigen_values.x() + eigen_values.y() - eigen_values.z())}; |
| 907 | + box_size = (6 / link->inertial->mass * box_size).cwiseSqrt(); |
| 908 | + const Eigen::Vector3f box_size_float{box_size.cast<float>()}; |
| 909 | + |
| 910 | + const Eigen::Quaternionf box_rotation_eigen{Eigen::Quaterniond{eigen_solver.eigenvectors()}.cast<float>()}; |
| 911 | + const Ogre::Quaternion box_rotation{box_rotation_eigen.w(), box_rotation_eigen.x(), |
| 912 | + box_rotation_eigen.y(), box_rotation_eigen.z()}; |
| 913 | + |
| 914 | + const urdf::Pose & pose{link->inertial->origin}; |
| 915 | + const Ogre::Vector3 translation{static_cast<float>(pose.position.x), |
| 916 | + static_cast<float>(pose.position.y), |
| 917 | + static_cast<float>(pose.position.z)}; |
| 918 | + const Ogre::Quaternion origin_rotation{static_cast<float>(pose.rotation.w), |
| 919 | + static_cast<float>(pose.rotation.x), static_cast<float>(pose.rotation.y), |
| 920 | + static_cast<float>(pose.rotation.z)}; |
| 921 | + const Ogre::Quaternion rotation{origin_rotation * box_rotation}; |
| 922 | + const Ogre::Vector3 scale{box_size_float.x(), box_size_float.y(), box_size_float.z()}; |
| 923 | + |
| 924 | + Ogre::SceneNode * offset_node = inertia_node_->createChildSceneNode(translation, rotation); |
| 925 | + inertia_shape_ = new Shape(Shape::Cube, scene_manager_, offset_node); |
| 926 | + inertia_shape_->setColor(1, 0, 0, 1); |
| 927 | + inertia_shape_->setScale(scale); |
923 | 928 | } |
924 | 929 |
|
925 | 930 | void RobotLink::createSelection() |
|
0 commit comments