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 &)