32 #include <QStringList> 36 #include <boost/format.hpp> 37 #include <boost/assign/list_of.hpp> 44 std::invalid_argument(msg)
49 const Eigen::Quaterniond& value,
50 const char *changed_slot,
53 "Angles specified in degrees.\n" 54 "Choose axes with spec like xyz, zxz, or rpy.\n" 55 "Composition w.r.t. the static or rotating frame\n" 56 "is selected by prefixing with 's' or 'r' (default).",
57 parent, changed_slot, receiver)
68 for (
int i=0; i < 3; ++i) {
84 q = Eigen::AngleAxisd(euler[2], Eigen::Vector3d::Unit(
axes_[2])) *
85 Eigen::AngleAxisd(euler[1], Eigen::Vector3d::Unit(
axes_[1])) *
86 Eigen::AngleAxisd(euler[0], Eigen::Vector3d::Unit(
axes_[0]));
88 q = Eigen::AngleAxisd(euler[0], Eigen::Vector3d::Unit(
axes_[0])) *
89 Eigen::AngleAxisd(euler[1], Eigen::Vector3d::Unit(
axes_[1])) *
90 Eigen::AngleAxisd(euler[2], Eigen::Vector3d::Unit(
axes_[2]));
94 for (
int i=0; i < 3; ++i) {
96 if (!Eigen::internal::isApprox(deg,
euler_[i]->getFloat())) {
119 double euler[3] = {e1,e2,e3};
125 static const std::vector<QString> xyzNames = boost::assign::list_of(
"x")(
"y")(
"z");
126 static const std::vector<QString> rpyNames = boost::assign::list_of(
"roll")(
"pitch")(
"yaw");
127 const std::vector<QString> *names = &xyzNames;
130 QString sAxes = axes_spec;
131 if (sAxes ==
"rpy") {
134 }
else if (sAxes ==
"ypr") {
140 QString::iterator pc = sAxes.begin();
142 if (*pc ==
's') fixed =
true;
143 else if (*pc ==
'r') fixed =
false;
144 else {fixed =
false; --pc;}
148 if (sAxes.end() - pc != 3)
149 throw invalid_axes((boost::format(
"Invalid axes spec: %s. Expecting 3 chars from [xyz]")
150 % axes_spec.toStdString()).str());
154 for (uint i=0; i < 3; ++i, ++pc) {
155 int idx = pc->toLatin1() -
'x';
156 if (idx < 0 || idx > 2)
157 throw invalid_axes((boost::format(
"invalid axis char: %c (only xyz allowed)") % pc->unicode()).str());
158 if (i > 0 && axes[i-1] == static_cast<uint>(idx))
159 throw invalid_axes(
"consecutive axes need to be different");
166 for (
int i=0; i < 3; ++i) {
178 static const QString statusAxes (
"Euler axes");
179 static const QString statusAngles (
"Euler angles");
181 const QRegExp axesSpec(
"\\s*([a-z]+)\\s*:?");
182 QString
s = value.toString();
185 if (axesSpec.indexIn(s) != -1) {
193 s = s.mid(axesSpec.matchedLength());
202 if (s.trimmed().isEmpty())
206 QStringList strings = s.split(
';');
209 for (
int i=0; i < 3 && ok; ++i)
211 if (i < strings.size())
219 "failed to parse angle value");
222 if (strings.size() != 3 && strings.size() != 1) {
224 "expecting 3 semicolon-separated values");
237 for (
int i = 0; i < 3; ++i)
256 std::swap(e[0], e[2]);
264 QString
s = QString(
"%1: %2; %3; %4")
266 .arg(
euler_[0]->getFloat(), 0,
'f', 1)
267 .arg(
euler_[1]->getFloat(), 0,
'f', 1)
268 .arg(
euler_[2]->getFloat(), 0,
'f', 1);
269 value_ = s.replace(
".0",
"");
285 for (
int i=0; i < 3; ++i)
306 for (
int i=0; i < 3; ++i)
virtual bool setValue(const QVariant &value)
virtual void setReadOnly(bool read_only)
Overridden from Property to propagate read-only-ness to children.
void quaternionChanged(Eigen::Quaterniond q)
Eigen::Quaterniond quaternion_
bool mapGetFloat(const QString &key, float *value_out) const
virtual void setName(const QString &name)
void setEulerAngles(double euler[3], bool normalize)
invalid_axes(const std::string &msg)
bool mapGetString(const QString &key, QString *value_out) const
virtual bool setValue(const QVariant &new_value)
void mapSetValue(const QString &key, QVariant value)
void updateAngles(const Eigen::Quaterniond &q)
static double from_degrees(double degrees)
void setQuaternion(const Eigen::Quaterniond &q)
void setEulerAxes(const QString &axes_spec)
static double to_degrees(double radians)
FloatProperty * euler_[3]
TFSIMD_FORCE_INLINE Vector3 & normalize()
bool ignore_child_updates_
void updateFromChildren()
virtual void save(Config config) const
virtual void load(const Config &config)
Load the value of this property and/or its children from the given Config node.
virtual QVariant getValue() const
EulerProperty(Property *parent=0, const QString &name=QString(), const Eigen::Quaterniond &value=Eigen::Quaterniond::Identity(), const char *changed_slot=0, QObject *receiver=0)
void statusUpdate(int, const QString &, const QString &)