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 <RobotAPI/gui-plugins/PlatformUnitPlugin/ui_PlatformUnitGuiPlugin.h>
27
28#include <Eigen/Geometry>
29
31
32#include <RobotAPI/gui-plugins/PlatformUnitPlugin/ui_PlatformUnitConfigDialog.h>
33
35
36// Qt headers
37#include <QHBoxLayout>
38#include <QLabel>
39#include <QLineEdit>
40#include <QPushButton>
41#include <Qt>
42#include <QtGlobal>
43
44//std
45#include <cmath>
46#include <memory>
47
48#include <SimoxUtility/math/convert/mat3f_to_rpy.h>
49
50#include <RobotAPI/interface/core/RobotLocalization.h>
51
52using namespace armarx;
53
58
60
62 platformUnitProxyName("PlatformUnit"), // overwritten in loadSettings() anyway?
63 platformName("Platform"),
64 speedCtrl{nullptr},
65 rotaCtrl{nullptr},
66 ctrlEvaluationTimer{},
67 platformRotation{0},
68 platformMoves{false}
69{
70 // init gui
71 ui = std::make_unique<Ui::PlatformUnitGuiPlugin>();
72 ui->setupUi(getWidget());
73 //init joystick controls
74 std::unique_ptr<JoystickControlWidget> speed{new JoystickControlWidget{}};
75 speedCtrl = speed.get();
76 speedCtrl->setSteps(0);
77 //use upper semicircle for rotation
78 std::unique_ptr<JoystickControlWidget> rotat{new JoystickControlWidget{false}};
79 rotaCtrl = rotat.get();
80 rotaCtrl->setSteps(0);
81 //add joystick controls
82 ui->gridLayout_2->addWidget(rotat.release(), 2, 0, 1, 2);
83 ui->gridLayout_3->addWidget(speed.release(), 2, 0, 1, 2);
84
85 ctrlEvaluationTimer.setSingleShot(false);
86 keyboardVelocityTimer.setInterval(50);
87 stopPlatformTimer.setInterval(100);
88 connect(&stopPlatformTimer, SIGNAL(timeout()), this, SLOT(stopControlTimer()));
89 connect(&stopPlatformTimer, SIGNAL(timeout()), this, SLOT(stopPlatform()));
90
91
92 connect(getWidget().data(),
93 SIGNAL(commandKeyPressed(int)),
94 this,
95 SLOT(controlPlatformWithKeyboard(int)));
96 connect(getWidget().data(),
97 SIGNAL(commandKeyReleased(int)),
98 this,
99 SLOT(stopPlatformWithKeyboard(int)));
100}
101
102void
104{
105 usingProxy(platformUnitProxyName);
106 usingTopic("GlobalRobotPoseLocalization");
107 // ARMARX_INFO << "Listening on Topic: " << platformName + "State";
108}
109
110void
112{
113 platformUnitProxy = getProxy<PlatformUnitInterfacePrx>(platformUnitProxyName);
114 connectSlots();
115}
116
117void
122
123void
127
128QPointer<QDialog>
130{
131 if (!dialog)
132 {
133 dialog = new PlatformUnitConfigDialog(parent);
134 }
135
136 dialog->ui->editPlatformName->setText(QString::fromStdString(platformName));
137 return qobject_cast<PlatformUnitConfigDialog*>(dialog);
138}
139
140void
142{
143 platformUnitProxyName = dialog->finder->getSelectedProxyName().toStdString();
144 platformName = dialog->ui->editPlatformName->text().toStdString();
145}
146
147void
149{
150 platformUnitProxyName =
151 settings->value("platformUnitProxyName", QString::fromStdString(platformUnitProxyName))
152 .toString()
153 .toStdString();
154 platformName = settings->value("platformName", QString::fromStdString(platformName))
155 .toString()
156 .toStdString();
157}
158
159void
161{
162 settings->setValue("platformUnitProxyName", QString::fromStdString(platformUnitProxyName));
163 settings->setValue("platformName", QString::fromStdString(platformName));
164}
165
166void
168{
169 connect(ui->buttonMoveToPosition, SIGNAL(clicked()), this, SLOT(moveTo()), Qt::UniqueConnection);
170 connect(&ctrlEvaluationTimer,
171 SIGNAL(timeout()),
172 this,
173 SLOT(controlTimerTick()),
174 Qt::UniqueConnection);
175 connect(&keyboardVelocityTimer,
176 SIGNAL(timeout()),
177 this,
178 SLOT(keyboardVelocityControl()),
179 Qt::UniqueConnection);
180 connect(speedCtrl, SIGNAL(pressed()), this, SLOT(startControlTimer()), Qt::UniqueConnection);
181 connect(
182 speedCtrl, SIGNAL(pressed()), &keyboardVelocityTimer, SLOT(stop()), Qt::UniqueConnection);
183 connect(rotaCtrl, SIGNAL(pressed()), this, SLOT(startControlTimer()), Qt::UniqueConnection);
184 connect(
185 rotaCtrl, SIGNAL(pressed()), &keyboardVelocityTimer, SLOT(stop()), Qt::UniqueConnection);
186 connect(speedCtrl, SIGNAL(released()), this, SLOT(stopPlatform()), Qt::UniqueConnection);
187 connect(speedCtrl, SIGNAL(released()), this, SLOT(stopControlTimer()), Qt::UniqueConnection);
188 connect(rotaCtrl, SIGNAL(released()), this, SLOT(stopPlatform()), Qt::UniqueConnection);
189 connect(rotaCtrl, SIGNAL(released()), this, SLOT(stopControlTimer()), Qt::UniqueConnection);
190 connect(
191 ui->buttonStopPlatform, SIGNAL(pressed()), this, SLOT(stopPlatform()), Qt::UniqueConnection);
192}
193
194void
196{
197 ARMARX_LOG << "Moving Platform";
198 ::Ice::Float positionX = ui->editTargetPositionX->text().toFloat();
199 ::Ice::Float positionY = ui->editTargetPositionY->text().toFloat();
200 ::Ice::Float rotation = ui->editTargetRotation->text().toFloat();
201 ::Ice::Float posAcc = 10.0f;
202 ::Ice::Float rotAcc = 0.1f;
203 platformUnitProxy->moveTo(positionX, positionY, rotation, posAcc, rotAcc);
204}
205
206void
208{
209 ui->labelCurrentPositionX->setText(QString::number(x));
210 ui->labelCurrentPositionY->setText(QString::number(y));
211 ui->labelCurrentRotation->setText(QString::number(alpha));
212}
213
214void
216{
217 ui->editTargetPositionX->setText(QString::number(x));
218 ui->editTargetPositionY->setText(QString::number(y));
219 ui->editTargetRotation->setText(QString::number(alpha));
220}
221
222void
224{
225 ctrlEvaluationTimer.start(CONTROL_TICK_RATE); //tickrate in ms
226}
227
228void
230{
231 ctrlEvaluationTimer.stop();
232 speedCtrl->setNibble({0, 0});
233 rotaCtrl->setNibble({0, 0});
234}
235
236void
237PlatformUnitWidget::reportGlobalRobotPose(const ::armarx::TransformStamped& transformStamped,
238 const ::Ice::Current&)
239{
240 const Eigen::Isometry3f global_T_robot(transformStamped.transform);
241 const float x = global_T_robot.translation().x();
242 const float y = global_T_robot.translation().y();
243 const float yaw = simox::math::mat3f_to_rpy(global_T_robot.linear()).z();
244
245 // moved to qt thread for thread safety
246 QMetaObject::invokeMethod(
247 this, "setNewPlatformPoseLabels", Q_ARG(float, x), Q_ARG(float, y), Q_ARG(float, yaw));
248 platformRotation = yaw;
249}
250
251void
252PlatformUnitWidget::stopPlatform()
253{
254 platformUnitProxy->stopPlatform();
255}
256
257void
258PlatformUnitWidget::controlPlatformWithKeyboard(int key)
259{
260 pressedKeys.insert(key);
261 if (!ctrlEvaluationTimer.isActive())
262 {
263 ctrlEvaluationTimer.start();
264 }
265 if (!keyboardVelocityTimer.isActive())
266 {
267 keyboardVelocityControl();
268 keyboardVelocityTimer.start();
269 }
270}
271
272void
273PlatformUnitWidget::stopPlatformWithKeyboard(int key)
274{
275 pressedKeys.remove(key);
276
277 if (!keyboardVelocityTimer.isActive())
278 {
279 keyboardVelocityControl();
280 keyboardVelocityTimer.start();
281 }
282}
283
284void
285PlatformUnitWidget::keyboardVelocityControl()
286{
287 if (!pressedKeys.contains(Qt::Key_A) && !pressedKeys.contains(Qt::Key_D))
288 {
289 currentKeyboardVelocityX *= deceleration;
290 if (fabs(currentKeyboardVelocityX) < 0.001)
291 {
292 currentKeyboardVelocityX = 0;
293 }
294 }
295 if (!pressedKeys.contains(Qt::Key_W) && !pressedKeys.contains(Qt::Key_S))
296 {
297 currentKeyboardVelocityY *= deceleration;
298 if (fabs(currentKeyboardVelocityY) < 0.001)
299 {
300 currentKeyboardVelocityY = 0;
301 }
302 }
303 if (!pressedKeys.contains(Qt::Key_Q) && !pressedKeys.contains(Qt::Key_E))
304 {
305 currentKeyboardVelocityAlpha *= deceleration;
306 if (fabs(currentKeyboardVelocityAlpha) < 0.001)
307 {
308 currentKeyboardVelocityAlpha = 0;
309 }
310 }
311
312 for (auto key : pressedKeys)
313 {
314 switch (key)
315 {
316 case Qt::Key_Q:
317 currentKeyboardVelocityAlpha -= acceleration;
318 break;
319 case Qt::Key_E:
320 currentKeyboardVelocityAlpha += acceleration;
321 break;
322 case Qt::Key_W:
323 currentKeyboardVelocityY -= acceleration;
324 break;
325 case Qt::Key_S:
326 currentKeyboardVelocityY += acceleration;
327 break;
328 case Qt::Key_A:
329 currentKeyboardVelocityX -= acceleration;
330 break;
331 case Qt::Key_D:
332 currentKeyboardVelocityX += acceleration;
333 break;
334 default:
335 break;
336 }
337 }
338
339 currentKeyboardVelocityAlpha = std::max(-1.f, currentKeyboardVelocityAlpha);
340 currentKeyboardVelocityAlpha = std::min(1.f, currentKeyboardVelocityAlpha);
341 currentKeyboardVelocityX = std::max(-1.f, currentKeyboardVelocityX);
342 currentKeyboardVelocityX = std::min(1.f, currentKeyboardVelocityX);
343 currentKeyboardVelocityY = std::max(-1.f, currentKeyboardVelocityY);
344 currentKeyboardVelocityY = std::min(1.f, currentKeyboardVelocityY);
345
346 float y = sin(acos(currentKeyboardVelocityAlpha));
347 speedCtrl->setNibble(QPointF(currentKeyboardVelocityX, currentKeyboardVelocityY));
348 rotaCtrl->setNibble(QPointF(currentKeyboardVelocityAlpha, -y));
349}
350
351QPointer<QWidget>
353{
354 if (!__widget)
355 {
356 __widget = new KeyboardPlatformHookWidget();
357 }
358
359 return __widget;
360}
361
362void
363PlatformUnitWidget::controlTimerTick()
364{
365 float translationFactor = ui->maxTranslationSpeed->value();
366 float rotationFactor = ui->maxRotationSpeed->value() * -1;
367 float rotationVel = rotaCtrl->getRotation() / M_PI_2 * rotationFactor;
368 ARMARX_INFO << deactivateSpam(0.5) << "Translation speed: ("
369 << speedCtrl->getPosition().x() * translationFactor << ", "
370 << speedCtrl->getPosition().y() * translationFactor << ")"
371 << ", \t rotation speed: " << (rotationVel);
372
373 platformUnitProxy->move(speedCtrl->getPosition().x() * translationFactor,
374 -1 * speedCtrl->getPosition().y() * translationFactor,
375 rotationVel);
376
377 if (speedCtrl->getPosition().x() == 0 && speedCtrl->getPosition().y() == 0 &&
378 rotaCtrl->getRotation() == 0)
379 {
381 }
382}
383
384void
386{
387 switch (event->key())
388 {
389 case Qt::Key_A:
390 case Qt::Key_W:
391 case Qt::Key_S:
392 case Qt::Key_D:
393 case Qt::Key_Q:
394 case Qt::Key_E:
395 if (!event->isAutoRepeat())
396 {
397 emit commandKeyPressed(event->key());
398 }
399 }
400 QWidget::keyPressEvent(event);
401}
402
403void
405{
406 switch (event->key())
407 {
408 case Qt::Key_A:
409 case Qt::Key_W:
410 case Qt::Key_S:
411 case Qt::Key_D:
412 case Qt::Key_Q:
413 case Qt::Key_E:
414 if (!event->isAutoRepeat())
415 {
416 emit commandKeyReleased(event->key());
417 }
418 }
419 QWidget::keyReleaseEvent(event);
420}
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.
std::unique_ptr< Ui::PlatformUnitGuiPlugin > ui
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.
void onExitComponent() override
Hook for subclass.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:179
#define ARMARX_LOG
Definition Logging.h:163
This file offers overloads of toIce() and fromIce() functions for STL container types.