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 "rotation_property.h"
00033
00034 using namespace rviz;
00035
00036 namespace agni_tf_tools
00037 {
00038
00039 RotationProperty::RotationProperty(Property* parent, const QString& name,
00040 const Eigen::Quaterniond& value,
00041 const char *changed_slot,
00042 QObject* receiver)
00043 : StringProperty(name, "",
00044 "Orientation specification using Euler angles or a quaternion.",
00045 parent, changed_slot, receiver)
00046 , ignore_quaternion_property_updates_(false)
00047 , show_euler_string_(true)
00048 {
00049 euler_property_ = new EulerProperty(this, "Euler angles", value);
00050 quaternion_property_ = new rviz::QuaternionProperty("quaternion",
00051 Ogre::Quaternion(value.w(), value.x(), value.y(), value.z()),
00052 "order: x, y, z, w", this);
00053 connect(euler_property_, SIGNAL(changed()), this, SLOT(updateFromEuler()));
00054 connect(quaternion_property_, SIGNAL(changed()), this, SLOT(updateFromQuaternion()));
00055
00056 connect(euler_property_, SIGNAL(statusUpdate(int,QString,QString)),
00057 this, SIGNAL(statusUpdate(int,QString,QString)));
00058
00059 connect(euler_property_, SIGNAL(quaternionChanged(Eigen::Quaterniond)),
00060 this, SIGNAL(quaternionChanged(Eigen::Quaterniond)));
00061 updateString();
00062 }
00063
00064 Eigen::Quaterniond RotationProperty::getQuaternion() const
00065 {
00066 return euler_property_->getQuaternion();
00067 }
00068
00069 void RotationProperty::setQuaternion(const Eigen::Quaterniond& q)
00070 {
00071 Eigen::Quaterniond qn = q.normalized();
00072 if (getQuaternion().isApprox(qn)) return;
00073
00074
00075 euler_property_->setQuaternion(qn);
00076 }
00077
00078 void RotationProperty::updateFromEuler()
00079 {
00080 const Eigen::Quaterniond q = euler_property_->getQuaternion();
00081
00082 if (!ignore_quaternion_property_updates_) {
00083 quaternion_property_->setQuaternion(Ogre::Quaternion(q.w(), q.x(), q.y(), q.z()));
00084 }
00085 show_euler_string_ = true;
00086 updateString();
00087 }
00088
00089 void RotationProperty::updateFromQuaternion()
00090 {
00091
00092 if (ignore_quaternion_property_updates_) return;
00093
00094 const Ogre::Quaternion &q = quaternion_property_->getQuaternion();
00095 Eigen::Quaternion<Ogre::Real> eigen_q(q.w, q.x, q.y, q.z);
00096
00097
00098 if (eigen_q.isApprox(getQuaternion().cast<Ogre::Real>())) return;
00099
00100 ignore_quaternion_property_updates_ = true;
00101 setQuaternion(eigen_q.cast<double>());
00102 ignore_quaternion_property_updates_ = false;
00103
00104 show_euler_string_ = false;
00105 updateString();
00106 }
00107
00108 void RotationProperty::setEulerAngles(double euler[], bool normalize)
00109 {
00110 euler_property_->setEulerAngles(euler, normalize);
00111 }
00112
00113 void RotationProperty::setEulerAngles(double e1, double e2, double e3, bool normalize)
00114 {
00115 euler_property_->setEulerAngles(e1, e2, e3, normalize);
00116 }
00117
00118 void RotationProperty::setEulerAxes(const QString &axes_spec)
00119 {
00120 euler_property_->setEulerAxes(axes_spec);
00121 }
00122
00123 bool RotationProperty::setValue(const QVariant& value)
00124 {
00125
00126 const QRegExp quatSpec("\\s*(quat:)?([^;]+;){3}");
00127 QString s = value.toString();
00128 if (quatSpec.indexIn(s) != -1)
00129 {
00130 s = s.mid(quatSpec.cap(1).length());
00131 return quaternion_property_->setValue(s);
00132 }
00133 return euler_property_->setValue(value);
00134 }
00135
00136 void RotationProperty::updateString()
00137 {
00138 QString euler = euler_property_->getValue().toString();
00139 QString quat = QString("quat: ") + quaternion_property_->getValue().toString();
00140 QString s = show_euler_string_ ? euler : quat;
00141 if (getString() != s) {
00142 Q_EMIT aboutToChange();
00143 value_ = s;
00144 Q_EMIT changed();
00145 }
00146 }
00147
00148 void RotationProperty::load(const Config& config)
00149 {
00150
00151 euler_property_->load(config);
00152 }
00153
00154 void RotationProperty::save(Config config) const
00155 {
00156
00157 euler_property_->save(config);
00158 }
00159
00160 void RotationProperty::setReadOnly(bool read_only)
00161 {
00162 euler_property_->setReadOnly(read_only);
00163 quaternion_property_->setReadOnly(read_only);
00164 }
00165
00166 }