@@ -56,6 +56,7 @@ bool RuckigFilterPlugin::initialize(rclcpp::Node::SharedPtr node, moveit::core::
56
56
node_ = node;
57
57
num_joints_ = num_joints;
58
58
robot_model_ = robot_model;
59
+ have_initial_ruckig_output_ = false ;
59
60
60
61
// get node parameters and store in member variables
61
62
auto param_listener = online_signal_smoothing::ParamListener (node_);
@@ -67,9 +68,9 @@ bool RuckigFilterPlugin::initialize(rclcpp::Node::SharedPtr node, moveit::core::
67
68
ruckig_input.max_velocity = joint_velocity_bounds_;
68
69
ruckig_input.max_acceleration = joint_acceleration_bounds_;
69
70
ruckig_input.max_jerk = joint_jerk_bounds_;
70
- // initialize positions. All other quantities are initialized to zero in the constructor.
71
- // This will be overwritten in the first control loop
72
71
ruckig_input.current_position = std::vector<double >(num_joints_, 0.0 );
72
+ ruckig_input.current_velocity = std::vector<double >(num_joints_, 0.0 );
73
+ ruckig_input.current_acceleration = std::vector<double >(num_joints_, 0.0 );
73
74
ruckig_input_ = ruckig_input;
74
75
75
76
ruckig_output_.emplace (ruckig::OutputParameter<ruckig::DynamicDOFs>(num_joints_));
@@ -82,12 +83,68 @@ bool RuckigFilterPlugin::initialize(rclcpp::Node::SharedPtr node, moveit::core::
82
83
bool RuckigFilterPlugin::doSmoothing (Eigen::VectorXd& positions, Eigen::VectorXd& velocities,
83
84
Eigen::VectorXd& accelerations)
84
85
{
86
+ if (have_initial_ruckig_output_ && ruckig_input_ && ruckig_output_)
87
+ {
88
+ ruckig_output_->pass_to_input (*ruckig_input_);
89
+ }
90
+ // else
91
+ // {
92
+ // // Force a new calculation
93
+ // ruckig_.reset();
94
+ // }
95
+
96
+ // Update Ruckig target state
97
+ // This assumes stationary at the target (zero vel, zero accel)
98
+ std::cerr << " Updating target position" << std::endl;
99
+ ruckig_input_->target_position = std::vector<double >(positions.data (), positions.data () + positions.size ());
100
+
101
+ // Call the Ruckig algorithm
102
+ std::cerr << " State prior to ruckig_.update()" << std::endl;
103
+ printRuckigState ();
104
+ ruckig::Result ruckig_result = ruckig_->update (*ruckig_input_, *ruckig_output_);
105
+
106
+ // Finished means the target state can be reached in this timestep.
107
+ // Working means the target state can be reached but not in this timestep.
108
+ // ErrorSynchronizationCalculation means smoothing was successful but the robot will deviate a bit from the desired
109
+ // path.
110
+ // See https://github.com/pantor/ruckig/blob/master/include/ruckig/input_parameter.hpp
111
+ if (ruckig_result != ruckig::Result::Finished && ruckig_result != ruckig::Result::Working &&
112
+ ruckig_result != ruckig::Result::ErrorSynchronizationCalculation)
113
+
114
+ {
115
+ RCLCPP_ERROR_STREAM (getLogger (), " Ruckig jerk-limited smoothing failed with code: " << ruckig_result);
116
+ printRuckigState ();
117
+ // Return without modifying the position/vel/accel
118
+ have_initial_ruckig_output_ = false ;
119
+ return true ;
120
+ }
121
+
122
+ // Update the target state with Ruckig output
123
+ positions = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(ruckig_output_->new_position .data (),
124
+ ruckig_output_->new_position .size ());
125
+ velocities = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(ruckig_output_->new_velocity .data (),
126
+ ruckig_output_->new_velocity .size ());
127
+ accelerations = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(ruckig_output_->new_acceleration .data (),
128
+ ruckig_output_->new_acceleration .size ());
129
+ have_initial_ruckig_output_ = true ;
130
+
85
131
return true ;
86
132
}
87
133
88
134
bool RuckigFilterPlugin::reset (const Eigen::VectorXd& positions, const Eigen::VectorXd& velocities,
89
135
const Eigen::VectorXd& accelerations)
90
136
{
137
+ // Initialize Ruckig
138
+ std::cerr << " Setting the current position in reset()!" << std::endl;
139
+ ruckig_input_->current_position = std::vector<double >(positions.data (), positions.data () + positions.size ());
140
+ ruckig_input_->current_velocity = std::vector<double >(velocities.data (), velocities.data () + velocities.size ());
141
+ ruckig_input_->current_acceleration =
142
+ std::vector<double >(accelerations.data (), accelerations.data () + accelerations.size ());
143
+
144
+ std::cerr << ruckig_input_->current_acceleration [0 ] << " " << ruckig_input_->current_acceleration [1 ] << " "
145
+ << ruckig_input_->current_acceleration [2 ] << std::endl;
146
+
147
+ have_initial_ruckig_output_ = false ;
91
148
return true ;
92
149
}
93
150
@@ -121,12 +178,28 @@ void RuckigFilterPlugin::getDefaultJointVelAccelBounds()
121
178
joint_acceleration_bounds_.push_back (DBL_MAX);
122
179
}
123
180
124
- // MoveIt and the URDF don't support jerk limits, so use a safe default always
125
- joint_jerk_bounds_.push_back (DEFAULT_JERK_BOUND);
181
+ if (bound.jerk_bounded_ )
182
+ {
183
+ // Assume symmetric limits
184
+ joint_jerk_bounds_.push_back (bound.max_jerk_ );
185
+ }
186
+ else
187
+ {
188
+ RCLCPP_ERROR_STREAM (getLogger (), " WARNING: No joint jerk limit defined. A default jerk limit of "
189
+ << DEFAULT_JERK_BOUND << " rad/s^3 has been applied." );
190
+ joint_jerk_bounds_.push_back (DEFAULT_JERK_BOUND);
191
+ }
126
192
}
127
193
128
194
assert (joint_jerk_bounds_.size () == num_joints_);
129
195
}
196
+
197
+ void RuckigFilterPlugin::printRuckigState ()
198
+ {
199
+ RCLCPP_ERROR_STREAM (getLogger (), ruckig_->delta_time << " \n Ruckig input:\n "
200
+ << ruckig_input_->to_string () << " \n Ruckig output:\n "
201
+ << ruckig_output_->to_string ());
202
+ }
130
203
} // namespace online_signal_smoothing
131
204
132
205
#include < pluginlib/class_list_macros.hpp>
0 commit comments