Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add primitive shapes widgets #2137

Closed
wants to merge 5 commits into from

Conversation

jrgnicho
Copy link
Contributor

@jrgnicho jrgnicho commented Jun 2, 2020

Description

Addresses issue #2063

Adds widgets into the moveit motion planning plugin that allows adding primitive shapes into the planning scene
rviz_screenshot_2020_06_02-16_13_31

Checklist

  • [x ] Required by CI: Code is auto formatted using clang-format
  • Extend the tutorials / documentation reference
  • Document API changes relevant to the user in the MIGRATION.md notes
  • Create tests, which fail without this PR reference
  • [x ] Include a screenshot if changing a GUI
  • While waiting for someone to review your request, please help review another open pull request to support the maintainers


// get selected shape
std::string selected_shape = ui_->shapes_combo_box->currentText().toStdString();
if (SHAPES_MAP.count(selected_shape) == 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also use auto selected_shape_it = SHAPES_MAP.find(selected_shape) and test if it's equal to SHAPES_MAP.end() and replace SHAPES_MAP.at(selected_shape); with the object it point to

Copy link
Contributor

@simonschmeisser simonschmeisser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice gimmick, would be even cooler if you would show/hide further SpinBoxes for additional dimensions but I guess time is over and it's nice as is (with the minor modifications requested)

@@ -128,6 +128,7 @@ MotionPlanningFrame::MotionPlanningFrame(MotionPlanningDisplay* pdisplay, rviz::
connect(ui_->planning_scene_tree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this,
SLOT(warehouseItemNameChanged(QTreeWidgetItem*, int)));
connect(ui_->reset_db_button, SIGNAL(clicked()), this, SLOT(resetDbButtonClicked()));
connect(ui_->add_shape_button, &QPushButton::clicked, [this]() { addPrimitiveShape(); });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
connect(ui_->add_shape_button, &QPushButton::clicked, [this]() { addPrimitiveShape(); });
connect(ui_->add_shape_button, &QPushButton::clicked, this, &MotionPlanningFrame::addPrimitiveShape);

No need for a lambda here. Also please be careful with this short version as this or other pointers bound in the lambda could be destroyed elsewhere and then crash on calling the lambda. There is a preferred variant with four arguments where the third denotes the scope of the connection and if either sender or receiver are destructed:

connect(ui_->add_shape_button, &QPushButton::clicked, this, [this]() { addPrimitiveShape(); });

But as stated above, this shouldn't be necessary here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simonschmeisser The this pointer points to the panel itself so I don't see how it could ever get destroyed in this context but I'll make the change

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, in this context it won't happen. ui_->shape_button is a child of this and therefore gets destroyed before this and cancels the connection ... just wanted to point out the general danger of that variant of connect()

My main remark was about the number of brackets and the unnecessary lambda however :)

if (SHAPES_MAP.count(selected_shape) == 0)
{
QMessageBox::warning(this, QString("Unsupported shape"),
QString("The '").append(selected_shape.c_str()).append("' is not supported."));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
QString("The '").append(selected_shape.c_str()).append("' is not supported."));
QString("The shape '%1' is not supported.").arg(selected_shape.c_str()));

This improves readability and also allows rearranging if we should ever start translating MoveIt into languages other than English.

@JafarAbdi
Copy link
Contributor

Thanks @jrgnicho for the PR, the CI is failing because you have unhandled ShapeType values see, one way to handle it would be

  std::string selected_shape_name = ui_->shapes_combo_box->currentText().toStdString();
  auto selected_shape = SHAPES_MAP.find(selected_shape_name);
  shapes::ShapeType shape_type = (selected_shape != SHAPES_MAP.end()) ? selected_shape->second : shapes::UNKNOWN_SHAPE;
  shapes::ShapeConstPtr shape;
  switch (shape_type)
  {
    case shapes::BOX:
      shape = std::make_shared<shapes::Box>(side_length, side_length, side_length);
      break;
    case shapes::SPHERE:
      shape = std::make_shared<shapes::Sphere>(0.5 * side_length);
      break;
    case shapes::CONE:
      shape = std::make_shared<shapes::Cone>(0.5 * side_length, side_length);
      break;
    case shapes::CYLINDER:
      shape = std::make_shared<shapes::Cylinder>(0.5 * side_length, side_length);
      break;
    default:
      QMessageBox::warning(this, QString("Unsupported shape"),
                           QString("The '").append(selected_shape_name.c_str()).append("' is not supported."));
      return;
  }

@AndyZe
Copy link
Member

AndyZe commented Jun 3, 2020

I would like this feature a lot!

@jrgnicho
Copy link
Contributor Author

jrgnicho commented Jun 3, 2020

Thanks @jrgnicho for the PR, the CI is failing because you have unhandled ShapeType values see, one way to handle it would be

  std::string selected_shape_name = ui_->shapes_combo_box->currentText().toStdString();
  auto selected_shape = SHAPES_MAP.find(selected_shape_name);
  shapes::ShapeType shape_type = (selected_shape != SHAPES_MAP.end()) ? selected_shape->second : shapes::UNKNOWN_SHAPE;
  shapes::ShapeConstPtr shape;
  switch (shape_type)
  {
    case shapes::BOX:
      shape = std::make_shared<shapes::Box>(side_length, side_length, side_length);
      break;
    case shapes::SPHERE:
      shape = std::make_shared<shapes::Sphere>(0.5 * side_length);
      break;
    case shapes::CONE:
      shape = std::make_shared<shapes::Cone>(0.5 * side_length, side_length);
      break;
    case shapes::CYLINDER:
      shape = std::make_shared<shapes::Cylinder>(0.5 * side_length, side_length);
      break;
    default:
      QMessageBox::warning(this, QString("Unsupported shape"),
                           QString("The '").append(selected_shape_name.c_str()).append("' is not supported."));
      return;
  }

