00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "ogre_visuals/marker_with_covariance.h"
00033 #include "rviz/ogre_helpers/shape.h"
00034
00035 #include <OGRE/OgreVector3.h>
00036 #include <OGRE/OgreSceneNode.h>
00037
00038 #define SHAPE_WIDTH_MIN 0.005f // Avoid a complete flat sphere/cylinder
00039
00040 namespace marker_rviz_plugin {
00041
00042 MarkerWithCovariance::MarkerWithCovariance(Ogre::SceneManager *scene_manager, Ogre::SceneNode *parent_node, int id)
00043 : Marker(scene_manager, parent_node, id) {
00044
00045 variance_pos_parent = scene_node_->getParentSceneNode()->createChildSceneNode();
00046
00047 variance_pos_ = new rviz::Shape(rviz::Shape::Sphere, scene_manager_, variance_pos_parent);
00048 variance_pos_->setColor(Ogre::ColourValue(1.0, 1.0, 0.0, 0.9f));
00049 variance_pos_->getMaterial()->setReceiveShadows(false);
00050
00051 for (int i = 0; i < 3; i++) {
00052 variance_rpy_[i] = new rviz::Shape(rviz::Shape::Cylinder, scene_manager_, scene_node_);
00053 variance_rpy_[i]->setColor(Ogre::ColourValue((255.0 / 255.0), (85.0 / 255.0), (255.0 / 255.0), 0.6f));
00054 variance_rpy_[i]->getMaterial()->setReceiveShadows(false);
00055 }
00056 }
00057
00058 MarkerWithCovariance::~MarkerWithCovariance() {
00059 if(variance_pos_parent)
00060 scene_manager_->destroySceneNode(variance_pos_parent);
00061
00062 delete variance_pos_;
00063 for (int i = 0; i < 3; i++)
00064 delete variance_rpy_[i];
00065 }
00066
00067 void MarkerWithCovariance::setCovarianceMatrix(boost::array<double, 36> m) {
00068 Ogre::Matrix3 cov_xyz = Ogre::Matrix3(
00069 m[6 * 0 + 0], m[6 * 0 + 1], m[6 * 0 + 2],
00070 m[6 * 1 + 0], m[6 * 1 + 1], m[6 * 1 + 2],
00071 m[6 * 2 + 0], m[6 * 2 + 1], m[6 * 2 + 2]
00072 );
00073
00074 Ogre::Real eigenvalues[3];
00075 Ogre::Vector3 eigenvectors[3];
00076 cov_xyz.EigenSolveSymmetric(eigenvalues, eigenvectors);
00077
00078 if (eigenvalues[0] < 0)
00079 eigenvalues[0] = 0;
00080
00081 if (eigenvalues[1] < 0)
00082 eigenvalues[1] = 0;
00083
00084 if (eigenvalues[2] < 0)
00085 eigenvalues[2] = 0;
00086
00087
00088 variance_pos_parent->setPosition(scene_node_->getPosition());
00089 variance_pos_->setOrientation(Ogre::Quaternion(eigenvectors[0], eigenvectors[1], eigenvectors[2]));
00090 variance_pos_->setScale(
00091 Ogre::Vector3(
00092 fmax(2 * sqrt(eigenvalues[0]), SHAPE_WIDTH_MIN),
00093 fmax(2 * sqrt(eigenvalues[1]), SHAPE_WIDTH_MIN),
00094 fmax(2 * sqrt(eigenvalues[2]), SHAPE_WIDTH_MIN)
00095 )
00096 );
00097
00098
00099
00100 Ogre::Matrix3 cov_roll = Ogre::Matrix3(
00101 m[6 * 4 + 4], m[6 * 4 + 5], 0,
00102 m[6 * 5 + 5], m[6 * 5 + 5], 0,
00103 0, 0, 0
00104 );
00105 cov_roll.EigenSolveSymmetric(eigenvalues, eigenvectors);
00106
00107 Ogre::Quaternion o = Ogre::Quaternion::IDENTITY;
00108 o = o * Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_Z);
00109 o = o * Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_Y);
00110 o = o * (Ogre::Quaternion(Ogre::Matrix3(1, 0, 0,
00111 0, eigenvectors[0][0], eigenvectors[0][1],
00112 0, eigenvectors[1][0], eigenvectors[1][1])));
00113
00114 variance_rpy_[0]->setOrientation(o);
00115 variance_rpy_[0]->setPosition(Ogre::Vector3(0.7f, 0.0f, 0.0f));
00116 variance_rpy_[0]->setScale(
00117 Ogre::Vector3(
00118 fmax(2 * sqrt(eigenvalues[0]), SHAPE_WIDTH_MIN),
00119 SHAPE_WIDTH_MIN,
00120 fmax(2 * sqrt(eigenvalues[1]), SHAPE_WIDTH_MIN)
00121 )
00122 );
00123
00124
00125 Ogre::Matrix3 cov_pitch = Ogre::Matrix3(
00126 m[6 * 3 + 3], m[6 * 3 + 5], 0,
00127 m[6 * 5 + 3], m[6 * 5 + 5], 0,
00128 0, 0, 0
00129 );
00130 cov_pitch.EigenSolveSymmetric(eigenvalues, eigenvectors);
00131
00132 o = Ogre::Quaternion::IDENTITY;
00133 o = o * Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_Y);
00134 o = o * (Ogre::Quaternion(Ogre::Matrix3(eigenvectors[0][0], 0, eigenvectors[0][1],
00135 0, 1, 0,
00136 0, eigenvectors[1][0], eigenvectors[1][1])));
00137
00138 variance_rpy_[1]->setOrientation(o);
00139 variance_rpy_[1]->setPosition(Ogre::Vector3(0.0f, 0.7f, 0.0f));
00140 variance_rpy_[1]->setScale(
00141 Ogre::Vector3(
00142 fmax(2 * sqrt(eigenvalues[0]), SHAPE_WIDTH_MIN),
00143 SHAPE_WIDTH_MIN,
00144 fmax(2 * sqrt(eigenvalues[1]), SHAPE_WIDTH_MIN)
00145 )
00146 );
00147
00148
00149 Ogre::Matrix3 cov_yaw = Ogre::Matrix3(
00150 m[6 * 3 + 3], m[6 * 3 + 4], 0,
00151 m[6 * 4 + 3], m[6 * 4 + 4], 0,
00152 0, 0, 0
00153 );
00154 cov_yaw.EigenSolveSymmetric(eigenvalues, eigenvectors);
00155
00156 o = Ogre::Quaternion::IDENTITY;
00157 o = o * Ogre::Quaternion(Ogre::Degree(90), Ogre::Vector3::UNIT_X);
00158 o = o * (Ogre::Quaternion(Ogre::Matrix3(eigenvectors[0][0], eigenvectors[0][1], 0,
00159 eigenvectors[1][0], eigenvectors[1][1], 0,
00160 0, 0, 1)));
00161
00162 variance_rpy_[2]->setOrientation(o);
00163 variance_rpy_[2]->setPosition(Ogre::Vector3(0.0f, 0.0f, 0.7f));
00164 variance_rpy_[2]->setScale(
00165 Ogre::Vector3(
00166 fmax(2 * sqrt(eigenvalues[0]), SHAPE_WIDTH_MIN),
00167 SHAPE_WIDTH_MIN,
00168 fmax(2 * sqrt(eigenvalues[1]), SHAPE_WIDTH_MIN)
00169 )
00170 );
00171 }
00172
00173 void MarkerWithCovariance::setScale(const Ogre::Vector3 &scale) {
00174 Marker::setScale(scale);
00175 variance_pos_parent->setScale(scale);
00176 }
00177
00178 }