3 #include <play_motion_builder_msgs/ListJointGroups.h> 4 #include <play_motion_builder_msgs/ChangeJoints.h> 7 #include <QRadioButton> 9 #include <QInputDialog> 13 #define JOINT_PRECISION 4 14 #define TIME_PRECISION 2 25 :
rqt_gui_cpp::Plugin(), widget_(0), editing_(false), updating_list_(false), editing_motion_(
"")
27 setObjectName(
"RQTPlayMotionBuilder");
38 QWidget *g_scroll_w =
new QWidget();
39 QVBoxLayout *g_scroll_l =
new QVBoxLayout();
40 g_scroll_w->setLayout(g_scroll_l);
41 ui_.group_area_->setWidget(g_scroll_w);
42 ui_.group_area_->setWidgetResizable(
true);
44 QWidget *scroll_w =
new QWidget();
45 QVBoxLayout *scroll_l =
new QVBoxLayout();
46 scroll_w->setLayout(scroll_l);
47 ui_.joint_area_->setWidget(scroll_w);
48 ui_.joint_area_->setWidgetResizable(
true);
59 connect(
ui_.movement_table_, SIGNAL(cellChanged(
int,
int)),
this,
63 ui_.movement_table_->setContextMenuPolicy(Qt::CustomContextMenu);
72 connect(
ui_.movement_table_, SIGNAL(customContextMenuRequested(
const QPoint &)),
this,
91 "/play_motion_builder_node/list_joint_groups");
93 "/play_motion_builder_node/edit_motion");
95 "/play_motion_builder_node/change_joints");
115 play_motion_builder_msgs::BuildMotionGoal goal;
121 play_motion_builder_msgs::ListJointGroups ljg_service;
124 qDeleteAll(
ui_.group_area_->widget()->findChildren<QWidget *>());
126 for (
const auto &group : ljg_service.response.groups)
129 QRadioButton *jsc =
new QRadioButton();
130 jsc->setChecked(
false);
131 jsc->setProperty(
"group_name", QString::fromStdString(group));
132 connect(jsc, SIGNAL(toggled(
bool)),
this, SLOT(
onGroupToggled(
bool)));
133 jsc->setText(QString::fromStdString(group));
134 ui_.group_area_->widget()->layout()->addWidget(jsc);
137 qDeleteAll(
ui_.joint_area_->widget()->findChildren<QWidget *>());
138 for (
const auto &joint : ljg_service.response.additional_joints)
141 QCheckBox *jsc =
new QCheckBox();
142 jsc->setChecked(
false);
143 jsc->setProperty(
"joint_name", QString::fromStdString(joint));
144 connect(jsc, SIGNAL(toggled(
bool)),
this, SLOT(
onJointToggled(
bool)));
145 jsc->setText(QString::fromStdString(joint));
146 ui_.joint_area_->widget()->layout()->addWidget(jsc);
150 play_motion_builder_msgs::EditMotion em;
151 em.request.action = play_motion_builder_msgs::EditMotion::Request::LIST;
178 for (
auto &group :
ui_.group_area_->widget()->findChildren<QRadioButton *>())
180 if (group->property(
"group_name").toString().toStdString() == motion.used_group)
183 group->setChecked(
true);
190 ui_.movement_table_->setColumnCount(motion.joints.size() + 1);
193 headers << QString(
"Time");
194 for (
const auto &joint : motion.joints)
196 headers << QString::fromStdString(joint.substr(0, joint.size() - 6));
199 ui_.movement_table_->setHorizontalHeaderLabels(headers);
201 ui_.movement_table_->setRowCount(0);
204 for (
auto &extra_joint :
ui_.joint_area_->widget()->findChildren<QCheckBox *>())
206 if (std::find(motion.joints.begin(), motion.joints.end(),
207 extra_joint->property(
"joint_name").toString().toStdString()) !=
210 extra_joint->setChecked(
true);
212 << extra_joint->property(
"joint_name").toString().toStdString());
216 ui_.movement_table_->setRowCount(motion.keyframes.size());
217 for (
unsigned int i = 0; i < motion.keyframes.size(); ++i)
221 QTableWidgetItem *time_item =
222 new QTableWidgetItem(QString::number(motion.keyframes[i].time_from_last,
'f', 2));
223 ui_.movement_table_->setItem(i, 0, time_item);
227 for (
int j = 1; j <
ui_.movement_table_->columnCount(); ++j)
230 QTableWidgetItem *joint_position_item =
new QTableWidgetItem(QString::number(
232 ui_.movement_table_->horizontalHeaderItem(j)->text().toStdString()),
234 joint_position_item->setFlags(joint_position_item->flags() ^ Qt::ItemIsEditable);
236 ui_.movement_table_->setItem(i, j, joint_position_item);
246 play_motion_builder_msgs::EditMotion em;
247 em.request.action = play_motion_builder_msgs::EditMotion::Request::LIST;
268 ui_.play_btn_->setText(
"Play");
269 ui_.play_btn_->setEnabled(
true);
270 ui_.downshift_->setEnabled(
true);
271 ui_.capture_btn_->setEnabled(
true);
272 ui_.save_btn_->setEnabled(
true);
277 ui_.play_btn_->setText(
"Stop");
278 ui_.downshift_->setEnabled(
false);
279 ui_.capture_btn_->setEnabled(
false);
280 ui_.save_btn_->setEnabled(
false);
284 const play_motion_builder_msgs::RunMotionResultConstPtr &)
290 const std::vector<double> &poses,
291 const std::string &joint_header)
293 for (
unsigned int i = 0; i < joints.size(); ++i)
295 if (joints[i] == joint_header +
"_joint")
310 QMessageBox::critical(
widget_, tr(
"Error"), tr(
"Could not load motions from ROS."));
314 for (
auto it : param)
316 motions << tr(it.first.c_str());
320 QString motion = QInputDialog::getItem(
widget_, tr(
"Load a motion"), tr(
"Motion:"),
321 motions, 0,
false, &ok);
323 if (ok && !motion.isEmpty())
331 play_motion_builder_msgs::BuildMotionGoal goal;
332 goal.motion = motion.toStdString();
338 play_motion_builder_msgs::ListJointGroups ljg_service;
342 qDeleteAll(
ui_.group_area_->widget()->findChildren<QWidget *>());
343 for (
const auto &group : ljg_service.response.groups)
345 QRadioButton *jsc =
new QRadioButton();
346 jsc->setChecked(
false);
347 jsc->setProperty(
"group_name", QString::fromStdString(group));
348 connect(jsc, SIGNAL(toggled(
bool)),
this, SLOT(
onGroupToggled(
bool)));
349 jsc->setText(QString::fromStdString(group));
350 ui_.group_area_->widget()->layout()->addWidget(jsc);
354 qDeleteAll(
ui_.joint_area_->widget()->findChildren<QWidget *>());
355 for (
const auto &joint : ljg_service.response.additional_joints)
357 QCheckBox *jsc =
new QCheckBox();
358 jsc->setChecked(
false);
359 jsc->setProperty(
"joint_name", QString::fromStdString(joint));
360 connect(jsc, SIGNAL(toggled(
bool)),
this, SLOT(
onJointToggled(
bool)));
361 jsc->setText(QString::fromStdString(joint));
362 ui_.joint_area_->widget()->layout()->addWidget(jsc);
366 play_motion_builder_msgs::EditMotion em;
367 em.request.action = play_motion_builder_msgs::EditMotion::Request::LIST;
391 play_motion_builder_msgs::EditMotion em;
392 em.request.action = play_motion_builder_msgs::EditMotion::Request::APPEND;
406 ROS_ERROR_STREAM(
"Error calling the edit_motion service to append keyframe");
414 play_motion_builder_msgs::RunMotionGoal goal;
415 goal.run_mode = play_motion_builder_msgs::RunMotionGoal::RUN_MOTION;
416 goal.downshift =
ui_.downshift_->value();
440 static_cast<std::string>(param[
"usage"]),
441 static_cast<std::string>(param[
"description"]));
453 QTableWidgetItem *clicked =
ui_.movement_table_->itemAt(point);
456 int row = clicked->row();
459 QAction *selectedItem =
table_menu_.exec(QCursor::pos());
462 ROS_DEBUG_STREAM(
"Item selected is " << selectedItem->text().toStdString());
464 if (selectedItem->text().toStdString() ==
GOTO_MENU)
468 else if (selectedItem->text().toStdString() ==
DELETE_MENU)
486 ROS_ERROR_STREAM(
"Selected unknown menu " << selectedItem->text().toStdString());
493 play_motion_builder_msgs::RunMotionGoal goal;
494 goal.run_mode = play_motion_builder_msgs::RunMotionGoal::GO_TO_STEP;
495 goal.step_id = frame;
504 play_motion_builder_msgs::EditMotion em;
505 em.request.action = play_motion_builder_msgs::EditMotion::Request::REMOVE;
506 em.request.step_id = frame;
525 play_motion_builder_msgs::EditMotion em;
526 em.request.action = play_motion_builder_msgs::EditMotion::Request::EDIT;
527 em.request.step_id = frame;
546 play_motion_builder_msgs::EditMotion em;
547 em.request.action = play_motion_builder_msgs::EditMotion::Request::COPY_AS_NEXT;
548 em.request.step_id = frame;
567 play_motion_builder_msgs::EditMotion em;
568 em.request.action = play_motion_builder_msgs::EditMotion::Request::COPY_AS_LAST;
569 em.request.step_id = frame;
583 ROS_ERROR_STREAM(
"Error calling the edit_motion service to copy-as-last keyframe");
591 QString group = sender()->property(
"group_name").toString();
594 play_motion_builder_msgs::ChangeJoints cj;
595 cj.request.group = group.toStdString();
609 ROS_ERROR_STREAM(
"Error calling the edit_motion service to copy-as-last keyframe");
618 QString joint = sender()->property(
"joint_name").toString();
620 << (state ?
"active" :
"inactive"));
622 play_motion_builder_msgs::ChangeJoints cj;
624 cj.request.joints_to_add.push_back(joint.toStdString());
626 cj.request.joints_to_remove.push_back(joint.toStdString());
641 ROS_ERROR_STREAM(
"Error calling the edit_motion service to copy-as-last keyframe");
651 play_motion_builder_msgs::EditMotion em;
652 em.request.action = play_motion_builder_msgs::EditMotion::Request::EDIT_TIME;
653 em.request.step_id = row;
654 em.request.time =
ui_.movement_table_->item(row, col)->text().toDouble();
669 ROS_ERROR_STREAM(
"Error calling the edit_motion service to copy-as-last keyframe");
void loadMotion(const play_motion_builder_msgs::Motion &motion)
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
ros::ServiceClient edit_motion_client_
void copyLastSelected(int row)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val)
std::unique_ptr< BMAC > builder_client_
ros::NodeHandle & getNodeHandle() const
static const std::string DELETE_MENU
void init(ros::NodeHandle &nh)
bool call(MReq &req, MRes &res)
actionlib::SimpleActionClient< play_motion_builder_msgs::RunMotionAction > RMAC
static const std::string COPY_LAST_MENU
void addWidget(QWidget *widget)
void onCopyLastSelected(int frame)
void onGroupToggled(bool state)
actionlib::SimpleActionClient< play_motion_builder_msgs::BuildMotionAction > BMAC
virtual void initPlugin(qt_gui_cpp::PluginContext &context) override
std::unique_ptr< RMAC > run_motion_client_
ros::ServiceClient change_joints_client_
void onSetToCurrentSelected(int frame)
void setToCurrentSelected(int row)
void onGotoSelected(int frame)
void onJointToggled(bool state)
void onMotionStored(QString motion_name)
Type const & getType() const
void goToSelected(int row)
ros::ServiceClient list_joints_client_
bool getParam(const std::string &key, std::string &s) const
virtual void shutdownPlugin() override
void runDone(const actionlib::SimpleClientGoalState &state, const play_motion_builder_msgs::RunMotionResultConstPtr &result)
void onContextMenuRequested(const QPoint &point)
double getJointPosition(const std::vector< std::string > &joints, const std::vector< double > &poses, const std::string &joint_header)
#define ROS_DEBUG_STREAM(args)
static const std::string SET_TO_CURRENT_MENU
void deleteSelected(int row)
void loadYamlName(const std::string &yaml_name)
#define ROS_INFO_STREAM(args)
void onCopyBelowSelected(int frame)
static const std::string GOTO_MENU
std::string editing_motion_
void onDeleteSelected(int frame)
void onCellChanged(int row, int col)
#define ROS_ERROR_STREAM(args)
static const std::string COPY_BELOW_MENU
void loadMeta(const std::string &name, const std::string &usage, const std::string &description)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
MotionProperties * properties_dialog_
void copyBelowSelected(int row)