11 setObjectName(
"Modify trajectory");
15 QWidget *scroll_widget =
new QWidget;
16 scroll_widget->setLayout(
layout_);
17 QScrollArea *scroll_area =
new QScrollArea;
18 scroll_area->setWidget(scroll_widget);
19 scroll_area->setWidgetResizable(
true);
20 scroll_area->setFrameShape(QFrame::NoFrame);
21 QVBoxLayout* main_layout =
new QVBoxLayout(
this);
22 main_layout->addWidget(scroll_area);
31 "ram/display/update_selection");
34 "ram/information/get_trajectory_size");
37 "ram/information/get_number_of_layers_levels");
40 "ram/information/get_layer_size");
43 "ram/pose_selector/get_poses_from_trajectory");
46 "ram/pose_selector/get_poses_from_layers_list");
49 "ram/pose_selector/get_poses_from_layer");
53 "ram/modify_trajectory/modify_selected_poses");
56 "ram/modify_trajectory/delete_selected_poses");
61 "ram/modify_trajectory/reset_selected_poses");
65 "ram/modify_trajectory/rotate_selected_poses");
68 "ram/modify_trajectory/reflect_selected_poses");
71 "ram/modify_trajectory/scale_selected_poses");
95 const bool old_state(isEnabled());
96 Q_EMIT setEnabled(
false);
98 while (QLayoutItem* item = layout->takeAt(0))
102 && (widget = item->widget()))
106 if (QLayout* childLayout = item->layout())
113 Q_EMIT setEnabled(old_state);
118 Q_EMIT setEnabled(
false);
124 ram_display::UpdateSelection srv;
127 QGridLayout *buttons =
new QGridLayout;
135 QLabel *label_1 =
new QLabel(
"Trajectory\nSelect one pose or more within the trajectory");
136 label_1->setWordWrap(
true);
137 buttons->addWidget(label_1, 0, 1);
140 QLabel *label_2 =
new QLabel(
"Layers\nSelect one layer or more");
141 label_2->setWordWrap(
true);
142 buttons->addWidget(label_2);
145 QLabel *label_3 =
new QLabel(
"Within layer\nSelect one pose or more within a specific layer.\n" 146 "You will be able to propagate this selection across layers afterwards.");
147 label_3->setWordWrap(
true);
148 buttons->addWidget(label_3);
150 QPushButton *start_selection =
new QPushButton(
"Start selection");
152 layout_->addWidget(
new QLabel(
"Selection mode:"));
158 layout_->addWidget(start_selection);
161 Q_EMIT setEnabled(
true);
167 unsigned selected_button(0);
170 if (button->isChecked())
179 unsigned min_value, max_value;
184 ram_utils::GetTrajectorySize srv;
193 if (srv.response.trajectory_size == 0)
196 "Generate a trajectory first");
201 help_string =
"Pick up the poses to be selected:";
203 max_value = srv.response.trajectory_size - 1;
208 ram_utils::GetNumberOfLayersLevels srv;
212 "The trajectory is probably empty");
217 if (srv.response.number_of_layers == 0)
220 "The trajectory is probably empty");
227 help_string =
"Pick up the layers to be selected:";
229 max_value = srv.response.number_of_layers - 1;
234 QDialog *window =
new QDialog;
235 window->setWindowTitle(
"Modify trajectory - Selection");
236 window->setModal(
true);
237 QVBoxLayout *window_layout =
new QVBoxLayout(window);
238 window->setLayout(window_layout);
239 window_layout->addWidget(
new QLabel(
"Pick a layer to work with:"));
240 QSpinBox *layers_list =
new QSpinBox;
241 layers_list->setRange(0, srv.response.number_of_layers - 1);
242 window_layout->addWidget(layers_list);
244 QDialogButtonBox *button_box =
new QDialogButtonBox(QDialogButtonBox::Ok
245 | QDialogButtonBox::Cancel);
246 window_layout->addStretch(1);
247 window_layout->addWidget(button_box);
248 connect(button_box, &QDialogButtonBox::accepted, window, &QDialog::accept);
249 connect(button_box, &QDialogButtonBox::rejected, window, &QDialog::reject);
258 ram_utils::GetLayerSize srv;
263 "Could not get the layer " + QString::number(
layer_level_) +
" size",
269 if (srv.response.layer_size == 0)
272 "Could not get the layer " + QString::number(
layer_level_) +
" size",
273 "It is probably empty!");
277 help_string =
"Pick up the poses to be selected inside layer " + QString::number(
layer_level_) +
":";
279 max_value = srv.response.layer_size - 1;
297 Q_EMIT setEnabled(
false);
306 Q_EMIT setEnabled(
true);
312 if (selected.empty())
318 Q_EMIT setEnabled(
false);
325 ram_modify_trajectory::GetPosesFromTrajectory srv;
326 srv.request.pose_index_list = selected;
330 "Could not get poses from the trajectory poses indices.",
332 Q_EMIT setEnabled(
true);
341 ram_modify_trajectory::GetPosesFromLayersList srv;
342 srv.request.layer_level_list = selected;
346 "Could not get poses from the layers list indices.",
348 Q_EMIT setEnabled(
true);
356 "The selection is empty, cannot continue.",
358 Q_EMIT setEnabled(
true);
365 ram_modify_trajectory::GetPosesFromLayer srv;
367 srv.request.index_list_relative = selected;
371 "Could not get poses from the layer relative indices list.",
373 Q_EMIT setEnabled(
true);
383 "Missing implementation in getSelection()",
386 Q_EMIT setEnabled(
true);
393 Q_EMIT setEnabled(
true);
398 ram_utils::GetNumberOfLayersLevels srv;
402 "The trajectory is probably empty");
407 Q_EMIT setEnabled(
false);
409 std::vector<unsigned> locked;
413 srv.response.number_of_layers - 1,
423 Q_EMIT setEnabled(
true);
441 Q_EMIT setEnabled(
false);
443 msg_box.setWindowTitle(
"Warning: propagating");
444 msg_box.setText(
"You are trying to propagate a selection on a trajectory with non-similar layers.");
445 msg_box.setInformativeText(
"Make sure your propagation makes sense!");
446 msg_box.setIcon(QMessageBox::Warning);
447 msg_box.setStandardButtons(QMessageBox::Cancel | QMessageBox::Ok);
448 if (msg_box.exec() != QMessageBox::Ok)
450 Q_EMIT setEnabled(
true);
454 Q_EMIT setEnabled(
true);
462 ram_modify_trajectory::GetPosesFromLayer srv;
468 "Propagate selection",
469 QString::fromStdString(
"Failed to propagate selection to layer " + std::to_string(
layers_to_propagate_[i])),
470 "De-select this layer and try again.");
484 Q_EMIT setEnabled(
false);
487 ram_display::UpdateSelection srv;
489 srv.request.temporary =
false;
492 displayErrorBoxHandler(
"Failed to display selection",
"The selection cannot be displayed",
"Aborting operation");
497 new QLabel(QString::fromStdString(std::to_string(
selected_poses_.size()) +
" poses are selected.")));
500 layout_->addWidget(
new QLabel(
"<b>Operation:</b>"));
502 QRadioButton *button_0 =
new QRadioButton(
"Modify");
503 QRadioButton *button_1 =
new QRadioButton(
"Add");
504 QRadioButton *button_2 =
new QRadioButton(
"Delete");
505 QRadioButton *button_3 =
new QRadioButton(
"Reset");
511 button_0->setChecked(
true);
517 layout_->addWidget(
new QLabel(
"<b>Geometric operation:</b>"));
519 QRadioButton *button_4 =
new QRadioButton(
"Rotate");
520 QRadioButton *button_5 =
new QRadioButton(
"Reflect");
521 QRadioButton *button_6 =
new QRadioButton(
"Scale");
531 QDialogButtonBox *button_box =
new QDialogButtonBox(QDialogButtonBox::Ok
532 | QDialogButtonBox::Cancel);
534 layout_->addWidget(button_box);
538 Q_EMIT setEnabled(
true);
543 unsigned operation_mode(0);
545 if (button && button->isChecked())
550 if (operation_mode == operations_.size())
553 if (button && button->isChecked())
559 Q_EMIT setEnabled(
false);
561 switch (operation_mode)
573 ram_modify_trajectory::AddPoses srv;
578 "Pick another one.");
579 Q_EMIT setEnabled(
true);
587 ram_modify_trajectory::DeleteSelectedPoses srv;
592 "Pick another one. Note that you cannot delete the whole trajectory");
593 Q_EMIT setEnabled(
true);
601 ram_modify_trajectory::ResetSelectedPoses srv;
606 "Pick another one.");
607 Q_EMIT setEnabled(
true);
640 Q_EMIT setEnabled(
true);
646 Q_EMIT setEnabled(
false);
656 Q_EMIT setEnabled(
true);
660 std::vector<ram_msgs::AdditiveManufacturingParams::_movement_type_type> move_types;
662 move_types.push_back(pose.params.movement_type);
664 if (std::all_of(move_types.cbegin(), move_types.cend(), [](
int i)
669 else if (std::all_of(move_types.cbegin(), move_types.cend(), [](
int i)
677 connect(
modify_poses_ui_, SIGNAL(setEnabled(
bool)),
this, SLOT(setEnabled(
bool)));
680 Q_EMIT setEnabled(
true);
686 std::vector<QCheckBox *> checkboxes;
697 std::vector<bool> checkbox_ticks;
698 for (
auto checkbox : checkboxes)
699 checkbox_ticks.push_back(checkbox->isChecked());
701 if (std::all_of(checkbox_ticks.begin(), checkbox_ticks.end(), [](
bool v)
710 ram_modify_trajectory::ModifySelectedPoses srv;
716 Eigen::Affine3d id(Eigen::Affine3d::Identity());
718 srv.request.pose =
false;
742 srv.request.pose_reference.params.blend_radius = 0;
743 srv.request.blend_radius =
false;
755 srv.request.pose_reference.params.speed = 0;
756 srv.request.speed =
false;
770 srv.request.pose_reference.params.laser_power = 0;
771 srv.request.laser_power =
false;
783 srv.request.pose_reference.params.feed_rate = 0;
784 srv.request.feed_rate =
false;
796 "Make sure none of the values go below zero!");
805 Q_EMIT setEnabled(
false);
812 QHBoxLayout * rotation_angle_layout =
new QHBoxLayout;
813 rotation_angle_layout->addWidget(
new QLabel(
"Rotation angle in z-axis:"));
824 QHBoxLayout * rotation_point_layout =
new QHBoxLayout;
825 rotation_point_layout->addWidget(
new QLabel(
"Rotation point:"));
826 rotation_point_layout->addWidget(
new QLabel(
"X:"));
828 rotation_point_layout->addWidget(
new QLabel(
"Y:"));
831 layout_->addLayout(rotation_angle_layout);
832 layout_->addLayout(rotation_point_layout);
835 QDialogButtonBox *button_box =
new QDialogButtonBox(QDialogButtonBox::Ok
836 | QDialogButtonBox::Cancel);
838 layout_->addWidget(button_box);
842 Q_EMIT setEnabled(
true);
847 ram_modify_trajectory::RotateSelectedPoses srv;
854 srv.request.center_of_rotation.z = 0;
869 Q_EMIT setEnabled(
false);
880 QHBoxLayout * reflect_vector_layout =
new QHBoxLayout;
881 reflect_vector_layout->addWidget(
new QLabel(
"X:"));
883 reflect_vector_layout->addWidget(
new QLabel(
"Y:"));
895 QHBoxLayout * reflect_point_layout =
new QHBoxLayout;
896 reflect_point_layout->addWidget(
new QLabel(
"X:"));
898 reflect_point_layout->addWidget(
new QLabel(
"Y:"));
901 layout_->addWidget(
new QLabel(
"Normal vector to reflection plane:"));
902 layout_->addLayout(reflect_vector_layout);
903 layout_->addWidget(
new QLabel(
"Point on reflection plane:"));
904 layout_->addLayout(reflect_point_layout);
907 QDialogButtonBox *button_box =
new QDialogButtonBox(QDialogButtonBox::Ok
908 | QDialogButtonBox::Cancel);
910 layout_->addWidget(button_box);
914 Q_EMIT setEnabled(
true);
919 ram_modify_trajectory::ReflectSelectedPoses srv;
925 srv.request.normal_vector.z = 0;
929 srv.request.point_on_plane.z = 0;
944 Q_EMIT setEnabled(
false);
952 QHBoxLayout * scale_factor_layout =
new QHBoxLayout;
953 scale_factor_layout->addWidget(
new QLabel(
"Scale factor :"));
964 QHBoxLayout * scale_center_layout =
new QHBoxLayout;
965 scale_center_layout->addWidget(
new QLabel(
"Center of scaling :"));
966 scale_center_layout->addWidget(
new QLabel(
"X:"));
968 scale_center_layout->addWidget(
new QLabel(
"Y:"));
971 layout_->addLayout(scale_factor_layout);
972 layout_->addLayout(scale_center_layout);
975 QDialogButtonBox *button_box =
new QDialogButtonBox(QDialogButtonBox::Ok
976 | QDialogButtonBox::Cancel);
978 layout_->addWidget(button_box);
982 Q_EMIT setEnabled(
true);
990 ram_modify_trajectory::ScaleSelectedPoses srv;
998 srv.request.center_of_scaling.z = 0;
1017 "RViz panel " <<
getName().toStdString() <<
" connected to the service " << client.
getService());
1023 "RViz panel " <<
getName().toStdString() <<
" could not connect to ROS service: " << client.
getService());
1031 Q_EMIT setEnabled(
false);
1051 Q_EMIT setEnabled(
true);
1058 if (config.
mapGetInt(
"selection_mode", &tmp))
1073 const QString message,
1074 const QString info_msg)
1076 bool old_state(isEnabled());
1077 Q_EMIT setEnabled(
false);
1078 QMessageBox msg_box;
1079 msg_box.setWindowTitle(title);
1080 msg_box.setText(message);
1081 msg_box.setInformativeText(info_msg);
1082 msg_box.setIcon(QMessageBox::Critical);
1083 msg_box.setStandardButtons(QMessageBox::Ok);
1085 Q_EMIT setEnabled(old_state);
1090 ram_display::UpdateSelection srv_tmp_select;
1091 srv_tmp_select.request.temporary =
true;
1097 ram_modify_trajectory::GetPosesFromTrajectory srv;
1098 srv.request.pose_index_list = selection;
1100 srv_tmp_select.request.selected_poses = srv.response.poses;
1105 ram_modify_trajectory::GetPosesFromLayersList srv;
1106 srv.request.layer_level_list = selection;
1108 srv_tmp_select.request.selected_poses = srv.response.poses;
1115 ram_modify_trajectory::GetPosesFromLayer srv;
1116 srv.request.index_list_relative = selection;
1120 srv_tmp_select.request.selected_poses.clear();
1122 srv_tmp_select.request.selected_poses = srv.response.poses;
1127 for (
unsigned i(0); i < selection.size(); ++i)
1129 ram_modify_trajectory::GetPosesFromLayer srv;
1131 srv.request.layer_level = selection[i];
1134 srv_tmp_select.request.selected_poses.clear();
1140 srv_tmp_select.request.selected_poses.insert(srv_tmp_select.request.selected_poses.end(),
1141 srv.response.poses.begin(),
1142 srv.response.poses.end());
1150 ROS_ERROR_STREAM(
"Missing implementation in Modify Qt panel inside updateTemporarySelection");
1157 ROS_WARN_STREAM(
"Could not update temporary selection in Modify Qt panel");
QComboBox * movement_type_
QDoubleSpinBox * reflect_point_y_
std::vector< unsigned > getSelection()
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
QComboBox * feed_rate_abs_rel_
ros::ServiceClient modify_selected_poses_client_
QComboBox * polygon_start_
void selectionModeSelected()
QDoubleSpinBox * reflect_vector_y_
QDoubleSpinBox * reflect_point_x_
void changeGUIToRangeListSelection(const QString help_string, const unsigned min, const unsigned max)
void connectToService(ros::ServiceClient &client)
ros::ServiceClient reset_selected_poses_client_
void trajReceived(const ram_msgs::AdditiveManufacturingTrajectory::Ptr &msg)
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ros::ServiceClient update_selection_client_
QCheckBox * approach_type_modify_
ros::ServiceClient get_poses_from_trajectory_client_
QCheckBox * polygon_end_modify_
ModifyPoses * modify_poses_ui_
std::vector< unsigned > relative_indices_
void changeGUIToOperationSelection()
double speed_conversion_factor_
QDoubleSpinBox * rotation_point_y_
void changeGUIToRotatePoses()
bool call(MReq &req, MRes &res)
void propagateSelection()
std::mutex trajectory_mutex_
QComboBox * blend_radius_abs_rel_
void getPose(Eigen::Affine3d &pose)
void clearLayout(QLayout *layout, bool delete_widgets=true)
ros::ServiceClient get_poses_from_layer_client_
void mapSetValue(const QString &key, QVariant value)
QComboBox * approach_type_
Modify(QWidget *parent=NULL)
std::vector< unsigned > layers_to_propagate_
void changeGUIToReflectPoses()
void save(rviz::Config config) const
QVector< QRadioButton * > selection_buttons_
QCheckBox * movement_type_modify_
QDoubleSpinBox * scale_factor_
virtual void setName(const QString &name)
std::vector< QRadioButton * > operations_
void updateTemporarySelection(std::vector< unsigned > selection)
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
QDoubleSpinBox * feed_rate_
ros::ServiceClient get_trajectory_size_client_
QCheckBox * polygon_start_modify_
QCheckBox * laser_power_modify_
QCheckBox * feed_rate_modify_
QDoubleSpinBox * scale_center_y_
void displayErrorBoxHandler(const QString title, const QString message, const QString info_msg)
ros::ServiceClient scale_selected_poses_client_
ros::ServiceClient rotate_selected_poses_client_
QDoubleSpinBox * rotation_point_x_
virtual QString getName() const
void load(const rviz::Config &config)
void changeGUIToSelectionMode()
ros::ServiceClient get_number_of_layers_client_
#define ROS_WARN_STREAM(args)
void displayErrorMessageBox(const QString, const QString, const QString)
bool mapGetInt(const QString &key, int *value_out) const
std::vector< ram_msgs::AdditiveManufacturingPose > selected_poses_
void changeGUIToModifyPoses()
ros::ServiceClient get_layer_size_client_
#define ROS_INFO_STREAM(args)
QDialogButtonBox * button_box_
ros::ServiceClient reflect_selected_poses_client_
ros::ServiceClient get_poses_from_layers_list_client_
ros::ServiceClient add_poses_client_
ros::ServiceClient delete_selected_poses_client_
std::vector< QRadioButton * > geometric_operations_
virtual void save(Config config) const
QDoubleSpinBox * reflect_vector_x_
QCheckBox * blend_radius_modify_
void changeGUIToScalePoses()
#define ROS_ERROR_STREAM(args)
QDoubleSpinBox * rotation_angle_
virtual void load(const Config &config)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
QComboBox * laser_power_abs_rel_
QComboBox * speed_abs_rel_
QDialogButtonBox * button_box_
QDoubleSpinBox * scale_center_x_
QCheckBox * speed_modify_
QComboBox * pose_abs_rel_
ram_msgs::AdditiveManufacturingTrajectory trajectory_
ModifyRangeListSelection * range_list_selection_ui_