35 #include <OgreSceneManager.h> 36 #include <OgreSceneNode.h> 37 #include <OgreQuaternion.h> 49 return degrees * 4.0 *
atan(1.0) / 180.0;
53 void makeRightHanded(Eigen::Matrix3d& eigenvectors, Eigen::Vector3d& eigenvalues)
57 Eigen::Vector3d c0 = eigenvectors.col(0);
59 Eigen::Vector3d c1 = eigenvectors.col(1);
61 Eigen::Vector3d c2 = eigenvectors.col(2);
63 Eigen::Vector3d cc = c0.cross(c1);
66 eigenvectors << c1, c0, c2;
67 std::swap(eigenvalues[0], eigenvalues[1]);
71 eigenvectors << c0, c1, c2;
76 void makeRightHanded(Eigen::Matrix2d& eigenvectors, Eigen::Vector2d& eigenvalues)
82 c0.head<2>() = eigenvectors.col(0);
86 c1.head<2>() = eigenvectors.col(1);
88 Eigen::Vector3d cc = c0.cross(c1);
91 eigenvectors << c1.head<2>(), c0.head<2>();
92 std::swap(eigenvalues[0], eigenvalues[1]);
96 eigenvectors << c0.head<2>(), c1.head<2>();
100 void computeShapeScaleAndOrientation3D(
const Eigen::Matrix3d& covariance,
101 Ogre::Vector3& scale,
102 Ogre::Quaternion& orientation)
104 Eigen::Vector3d eigenvalues(Eigen::Vector3d::Identity());
105 Eigen::Matrix3d eigenvectors(Eigen::Matrix3d::Zero());
109 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(covariance);
111 if (eigensolver.info() == Eigen::Success)
113 eigenvalues = eigensolver.eigenvalues();
114 eigenvectors = eigensolver.eigenvectors();
119 1,
"failed to compute eigen vectors/values for position. Is the covariance matrix correct?");
120 eigenvalues = Eigen::Vector3d::Zero();
121 eigenvectors = Eigen::Matrix3d::Identity();
125 makeRightHanded(eigenvectors, eigenvalues);
128 orientation.FromRotationMatrix(Ogre::Matrix3(
129 eigenvectors(0, 0), eigenvectors(0, 1), eigenvectors(0, 2),
130 eigenvectors(1, 0), eigenvectors(1, 1), eigenvectors(1, 2),
131 eigenvectors(2, 0), eigenvectors(2, 1), eigenvectors(2, 2)));
134 scale.x = 2 * std::sqrt(eigenvalues[0]);
135 scale.y = 2 * std::sqrt(eigenvalues[1]);
136 scale.z = 2 * std::sqrt(eigenvalues[2]);
146 void computeShapeScaleAndOrientation2D(
const Eigen::Matrix2d& covariance,
147 Ogre::Vector3& scale,
148 Ogre::Quaternion& orientation,
149 Plane plane = XY_PLANE)
151 Eigen::Vector2d eigenvalues(Eigen::Vector2d::Identity());
152 Eigen::Matrix2d eigenvectors(Eigen::Matrix2d::Zero());
156 Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> eigensolver(covariance);
158 if (eigensolver.info() == Eigen::Success)
160 eigenvalues = eigensolver.eigenvalues();
161 eigenvectors = eigensolver.eigenvectors();
166 1,
"failed to compute eigen vectors/values for position. Is the covariance matrix correct?");
167 eigenvalues = Eigen::Vector2d::Zero();
168 eigenvectors = Eigen::Matrix2d::Identity();
172 makeRightHanded(eigenvectors, eigenvalues);
177 if (plane == YZ_PLANE)
179 orientation.FromRotationMatrix(Ogre::Matrix3(1, 0, 0,
180 0, eigenvectors(0, 0), eigenvectors(0, 1),
181 0, eigenvectors(1, 0), eigenvectors(1, 1)));
184 scale.y = 2 * std::sqrt(eigenvalues[0]);
185 scale.z = 2 * std::sqrt(eigenvalues[1]);
187 else if (plane == XZ_PLANE)
189 orientation.FromRotationMatrix(
190 Ogre::Matrix3(eigenvectors(0, 0), 0, eigenvectors(0, 1),
192 eigenvectors(1, 0), 0, eigenvectors(1, 1)));
194 scale.x = 2 * std::sqrt(eigenvalues[0]);
196 scale.z = 2 * std::sqrt(eigenvalues[1]);
200 orientation.FromRotationMatrix(
201 Ogre::Matrix3(eigenvectors(0, 0), eigenvectors(0, 1), 0,
202 eigenvectors(1, 0), eigenvectors(1, 1), 0,
205 scale.x = 2 * std::sqrt(eigenvalues[0]);
206 scale.y = 2 * std::sqrt(eigenvalues[1]);
211 void radianScaleToMetricScaleBounded(Ogre::Real& radian_scale,
float max_degrees)
214 if (radian_scale >
deg2rad(max_degrees))
215 radian_scale =
deg2rad(max_degrees);
216 radian_scale = 2.0 *
tan(radian_scale);
225 Ogre::SceneNode* parent_node,
226 bool is_local_rotation,
232 , local_rotation_(is_local_rotation)
234 , orientation_visible_(is_visible)
237 root_node_ = parent_node->createChildSceneNode();
278 Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_X) *
279 Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_Z));
283 Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_Y));
287 Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_X));
297 static const double cone_origin_to_top = 0.49115;
300 Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_Z));
329 for (
unsigned i = 0; i < 3; ++i)
331 if (std::isnan(pose.covariance[i]))
338 pose_2d_ = pose.covariance[14] <= 0 && pose.covariance[21] <= 0 && pose.covariance[28] <= 0;
343 Ogre::Quaternion ori;
351 Eigen::Map<const Eigen::Matrix<double, 6, 6> > covariance(pose.covariance.data());
369 Ogre::Vector3 shape_scale;
370 Ogre::Quaternion shape_orientation;
373 computeShapeScaleAndOrientation2D(covariance.topLeftCorner<2, 2>(), shape_scale, shape_orientation,
376 shape_scale.z = 0.001;
380 computeShapeScaleAndOrientation3D(covariance.topLeftCorner<3, 3>(), shape_scale, shape_orientation);
384 if (!shape_scale.isNaN())
392 Ogre::Vector3 shape_scale;
393 Ogre::Quaternion shape_orientation;
400 shape_scale.x = 2.0 *
sqrt(covariance(5, 5));
404 shape_scale.z = 0.001;
412 radianScaleToMetricScaleBounded(shape_scale.x,
max_degrees);
419 Eigen::Matrix2d covarianceAxis;
422 covarianceAxis = covariance.bottomRightCorner<2, 2>();
426 covarianceAxis << covariance(3, 3), covariance(3, 5), covariance(5, 3), covariance(5, 5);
428 else if (index ==
kYaw)
430 covarianceAxis = covariance.block<2, 2>(3, 3);
434 computeShapeScaleAndOrientation2D(covarianceAxis, shape_scale, shape_orientation, XZ_PLANE);
436 shape_scale.y = 0.001;
445 radianScaleToMetricScaleBounded(shape_scale.x,
max_degrees);
446 radianScaleToMetricScaleBounded(shape_scale.z,
max_degrees);
451 if (!shape_scale.isNaN())
454 ROS_WARN_STREAM(
"orientation shape_scale contains NaN: " << shape_scale);
511 radianScaleToMetricScaleBounded(shape_scale.x,
max_degrees);
520 radianScaleToMetricScaleBounded(shape_scale.x,
max_degrees);
521 radianScaleToMetricScaleBounded(shape_scale.z,
max_degrees);
virtual void setCovariance(const geometry_msgs::PoseWithCovariance &pose)
Set the covariance.
void setOrientation(const Ogre::Quaternion &orientation) override
Set the orientation of the object.
void setPositionScale(float pos_scale)
void setScale(const Ogre::Vector3 &scale) override
Set the scale of the object. Always relative to the identity orientation of the object.
void setScales(float pos_scale, float ori_scale)
Set the position and orientation scales for this covariance.
Ogre::SceneNode * position_node_
virtual void setPositionVisible(bool visible)
Sets visibility of the position part of this covariance.
ROSCONSOLE_CONSOLE_IMPL_DECL std::string getName(void *handle)
virtual void setOrientationColor(float r, float g, float b, float a)
Set the color of the orientation covariance. Values are in the range [0, 1].
~CovarianceVisual() override
rviz::Shape * getOrientationShape(ShapeIndex index)
Get the shape used to display orientation covariance in an especific axis.
void setUserData(const Ogre::Any &data) override
Sets user data on all ogre objects we own.
void setOrientationColorToRGB(float a)
void updatePosition(const Eigen::Matrix6d &covariance)
void setColor(float r, float g, float b, float a) override
Set the color of the object. Values are in the range [0, 1].
void updateOrientationVisibility()
Base class for visible objects, providing a minimal generic interface.
void setUserData(const Ogre::Any &data) override
Sets user data on all ogre objects we own.
const Ogre::Vector3 & getPosition() override
Get the local position of this object.
virtual const Ogre::Vector3 & getPositionCovarianceScale()
virtual void setOrientationVisible(bool visible)
Sets visibility of the orientation part of this covariance.
void setOrientationOffset(float ori_offset)
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
#define ROS_WARN_THROTTLE(period,...)
Ogre::SceneNode * orientation_root_node_
virtual void setRotatingFrame(bool use_rotating_frame)
Sets which frame to attach the covariance of the orientation.
Matrix< double, 6, 6 > Matrix6d
Ogre::SceneNode * fixed_orientation_node_
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
void setPosition(const Ogre::Vector3 &position) override
Sets position of the frame this covariance is attached.
#define ROS_WARN_STREAM(args)
float normalizeQuaternion(float &w, float &x, float &y, float &z)
float current_ori_scale_factor_
void setOrientation(const Ogre::Quaternion &orientation) override
Sets orientation of the frame this covariance is attached.
bool orientation_visible_
If the orientation component is visible.
Ogre::SceneNode * position_scale_node_
virtual void setPositionColor(float r, float g, float b, float a)
Set the color of the position covariance. Values are in the range [0, 1].
Ogre::Vector3 current_ori_scale_[kNumOriShapes]
void setScale(const Ogre::Vector3 &) override
Set the scale of the object. Always relative to the identity orientation of the object.
Ogre::SceneManager * scene_manager_
Ogre scene manager this object is part of.
rviz::Shape * orientation_shape_[kNumOriShapes]
Cylinders used for the orientation covariance.
INLINE Rall1d< T, V, S > tan(const Rall1d< T, V, S > &arg)
virtual const Ogre::Quaternion & getPositionCovarianceOrientation()
virtual void setVisible(bool visible)
Sets visibility of this covariance.
CovarianceVisual(Ogre::SceneManager *scene_manager, Ogre::SceneNode *parent_node, bool is_local_rotation, bool is_visible=true, float pos_scale=1.0f, float ori_scale=0.1f, float ori_offset=0.1f)
Constructor.
void setOrientationScale(float ori_scale)
void updateOrientation(const Eigen::Matrix6d &covariance, ShapeIndex index)
rviz::Shape * position_shape_
Ellipse used for the position covariance.
Ogre::SceneNode * orientation_offset_node_[kNumOriShapes]
static const float max_degrees
Ogre::SceneNode * root_node_
const Ogre::Quaternion & getOrientation() override
Get the local orientation of this object.