|
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