Matrix4fWidgets.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <QDoubleSpinBox>
4 #include <QHBoxLayout>
5 #include <QLabel>
6 #include <QWidget>
7 
8 #include "Basic.h"
9 
10 namespace armarx::RemoteGui
11 {
12  struct PosRPYSpinBoxesHandler : TypedWidget<PosRPYSpinBoxes, QWidget, VALUE_VARIANT_MATRIX4>
13  {
14  static bool
15  isValid(RemoteWidgetT const& desc, std::ostream& out)
16  {
17 #define cmp_or_log(l, c, r) \
18  (l c r ? true \
19  : (out << " FAILED: " #l " " #c " " #r " " << VAROUT(l) << ", " << VAROUT(r) << '\n', \
20  false))
21 
22  return cmp_or_log(desc.minPos.x, <=, desc.maxPos.x) &&
23  cmp_or_log(desc.minPos.y, <=, desc.maxPos.y) &&
24  cmp_or_log(desc.minPos.z, <=, desc.maxPos.z) &&
25  cmp_or_log(desc.stepsPos.x, >, 0) && cmp_or_log(desc.stepsPos.y, >, 0) &&
26  cmp_or_log(desc.stepsPos.z, >, 0) && cmp_or_log(desc.decimalsPos.x, >=, 0) &&
27  cmp_or_log(desc.decimalsPos.y, >=, 0) && cmp_or_log(desc.decimalsPos.z, >=, 0)
28 
29  && cmp_or_log(desc.minRPY.x, <=, desc.maxRPY.x) &&
30  cmp_or_log(desc.minRPY.y, <=, desc.maxRPY.y) &&
31  cmp_or_log(desc.minRPY.z, <=, desc.maxRPY.z) &&
32  cmp_or_log(desc.stepsRPY.x, >, 0) && cmp_or_log(desc.stepsRPY.y, >, 0) &&
33  cmp_or_log(desc.stepsRPY.z, >, 0) && cmp_or_log(desc.decimalsRPY.x, >=, 0) &&
34  cmp_or_log(desc.decimalsRPY.y, >=, 0) && cmp_or_log(desc.decimalsRPY.z, >=, 0);
35 #undef cmp_or_log
36  }
37 
38  static QWidgetT*
40  CreateWidgetCallback const& createChild,
41  const QObject* stateChangeReceiver,
42  const char* stateChangeSlot)
43  {
45  QWidget* widget = new QWidget;
46  QHBoxLayout* l = new QHBoxLayout;
47  l->setContentsMargins(0, 0, 0, 0);
48  widget->setLayout(l);
49  widget->setToolTip(QString::fromStdString(desc.toolTip));
50 
51  Eigen::Vector3f minPos = fromIce(desc.minPos);
52  Eigen::Vector3f maxPos = fromIce(desc.maxPos);
53  Eigen::Vector3i decimalsPos = fromIce(desc.decimalsPos);
54  Eigen::Vector3i stepsPos = fromIce(desc.stepsPos);
55  for (int i = 0; i < 3; ++i)
56  {
57  QDoubleSpinBox* e = new QDoubleSpinBox;
58  l->addWidget(e);
59  e->setMinimum(minPos(i));
60  e->setMaximum(maxPos(i));
61  e->setDecimals(decimalsPos(i));
62  e->setSingleStep((maxPos(i) - minPos(i)) / stepsPos(i));
63  QObject::connect(
64  e, SIGNAL(valueChanged(double)), stateChangeReceiver, stateChangeSlot);
65  }
66  l->addWidget(new QLabel{"/"});
67 
68  Eigen::Vector3f minRPY = fromIce(desc.minRPY);
69  Eigen::Vector3f maxRPY = fromIce(desc.maxRPY);
70  Eigen::Vector3i decimalsRPY = fromIce(desc.decimalsRPY);
71  Eigen::Vector3i stepsRPY = fromIce(desc.stepsRPY);
72  for (int i = 0; i < 3; ++i)
73  {
74  QDoubleSpinBox* e = new QDoubleSpinBox;
75  l->addWidget(e);
76  e->setMinimum(minRPY(i));
77  e->setMaximum(maxRPY(i));
78  e->setDecimals(decimalsRPY(i));
79  e->setSingleStep((maxRPY(i) - minRPY(i)) / stepsRPY(i));
80  QObject::connect(
81  e, SIGNAL(valueChanged(double)), stateChangeReceiver, stateChangeSlot);
82  }
83  return widget;
84  }
85 
86  static void
87  updateGui(RemoteWidgetT const&, QWidgetT* widget, ValueT const& m)
88  {
89  float rx, ry, rz;
90  ry = std::atan2(-m(2, 0), sqrtf(m(0, 0) * m(0, 0) + m(1, 0) * m(1, 0)));
91 
92  if (fabs(ry - static_cast<float>(M_PI) * 0.5f) < 1e-10f)
93  {
94  rx = 0;
95  rz = std::atan2(m(0, 1), m(1, 1));
96  }
97  else if (std::fabs(ry + static_cast<float>(M_PI) * 0.5f) < 1e-10f)
98  {
99  rx = 0;
100  rz = -std::atan2(m(0, 1), m(1, 1));
101  }
102  else
103  {
104  float cb = 1.0f / std::cos(ry);
105  rx = std::atan2(m(2, 1) * cb, m(2, 2) * cb);
106  rz = std::atan2(m(1, 0) * cb, m(0, 0) * cb);
107  }
108 
109  static_cast<QDoubleSpinBox*>(widget->layout()->itemAt(0)->widget())->setValue(m(0, 3));
110  static_cast<QDoubleSpinBox*>(widget->layout()->itemAt(1)->widget())->setValue(m(1, 3));
111  static_cast<QDoubleSpinBox*>(widget->layout()->itemAt(2)->widget())->setValue(m(2, 3));
112 
113  static_cast<QDoubleSpinBox*>(widget->layout()->itemAt(4)->widget())->setValue(rx);
114  static_cast<QDoubleSpinBox*>(widget->layout()->itemAt(5)->widget())->setValue(ry);
115  static_cast<QDoubleSpinBox*>(widget->layout()->itemAt(6)->widget())->setValue(rz);
116  }
117 
118  static ValueT
120  {
121  QWidgetT* parent = static_cast<QWidget*>(widget->parent());
122 
124 
125  const float tx = static_cast<float>(
126  static_cast<QDoubleSpinBox*>(parent->layout()->itemAt(0)->widget())->value());
127  const float ty = static_cast<float>(
128  static_cast<QDoubleSpinBox*>(parent->layout()->itemAt(1)->widget())->value());
129  const float tz = static_cast<float>(
130  static_cast<QDoubleSpinBox*>(parent->layout()->itemAt(2)->widget())->value());
131  const float rx = static_cast<float>(
132  static_cast<QDoubleSpinBox*>(parent->layout()->itemAt(4)->widget())->value());
133  const float ry = static_cast<float>(
134  static_cast<QDoubleSpinBox*>(parent->layout()->itemAt(5)->widget())->value());
135  const float rz = static_cast<float>(
136  static_cast<QDoubleSpinBox*>(parent->layout()->itemAt(6)->widget())->value());
137 
138  const float sgamma = sinf(rx);
139  const float cgamma = cosf(rx);
140  const float sbeta = sinf(ry);
141  const float cbeta = cosf(ry);
142  const float salpha = sinf(rz);
143  const float calpha = cosf(rz);
144 
145  m(0, 0) = calpha * cbeta;
146  m(0, 1) = calpha * sbeta * sgamma - salpha * cgamma;
147  m(0, 2) = calpha * sbeta * cgamma + salpha * sgamma;
148  m(0, 3) = tx;
149 
150  m(1, 0) = salpha * cbeta;
151  m(1, 1) = salpha * sbeta * sgamma + calpha * cgamma;
152  m(1, 2) = salpha * sbeta * cgamma - calpha * sgamma;
153  m(1, 3) = ty;
154 
155  m(2, 0) = -sbeta;
156  m(2, 1) = cbeta * sgamma;
157  m(2, 2) = cbeta * cgamma;
158  m(2, 3) = tz;
159 
160  return m;
161  }
162  };
163 } // namespace armarx::RemoteGui
armarx::RemoteGui::PosRPYSpinBoxesHandler::createWidget
static QWidgetT * createWidget(RemoteWidgetT const &desc, CreateWidgetCallback const &createChild, const QObject *stateChangeReceiver, const char *stateChangeSlot)
Definition: Matrix4fWidgets.h:39
armarx::RemoteGui::PosRPYSpinBoxesHandler
Definition: Matrix4fWidgets.h:12
armarx::RemoteGui
Definition: LightweightRemoteGuiComponentPlugin.h:30
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::RemoteGui::TypedWidget
Definition: TypedWidget.h:113
armarx::RemoteGui::TypedWidget< PosRPYSpinBoxes, QWidget, VALUE_VARIANT_MATRIX4 >::ValueT
typename Storage< ValueType >::Type ValueT
Definition: TypedWidget.h:118
armarx::RemoteGui::PosRPYSpinBoxesHandler::updateGui
static void updateGui(RemoteWidgetT const &, QWidgetT *widget, ValueT const &m)
Definition: Matrix4fWidgets.h:87
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:77
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
cmp_or_log
#define cmp_or_log(l, c, r)
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
M_PI
#define M_PI
Definition: MathTools.h:17
Basic.h
armarx::RemoteGui::TypedWidget< PosRPYSpinBoxes, QWidget, VALUE_VARIANT_MATRIX4 >::QWidgetT
QWidget QWidgetT
Definition: TypedWidget.h:116
armarx::RemoteGui::fromIce
Eigen::Vector3f fromIce(Vector3f v)
Definition: Storage.cpp:100
armarx::RemoteGui::PosRPYSpinBoxesHandler::isValid
static bool isValid(RemoteWidgetT const &desc, std::ostream &out)
Definition: Matrix4fWidgets.h:15
armarx::RemoteGui::PosRPYSpinBoxesHandler::handleGuiChange
static ValueT handleGuiChange(RemoteWidgetT const &, QWidgetT *widget)
Definition: Matrix4fWidgets.h:119
armarx::RemoteGui::CreateWidgetCallback
std::function< QWidgetPtr(WidgetPtr const &)> CreateWidgetCallback
Definition: WidgetHandler.h:20
armarx::RemoteGui::TypedWidget< PosRPYSpinBoxes, QWidget, VALUE_VARIANT_MATRIX4 >::RemoteWidgetT
PosRPYSpinBoxes RemoteWidgetT
Definition: TypedWidget.h:115