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
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::INT16:
261  dataSize = 2;
262  break;
263  case armarx::aron::type::matrix::INT32:
264  case armarx::aron::type::matrix::FLOAT32:
265  dataSize = 4;
266  break;
267  case armarx::aron::type::matrix::FLOAT64:
268  case armarx::aron::type::matrix::INT64:
269  dataSize = 8;
270  break;
271  };
272 
273  // UGLY HACK: FIX ME!!!
274  switch (i->getElementType())
275  {
276  case armarx::aron::type::matrix::INT16:
277  createdMatrix->setType("short");
278  break;
279  case armarx::aron::type::matrix::INT32:
280  createdMatrix->setType("int");
281  break;
282  case armarx::aron::type::matrix::FLOAT32:
283  createdMatrix->setType("float");
284  break;
285  case armarx::aron::type::matrix::FLOAT64:
286  createdMatrix->setType("double");
287  break;
288  case armarx::aron::type::matrix::INT64:
289  createdMatrix->setType("long");
290  break;
291  };
292 
293  createdMatrix->setShape({i->getRows(), i->getCols(), dataSize});
294  int totalByteSize = i->getRows() * i->getCols() * dataSize;
295  createdAron = createdMatrix;
296  auto* el = parentItem->child(index);
297 
298  if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
299  {
300  // its a maybetype. We have to check the state
301  if (el->checkState(1) == Qt::CheckState::Unchecked)
302  {
303  createdAron = nullptr;
304  return;
305  }
306  }
307 
308 
309  auto* rootWidget = el->treeWidget();
310  ARMARX_CHECK(rootWidget);
311  auto* widget = rootWidget->itemWidget(el, 1);
312  auto* matrixWidget = EditMatrixWidget::DynamicCastAndCheck(widget);
313 
314  handleErrors(matrixWidget->hasParseErrors());
315  if (matrixWidget->hasParseErrors())
316  {
317  return;
318  }
319  // write to aron data
320  std::vector<unsigned char> elems;
321  elems.reserve(totalByteSize);
322  // CAUTION: Raw data has column based storage
323  for (size_t col = 0; col < (size_t)i->getCols(); ++col)
324  {
325  for (size_t row = 0; row < (size_t)i->getRows(); ++row)
326  {
327  // gets us directly the byte wise format
328  auto parsed = matrixWidget->parseElement(row, col);
329  // append vector to vector
330  elems.insert(elems.end(), parsed.begin(), parsed.end());
331  }
332  }
333  createdMatrix->setData(totalByteSize, elems.data());
334  }
335 
336  void
338  {
339  ARMARX_TRACE;
340  auto createdQuat = std::make_shared<aron::data::NDArray>(i->getPath());
341  createdAron = createdQuat;
342  int dataSize = i->getElementType() == aron::type::quaternion::ElementType::FLOAT32 ? 4 : 8;
343  createdQuat->setShape({1, 4, dataSize});
344  createdQuat->setType(i->getFullName());
345  auto* el = parentItem->child(index);
346 
347  if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
348  {
349  // its a maybetype. We have to check the state
350  if (el->checkState(1) == Qt::CheckState::Unchecked)
351  {
352  createdAron = nullptr;
353  return;
354  }
355  }
356 
357  auto* itemWidget = el->treeWidget()->itemWidget(el, 1);
358  auto* quatWidget = QuaternionWidget::DynamicCastAndCheck(itemWidget);
359 
360  // error handling
361  handleErrors(quatWidget->hasParseErrors());
362  if (quatWidget->hasParseErrors())
363  {
364  return;
365  }
366 
367  // write to aron data
368  auto serialized = quatWidget->parseAllToNDArray();
369  if ((int)serialized.size() != dataSize * 4)
370  {
372  << "serialized quaternions did not return byte sequence of correct length!";
373  }
374  createdQuat->setData(serialized.size(), serialized.data());
375  }
376 
377  void
379  {
380  ARMARX_TRACE;
381  // TODO
382  }
383 
384  void
386  {
387  ARMARX_TRACE;
388  // TODO
389  }
390 
391  void
393  {
394  ARMARX_TRACE;
395  QTreeWidgetItem* el = parentItem->child(index);
396 
397  if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
398  {
399  // its a maybetype. We have to check the state
400  if (el->checkState(1) == Qt::CheckState::Unchecked)
401  {
402  createdAron = nullptr;
403  return;
404  }
405  }
406 
407  auto* genericWidget = el->treeWidget()->itemWidget(el, 1);
408  auto* intEnumWidget = IntEnumWidget::DynamicCastAndCheck(genericWidget);
409  if (!intEnumWidget)
410  {
411  // already reporting error; continue here
412  return;
413  }
414  bool success;
415  std::tie(success, createdAron) = intEnumWidget->parseToAron();
416 
417  handleErrors(!success);
418  }
419 
420  void
422  {
423  ARMARX_TRACE;
424  auto createdAronInt = std::make_shared<aron::data::Int>(i->getPath());
425  createdAron = createdAronInt;
426  QTreeWidgetItem* el = parentItem->child(index);
427 
428  if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
429  {
430  // its a maybetype. We have to check the state
431  if (el->checkState(1) == Qt::CheckState::Unchecked)
432  {
433  createdAron = nullptr;
434  return;
435  }
436  }
437 
438  std::string str = el->text(1).toStdString();
439  if (str.empty())
440  {
441  createdAronInt->setValue(0);
442  return;
443  }
444  try
445  {
446  int val = simox::alg::to_<int>(str);
447  createdAronInt->setValue(val);
448  }
449  catch (const simox::error::SimoxError& err)
450  {
451  handleErrors();
452  ARMARX_VERBOSE << "Conversion from String to Int failed. Error:\"" << err.what()
453  << "\"";
454  return;
455  }
456  handleErrors(false);
457  }
458 
459  void
461  {
462  ARMARX_TRACE;
463  auto createdAronLong = std::make_shared<aron::data::Long>(i->getPath());
464  createdAron = createdAronLong;
465  QTreeWidgetItem* el = parentItem->child(index);
466 
467  if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
468  {
469  // its a maybetype. We have to check the state
470  if (el->checkState(1) == Qt::CheckState::Unchecked)
471  {
472  createdAron = nullptr;
473  return;
474  }
475  }
476 
477  std::string str = el->text(1).toStdString();
478  if (str.empty())
479  {
480  //TODO: similar behaviour for rest?
481  str = el->text(3).toStdString();
482  }
483  try
484  {
485  createdAronLong->setValue(simox::alg::to_<long>(str));
486  }
487  catch (const simox::error::SimoxError& err)
488  {
489  handleErrors();
490  ARMARX_VERBOSE << "Conversion from String to Long failed. Error:\"" << err.what()
491  << "\"";
492  return;
493  }
494  handleErrors(false);
495  }
496 
497  void
499  {
500  ARMARX_TRACE;
501  auto createdAronFloat = std::make_shared<aron::data::Float>(i->getPath());
502  createdAron = createdAronFloat;
503  QTreeWidgetItem* el = parentItem->child(index);
504 
505  if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
506  {
507  // its a maybetype. We have to check the state
508  if (el->checkState(1) == Qt::CheckState::Unchecked)
509  {
510  createdAron = nullptr;
511  return;
512  }
513  }
514 
515  std::string str = el->text(1).toStdString();
516  if (str.empty())
517  {
518  str = el->text(3).toStdString();
519  }
520  try
521  {
522  createdAronFloat->setValue(simox::alg::to_<float>(str));
523  }
524  catch (const simox::error::SimoxError& err)
525  {
526  handleErrors();
527  ARMARX_VERBOSE << "Conversion from String to Float failed. Error:\"" << err.what()
528  << "\"";
529  return;
530  }
531  handleErrors(false);
532  }
533 
534  void
536  {
537  ARMARX_TRACE;
538  auto createdAronDouble = std::make_shared<aron::data::Double>(i->getPath());
539  createdAron = createdAronDouble;
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(1) == 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  createdAronDouble->setValue(simox::alg::to_<double>(str));
560  }
561  catch (const simox::error::SimoxError& err)
562  {
563  handleErrors();
564  ARMARX_VERBOSE << "Conversion from String to Double failed. Error:\"" << err.what()
565  << "\"";
566  return;
567  }
568  handleErrors(false);
569  }
570 
571  void
573  {
574  ARMARX_TRACE;
575  auto createdAronBool = std::make_shared<aron::data::Bool>(i->getPath());
576  createdAron = createdAronBool;
577  QTreeWidgetItem* el = parentItem->child(index);
578 
579  if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
580  {
581  // its a maybetype. We have to check the state
582  if (el->checkState(1) == Qt::CheckState::Unchecked)
583  {
584  createdAron = nullptr;
585  return;
586  }
587  }
588 
589  std::string str = el->text(1).toStdString();
590  if (str.empty())
591  {
592  str = el->text(3).toStdString();
593  }
594  try
595  {
596  createdAronBool->setValue(simox::alg::to_<bool>(str));
597  }
598  catch (const simox::error::SimoxError& err)
599  {
600  handleErrors();
601  ARMARX_VERBOSE << "Conversion from String to Bool failed. Error:\"" << err.what()
602  << "\"";
603  return;
604  }
605  handleErrors(false);
606  }
607 
608  void
610  {
611  ARMARX_TRACE;
612  auto createdAronString = std::make_shared<aron::data::String>(i->getPath());
613  createdAron = createdAronString;
614  QTreeWidgetItem* el = parentItem->child(index);
615 
616  if (i->getMaybe() != armarx::aron::type::Maybe::NONE)
617  {
618  // its a maybetype. We have to check the state
619  if (el->checkState(1) == Qt::CheckState::Unchecked)
620  {
621  createdAron = nullptr;
622  return;
623  }
624  }
625 
626  std::string str = el->text(1).toStdString();
627  createdAronString->setValue(str);
628  }
629 
630  void
632  {
633  ARMARX_WARNING_S << "Received an unknown type when trying to convert a skill argument type "
634  "to an aron data object.";
635  }
636 } // namespace armarx
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::AronTreeWidgetConverterVisitor::isConversionSuccessful
bool isConversionSuccessful()
Definition: AronTreeWidgetConverter.cpp:45
armarx::IntEnumWidget::DynamicCastAndCheck
static IntEnumWidget * DynamicCastAndCheck(QWidget *)
Definition: IntEnumWidget.cpp:44
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::AronTreeWidgetConverterVisitor::visitAronVariant
void visitAronVariant(const aron::type::ObjectPtr &) final
Definition: AronTreeWidgetConverter.cpp:86
armarx::AronTreeWidgetConverterVisitor::createdAron
aron::data::VariantPtr createdAron
Definition: AronTreeWidgetConverter.h:40
armarx::AronTreeWidgetConverterVisitor::parentItem
QTreeWidgetItem * parentItem
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
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
armarx::EditMatrixWidget::DynamicCastAndCheck
static EditMatrixWidget * DynamicCastAndCheck(QWidget *)
Definition: EditMatrixWidget.cpp:92
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::aron::type::StringPtr
std::shared_ptr< class String > StringPtr
Definition: forward_declarations.h:31
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_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::QuaternionWidget::DynamicCastAndCheck
static QuaternionWidget * DynamicCastAndCheck(QWidget *)
Definition: QuaternionWidget.cpp:19
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
armarx::AronTreeWidgetConverterVisitor::onlyChildFailedConversion
bool onlyChildFailedConversion()
Definition: AronTreeWidgetConverter.cpp:51
armarx::aron::similarity::FloatSimilarity::NONE
@ NONE
Definition: FloatSimilarity.h:11
armarx::AronTreeWidgetItem::DynamicCast
static AronTreeWidgetItem * DynamicCast(QTreeWidgetItem *)
Definition: AronTreeWidgetItem.cpp:15
armarx::AronTreeWidgetConverterVisitor::index
int index
Definition: AronTreeWidgetConverter.h:39
armarx::aron::type::visit
void visit(VisitorImplementation &v, typename VisitorImplementation::Input &t)
The visit function.
Definition: Visitor.h:42
armarx::AronTreeWidgetConverterVisitor::visitUnknown
void visitUnknown(Input &) final
Definition: AronTreeWidgetConverter.cpp:631
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
AronTreeWidgetConverter.h
armarx::AronTreeWidgetConverterVisitor
Definition: AronTreeWidgetConverter.h:35
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::AronTreeWidgetConverterVisitor::hasDirectError
bool hasDirectError() const
Definition: AronTreeWidgetConverter.cpp:57
armarx::status::success
@ success