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
10namespace 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
123 Eigen::Matrix4f m = Eigen::Matrix4f::Identity();
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
#define M_PI
Definition MathTools.h:17
#define cmp_or_log(l, c, r)
Eigen::Vector3f fromIce(Vector3f v)
Definition Storage.cpp:100
std::function< QWidgetPtr(WidgetPtr const &)> CreateWidgetCallback
static ValueT handleGuiChange(RemoteWidgetT const &, QWidgetT *widget)
static QWidgetT * createWidget(RemoteWidgetT const &desc, CreateWidgetCallback const &createChild, const QObject *stateChangeReceiver, const char *stateChangeSlot)
static void updateGui(RemoteWidgetT const &, QWidgetT *widget, ValueT const &m)
static bool isValid(RemoteWidgetT const &desc, std::ostream &out)
#define ARMARX_TRACE
Definition trace.h:77