@@ -177,21 +177,24 @@ void JointSaturationLimiter<trajectory_msgs::msg::JointTrajectoryPoint>::clamp_j
177177
178178 for (size_t index = 0 ; index < number_of_joints_; ++index)
179179 {
180+ auto clamp_pos_limit = [&]()
181+ {
182+ auto pos = std::clamp (
183+ desired_pos_[index], joint_limits_[index].min_position , joint_limits_[index].max_position );
184+ if (pos != desired_pos_[index])
185+ {
186+ desired_pos_[index] = pos;
187+ pos_limit_hit_[index] = true ;
188+ limits_enforced = true ;
189+ }
190+ };
191+
180192 if (has_desired_position)
181193 {
182194 // limit position
183195 if (joint_limits_[index].has_position_limits )
184196 {
185- // clamp input pos_cmd
186- auto pos = std::clamp (
187- desired_pos_[index], joint_limits_[index].min_position ,
188- joint_limits_[index].max_position );
189- if (pos != desired_pos_[index])
190- {
191- desired_pos_[index] = pos;
192- pos_limit_hit_[index] = true ;
193- limits_enforced = true ;
194- }
197+ clamp_pos_limit ();
195198 }
196199 // priority to pos_cmd derivative over cmd_vel when not defined. If done always then we might
197200 // get jumps in the velocity based on the system's dynamics. Position limit clamping is done
@@ -206,6 +209,23 @@ void JointSaturationLimiter<trajectory_msgs::msg::JointTrajectoryPoint>::clamp_j
206209 }
207210 }
208211
212+ auto clamp_vel_limit = [&]()
213+ {
214+ desired_vel_[index] = std::copysign (joint_limits_[index].max_velocity , desired_vel_[index]);
215+ vel_limit_hit_[index] = true ;
216+ limits_enforced = true ;
217+
218+ // recompute pos_cmd if needed
219+ if (has_desired_position)
220+ {
221+ desired_pos_[index] =
222+ current_joint_states.positions [index] + desired_vel_[index] * dt_seconds;
223+ clamp_pos_limit ();
224+ }
225+
226+ desired_acc_[index] = (desired_vel_[index] - current_joint_velocities[index]) / dt_seconds;
227+ };
228+
209229 // limit velocity
210230 if (joint_limits_[index].has_velocity_limits )
211231 {
@@ -219,18 +239,7 @@ void JointSaturationLimiter<trajectory_msgs::msg::JointTrajectoryPoint>::clamp_j
219239 // clamp input vel_cmd
220240 if (std::fabs (desired_vel_[index]) > joint_limits_[index].max_velocity )
221241 {
222- desired_vel_[index] = std::copysign (joint_limits_[index].max_velocity , desired_vel_[index]);
223- vel_limit_hit_[index] = true ;
224- limits_enforced = true ;
225-
226- // recompute pos_cmd if needed
227- if (has_desired_position)
228- {
229- desired_pos_[index] =
230- current_joint_states.positions [index] + desired_vel_[index] * dt_seconds;
231- }
232-
233- desired_acc_[index] = (desired_vel_[index] - current_joint_velocities[index]) / dt_seconds;
242+ clamp_vel_limit ();
234243 }
235244 }
236245
@@ -313,34 +322,12 @@ void JointSaturationLimiter<trajectory_msgs::msg::JointTrajectoryPoint>::clamp_j
313322 }
314323 }
315324
316- // Re-clamp velocity if it exceeds the max velocity
317- auto post_velocity_check_and_clamp = [&](size_t joint_index) -> bool
318- {
319- // Clamp velocity to max allowed
320- desired_vel_[joint_index] =
321- std::copysign (joint_limits_[joint_index].max_velocity , desired_vel_[joint_index]);
322- vel_limit_hit_[joint_index] = true ;
323-
324- // Recalculate acceleration based on clamped velocity
325- desired_acc_[joint_index] =
326- (desired_vel_[joint_index] - current_joint_velocities[joint_index]) / dt_seconds;
327-
328- // Update position if needed
329- if (has_desired_position)
330- {
331- desired_pos_[joint_index] =
332- current_joint_states.positions [joint_index] + desired_vel_[joint_index] * dt_seconds;
333- }
334-
335- return true ; // Indicates a limit was enforced
336- };
337-
338325 // Check if joint velocity exceeds max velocity
339326 if (
340327 joint_limits_[index].has_velocity_limits &&
341328 std::fabs (desired_vel_[index]) > joint_limits_[index].max_velocity )
342329 {
343- limits_enforced = post_velocity_check_and_clamp (index );
330+ clamp_vel_limit ( );
344331 }
345332
346333 // Limit jerk
@@ -384,7 +371,7 @@ void JointSaturationLimiter<trajectory_msgs::msg::JointTrajectoryPoint>::clamp_j
384371 joint_limits_[index].has_velocity_limits &&
385372 std::fabs (desired_vel_[index]) > joint_limits_[index].max_velocity )
386373 {
387- limits_enforced = post_velocity_check_and_clamp (index );
374+ clamp_vel_limit ( );
388375 }
389376
390377 // Re-check acceleration and deceleration
@@ -450,6 +437,12 @@ void JointSaturationLimiter<trajectory_msgs::msg::JointTrajectoryPoint>::clamp_j
450437 }
451438 }
452439
440+ // Re-clamp desired position after acceleration/jerk may have recomputed it
441+ if (has_desired_position && joint_limits_[index].has_position_limits )
442+ {
443+ clamp_pos_limit ();
444+ }
445+
453446 // plan ahead for position limits
454447 if (joint_limits_[index].has_position_limits )
455448 {
0 commit comments