Skip to content

Commit 3ec4a18

Browse files
committed
Optional jerk bounds
1 parent b355602 commit 3ec4a18

File tree

3 files changed

+67
-21
lines changed

3 files changed

+67
-21
lines changed

moveit_core/online_signal_smoothing/include/moveit/online_signal_smoothing/ruckig_filter.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ class RuckigFilterPlugin : public SmoothingBaseClass
8989

9090
/**
9191
* A utility to get velocity/acceleration/jerk bounds from the robot model
92+
* @return true if all bounds are defined
9293
*/
93-
void getVelAccelJerkBounds();
94+
bool getVelAccelJerkBounds();
9495

9596
rclcpp::Node::SharedPtr node_;
9697
/** \brief Parameters loaded from yaml file at runtime */
@@ -105,6 +106,6 @@ class RuckigFilterPlugin : public SmoothingBaseClass
105106

106107
std::vector<double> joint_velocity_bounds_;
107108
std::vector<double> joint_acceleration_bounds_;
108-
std::vector<double> joint_jerk_bounds_;
109+
std::optional<std::vector<double>> joint_jerk_bounds_;
109110
};
110111
} // namespace online_signal_smoothing

moveit_core/online_signal_smoothing/src/ruckig_filter.cpp

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ rclcpp::Logger getLogger()
4747
{
4848
return moveit::getLogger("moveit.core.ruckig_filter_plugin");
4949
}
50-
inline constexpr double DEFAULT_JERK_BOUND = 300; // rad/s^3
5150
} // namespace
5251

