EmergencyStopWidget.cpp
Go to the documentation of this file.
1
/*
2
* This file is part of ArmarX.
3
*
4
* ArmarX is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 2 as
6
* published by the Free Software Foundation.
7
*
8
* ArmarX is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
12
*
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15
*
16
* @package ArmarXCore::ArmarXObjects::EmergencyStop
17
* @author Stefan Reither ( stef dot reither at web dot de )
18
* @date 2016
19
* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20
* GNU General Public License
21
*/
22
23
#include "
EmergencyStopWidget.h
"
24
25
#include <QGridLayout>
26
#include <QShortcut>
27
#include <QTimer>
28
#include <QToolTip>
29
30
31
#define EMERGENCY_STOP_PROXY "EmergencyStopMaster"
32
#define EMERGENCY_STOP_TOPIC_NAME "EmergencyStop"
33
34
namespace
armarx
35
{
36
37
static
const
std::string ss2_active_tooltip =
38
"Release SS2 emergency stop (only possible after a short cooldown period. Shortcut: "
39
"Shift+Pause or Shift+End."
;
40
static
const
std::string ss2_inactive_tooltip =
41
"Enable SS2 emergency stop. Shortcut: Pause or End."
;
42
43
EmergencyStopWidget::EmergencyStopWidget
(QWidget* parent,
ArmarXMainWindow
* mainWindow) :
44
mainWindow(mainWindow),
45
iconNormal(QPixmap::fromImage(QImage(QString::fromUtf8(
":/icons/emergency-stop.png"
)))),
46
iconDark(QPixmap::fromImage(QImage(QString::fromUtf8(
":/icons/emergency-stop-dark.png"
)))),
47
lastKnownEmergencyStopState(EmergencyStopState::eEmergencyStopInactive),
48
timer(new QTimer(this))
49
{
50
qRegisterMetaType<EmergencyStopState>(
"EmergencyStopState"
);
51
52
// Redundant timer apart from the topic in order to recover from bad states if a topic
53
// message was lost.
54
timer->setInterval(std::chrono::milliseconds(1
'000));
55
connect(timer, &QTimer::timeout, this, &EmergencyStopWidget::updateEmergencyStopState);
56
connect(this,
57
&EmergencyStopWidget::startPeriodicStateUpdate,
58
timer,
59
qOverload<>(&QTimer::start));
60
connect(this, &EmergencyStopWidget::stopPeriodicStateUpdate, timer, &QTimer::stop);
61
QIcon icon;
62
icon.addPixmap(iconNormal, QIcon::Normal, QIcon::Off);
63
icon.addPixmap(iconDark, QIcon::Normal, QIcon::On);
64
65
button = new QToolButton();
66
button->setCheckable(true);
67
button->setIcon(icon);
68
button->setIconSize(QSize(68, 28));
69
button->setToolTip(QString::fromStdString(ss2_active_tooltip));
70
button->setVisible(false);
71
QGridLayout* l = new QGridLayout(this->getWidget());
72
l->setMargin(0);
73
l->setContentsMargins(0, 0, 0, 0);
74
this->getWidget()->setLayout(l);
75
this->getWidget()->layout()->addWidget(button);
76
77
QShortcut* enableSS2Shortcut1 = new QShortcut(this->getWidget());
78
enableSS2Shortcut1->setContext(Qt::ApplicationShortcut);
79
enableSS2Shortcut1->setKey(Qt::Key_Pause);
80
QShortcut* enableSS2Shortcut2 = new QShortcut(this->getWidget());
81
enableSS2Shortcut2->setContext(Qt::ApplicationShortcut);
82
enableSS2Shortcut2->setKey(Qt::Key_End);
83
connect(enableSS2Shortcut1, &QShortcut::activated, this, &EmergencyStopWidget::enableSS2);
84
connect(enableSS2Shortcut2, &QShortcut::activated, this, &EmergencyStopWidget::enableSS2);
85
86
QShortcut* releaseSS2Shortcut1 = new QShortcut(this->getWidget());
87
releaseSS2Shortcut1->setContext(Qt::ApplicationShortcut);
88
releaseSS2Shortcut1->setKey(Qt::SHIFT | Qt::Key_Pause);
89
QShortcut* releaseSS2Shortcut2 = new QShortcut(this->getWidget());
90
releaseSS2Shortcut2->setContext(Qt::ApplicationShortcut);
91
releaseSS2Shortcut2->setKey(Qt::SHIFT | Qt::Key_End);
92
connect(releaseSS2Shortcut1, &QShortcut::activated, this, &EmergencyStopWidget::releaseSS2);
93
connect(releaseSS2Shortcut2, &QShortcut::activated, this, &EmergencyStopWidget::releaseSS2);
94
95
connect(button, &QPushButton::clicked, this, &EmergencyStopWidget::clicked);
96
}
97
98
QWidget*
99
EmergencyStopWidget::getButtonWidget()
100
{
101
return this->getWidget();
102
}
103
104
void
105
EmergencyStopWidget::onInitComponent()
106
{
107
usingProxy(EMERGENCY_STOP_PROXY);
108
usingTopic(EMERGENCY_STOP_TOPIC_NAME);
109
}
110
111
void
112
EmergencyStopWidget::onConnectComponent()
113
{
114
ARMARX_INFO << "SS2 widget connected.";
115
emergencyStopMasterPrx = getProxy<EmergencyStopMasterInterfacePrx>(EMERGENCY_STOP_PROXY);
116
QMetaObject::invokeMethod(button, "setVisible", Qt::QueuedConnection, Q_ARG(bool, true));
117
EmergencyStopState state = EmergencyStopState::eEmergencyStopActive;
118
119
try
120
{
121
state = emergencyStopMasterPrx->getEmergencyStopState();
122
}
123
catch (Ice::Exception const& e)
124
{
125
ARMARX_ERROR << "Could not query SS2 state." << deactivateSpam(2);
126
}
127
128
QMetaObject::invokeMethod(
129
this, "setChecked", Qt::QueuedConnection, Q_ARG(EmergencyStopState, state));
130
131
emit startPeriodicStateUpdate();
132
}
133
134
void
135
EmergencyStopWidget::onDisconnectComponent()
136
{
137
ARMARX_IMPORTANT << "SS2 widget disconnected. This is expected if the earlier connected "
138
"robot unit shut down.";
139
QMetaObject::invokeMethod(button, "setVisible", Qt::QueuedConnection, Q_ARG(bool, false));
140
141
emit stopPeriodicStateUpdate();
142
}
143
144
void
145
EmergencyStopWidget::loadSettings(QSettings* settings)
146
{
147
;
148
}
149
150
void
151
EmergencyStopWidget::saveSettings(QSettings* settings)
152
{
153
;
154
}
155
156
void
157
EmergencyStopWidget::reportEmergencyStopState(EmergencyStopState state, const Ice::Current&)
158
{
159
QMetaObject::invokeMethod(
160
this, "setChecked", Qt::QueuedConnection, Q_ARG(EmergencyStopState, state));
161
}
162
163
void
164
EmergencyStopWidget::enableSS2()
165
{
166
if (emergencyStopMasterPrx)
167
{
168
emergencyStopMasterPrx->setEmergencyStopState(EmergencyStopState::eEmergencyStopActive);
169
170
if (lastKnownEmergencyStopState == EmergencyStopState::eEmergencyStopActive)
171
{
172
std::string const message =
173
"SS2 already active. Press Shift+Pause or Shift+End to release SS2.";
174
175
QPoint globalPos =
176
button->mapToGlobal(QPoint(button->width() / 2, button->height() / 2));
177
QToolTip::showText(globalPos, QString::fromStdString(message), button);
178
ARMARX_INFO << message;
179
}
180
}
181
}
182
183
void
184
EmergencyStopWidget::releaseSS2()
185
{
186
if (emergencyStopMasterPrx)
187
{
188
lastKnownEmergencyStopState = releaseSS2OnMaster();
189
190
if (lastKnownEmergencyStopState == EmergencyStopState::eEmergencyStopActive)
191
{
192
std::string const message = "SS2 cannot be released since it was just activated.";
193
194
QPoint globalPos =
195
button->mapToGlobal(QPoint(button->width() / 2, button->height() / 2));
196
QToolTip::showText(globalPos, QString::fromStdString(message), button);
197
ARMARX_INFO << message;
198
}
199
}
200
}
201
202
void
203
EmergencyStopWidget::clicked(bool checked)
204
{
205
if (not emergencyStopMasterPrx)
206
{
207
return;
208
}
209
210
switch (lastKnownEmergencyStopState)
211
{
212
case EmergencyStopState::eEmergencyStopActive:
213
{
214
// Only release SS2 if the state we received still is "Active". Fail otherwise.
215
lastKnownEmergencyStopState = releaseSS2OnMaster();
216
if (lastKnownEmergencyStopState == EmergencyStopState::eEmergencyStopActive)
217
{
218
ARMARX_INFO << "SS2 cannot be released since it was just activated.";
219
button->setChecked(true);
220
}
221
}
222
break;
223
case EmergencyStopState::eEmergencyStopInactive:
224
// Always enable SS2 without checking.
225
enableSS2();
226
break;
227
}
228
}
229
230
std::string
231
EmergencyStopWidget::getDefaultName() const
232
{
233
return "EmergencyStopGuiWidget" + iceNameUUID;
234
}
235
236
237
EmergencyStopState
238
EmergencyStopWidget::releaseSS2OnMaster() const
239
{
240
// If emergency stop master is not available, assume that SS2 is still active and cannot
241
// be released.
242
if (not emergencyStopMasterPrx)
243
{
244
return EmergencyStopState::eEmergencyStopActive;
245
}
246
247
try
248
{
249
return emergencyStopMasterPrx->trySetEmergencyStopState(
250
EmergencyStopState::eEmergencyStopInactive);
251
}
252
// This catch is only required as long as the stable robot workspaces are using the old
253
// interface. The changes for the new interface were done in July 2024. It can safely be
254
// removed after a few months.
255
catch (Ice::OperationNotExistException const&)
256
{
257
ARMARX_WARNING << "Cannot safely release SS2. This only happens if your ArmarX GUI "
258
"is using a newer version of the emergency stop interface than the "
259
"emergency stop master or the robot unit provides. Will use a less "
260
"safe fallback interface method now.";
261
emergencyStopMasterPrx->setEmergencyStopState(
262
EmergencyStopState::eEmergencyStopInactive);
263
return emergencyStopMasterPrx->getEmergencyStopState();
264
}
265
}
266
267
void
268
EmergencyStopWidget::setChecked(const EmergencyStopState state)
269
{
270
switch (state)
271
{
272
case EmergencyStopState::eEmergencyStopActive:
273
button->setChecked(true);
274
button->setToolTip(QString::fromStdString(ss2_active_tooltip));
275
break;
276
case EmergencyStopState::eEmergencyStopInactive:
277
default:
278
button->setChecked(false);
279
button->setToolTip(QString::fromStdString(ss2_inactive_tooltip));
280
break;
281
}
282
283
lastKnownEmergencyStopState = state;
284
}
285
286
void
287
EmergencyStopWidget::updateEmergencyStopState()
288
{
289
try
290
{
291
if (emergencyStopMasterPrx)
292
{
293
setChecked(emergencyStopMasterPrx->getEmergencyStopState());
294
}
295
}
296
catch (Ice::Exception const& e)
297
{
298
ARMARX_ERROR << "Could not query SS2 state." << deactivateSpam(2);
299
setChecked(EmergencyStopState::eEmergencyStopActive);
300
}
301
}
302
303
} // namespace armarx
armarx::EmergencyStopWidget::EmergencyStopWidget
EmergencyStopWidget(QWidget *parent=0, ArmarXMainWindow *mainWindow=0)
Definition:
EmergencyStopWidget.cpp:43
armarx::ArmarXMainWindow
The ArmarXMainWindow class.
Definition:
ArmarXMainWindow.h:76
EmergencyStopWidget.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition:
ArmarXTimeserver.cpp:28
ArmarXGui
applications
ArmarXGui
Widgets
EmergencyStopWidget.cpp
Generated on Sat Oct 12 2024 09:14:02 for armarx_documentation by
1.8.17