AronTreeWidgetConverter.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::SkillManagerMonitorWidgetController
17 * \author Raphael Grimm ( raphael dot grimm at kit dot edu )
18 * \date 2020
19 * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#include <string>
24
25// base class
27
28// armarx
29#include <SimoxUtility/algorithm/string.h>
30
32
34
35// qt
36#include <QTreeWidgetItem>
37
41
42namespace armarx
43{
44 bool
46 {
47 return !isDirectError && !hasTransitiveError;
48 }
49
50 bool
52 {
53 return hasTransitiveError;
54 }
55
56 bool
58 {
59 return isDirectError;
60 }
61
62 void
63 AronTreeWidgetConverterVisitor::handleErrors(AronTreeWidgetConverterVisitor childV,
64 bool ownFault)
65 {
67 isDirectError |= ownFault;
68 hasTransitiveError |= childV.isDirectError || childV.hasTransitiveError;
69
70 auto* aronItem = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
71 ARMARX_CHECK(aronItem);
72 aronItem->setValueErrorState(isDirectError, hasTransitiveError);
73 }
74
75 void
76 AronTreeWidgetConverterVisitor::handleErrors(bool ownFault)
77 {
79 isDirectError = ownFault;
80 auto* aronItem = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
81 ARMARX_CHECK(aronItem);
82 aronItem->setValueErrorState(isDirectError, false);
83 }
84
85 void
87 {
89 auto createdAronDict = std::make_shared<aron::data::Dict>(i->getPath());
90 createdAron = createdAronDict;
91 QTreeWidgetItem* el = parentItem->child(index);
92
93 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
94 {
95 // its a maybetype. We have to check the state
96 if (el->checkState(1) == Qt::CheckState::Unchecked)
97 {
98 createdAron = nullptr;
99 return;
100 }
101 }
102
103 unsigned int x = 0;
104 for (const auto& [key, value] : i->getMemberTypes())
105 {
108 aron::type::visit(v, value);
109
110 handleErrors(v);
111 if (v.isConversionSuccessful())
112 {
113 createdAronDict->addElement(key, v.createdAron);
114 }
115 }
116 }
117
118 void
120 {
122 auto createdAronDict = std::make_shared<aron::data::Dict>(i->getPath());
123 createdAron = createdAronDict;
124 QTreeWidgetItem* el = parentItem->child(index);
125
126 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
127 {
128 // its a maybetype. We have to check the state
129 if (el->checkState(1) == Qt::CheckState::Unchecked)
130 {
131 createdAron = nullptr;
132 return;
133 }
134 }
135
136 for (int x = 0; x < el->childCount(); ++x)
137 {
138 auto it = el->child(x);
140 aron::type::visit(v, i->getAcceptedType());
141 auto key = it->text(0).toStdString();
142 // TODO: handle key errors more elegantly / separately, fine for now
143 handleErrors(v, createdAronDict->hasElement(key));
144 if (v.createdAron && v.isConversionSuccessful() && !createdAronDict->hasElement(key))
145 {
146 createdAronDict->addElement(key, v.createdAron);
147 }
148 }
149 }
150
151 void
153 {
155 auto createdAronList = std::make_shared<aron::data::List>(i->getPath());
156 createdAron = createdAronList;
157 auto* el = parentItem->child(index);
158
159 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
160 {
161 // its a maybetype. We have to check the state
162 if (el->checkState(1) == Qt::CheckState::Unchecked)
163 {
164 createdAron = nullptr;
165 return;
166 }
167 }
168
169 auto childrenTypes = i->getChildren();
170 ARMARX_CHECK(childrenTypes.size() == 1);
171 for (int j = 0; j < el->childCount(); ++j)
172 {
173 AronTreeWidgetConverterVisitor convVisitor(el, j);
174 aron::type::visit(convVisitor, childrenTypes[0]);
175 handleErrors(convVisitor);
176
177 if (convVisitor.createdAron && convVisitor.isConversionSuccessful())
178 {
179 createdAronList->addElement(convVisitor.createdAron);
180 }
181 }
182 }
183
184 void
186 {
188 auto createdAronPair = std::make_shared<aron::data::List>(i->getPath());
189 createdAron = createdAronPair;
190 auto* el = parentItem->child(index);
191
192 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
193 {
194 // its a maybetype. We have to check the state
195 if (el->checkState(1) == Qt::CheckState::Unchecked)
196 {
197 createdAron = nullptr;
198 return;
199 }
200 }
201
202 for (int j = 0; j < 2; ++j)
203 {
204 AronTreeWidgetConverterVisitor convVisitor(el, j);
205 handleErrors(convVisitor);
206 if (convVisitor.createdAron && convVisitor.isConversionSuccessful())
207 {
208 createdAronPair->addElement(convVisitor.createdAron);
209 }
210 }
211 }
212
213 void
215 {
217 auto createdAronList = std::make_shared<aron::data::List>(i->getPath());
218 createdAron = createdAronList;
219 QTreeWidgetItem* el = parentItem->child(index);
220
221 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
222 {
223 // its a maybetype. We have to check the state
224 if (el->checkState(1) == Qt::CheckState::Unchecked)
225 {
226 createdAron = nullptr;
227 return;
228 }
229 }
230
231 for (int x = 0; x < el->childCount(); ++x)
232 {
233 auto* it = el->child(x);
235 aron::type::visit(v, i->getAcceptedType(x));
236 handleErrors(v);
237
238 if (v.createdAron)
239 {
240 createdAronList->addElement(v.createdAron);
241 }
242 }
243 }
244
245 void
247 {
249 ARMARX_ERROR << "Currently do not support supplying raw NDArrays!";
250 }
251
252 void
254 {
256 auto createdMatrix = std::make_shared<aron::data::NDArray>(i->getPath());
257 int dataSize = 0;
258 switch (i->getElementType())
259 {
260 case armarx::aron::type::matrix::INT8:
261 case armarx::aron::type::matrix::UINT8:
262 dataSize = 1;
263 break;
264 case armarx::aron::type::matrix::INT16:
265 case armarx::aron::type::matrix::UINT16:
266 dataSize = 2;
267 break;
268 case armarx::aron::type::matrix::UINT32:
269 case armarx::aron::type::matrix::INT32:
270 case armarx::aron::type::matrix::FLOAT32:
271 dataSize = 4;
272 break;
273 case armarx::aron::type::matrix::FLOAT64:
274 case armarx::aron::type::matrix::INT64:
275 dataSize = 8;
276 break;
277 };
278
279 // UGLY HACK: FIX ME!!!
280 switch (i->getElementType())
281 {
282 case armarx::aron::type::matrix::UINT8:
283 createdMatrix->setType("unsigned char");
284 break;
285 case armarx::aron::type::matrix::UINT16:
286 createdMatrix->setType("unsigned short");
287 break;
288 case armarx::aron::type::matrix::UINT32:
289 createdMatrix->setType("unsigned int");
290 break;
291 case armarx::aron::type::matrix::INT8:
292 createdMatrix->setType("char");
293 break;
294 case armarx::aron::type::matrix::INT16:
295 createdMatrix->setType("short");
296 break;
297 case armarx::aron::type::matrix::INT32:
298 createdMatrix->setType("int");
299 break;
300 case armarx::aron::type::matrix::FLOAT32:
301 createdMatrix->setType("float");
302 break;
303 case armarx::aron::type::matrix::FLOAT64:
304 createdMatrix->setType("double");
305 break;
306 case armarx::aron::type::matrix::INT64:
307 createdMatrix->setType("long");
308 break;
309 };
310
311 createdMatrix->setShape({i->getRows(), i->getCols(), dataSize});
312 int totalByteSize = i->getRows() * i->getCols() * dataSize;
313 createdAron = createdMatrix;
314 auto* el = parentItem->child(index);
315
316 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
317 {
318 // its a maybetype. We have to check the state
319 if (el->checkState(1) == Qt::CheckState::Unchecked)
320 {
321 createdAron = nullptr;
322 return;
323 }
324 }
325
326
327 auto* rootWidget = el->treeWidget();
328 ARMARX_CHECK(rootWidget);
329 auto* widget = rootWidget->itemWidget(el, 1);
330 auto* matrixWidget = EditMatrixWidget::DynamicCastAndCheck(widget);
331
332 handleErrors(matrixWidget->hasParseErrors());
333 if (matrixWidget->hasParseErrors())
334 {
335 return;
336 }
337 // write to aron data
338 std::vector<unsigned char> elems;
339 elems.reserve(totalByteSize);
340 // CAUTION: Raw data has column based storage
341 for (size_t col = 0; col < (size_t)i->getCols(); ++col)
342 {
343 for (size_t row = 0; row < (size_t)i->getRows(); ++row)
344 {
345 // gets us directly the byte wise format
346 auto parsed = matrixWidget->parseElement(row, col);
347 // append vector to vector
348 elems.insert(elems.end(), parsed.begin(), parsed.end());
349 }
350 }
351 createdMatrix->setData(totalByteSize, elems.data());
352 }
353
354 void
356 {
358 auto createdQuat = std::make_shared<aron::data::NDArray>(i->getPath());
359 createdAron = createdQuat;
360 int dataSize = i->getElementType() == aron::type::quaternion::ElementType::FLOAT32 ? 4 : 8;
361 createdQuat->setShape({1, 4, dataSize});
362 createdQuat->setType(i->getFullName());
363 auto* el = parentItem->child(index);
364
365 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
366 {
367 // its a maybetype. We have to check the state
368 if (el->checkState(1) == Qt::CheckState::Unchecked)
369 {
370 createdAron = nullptr;
371 return;
372 }
373 }
374
375 auto* itemWidget = el->treeWidget()->itemWidget(el, 1);
376 auto* quatWidget = QuaternionWidget::DynamicCastAndCheck(itemWidget);
377
378 // error handling
379 handleErrors(quatWidget->hasParseErrors());
380 if (quatWidget->hasParseErrors())
381 {
382 return;
383 }
384
385 // write to aron data
386 auto serialized = quatWidget->parseAllToNDArray();
387 if ((int)serialized.size() != dataSize * 4)
388 {
390 << "serialized quaternions did not return byte sequence of correct length!";
391 }
392 createdQuat->setData(serialized.size(), serialized.data());
393 }
394
395 void
401
402 void
408
409 void
411 {
413 QTreeWidgetItem* el = parentItem->child(index);
414
415 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
416 {
417 // its a maybetype. We have to check the state
418 if (el->checkState(1) == Qt::CheckState::Unchecked)
419 {
420 createdAron = nullptr;
421 return;
422 }
423 }
424
425 auto* genericWidget = el->treeWidget()->itemWidget(el, 1);
426 auto* intEnumWidget = IntEnumWidget::DynamicCastAndCheck(genericWidget);
427 if (!intEnumWidget)
428 {
429 // already reporting error; continue here
430 return;
431 }
432 bool success;
433 std::tie(success, createdAron) = intEnumWidget->parseToAron();
434
435 handleErrors(!success);
436 }
437
438 void
440 {
442 auto createdAronInt = std::make_shared<aron::data::Int>(i->getPath());
443 createdAron = createdAronInt;
444 QTreeWidgetItem* el = parentItem->child(index);
445
446 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
447 {
448 // its a maybetype. We have to check the state
449 if (el->checkState(1) == Qt::CheckState::Unchecked)
450 {
451 createdAron = nullptr;
452 return;
453 }
454 }
455
456 std::string str = el->text(1).toStdString();
457 if (str.empty())
458 {
459 createdAronInt->setValue(0);
460 return;
461 }
462 try
463 {
464 int val = simox::alg::to_<int>(str);
465 createdAronInt->setValue(val);
466 }
467 catch (const simox::error::SimoxError& err)
468 {
469 handleErrors();
470 ARMARX_VERBOSE << "Conversion from String to Int failed. Error:\"" << err.what()
471 << "\"";
472 return;
473 }
474 handleErrors(false);
475 }
476
477 void
479 {
481 auto createdAronLong = std::make_shared<aron::data::Long>(i->getPath());
482 createdAron = createdAronLong;
483 QTreeWidgetItem* el = parentItem->child(index);
484
485 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
486 {
487 // its a maybetype. We have to check the state
488 if (el->checkState(1) == Qt::CheckState::Unchecked)
489 {
490 createdAron = nullptr;
491 return;
492 }
493 }
494
495 std::string str = el->text(1).toStdString();
496 if (str.empty())
497 {
498 //TODO: similar behaviour for rest?
499 str = el->text(3).toStdString();
500 }
501 try
502 {
503 createdAronLong->setValue(simox::alg::to_<long>(str));
504 }
505 catch (const simox::error::SimoxError& err)
506 {
507 handleErrors();
508 ARMARX_VERBOSE << "Conversion from String to Long failed. Error:\"" << err.what()
509 << "\"";
510 return;
511 }
512 handleErrors(false);
513 }
514
515 void
517 {
519 auto createdAronFloat = std::make_shared<aron::data::Float>(i->getPath());
520 createdAron = createdAronFloat;
521 QTreeWidgetItem* el = parentItem->child(index);
522
523 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
524 {
525 // its a maybetype. We have to check the state
526 if (el->checkState(1) == Qt::CheckState::Unchecked)
527 {
528 createdAron = nullptr;
529 return;
530 }
531 }
532
533 std::string str = el->text(1).toStdString();
534 if (str.empty())
535 {
536 str = el->text(3).toStdString();
537 }
538 try
539 {
540 createdAronFloat->setValue(simox::alg::to_<float>(str));
541 }
542 catch (const simox::error::SimoxError& err)
543 {
544 handleErrors();
545 ARMARX_VERBOSE << "Conversion from String to Float failed. Error:\"" << err.what()
546 << "\"";
547 return;
548 }
549 handleErrors(false);
550 }
551
552 void
554 {
556 auto createdAronDouble = std::make_shared<aron::data::Double>(i->getPath());
557 createdAron = createdAronDouble;
558 QTreeWidgetItem* el = parentItem->child(index);
559
560 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
561 {
562 // its a maybetype. We have to check the state
563 if (el->checkState(1) == Qt::CheckState::Unchecked)
564 {
565 createdAron = nullptr;
566 return;
567 }
568 }
569
570 std::string str = el->text(1).toStdString();
571 if (str.empty())
572 {
573 str = el->text(3).toStdString();
574 }
575 try
576 {
577 createdAronDouble->setValue(simox::alg::to_<double>(str));
578 }
579 catch (const simox::error::SimoxError& err)
580 {
581 handleErrors();
582 ARMARX_VERBOSE << "Conversion from String to Double failed. Error:\"" << err.what()
583 << "\"";
584 return;
585 }
586 handleErrors(false);
587 }
588
589 void
591 {
593 auto createdAronBool = std::make_shared<aron::data::Bool>(i->getPath());
594 createdAron = createdAronBool;
595 QTreeWidgetItem* el = parentItem->child(index);
596
597 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
598 {
599 // its a maybetype. We have to check the state
600 if (el->checkState(1) == Qt::CheckState::Unchecked)
601 {
602 createdAron = nullptr;
603 return;
604 }
605 }
606
607 std::string str = el->text(1).toStdString();
608 if (str.empty())
609 {
610 str = el->text(3).toStdString();
611 }
612 try
613 {
614 createdAronBool->setValue(simox::alg::to_<bool>(str));
615 }
616 catch (const simox::error::SimoxError& err)
617 {
618 handleErrors();
619 ARMARX_VERBOSE << "Conversion from String to Bool failed. Error:\"" << err.what()
620 << "\"";
621 return;
622 }
623 handleErrors(false);
624 }
625
626 void
628 {
630 auto createdAronString = std::make_shared<aron::data::String>(i->getPath());
631 createdAron = createdAronString;
632 QTreeWidgetItem* el = parentItem->child(index);
633
634 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
635 {
636 // its a maybetype. We have to check the state
637 if (el->checkState(1) == Qt::CheckState::Unchecked)
638 {
639 createdAron = nullptr;
640 return;
641 }
642 }
643
644 std::string str = el->text(1).toStdString();
645 createdAronString->setValue(str);
646 }
647
648 void
650 {
651 ARMARX_WARNING_S << "Received an unknown type when trying to convert a skill argument type "
652 "to an aron data object.";
653 }
654} // namespace armarx
uint8_t index
std::string str(const T &t)
void visitAronVariant(const aron::type::ObjectPtr &) final
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
static EditMatrixWidget * DynamicCastAndCheck(QWidget *)
static IntEnumWidget * DynamicCastAndCheck(QWidget *)
static QuaternionWidget * DynamicCastAndCheck(QWidget *)
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
void visit(VisitorImplementation &v, typename VisitorImplementation::Input &t)
The visit function.
Definition Visitor.h:39
std::shared_ptr< class Quaternion > QuaternionPtr
std::shared_ptr< Object > ObjectPtr
Definition Object.h:36
std::shared_ptr< class Double > DoublePtr
std::shared_ptr< class Matrix > MatrixPtr
std::shared_ptr< class Image > ImagePtr
std::shared_ptr< class Long > LongPtr
std::shared_ptr< class String > StringPtr
std::shared_ptr< class PointCloud > PointCloudPtr
std::shared_ptr< class Pair > PairPtr
std::shared_ptr< class NDArray > NDArrayPtr
std::shared_ptr< class Int > IntPtr
std::shared_ptr< class Float > FloatPtr
std::shared_ptr< class Bool > BoolPtr
std::shared_ptr< class Tuple > TuplePtr
std::shared_ptr< class Dict > DictPtr
std::shared_ptr< IntEnum > IntEnumPtr
Definition IntEnum.h:36
std::shared_ptr< class List > ListPtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
typename VisitorBase< const type::VariantPtr >::Input Input
Definition Visitor.h:103
#define ARMARX_TRACE
Definition trace.h:77