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 
38 #include "../widgets/EditMatrixWidget.h"
39 #include "../widgets/IntEnumWidget.h"
40 #include "../widgets/QuaternionWidget.h"
41 
42 namespace 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  {
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  {
106  ARMARX_TRACE;
109 
110  handleErrors(v);
111  if (v.isConversionSuccessful())
112  {
113  createdAronDict->addElement(key, v.createdAron);
114  }
115  }
116  }
117 
118  void
120  {
121  ARMARX_TRACE;
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  {
154  ARMARX_TRACE;
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  {
187  ARMARX_TRACE;
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  {
216  ARMARX_TRACE;
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  {
248  ARMARX_TRACE;
249  ARMARX_ERROR << "Currently do not support supplying raw NDArrays!";
250  }
251 
252  void
254  {
255  ARMARX_TRACE;
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::UINT8:
261  case armarx::aron::type::matrix::INT8:
262  dataSize = 1;
263  break;
264  case armarx::aron::type::matrix::UINT16:
265  case armarx::aron::type::matrix::INT16:
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  {
357  ARMARX_TRACE;
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
397  {
398  ARMARX_TRACE;
399  // TODO
400  }
401 
402  void
404  {
405  ARMARX_TRACE;
406  // TODO
407  }
408 
409  void
411  {
412  ARMARX_TRACE;
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  {
441  ARMARX_TRACE;
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  {
480  ARMARX_TRACE;
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  {
518  ARMARX_TRACE;
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  {
555  ARMARX_TRACE;
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  {
592  ARMARX_TRACE;
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  {
629  ARMARX_TRACE;
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::skills::gui
armarx::aron::type::VisitorBase< const type::VariantPtr >::Input
const type::VariantPtr Input
Definition: Visitor.h:94
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::aron::type::MatrixPtr
std::shared_ptr< class Matrix > MatrixPtr
Definition: forward_declarations.h:20
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:42
armarx::skills::gui::AronTreeWidgetConverterVisitor::hasDirectError
bool hasDirectError() const
Definition: AronTreeWidgetConverter.cpp:57
armarx::aron::type::ImagePtr
std::shared_ptr< class Image > ImagePtr
Definition: forward_declarations.h:22
armarx::aron::type::NDArrayPtr
std::shared_ptr< class NDArray > NDArrayPtr
Definition: forward_declarations.h:19
armarx::skills::gui::AronTreeWidgetConverterVisitor
Definition: AronTreeWidgetConverter.h:34
armarx::skills::gui::EditMatrixWidget::DynamicCastAndCheck
static EditMatrixWidget * DynamicCastAndCheck(QWidget *)
Definition: EditMatrixWidget.cpp:92
armarx::skills::gui::AronTreeWidgetConverterVisitor::index
int index
Definition: AronTreeWidgetConverter.h:38
armarx::aron::type::TuplePtr
std::shared_ptr< class Tuple > TuplePtr
Definition: forward_declarations.h:17
armarx::aron::type::PointCloudPtr
std::shared_ptr< class PointCloud > PointCloudPtr
Definition: forward_declarations.h:23
armarx::aron::type::FloatPtr
std::shared_ptr< class Float > FloatPtr
Definition: forward_declarations.h:29
AronTreeWidgetConverter.h
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::skills::gui::AronTreeWidgetItem::DynamicCast
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:15
armarx::aron::type::ListPtr
std::shared_ptr< class List > ListPtr
Definition: forward_declarations.h:14
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
armarx::aron::type::LongPtr
std::shared_ptr< class Long > LongPtr
Definition: forward_declarations.h:28
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::skills::gui::AronTreeWidgetConverterVisitor::createdAron
aron::data::VariantPtr createdAron
Definition: AronTreeWidgetConverter.h:39
armarx::aron::type::StringPtr
std::shared_ptr< class String > StringPtr
Definition: forward_declarations.h:31
armarx::skills::gui::AronTreeWidgetConverterVisitor::parentItem
QTreeWidgetItem * parentItem
Definition: AronTreeWidgetConverter.h:37
armarx::skills::gui::AronTreeWidgetConverterVisitor::isConversionSuccessful
bool isConversionSuccessful()
Definition: AronTreeWidgetConverter.cpp:45
armarx::skills::gui::IntEnumWidget::DynamicCastAndCheck
static IntEnumWidget * DynamicCastAndCheck(QWidget *)
Definition: IntEnumWidget.cpp:44
All.h
armarx::aron::type::PairPtr
std::shared_ptr< class Pair > PairPtr
Definition: forward_declarations.h:16
armarx::aron::type::DictPtr
std::shared_ptr< class Dict > DictPtr
Definition: forward_declarations.h:13
armarx::skills::gui
Definition: PeriodicUpdateWidget.cpp:11
armarx::skills::gui::AronTreeWidgetConverterVisitor::visitAronVariant
void visitAronVariant(const aron::type::ObjectPtr &) final
Definition: AronTreeWidgetConverter.cpp:86
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::aron::type::BoolPtr
std::shared_ptr< class Bool > BoolPtr
Definition: forward_declarations.h:32
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::skills::gui::AronTreeWidgetConverterVisitor::visitUnknown
void visitUnknown(Input &) final
Definition: AronTreeWidgetConverter.cpp:649
armarx::skills::gui::QuaternionWidget::DynamicCastAndCheck
static QuaternionWidget * DynamicCastAndCheck(QWidget *)
Definition: QuaternionWidget.cpp:20
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
armarx::aron::similarity::FloatSimilarity::NONE
@ NONE
Definition: FloatSimilarity.h:11
armarx::skills::gui::AronTreeWidgetConverterVisitor::onlyChildFailedConversion
bool onlyChildFailedConversion()
Definition: AronTreeWidgetConverter.cpp:51
armarx::aron::type::visit
void visit(VisitorImplementation &v, typename VisitorImplementation::Input &t)
The visit function.
Definition: Visitor.h:42
armarx::aron::type::IntEnumPtr
std::shared_ptr< IntEnum > IntEnumPtr
Definition: IntEnum.h:36
armarx::aron::type::ObjectPtr
std::shared_ptr< Object > ObjectPtr
Definition: Object.h:36
Logging.h
armarx::aron::type::QuaternionPtr
std::shared_ptr< class Quaternion > QuaternionPtr
Definition: forward_declarations.h:21
armarx::aron::type::IntPtr
std::shared_ptr< class Int > IntPtr
Definition: forward_declarations.h:27
armarx::aron::type::DoublePtr
std::shared_ptr< class Double > DoublePtr
Definition: forward_declarations.h:30
armarx::status::success
@ success