@@ -115,16 +115,21 @@ PositionLimits compute_position_limits(
115115 : limits.max_velocity ;
116116 const double max_vel = std::min (limits.max_velocity , delta_vel);
117117 const double delta_pos = max_vel * dt;
118- // / @note: We use the previous command position to compute the limits here because using the
119- // / actual position would be too conservative, usually there is a couple of cycles of delay
120- // / between the command sent to the robot and the robot actually showing that in the state. That
121- // / effectively limits the velocity with which the joint can be moved which is much lower than
122- // / the actual velocity limit.
123- const double position_reference = prev_command_pos.value ();
124- pos_limits.lower_limit = std::max (
125- std::min (position_reference - delta_pos, pos_limits.upper_limit ), pos_limits.lower_limit );
126- pos_limits.upper_limit = std::min (
127- std::max (position_reference + delta_pos, pos_limits.lower_limit ), pos_limits.upper_limit );
118+ // / @note: We prefer the previous command position over actual position because using the actual
119+ // / position would be too conservative — there is typically a couple of cycles of delay between
120+ // / the command and the robot state. Fall back to actual position when no previous command
121+ // / exists (e.g., first position command after operating in another mode). Skip
122+ // / velocity-constrained narrowing entirely when neither reference is available.
123+ const std::optional<double > & pos_ref =
124+ prev_command_pos.has_value () ? prev_command_pos : act_pos;
125+ if (pos_ref.has_value ())
126+ {
127+ const double position_reference = pos_ref.value ();
128+ pos_limits.lower_limit = std::max (
129+ std::min (position_reference - delta_pos, pos_limits.upper_limit ), pos_limits.lower_limit );
130+ pos_limits.upper_limit = std::min (
131+ std::max (position_reference + delta_pos, pos_limits.lower_limit ), pos_limits.upper_limit );
132+ }
128133 }
129134 internal::check_and_swap_limits (pos_limits.lower_limit , pos_limits.upper_limit );
130135 return pos_limits;
0 commit comments