PlatformUnitGuiPlugin.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
25
26#include <Eigen/Geometry>
27
29
30#include <RobotAPI/gui-plugins/PlatformUnitPlugin/ui_PlatformUnitConfigDialog.h>
31
33
34// Qt headers
35#include <QHBoxLayout>
36#include <QLabel>
37#include <QLineEdit>
38#include <QPushButton>
39#include <Qt>
40#include <QtGlobal>
41
42//std
43#include <cmath>
44#include <memory>
45
46#include <SimoxUtility/math/convert/mat3f_to_rpy.h>
47
48#include <RobotAPI/interface/core/RobotLocalization.h>
49
50using namespace armarx;
51
56
58 platformUnitProxyName("PlatformUnit"), // overwritten in loadSettings() anyway?
59 platformName("Platform"),
60 speedCtrl{nullptr},
61 rotaCtrl{nullptr},
62 ctrlEvaluationTimer{},
63 platformRotation{0},
64 platformMoves{false}
65{
66 // init gui
67 ui.setupUi(getWidget());
68 //init joystick controls
69 std::unique_ptr<JoystickControlWidget> speed{new JoystickControlWidget{}};
70 speedCtrl = speed.get();
71 speedCtrl->setSteps(0);
72 //use upper semicircle for rotation
73 std::unique_ptr<JoystickControlWidget> rotat{new JoystickControlWidget{false}};
74 rotaCtrl = rotat.get();
75 rotaCtrl->setSteps(0);
76 //add joystick controls
77 ui.gridLayout_2->addWidget(rotat.release(), 2, 0, 1, 2);
78 ui.gridLayout_3->addWidget(speed.release(), 2, 0, 1, 2);
79
80 ctrlEvaluationTimer.setSingleShot(false);
81 keyboardVelocityTimer.setInterval(50);
82 stopPlatformTimer.setInterval(100);
83 connect(&stopPlatformTimer, SIGNAL(timeout()), this, SLOT(stopControlTimer()));
84 connect(&stopPlatformTimer, SIGNAL(timeout()), this, SLOT(stopPlatform()));
85
86
87 connect(getWidget().data(),
88 SIGNAL(commandKeyPressed(int)),
89 this,
90 SLOT(controlPlatformWithKeyboard(int)));
91 connect(getWidget().data(),
92 SIGNAL(commandKeyReleased(int)),
93 this,
94 SLOT(stopPlatformWithKeyboard(int)));
95}
96
97void
99{
100 usingProxy(platformUnitProxyName);
101 usingTopic("GlobalRobotPoseLocalization");
102 // ARMARX_INFO << "Listening on Topic: " << platformName + "State";
103}
104
105void
107{
108 platformUnitProxy = getProxy<PlatformUnitInterfacePrx>(platformUnitProxyName);
109 connectSlots();
110}
111
112void
117
118void
122
123QPointer<QDialog>
125{
126 if (!dialog)
127 {
128 dialog = new PlatformUnitConfigDialog(parent);
129 }
130
131 dialog->ui->editPlatformName->setText(QString::fromStdString(platformName));
132 return qobject_cast<PlatformUnitConfigDialog*>(dialog);
133}
134
135void
137{
138 platformUnitProxyName = dialog->finder->getSelectedProxyName().toStdString();
139 platformName = dialog->ui->editPlatformName->text().toStdString();
140}
141
142void
144{
145 platformUnitProxyName =
146 settings->value("platformUnitProxyName", QString::fromStdString(platformUnitProxyName))
147 .toString()
148 .toStdString();
149 platformName = settings->value("platformName", QString::fromStdString(platformName))
150 .toString()
151 .toStdString();
152}
153
154void
156{
157 settings->setValue("platformUnitProxyName", QString::fromStdString(platformUnitProxyName));
158 settings->setValue("platformName", QString::fromStdString(platformName));
159}
160
161void
163{
164 connect(ui.buttonMoveToPosition, SIGNAL(clicked()), this, SLOT(moveTo()), Qt::UniqueConnection);
165 connect(&ctrlEvaluationTimer,
166 SIGNAL(timeout()),
167 this,
168 SLOT(controlTimerTick()),
169 Qt::UniqueConnection);
170 connect(&keyboardVelocityTimer,
171 SIGNAL(timeout()),
172 this,
173 SLOT(keyboardVelocityControl()),
174 Qt::UniqueConnection);
175 connect(speedCtrl, SIGNAL(pressed()), this, SLOT(startControlTimer()), Qt::UniqueConnection);
176 connect(
177 speedCtrl, SIGNAL(pressed()), &keyboardVelocityTimer, SLOT(stop()), Qt::UniqueConnection);
178 connect(rotaCtrl, SIGNAL(pressed()), this, SLOT(startControlTimer()), Qt::UniqueConnection);
179 connect(
180 rotaCtrl, SIGNAL(pressed()), &keyboardVelocityTimer, SLOT(stop()), Qt::UniqueConnection);
181 connect(speedCtrl, SIGNAL(released()), this, SLOT(stopPlatform()), Qt::UniqueConnection);
182 connect(speedCtrl, SIGNAL(released()), this, SLOT(stopControlTimer()), Qt::UniqueConnection);
183 connect(rotaCtrl, SIGNAL(released()), this, SLOT(stopPlatform()), Qt::UniqueConnection);
184 connect(rotaCtrl, SIGNAL(released()), this, SLOT(stopControlTimer()), Qt::UniqueConnection);
185 connect(
186 ui.buttonStopPlatform, SIGNAL(pressed()), this, SLOT(stopPlatform()), Qt::UniqueConnection);
187}
188
189void
191{
192 ARMARX_LOG << "Moving Platform";
193 ::Ice::Float positionX = ui.editTargetPositionX->text().toFloat();
194 ::Ice::Float positionY = ui.editTargetPositionY->text().toFloat();
195 ::Ice::Float rotation = ui.editTargetRotation->text().toFloat();
196 ::Ice::Float posAcc = 10.0f;
197 ::Ice::Float rotAcc = 0.1f;
198 platformUnitProxy->moveTo(positionX, positionY, rotation, posAcc, rotAcc);
199}
200
201void
203{
204 ui.labelCurrentPositionX->setText(QString::number(x));
205 ui.labelCurrentPositionY->setText(QString::number(y));
206 ui.labelCurrentRotation->setText(QString::number(alpha));
207}
208
209void
211{
212 ui.editTargetPositionX->setText(QString::number(x));
213 ui.editTargetPositionY->setText(QString::number(y));
214 ui.editTargetRotation->setText(QString::number(alpha));
215}
216
217void
219{
220 ctrlEvaluationTimer.start(CONTROL_TICK_RATE); //tickrate in ms
221}
222
223void
225{
226 ctrlEvaluationTimer.stop();
227 speedCtrl->setNibble({0, 0});
228 rotaCtrl->setNibble({0, 0});
229}
230
231void
232PlatformUnitWidget::reportGlobalRobotPose(const ::armarx::TransformStamped& transformStamped,
233 const ::Ice::Current&)
234{
235 const Eigen::Isometry3f global_T_robot(transformStamped.transform);
236 const float x = global_T_robot.translation().x();
237 const float y = global_T_robot.translation().y();
238 const float yaw = simox::math::mat3f_to_rpy(global_T_robot.linear()).z();
239
240 // moved to qt thread for thread safety
241 QMetaObject::invokeMethod(
242 this, "setNewPlatformPoseLabels", Q_ARG(float, x), Q_ARG(float, y), Q_ARG(float, yaw));
243 platformRotation = yaw;
244}
245
246void
247PlatformUnitWidget::stopPlatform()
248{
249 platformUnitProxy->stopPlatform();
250}
251
252void
253PlatformUnitWidget::controlPlatformWithKeyboard(int key)
254{
255 pressedKeys.insert(key);
256 if (!ctrlEvaluationTimer.isActive())
257 {
258 ctrlEvaluationTimer.start();
259 }
260 if (!keyboardVelocityTimer.isActive())
261 {
262 keyboardVelocityControl();
263 keyboardVelocityTimer.start();
264 }
265}
266
267void
268PlatformUnitWidget::stopPlatformWithKeyboard(int key)
269{
270 pressedKeys.remove(key);
271
272 if (!keyboardVelocityTimer.isActive())
273 {
274 keyboardVelocityControl();
275 keyboardVelocityTimer.start();
276 }
277}
278
279void
280PlatformUnitWidget::keyboardVelocityControl()
281{
282 if (!pressedKeys.contains(Qt::Key_A) && !pressedKeys.contains(Qt::Key_D))
283 {
284 currentKeyboardVelocityX *= deceleration;
285 if (fabs(currentKeyboardVelocityX) < 0.001)
286 {
287 currentKeyboardVelocityX = 0;
288 }
289 }
290 if (!pressedKeys.contains(Qt::Key_W) && !pressedKeys.contains(Qt::Key_S))
291 {
292 currentKeyboardVelocityY *= deceleration;
293 if (fabs(currentKeyboardVelocityY) < 0.001)
294 {
295 currentKeyboardVelocityY = 0;
296 }
297 }
298 if (!pressedKeys.contains(Qt::Key_Q) && !pressedKeys.contains(Qt::Key_E))
299 {
300 currentKeyboardVelocityAlpha *= deceleration;
301 if (fabs(currentKeyboardVelocityAlpha) < 0.001)
302 {
303 currentKeyboardVelocityAlpha = 0;
304 }
305 }
306
307 for (auto key : pressedKeys)
308 {
309 switch (key)
310 {
311 case Qt::Key_Q:
312 currentKeyboardVelocityAlpha -= acceleration;
313 break;
314 case Qt::Key_E:
315 currentKeyboardVelocityAlpha += acceleration;
316 break;
317 case Qt::Key_W:
318 currentKeyboardVelocityY -= acceleration;
319 break;
320 case Qt::Key_S:
321 currentKeyboardVelocityY += acceleration;
322 break;
323 case Qt::Key_A:
324 currentKeyboardVelocityX -= acceleration;
325 break;
326 case Qt::Key_D:
327 currentKeyboardVelocityX += acceleration;
328 break;
329 default:
330 break;
331 }
332 }
333
334 currentKeyboardVelocityAlpha = std::max(-1.f, currentKeyboardVelocityAlpha);
335 currentKeyboardVelocityAlpha = std::min(1.f, currentKeyboardVelocityAlpha);
336 currentKeyboardVelocityX = std::max(-1.f, currentKeyboardVelocityX);
337 currentKeyboardVelocityX = std::min(1.f, currentKeyboardVelocityX);
338 currentKeyboardVelocityY = std::max(-1.f, currentKeyboardVelocityY);
339 currentKeyboardVelocityY = std::min(1.f, currentKeyboardVelocityY);
340
341 float y = sin(acos(currentKeyboardVelocityAlpha));
342 speedCtrl->setNibble(QPointF(currentKeyboardVelocityX, currentKeyboardVelocityY));
343 rotaCtrl->setNibble(QPointF(currentKeyboardVelocityAlpha, -y));
344}
345
346QPointer<QWidget>
348{
349 if (!__widget)
350 {
351 __widget = new KeyboardPlatformHookWidget();
352 }
353
354 return __widget;
355}
356
357void
358PlatformUnitWidget::controlTimerTick()
359{
360 float translationFactor = ui.maxTranslationSpeed->value();
361 float rotationFactor = ui.maxRotationSpeed->value() * -1;
362 float rotationVel = rotaCtrl->getRotation() / M_PI_2 * rotationFactor;
363 ARMARX_INFO << deactivateSpam(0.5) << "Translation speed: ("
364 << speedCtrl->getPosition().x() * translationFactor << ", "
365 << speedCtrl->getPosition().y() * translationFactor << ")"
366 << ", \t rotation speed: " << (rotationVel);
367
368 platformUnitProxy->move(speedCtrl->getPosition().x() * translationFactor,
369 -1 * speedCtrl->getPosition().y() * translationFactor,
370 rotationVel);
371
372 if (speedCtrl->getPosition().x() == 0 && speedCtrl->getPosition().y() == 0 &&
373 rotaCtrl->getRotation() == 0)
374 {
376 }
377}
378
379void
381{
382 switch (event->key())
383 {
384 case Qt::Key_A:
385 case Qt::Key_W:
386 case Qt::Key_S:
387 case Qt::Key_D:
388 case Qt::Key_Q:
389 case Qt::Key_E:
390 if (!event->isAutoRepeat())
391 {
392 emit commandKeyPressed(event->key());
393 }
394 }
395 QWidget::keyPressEvent(event);
396}
397
398void
400{
401 switch (event->key())
402 {
403 case Qt::Key_A:
404 case Qt::Key_W:
405 case Qt::Key_S:
406 case Qt::Key_D:
407 case Qt::Key_Q:
408 case Qt::Key_E:
409 if (!event->isAutoRepeat())
410 {
411 emit commandKeyReleased(event->key());
412 }
413 }
414 QWidget::keyReleaseEvent(event);
415}
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
std::enable_if<!HasGetWidgetName< ArmarXWidgetType >::value >::type addWidget()
Provides a simple joystick control.
void keyReleaseEvent(QKeyEvent *event) override
void keyPressEvent(QKeyEvent *event) override
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
void onInitComponent() override
Pure virtual hook for the subclass.
void onDisconnectComponent() override
Hook for subclass.
void loadSettings(QSettings *settings) override
Implement to load the settings that are part of the GUI configuration.
void setNewPlatformPoseLabels(float x, float y, float alpha)
void saveSettings(QSettings *settings) override
Implement to save the settings as part of the GUI configuration.
void setNewTargetPoseLabels(float x, float y, float alpha)
QPointer< QDialog > getConfigDialog(QWidget *parent=0) override
getConfigDialog returns a pointer to the a configuration widget of this controller.
QPointer< QWidget > getWidget() override
getWidget returns a pointer to the a widget of this controller.
void onConnectComponent() override
Pure virtual hook for the subclass.
void reportGlobalRobotPose(const ::armarx::TransformStamped &transformStamped, const ::Ice::Current &=::Ice::emptyCurrent) override
void configured() override
This function must be implemented by the user, if he supplies a config dialog.
Ui::PlatformUnitGuiPlugin ui
void onExitComponent() override
Hook for subclass.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_LOG
Definition Logging.h:165
This file offers overloads of toIce() and fromIce() functions for STL container types.