@JafarAbdi thanks for the tip, the logic prior to the switch statement makes it so that an unhandled shape type can never be assigned but I'll make the change to comply with the CI

@jrgnicho
Copy link
Contributor Author

jrgnicho commented Jun 3, 2020

I've made the suggested changes and added double spin boxes to set the x, y and z dimensions which get toggled based on the shape
add_primitive_shapes_widgets_v3

@codecov
Copy link

codecov bot commented Jun 3, 2020

Codecov Report

Merging #2137 into master will decrease coverage by 0.34%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2137      +/-   ##
==========================================
- Coverage   57.79%   57.45%   -0.35%     
==========================================
  Files         328      328              
  Lines       25700    25735      +35     
==========================================
- Hits        14854    14786      -68     
- Misses      10846    10949     +103     
Impacted Files Coverage Δ
...ls/include/moveit/py_bindings_tools/gil_releaser.h 0.00% <0.00%> (-100.00%) ⬇️
.../include/moveit/py_bindings_tools/py_conversions.h 0.00% <0.00%> (-86.67%) ⬇️
...s/include/moveit/py_bindings_tools/serialize_msg.h 0.00% <0.00%> (-80.00%) ⬇️
...ove_group_interface/src/wrap_python_move_group.cpp 31.96% <0.00%> (-11.08%) ⬇️
...ntal/moveit_jog_arm/src/collision_check_thread.cpp 80.59% <0.00%> (-9.97%) ⬇️
.../move_group_interface/src/move_group_interface.cpp 44.44% <0.00%> (-3.64%) ⬇️
...veit_experimental/moveit_jog_arm/src/jog_calcs.cpp 70.93% <0.00%> (-2.05%) ⬇️
...meterization/work_space/pose_model_state_space.cpp 82.31% <0.00%> (-0.69%) ⬇️
...rimental/moveit_jog_arm/src/jog_interface_base.cpp 72.79% <0.00%> (-0.23%) ⬇️
moveit_core/planning_scene/src/planning_scene.cpp 59.47% <0.00%> (ø)
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1ae4318...81c81d3. Read the comment docs.

Copy link
Contributor

@felixvd felixvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that I didn't post this review yesterday. Oops.

If you could change the default values of the sliders, this looks ready to merge for me.

If you have the energy to try adding in the mesh option, that would be amazing and really complete this feature, but if not just open an issue as a reminder. Would be a great addition we shouldn't forget about.

{
static const double MIN_VAL = 1e-6;
static const std::map<std::string, shapes::ShapeType> SHAPES_MAP = {
{ "box", shapes::BOX }, { "sphere", shapes::SPHERE }, { "cone", shapes::CONE }, { "cylinder", shapes::CYLINDER }
Copy link
Contributor

@felixvd felixvd Jun 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should shoot for the moon and add shapes::MESH while we're at it

Copy link
Contributor Author

@jrgnicho jrgnicho Jun 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would't that be redundant since there are already import buttons?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a closer look, and you're right: the "Import File" button actually accepts an STL file. I just assumed it's a scene file or something, since nothing tells you about the expected format. I'll fix that in a separate PR.

<property name="text">
<string>Status</string>
<string>Import &amp;File</string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always wished this would say Import Scene, because it's not clear if the file is an object or a scene.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't recall changing this, I made my edits with QT designer so sometimes things get changed without one knowing about it.

</widget>
</item>
<item row="3" column="1">
<widget class="QGroupBox" name="groupBox_4">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about changing this box to a layout like this? The Load button next to the dropdown menu would be greyed out unless the type is "MESH", and need the tooltip "Choose mesh location". Alternatively, a file dialog could open when "mesh" is selected in the dropdown menu. That would be very smooth!

IMG_2001

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to add a second column as there were some concerns with increasing the panel's height. Furthermore, having yet another "scale" section might be confusing, would't "size" be more appropriate.
See my comments above on the "mesh" option

Copy link
Contributor

@felixvd felixvd Jun 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I drew this when the new section was still on the left. It's fine now, I just don't see a Resolve button to close this thread

<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
Copy link
Contributor

@felixvd felixvd Jun 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would prefer a default value of 0.1 and a step value of 0.01. It will be a smoother experience and fit the dimensions of the demo/tutorial robot.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's not really important, I just feel like the default will force users to zoom out when their robot fills most of the screen. 0.2 and 0.05 could be a good compromise.

Screenshot from 2020-06-04 18-34-39

Screenshot from 2020-06-04 18-24-21

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixvd I agree, I'll update those values

Copy link
Contributor

@felixvd felixvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing to add, this is great.

@jrgnicho
Copy link
Contributor Author

jrgnicho commented Jun 7, 2020

Nothing to add, this is great.

@felixvd thanks for reviewing

@jrgnicho
Copy link
Contributor Author

This should be ready to merge unless someone has additional change requests

@rhaschke
Copy link
Contributor

rhaschke commented Jul 6, 2020

Great work! I file a new PR resolving the conflicts by a rebase in #2198.

@rhaschke rhaschke closed this Jul 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants