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::skills::gui
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 {
78
80 isDirectError = ownFault;
81 auto* aronItem = AronTreeWidgetItem::DynamicCast(parentItem->child(index));
82 ARMARX_CHECK(aronItem);
83 aronItem->setValueErrorState(isDirectError, false);
84 }
85
86 void
88 {
89
91 auto createdAronDict = std::make_shared<aron::data::Dict>(i->getPath());
92 createdAron = createdAronDict;
93 QTreeWidgetItem* el = parentItem->child(index);
94
95 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
96 {
97 // its a maybetype. We have to check the state
98 if (el->checkState(2) == Qt::CheckState::Unchecked)
99 {
100 createdAron = nullptr;
101 return;
102 }
103 }
104
105 unsigned int x = 0;
106 for (const auto& [key, value] : i->getMemberTypes())
107 {
110 aron::type::visit(v, value);
111
112 handleErrors(v);
113 if (v.isConversionSuccessful())
114 {
115 createdAronDict->addElement(key, v.createdAron);
116 }
117 }
118 }
119
120 void
122 {
123
125 auto createdAronDict = std::make_shared<aron::data::Dict>(i->getPath());
126 createdAron = createdAronDict;
127 QTreeWidgetItem* el = parentItem->child(index);
128
129 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
130 {
131 // its a maybetype. We have to check the state
132 if (el->checkState(2) == Qt::CheckState::Unchecked)
133 {
134 createdAron = nullptr;
135 return;
136 }
137 }
138
139 for (int x = 0; x < el->childCount(); ++x)
140 {
141 auto it = el->child(x);
143 aron::type::visit(v, i->getAcceptedType());
144 auto key = it->text(0).toStdString();
145 // TODO: handle key errors more elegantly / separately, fine for now
146 handleErrors(v, createdAronDict->hasElement(key));
147 if (v.createdAron && v.isConversionSuccessful() && !createdAronDict->hasElement(key))
148 {
149 createdAronDict->addElement(key, v.createdAron);
150 }
151 }
152 }
153
154 void
156 {
157
159 auto createdAronList = std::make_shared<aron::data::List>(i->getPath());
160 createdAron = createdAronList;
161 auto* el = parentItem->child(index);
162
163 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
164 {
165 // its a maybetype. We have to check the state
166 if (el->checkState(2) == Qt::CheckState::Unchecked)
167 {
168 createdAron = nullptr;
169 return;
170 }
171 }
172
173 auto childrenTypes = i->getChildren();
174 ARMARX_CHECK(childrenTypes.size() == 1);
175 for (int j = 0; j < el->childCount(); ++j)
176 {
177 AronTreeWidgetConverterVisitor convVisitor(el, j);
178 aron::type::visit(convVisitor, childrenTypes[0]);
179 handleErrors(convVisitor);
180
181 if (convVisitor.createdAron && convVisitor.isConversionSuccessful())
182 {
183 createdAronList->addElement(convVisitor.createdAron);
184 }
185 }
186 }
187
188 void
190 {
191
193 auto createdAronPair = std::make_shared<aron::data::List>(i->getPath());
194 createdAron = createdAronPair;
195 auto* el = parentItem->child(index);
196
197 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
198 {
199 // its a maybetype. We have to check the state
200 if (el->checkState(2) == Qt::CheckState::Unchecked)
201 {
202 createdAron = nullptr;
203 return;
204 }
205 }
206
207 for (int j = 0; j < 2; ++j)
208 {
209 AronTreeWidgetConverterVisitor convVisitor(el, j);
210 handleErrors(convVisitor);
211 if (convVisitor.createdAron && convVisitor.isConversionSuccessful())
212 {
213 createdAronPair->addElement(convVisitor.createdAron);
214 }
215 }
216 }
217
218 void
220 {
221
223 auto createdAronList = std::make_shared<aron::data::List>(i->getPath());
224 createdAron = createdAronList;
225 QTreeWidgetItem* el = parentItem->child(index);
226
227 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
228 {
229 // its a maybetype. We have to check the state
230 if (el->checkState(2) == Qt::CheckState::Unchecked)
231 {
232 createdAron = nullptr;
233 return;
234 }
235 }
236
237 for (int x = 0; x < el->childCount(); ++x)
238 {
239 auto* it = el->child(x);
241 aron::type::visit(v, i->getAcceptedType(x));
242 handleErrors(v);
243
244 if (v.createdAron)
245 {
246 createdAronList->addElement(v.createdAron);
247 }
248 }
249 }
250
251 void
253 {
255 ARMARX_ERROR << "Currently do not support supplying raw NDArrays!";
256 }
257
258 void
260 {
261
263 auto createdMatrix = std::make_shared<aron::data::NDArray>(i->getPath());
264 int dataSize = 0;
265 switch (i->getElementType())
266 {
267 case armarx::aron::type::matrix::UINT8:
268 case armarx::aron::type::matrix::INT8:
269 dataSize = 1;
270 break;
271 case armarx::aron::type::matrix::UINT16:
272 case armarx::aron::type::matrix::INT16:
273 dataSize = 2;
274 break;
275 case armarx::aron::type::matrix::UINT32:
276 case armarx::aron::type::matrix::INT32:
277 case armarx::aron::type::matrix::FLOAT32:
278 dataSize = 4;
279 break;
280 case armarx::aron::type::matrix::FLOAT64:
281 case armarx::aron::type::matrix::INT64:
282 dataSize = 8;
283 break;
284 };
285
286
287 // UGLY HACK: FIX ME!!!
288 switch (i->getElementType())
289 {
290 case armarx::aron::type::matrix::UINT8:
291 createdMatrix->setType("unsigned char");
292 break;
293 case armarx::aron::type::matrix::UINT16:
294 createdMatrix->setType("unsigned short");
295 break;
296 case armarx::aron::type::matrix::UINT32:
297 createdMatrix->setType("unsigned int");
298 break;
299 case armarx::aron::type::matrix::INT8:
300 createdMatrix->setType("char");
301 break;
302 case armarx::aron::type::matrix::INT16:
303 createdMatrix->setType("short");
304 break;
305 case armarx::aron::type::matrix::INT32:
306 createdMatrix->setType("int");
307 break;
308 case armarx::aron::type::matrix::FLOAT32:
309 createdMatrix->setType("float");
310 break;
311 case armarx::aron::type::matrix::FLOAT64:
312 createdMatrix->setType("double");
313 break;
314 case armarx::aron::type::matrix::INT64:
315 createdMatrix->setType("long");
316 break;
317 };
318
319
320 createdMatrix->setShape({i->getRows(), i->getCols(), dataSize});
321 int totalByteSize = i->getRows() * i->getCols() * dataSize;
322 createdAron = createdMatrix;
323 auto* el = parentItem->child(index);
324
325 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
326 {
327 // its a maybetype. We have to check the state
328 if (el->checkState(2) == Qt::CheckState::Unchecked)
329 {
330 createdAron = nullptr;
331 return;
332 }
333 }
334
335
336 auto* rootWidget = el->treeWidget();
337 ARMARX_CHECK(rootWidget);
338 auto* widget = rootWidget->itemWidget(el, 1);
339 ARMARX_CHECK(rootWidget);
340 auto* matrixWidget = EditMatrixWidget::DynamicCastAndCheck(widget);
341 ARMARX_CHECK(matrixWidget);
342
343 handleErrors(matrixWidget->hasParseErrors());
344 if (matrixWidget->hasParseErrors())
345 {
346 return;
347 }
348
349 // write to aron data
350 std::vector<unsigned char> elems;
351 elems.reserve(totalByteSize);
352
353 // Raw data has column based storage
354 // However, in Aron, we use row-major Eigen matrices
355 for (size_t row = 0; row < (size_t)i->getRows(); ++row)
356 {
357 for (size_t col = 0; col < (size_t)i->getCols(); ++col)
358 {
359 // gets us directly the byte wise format
360 auto parsed = matrixWidget->parseElement(row, col);
361 // append vector to vector
362 elems.insert(elems.end(), parsed.begin(), parsed.end());
363 }
364 }
365 createdMatrix->setData(totalByteSize, elems.data());
366 }
367
368 void
370 {
371
373 auto createdQuat = std::make_shared<aron::data::NDArray>(i->getPath());
374 createdAron = createdQuat;
375 int dataSize = i->getElementType() == aron::type::quaternion::ElementType::FLOAT32 ? 4 : 8;
376 createdQuat->setShape({1, 4, dataSize});
377 createdQuat->setType(i->getFullName());
378 auto* el = parentItem->child(index);
379
380 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
381 {
382 // its a maybetype. We have to check the state
383 if (el->checkState(2) == Qt::CheckState::Unchecked)
384 {
385 createdAron = nullptr;
386 return;
387 }
388 }
389
390 auto* itemWidget = el->treeWidget()->itemWidget(el, 1);
391 auto* quatWidget = QuaternionWidget::DynamicCastAndCheck(itemWidget);
392
393 // error handling
394 handleErrors(quatWidget->hasParseErrors());
395 if (quatWidget->hasParseErrors())
396 {
397 return;
398 }
399
400 // write to aron data
401 auto serialized = quatWidget->parseAllToNDArray();
402 if ((int)serialized.size() != dataSize * 4)
403 {
405 << "serialized quaternions did not return byte sequence of correct length!";
406 }
407 createdQuat->setData(serialized.size(), serialized.data());
408 }
409
410 void
416
417 void
423
424 void
426 {
427
429 QTreeWidgetItem* el = parentItem->child(index);
430
431 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
432 {
433 // its a maybetype. We have to check the state
434 if (el->checkState(2) == Qt::CheckState::Unchecked)
435 {
436 createdAron = nullptr;
437 return;
438 }
439 }
440
441 auto* genericWidget = el->treeWidget()->itemWidget(el, 1);
442 auto* intEnumWidget = IntEnumWidget::DynamicCastAndCheck(genericWidget);
443 if (!intEnumWidget)
444 {
445 // already reporting error; continue here
446 return;
447 }
448 bool success;
449 std::tie(success, createdAron) = intEnumWidget->parseToAron();
450
451 handleErrors(!success);
452 }
453
454 void
456 {
457
459 auto createdAronInt = std::make_shared<aron::data::Int>(i->getPath());
460 createdAron = createdAronInt;
461 QTreeWidgetItem* el = parentItem->child(index);
462
463 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
464 {
465 // its a maybetype. We have to check the state
466 if (el->checkState(2) == Qt::CheckState::Unchecked)
467 {
468 createdAron = nullptr;
469 return;
470 }
471 }
472
473 std::string str = el->text(1).toStdString();
474 if (str.empty())
475 {
476 createdAronInt->setValue(0);
477 return;
478 }
479 try
480 {
481 int val = simox::alg::to_<int>(str);
482 createdAronInt->setValue(val);
483 }
484 catch (const simox::error::SimoxError& err)
485 {
486 handleErrors();
487 ARMARX_VERBOSE << "Conversion from String to Int failed. Error:\"" << err.what()
488 << "\"";
489 return;
490 }
491 handleErrors(false);
492 }
493
494 void
496 {
497
499 auto createdAronLong = std::make_shared<aron::data::Long>(i->getPath());
500 createdAron = createdAronLong;
501 QTreeWidgetItem* el = parentItem->child(index);
502
503 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
504 {
505 // its a maybetype. We have to check the state
506 if (el->checkState(2) == Qt::CheckState::Unchecked)
507 {
508 createdAron = nullptr;
509 return;
510 }
511 }
512
513 std::string str = el->text(1).toStdString();
514 if (str.empty())
515 {
516 //TODO: similar behaviour for rest?
517 str = el->text(3).toStdString();
518 }
519 try
520 {
521 createdAronLong->setValue(simox::alg::to_<long>(str));
522 }
523 catch (const simox::error::SimoxError& err)
524 {
525 handleErrors();
526 ARMARX_VERBOSE << "Conversion from String to Long failed. Error:\"" << err.what()
527 << "\"";
528 return;
529 }
530 handleErrors(false);
531 }
532
533 void
535 {
536
538 auto createdAronFloat = std::make_shared<aron::data::Float>(i->getPath());
539 createdAron = createdAronFloat;
540 QTreeWidgetItem* el = parentItem->child(index);
541
542 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
543 {
544 // its a maybetype. We have to check the state
545 if (el->checkState(2) == Qt::CheckState::Unchecked)
546 {
547 createdAron = nullptr;
548 return;
549 }
550 }
551
552 std::string str = el->text(1).toStdString();
553 if (str.empty())
554 {
555 str = el->text(3).toStdString();
556 }
557 try
558 {
559 createdAronFloat->setValue(simox::alg::to_<float>(str));
560 }
561 catch (const simox::error::SimoxError& err)
562 {
563 handleErrors();
564 ARMARX_VERBOSE << "Conversion from String to Float failed. Error:\"" << err.what()
565 << "\"";
566 return;
567 }
568 handleErrors(false);
569 }
570
571 void
573 {
574
576 auto createdAronDouble = std::make_shared<aron::data::Double>(i->getPath());
577 createdAron = createdAronDouble;
578 QTreeWidgetItem* el = parentItem->child(index);
579
580 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
581 {
582 // its a maybetype. We have to check the state
583 if (el->checkState(2) == Qt::CheckState::Unchecked)
584 {
585 createdAron = nullptr;
586 return;
587 }
588 }
589
590 std::string str = el->text(1).toStdString();
591 if (str.empty())
592 {
593 str = el->text(3).toStdString();
594 }
595 try
596 {
597 createdAronDouble->setValue(simox::alg::to_<double>(str));
598 }
599 catch (const simox::error::SimoxError& err)
600 {
601 handleErrors();
602 ARMARX_VERBOSE << "Conversion from String to Double failed. Error:\"" << err.what()
603 << "\"";
604 return;
605 }
606 handleErrors(false);
607 }
608
609 void
611 {
612
614 auto createdAronBool = std::make_shared<aron::data::Bool>(i->getPath());
615 createdAron = createdAronBool;
616 QTreeWidgetItem* el = parentItem->child(index);
617
618 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
619 {
620 // its a maybetype. We have to check the state
621 if (el->checkState(2) == Qt::CheckState::Unchecked)
622 {
623 createdAron = nullptr;
624 return;
625 }
626 }
627
628 std::string str = el->text(1).toStdString();
629 if (str.empty())
630 {
631 str = el->text(3).toStdString();
632 }
633 try
634 {
635 createdAronBool->setValue(simox::alg::to_<bool>(str));
636 }
637 catch (const simox::error::SimoxError& err)
638 {
639 handleErrors();
640 ARMARX_VERBOSE << "Conversion from String to Bool failed. Error:\"" << err.what()
641 << "\"";
642 return;
643 }
644 handleErrors(false);
645 }
646
647 void
649 {
650
652 auto createdAronString = std::make_shared<aron::data::String>(i->getPath());
653 createdAron = createdAronString;
654 QTreeWidgetItem* el = parentItem->child(index);
655
656 if (el == nullptr)
657 {
658 return;
659 }
660
661 if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
662 {
663 // its a maybetype. We have to check the state
664 if (el->checkState(2) == Qt::CheckState::Unchecked)
665 {
666 createdAron = nullptr;
667 return;
668 }
669 }
670
671 std::string str = el->text(1).toStdString();
672 createdAronString->setValue(str);
673 }
674
675 void
677 {
678 ARMARX_WARNING_S << "Received an unknown type when trying to convert a skill argument type "
679 "to an aron data object.";
680 }
681} // namespace armarx::skills::gui
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