GuiHealthClientWidgetController.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 RobotAPI::gui-plugins::GuiHealthClientWidgetController
17 * \author Simon Ottenhaus ( simon dot ottenhaus at kit dot edu )
18 * \date 2018
19 * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <iomanip>
26#include <string>
27
28#include <QLabel>
29#include <QPushButton>
30#include <qcolor.h>
31#include <qnamespace.h>
32#include <qrgb.h>
33#include <qtablewidget.h>
34
35#include <SimoxUtility/algorithm/get_map_keys_values.h>
36
40
41namespace armarx
42{
43 std::string
44 serializeList(const std::vector<std::string>& l)
45 {
46 std::string s;
47 for (std::size_t i = 0; i < l.size(); i++)
48 {
49 const auto& tag = l.at(i);
50 s += tag;
51
52 if (i != l.size() - 1)
53 {
54 s += ", ";
55 }
56 }
57
58 return s;
59 }
60
62 {
63 widget.setupUi(getWidget());
64
65 connect(this,
67 this,
69 Qt::QueuedConnection);
70 connect(this,
72 this,
74 Qt::QueuedConnection);
75
76 connect(widget.pushButtonUnrequireAll, SIGNAL(clicked()), this, SLOT(unrequireAll()));
77
78 updateSummaryTimer = new QTimer(this);
79 updateSummaryTimer->setInterval(100);
80 connect(updateSummaryTimer, SIGNAL(timeout()), this, SLOT(updateSummaryTimerClb()));
81 }
82
86
87 void
89 {
90 }
91
92 void
94 {
95 }
96
97 void
99 {
100 //ARMARX_IMPORTANT << "onInitComponent";
101 usingProxy("RobotHealth");
102 offeringTopic("RobotHealthTopic");
103 }
104
105 void
107 {
108 armarx::core::time::dto::DateTime now;
110 robotHealthTopicPrx->heartbeat(getName(), now);
111 }
112
113 std::string
114 to_string_rounded(float value, int decimals = 100)
115 {
116 std::stringstream ss;
117 ss << std::fixed << std::setprecision(3) << value;
118 return ss.str();
119 }
120
121 QTableWidgetItem*
122 make_item(const std::string& text, Qt::AlignmentFlag horAlignment = Qt::AlignLeft)
123 {
124 auto* item = new QTableWidgetItem(QString::fromStdString(text));
125 item->setTextAlignment(horAlignment | Qt::AlignVCenter);
126 return item;
127 }
128
129 void
131 {
132 //ARMARX_IMPORTANT << "updateSummaryTimerClb";
133 if (robotHealthComponentPrx)
134 {
135 //ARMARX_IMPORTANT << "has robotHealthComponentPrx";
136 try
137 {
138 auto summary = robotHealthComponentPrx->getSummary();
139
140 const std::size_t nCols = 10;
141
142 auto& tableWidget = widget.tableHealthState;
143 tableWidget->setRowCount(summary.entries.size());
144 tableWidget->setColumnCount(nCols);
145
146 const auto summaryVals = simox::alg::get_values(summary.entries);
147
148 tableWidget->setHorizontalHeaderLabels({"identifier",
149 "required",
150 "keeps frequency",
151 "tags",
152 "time since\nlast arrival [ms]",
153 "time to\nreference [ms]",
154 "time sync \n+ Ice [ms]",
155 "warning\nthreshold [ms]",
156 "error\nthreshold [ms]",
157 "hostname"});
158
159 tableWidget->setColumnWidth(0, 250);
160 tableWidget->setColumnWidth(1, 80);
161 tableWidget->setColumnWidth(2, 120);
162 tableWidget->setColumnWidth(3, 180);
163 tableWidget->setColumnWidth(4, 120);
164 tableWidget->setColumnWidth(5, 120);
165 tableWidget->setColumnWidth(6, 120);
166 tableWidget->setColumnWidth(7, 120);
167
168 for (std::size_t i = 0; i < summary.entries.size(); i++)
169 {
170 const auto& entry = summaryVals.at(i);
171
172 std::string stateRepr;
173 QColor stateColor;
174 switch (entry.state)
175 {
176 case HealthOK:
177 stateRepr = "yes";
178 stateColor.setRgb(0, 255, 0); // green
179 break;
180 case HealthWarning:
181 stateRepr = "yes";
182 stateColor.setRgb(255, 165, 0); // orange
183 break;
184 case HealthError:
185 stateRepr = "no";
186 stateColor.setRgb(255, 0, 0); // red
187 break;
188 }
189
190 const std::string hostname = entry.lastReferenceTimestamp.hostname;
191
192 const std::string timeSinceLastArrivalRepr =
193 to_string_rounded(entry.timeSinceLastArrival.microSeconds / 1000.0);
194 const std::string timeToLastReferenceRepr =
195 to_string_rounded(entry.timeSinceLastUpdateReference.microSeconds / 1000.0);
196 const std::string tagsRepr = serializeList(entry.tags);
197
198 const float syncErrorMilliSeconds =
199 std::abs(entry.timeSinceLastArrival.microSeconds -
200 entry.timeSinceLastUpdateReference.microSeconds) /
201 1000.0;
202
203 tableWidget->setItem(
204 i, 0, new QTableWidgetItem(QString::fromStdString(entry.identifier)));
205 tableWidget->setItem(
206 i, 1, make_item(entry.required ? "yes" : "no", Qt::AlignHCenter));
207
208 {
209 auto* item = make_item(stateRepr, Qt::AlignHCenter);
210 item->setBackgroundColor(stateColor);
211 tableWidget->setItem(i, 2, item);
212 }
213
214 tableWidget->setItem(
215 i, 3, new QTableWidgetItem(QString::fromStdString(tagsRepr)));
216 tableWidget->setItem(i, 4, make_item(timeSinceLastArrivalRepr, Qt::AlignRight));
217 tableWidget->setItem(i, 5, make_item(timeToLastReferenceRepr, Qt::AlignRight));
218
219 {
220 auto* item =
221 make_item(to_string_rounded(syncErrorMilliSeconds), Qt::AlignRight);
222
223 QColor timeSyncColor;
224 if (syncErrorMilliSeconds > 20.)
225 {
226 timeSyncColor.setRgb(255, 0, 0);
227 }
228 else
229 {
230 timeSyncColor.setRgb(0, 255, 0);
231 }
232 item->setBackgroundColor(timeSyncColor);
233
234 tableWidget->setItem(i, 6, item);
235 }
236
237 tableWidget->setItem(
238 i,
239 7,
240 make_item(
241 to_string_rounded(entry.maximumCycleTimeWarning.microSeconds / 1000.),
242 Qt::AlignRight));
243 tableWidget->setItem(
244 i,
245 8,
246 make_item(
247 to_string_rounded(entry.maximumCycleTimeError.microSeconds / 1000.),
248 Qt::AlignRight));
249 tableWidget->setItem(
250 i, 9, new QTableWidgetItem(QString::fromStdString(hostname)));
251 }
252
253 std::string tagsText = "Active tags: [";
254 {
255 std::sort(summary.activeTags.begin(), summary.activeTags.end());
256
257 tagsText += serializeList(summary.activeTags);
258
259 tagsText += "]";
260 }
261
262 widget.labelTags->setText(QString::fromStdString(tagsText));
263 }
264 catch (...)
265 {
266 }
267 }
268 }
269
270 void
272 {
273 ARMARX_INFO << "UnrequireAll.";
274 if (robotHealthComponentPrx)
275 {
276 try
277 {
278 robotHealthComponentPrx->resetRequiredTags();
279 }
280 catch (...)
281 {
282 }
283 }
284 }
285
286 void
288 {
289 //ARMARX_IMPORTANT << "onConnectComponent";
290 robotHealthTopicPrx = getTopic<RobotHealthInterfacePrx>("RobotHealthTopic");
291 robotHealthComponentPrx = getProxy<RobotHealthComponentInterfacePrx>("RobotHealth");
293 }
294
295 void
297 {
298 //healthTimer->start();
299 //ARMARX_IMPORTANT <<ame "updateSummaryTimer->start";
300 updateSummaryTimer->start();
301 }
302
303 void
308
309 void
311 {
312 updateSummaryTimer->stop();
313 }
314} // namespace armarx
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
virtual ~GuiHealthClientWidgetController()
Controller destructor.
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
std::string getName() const
Retrieve name of object.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
static DateTime Now()
Definition DateTime.cpp:51
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
void toIce(dto::ClockType::ClockTypeEnum &dto, const ClockType &bo)
This file offers overloads of toIce() and fromIce() functions for STL container types.
QTableWidgetItem * make_item(const std::string &text, Qt::AlignmentFlag horAlignment=Qt::AlignLeft)
std::string serializeList(const std::vector< std::string > &l)
std::string to_string_rounded(float value, int decimals=100)