Skip to content

Commit

Permalink
Add radio buttons to switch degrees/radians in MotionPlanning's Joint…
Browse files Browse the repository at this point in the history
…s tab (moveit#3516)

Co-authored-by: Robert Haschke <[email protected]>
  • Loading branch information
aaryanmurgunde and rhaschke authored Nov 12, 2023
1 parent 942abef commit 979ef6a
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ class MotionPlanningFrameJointsWidget : public QWidget
const robot_interaction::InteractionHandlerPtr& start_state_handler,
const robot_interaction::InteractionHandlerPtr& goal_state_handler);

bool useRadians() const;
void setUseRadians(bool use_radians);

Q_SIGNALS:
void configChanged();

public Q_SLOTS:
void queryStartStateChanged();
void queryGoalStateChanged();
Expand Down Expand Up @@ -171,13 +177,24 @@ class ProgressBarDelegate : public QStyledItemDelegate
JointTypeRole = Qt::UserRole, // NOLINT(readability-identifier-naming)
VariableBoundsRole // NOLINT(readability-identifier-naming)
};
enum RevoluteUnit
{
DEGREES = 0,
RADIANS = 1,
};

ProgressBarDelegate(QWidget* parent = nullptr) : QStyledItemDelegate(parent)
ProgressBarDelegate(QWidget* parent = nullptr) : QStyledItemDelegate(parent), unit_(DEGREES)
{
}

void setUnit(RevoluteUnit unit)
{
unit_ = unit;
}
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;

RevoluteUnit unit_;
};

/// Slider that jumps back to zero
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,8 @@ void MotionPlanningDisplay::load(const rviz::Config& config)
frame_->ui_->collision_aware_ik->setChecked(b);
if (config.mapGetBool("MoveIt_Allow_Approximate_IK", &b))
frame_->ui_->approximate_ik->setChecked(b);
if (config.mapGetBool("JointsTab_Use_Radians", &b))
frame_->joints_tab_->setUseRadians(true);

rviz::Config workspace = config.mapGetChild("MoveIt_Workspace");
rviz::Config ws_center = workspace.mapGetChild("Center");
Expand Down Expand Up @@ -1413,6 +1415,7 @@ void MotionPlanningDisplay::save(rviz::Config config) const
config.mapSetValue("MoveIt_Use_Cartesian_Path", frame_->ui_->use_cartesian_path->isChecked());
config.mapSetValue("MoveIt_Use_Constraint_Aware_IK", frame_->ui_->collision_aware_ik->isChecked());
config.mapSetValue("MoveIt_Allow_Approximate_IK", frame_->ui_->approximate_ik->isChecked());
config.mapSetValue("JointsTab_Use_Radians", frame_->joints_tab_->useRadians());

rviz::Config workspace = config.mapMakeChild("MoveIt_Workspace");
rviz::Config ws_center = workspace.mapMakeChild("Center");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,12 @@ MotionPlanningFrame::MotionPlanningFrame(MotionPlanningDisplay* pdisplay, rviz::

connect(ui_->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));

/* Notice changes to be safed in config file */
/* Notice changes to be saved in config file */
connect(ui_->database_host, SIGNAL(textChanged(QString)), this, SIGNAL(configChanged()));
connect(ui_->database_port, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));

connect(joints_tab_, SIGNAL(configChanged()), this, SIGNAL(configChanged()));