5352
bool RuckigFilterPlugin::initialize(rclcpp::Node::SharedPtr node, moveit::core::RobotModelConstPtr robot_model,
@@ -62,15 +61,25 @@ bool RuckigFilterPlugin::initialize(rclcpp::Node::SharedPtr node, moveit::core::
6261
auto param_listener = online_signal_smoothing::ParamListener(node_);
6362
params_ = param_listener.get_params();
6463

65-
// Ruckig needs the joint vel/accel/jerk bounds.
64+
// Ruckig needs the joint vel/accel bounds, jerk bounds are optional
6665
getVelAccelJerkBounds();
6766
ruckig::InputParameter<ruckig::DynamicDOFs> ruckig_input(num_joints_);
6867
ruckig_input.max_velocity = joint_velocity_bounds_;
6968
ruckig_input.max_acceleration = joint_acceleration_bounds_;
70-
ruckig_input.max_jerk = joint_jerk_bounds_;
7169
ruckig_input.current_position = std::vector<double>(num_joints_, 0.0);
7270
ruckig_input.current_velocity = std::vector<double>(num_joints_, 0.0);
7371
ruckig_input.current_acceleration = std::vector<double>(num_joints_, 0.0);
72+
73+
// These quantities can be omitted if jerk limits are not applied
74+
if (joint_jerk_bounds_)
75+
{
76+
ruckig_input.max_jerk = *joint_jerk_bounds_;
77+
}
78+
else
79+
{
80+
ruckig_input.max_jerk = std::vector<double>(num_joints_, 0.0);
81+
}
82+
7483
ruckig_input_ = ruckig_input;
7584

7685
ruckig_output_.emplace(ruckig::OutputParameter<ruckig::DynamicDOFs>(num_joints_));
@@ -83,14 +92,33 @@ bool RuckigFilterPlugin::initialize(rclcpp::Node::SharedPtr node, moveit::core::
8392
bool RuckigFilterPlugin::doSmoothing(Eigen::VectorXd& positions, Eigen::VectorXd& velocities,
8493
Eigen::VectorXd& accelerations)
8594
{
86-
if (have_initial_ruckig_output_ && ruckig_input_ && ruckig_output_)
95+
if (have_initial_ruckig_output_)
8796
{
88-
ruckig_output_->pass_to_input(*ruckig_input_);
97+
if (joint_jerk_bounds_)
98+
{
99+
ruckig_output_->pass_to_input(*ruckig_input_);
100+
}
101+
else
102+
{
103+
ruckig_input_->current_position = ruckig_output_->new_position;
104+
ruckig_input_->current_velocity = ruckig_output_->new_velocity;
105+
}
106+
}
107+
else
108+
{
109+
// TODO
110+
;
89111
}
90112

91113
// Update Ruckig target state
92114
// This assumes stationary at the target (zero vel, zero accel)
93115
ruckig_input_->target_position = std::vector<double>(positions.data(), positions.data() + positions.size());
116+
ruckig_input_->target_velocity = std::vector<double>(num_joints_, 0);
117+
ruckig_input_->target_acceleration = std::vector<double>(num_joints_, 0);
118+
if (!joint_jerk_bounds_)
119+
{
120+
ruckig_input_->current_acceleration = std::vector<double>(num_joints_, 0.0);
121+
}
94122

95123
// Call the Ruckig algorithm
96124
ruckig::Result ruckig_result = ruckig_->update(*ruckig_input_, *ruckig_output_);
@@ -129,16 +157,21 @@ bool RuckigFilterPlugin::reset(const Eigen::VectorXd& positions, const Eigen::Ve
129157
// Initialize Ruckig
130158
ruckig_input_->current_position = std::vector<double>(positions.data(), positions.data() + positions.size());
131159
ruckig_input_->current_velocity = std::vector<double>(velocities.data(), velocities.data() + velocities.size());
132-
ruckig_input_->current_acceleration =
133-
std::vector<double>(accelerations.data(), accelerations.data() + accelerations.size());
160+
if (joint_jerk_bounds_)
161+
{
162+
ruckig_input_->current_acceleration =
163+
std::vector<double>(accelerations.data(), accelerations.data() + accelerations.size());
164+
}
134165

135166
have_initial_ruckig_output_ = false;
136167
return true;
137168
}
138169

139-
void RuckigFilterPlugin::getVelAccelJerkBounds()
170+
bool RuckigFilterPlugin::getVelAccelJerkBounds()
140171
{
141172
auto joint_model_group = robot_model_->getJointModelGroup(params_.planning_group_name);
173+
bool have_all_jerk_bounds = true;
174+
std::vector<double> jerk_bounds;
142175
for (const auto& joint : joint_model_group->getActiveJointModels())
143176
{
144177
const auto& bound = joint->getVariableBounds(joint->getName());
@@ -169,17 +202,26 @@ void RuckigFilterPlugin::getVelAccelJerkBounds()
169202
if (bound.jerk_bounded_)
170203
{
171204
// Assume symmetric limits
172-
joint_jerk_bounds_.push_back(bound.max_jerk_);
205+
jerk_bounds.push_back(bound.max_jerk_);
173206
}
207+
// else, joint_jerk_bounds_ will be a std::nullopt and Ruckig doesn't apply jerk limits
174208
else
175209
{
176-
RCLCPP_ERROR_STREAM(getLogger(), "WARNING: No joint jerk limit defined. A default jerk limit of "
177-
<< DEFAULT_JERK_BOUND << " rad/s^3 has been applied.");
178-
joint_jerk_bounds_.push_back(DEFAULT_JERK_BOUND);
210+
have_all_jerk_bounds = false;
179211
}
180212
}
181213

182-
assert(joint_jerk_bounds_.size() == num_joints_);
214+
if (!have_all_jerk_bounds)
215+
{
216+
joint_jerk_bounds_ = std::nullopt;
217+
RCLCPP_WARN(getLogger(), "No joint jerk limit was defined. The output from Ruckig will not be jerk-limited.");
218+
}
219+
else
220+
{
221+
joint_jerk_bounds_ = jerk_bounds;
222+
}
223+
224+
return true;
183225
}
184226

185227
void RuckigFilterPlugin::printRuckigState()

moveit_ros/moveit_servo/src/servo.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -646,14 +646,17 @@ std::optional<PoseCommand> Servo::toPlanningFrame(const PoseCommand& command, co
646646

647647
KinematicState Servo::getCurrentRobotState(bool block_for_current_state) const
648648
{
649-
bool have_current_state = false;
650-
while (rclcpp::ok() && !have_current_state)
649+
if (block_for_current_state)
651650
{
652-
have_current_state = planning_scene_monitor_->getStateMonitor()->waitForCurrentState(
653-
rclcpp::Clock(RCL_ROS_TIME).now(), ROBOT_STATE_WAIT_TIME /* s */);
654-
if (!have_current_state)
651+
bool have_current_state = false;
652+
while (rclcpp::ok() && !have_current_state)
655653
{
656-
RCLCPP_WARN(logger_, "Waiting for the current state");
654+
have_current_state = planning_scene_monitor_->getStateMonitor()->waitForCurrentState(
655+
rclcpp::Clock(RCL_ROS_TIME).now(), ROBOT_STATE_WAIT_TIME /* s */);
656+
if (!have_current_state)
657+
{
658+
RCLCPP_WARN(logger_, "Waiting for the current state");
659+
}
657660
}
658661
}
659662
moveit::core::RobotStatePtr robot_state = planning_scene_monitor_->getStateMonitor()->getCurrentState();

0 commit comments

Comments
 (0)