connect(ui_->planning_time, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(ui_->planning_attempts, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(ui_->velocity_scaling_factor, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,23 @@ MotionPlanningFrameJointsWidget::MotionPlanningFrameJointsWidget(MotionPlanningD
ui_->joints_view_->viewport()->installEventFilter(new JointsWidgetEventFilter(ui_->joints_view_));
// intercept keyboard events delivered to joints_view_ to operate joints directly
ui_->joints_view_->installEventFilter(new JointsWidgetEventFilter(ui_->joints_view_));
ui_->joints_view_->setItemDelegateForColumn(1, new ProgressBarDelegate(this));

auto delegate = new ProgressBarDelegate(this);
ui_->button_group_units_->setId(ui_->radio_degree_, ProgressBarDelegate::DEGREES);
ui_->button_group_units_->setId(ui_->radio_radian_, ProgressBarDelegate::RADIANS);
connect(ui_->button_group_units_, QOverload<QAbstractButton*, bool>::of(&QButtonGroup::buttonToggled),
ui_->joints_view_, [delegate, this](QAbstractButton* button, bool checked) {
if (checked)
{
delegate->setUnit(static_cast<ProgressBarDelegate::RevoluteUnit>(ui_->button_group_units_->id(button)));
// trigger repaint of joint values
auto model = ui_->joints_view_->model();
if (model) // during initial loading, the model is not yet set
ui_->joints_view_->dataChanged(model->index(0, 1), model->index(model->rowCount() - 1, 1));
Q_EMIT configChanged();
}
});
ui_->joints_view_->setItemDelegateForColumn(1, delegate);
svd_.setThreshold(0.001);
}

Expand All @@ -201,6 +217,15 @@ MotionPlanningFrameJointsWidget::~MotionPlanningFrameJointsWidget()
delete ui_;
}

bool MotionPlanningFrameJointsWidget::useRadians() const
{
return ui_->radio_radian_->isChecked();
}
void MotionPlanningFrameJointsWidget::setUseRadians(bool use_radians)
{
ui_->radio_radian_->setChecked(use_radians);
}

void MotionPlanningFrameJointsWidget::clearRobotModel()
{
ui_->joints_view_->setModel(nullptr);
Expand Down Expand Up @@ -417,7 +442,10 @@ void ProgressBarDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
switch (joint_type.toInt())
{
case moveit::core::JointModel::REVOLUTE:
style_option.text = option.locale.toString(value * 180 / M_PI, 'f', 0).append("°");
if (unit_ == RADIANS)
style_option.text = option.locale.toString(value, 'f', 3);
else
style_option.text = option.locale.toString(value * 180 / M_PI, 'f', 0).append("°");
break;
case moveit::core::JointModel::PRISMATIC:
style_option.text = option.locale.toString(value, 'f', 3).append("m");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="joints_layout_">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="joints_view_label_">
<property name="text">
Expand All @@ -24,68 +24,107 @@
</widget>
</item>
<item>
<widget class="QTreeView" name="joints_view_">
<property name="editTriggers">
<set>QAbstractItemView::EditKeyPressed</set>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="radio_degree_">
<property name="text">
<string>degree</string>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">button_group_units_</string>
</attribute>
</widget>
</item>
<item>
<widget class="QLabel" name="nullspace_label">
<property name="toolTip">
<string>The sliders below allow for jogging the nullspace of the current configuration,
<widget class="QRadioButton" name="radio_radian_">
<property name="text">
<string>radian</string>
</property>
<attribute name="buttonGroup">
<string notr="true">button_group_units_</string>
</attribute>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="joints_view_">
<property name="editTriggers">
<set>QAbstractItemView::EditKeyPressed</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="nullspace_label">
<property name="toolTip">
<string>The sliders below allow for jogging the nullspace of the current configuration,
i.e. trigger joint motions that don't affect the end-effector pose.

Typically, redundant arms (with 7+ joints) offer such a nullspace.
However, also singular configurations provide a nullspace.

Each basis vector of the (linear) nullspace is represented by a separate slider.</string>
</property>
<property name="text">
<string>Nullspace exploration:</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="nullspace_layout_">
<item>
<widget class="QSlider" name="dummy_ns_slider_">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Nullspace exploration:</string>
<property name="toolTip">
<string>The slider will become active if the current robot configuration has a nullspace.
That's typically the case for redundant robots, i.e. 7+ joints, or singular configurations.</string>
</property>
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="nullspace_layout_">
<item>
<widget class="QSlider" name="dummy_ns_slider_">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>The slider will become active if the current robot configuration has a nullspace.
That's typically the case for redundant robots, i.e. 7+ joints, or singular configurations.</string>
</property>
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
<buttongroups>
<buttongroup name="button_group_units_"/>
</buttongroups>
</ui>

0 comments on commit 979ef6a

Please sign in to comment.