153 const joint_limits_interface::JointLimits& limits,
154 const joint_limits_interface::SoftJointLimits& soft_limits)
155 : hjh_(hjh), limits_(limits), soft_limits_(soft_limits)
157 if (!limits.has_velocity_limits)
159 throw joint_limits_interface::JointLimitsInterfaceException(
"Cannot enforce limits for joint '" + getName() +
160 "'. It has no velocity limits specification.");
162 if (!limits.has_effort_limits)
164 throw joint_limits_interface::JointLimitsInterfaceException(
"Cannot enforce limits for joint '" + getName() +
165 "'. It has no effort limits specification.");
182 using joint_limits_interface::internal::saturate;
186 double pos = hjh_.getPosition();
187 double vel = hjh_.getVelocity();
190 double soft_min_vel{};
191 double soft_max_vel{};
193 if (limits_.has_position_limits)
196 soft_min_vel = saturate(-soft_limits_.k_position * (pos - soft_limits_.min_position), -limits_.max_velocity,
197 limits_.max_velocity);
199 soft_max_vel = saturate(-soft_limits_.k_position * (pos - soft_limits_.max_position), -limits_.max_velocity,
200 limits_.max_velocity);
205 soft_min_vel = -limits_.max_velocity;
206 soft_max_vel = limits_.max_velocity;
210 const double soft_min_eff =
211 saturate(-soft_limits_.k_velocity * (vel - soft_min_vel), -limits_.max_effort, limits_.max_effort);
213 const double soft_max_eff =
214 saturate(-soft_limits_.k_velocity * (vel - soft_max_vel), -limits_.max_effort, limits_.max_effort);
217 const double eff_cmd = saturate(hjh_.
getFeedforward(), soft_min_eff, soft_max_eff);
219 assert(period.toSec() > 0.0);
221 if (std::isnan(prev_pos_cmd_))
223 prev_pos_cmd_ = hjh_.getPosition();
227 if (limits_.has_position_limits)
230 soft_min_vel = saturate(-soft_limits_.k_position * (pos - soft_limits_.min_position), -limits_.max_velocity,
231 limits_.max_velocity);
233 soft_max_vel = saturate(-soft_limits_.k_position * (pos - soft_limits_.max_position), -limits_.max_velocity,
234 limits_.max_velocity);
239 soft_min_vel = -limits_.max_velocity;
240 soft_max_vel = limits_.max_velocity;
245 const double dt = period.toSec();
246 double pos_low = pos + soft_min_vel * dt;
247 double pos_high = pos + soft_max_vel * dt;
249 if (limits_.has_position_limits)
252 pos_low = std::max(pos_low, limits_.min_position);
253 pos_high = std::min(pos_high, limits_.max_position);
260 prev_pos_cmd_ = pos_cmd;
263 double min_vel{}, max_vel{};
264 if (limits_.has_position_limits)
267 pos = hjh_.getPosition();
268 min_vel = saturate(-soft_limits_.k_position * (pos - soft_limits_.min_position), -max_vel_limit_, max_vel_limit_);
269 max_vel = saturate(-soft_limits_.k_position * (pos - soft_limits_.max_position), -max_vel_limit_, max_vel_limit_);
273 min_vel = -max_vel_limit_;
274 max_vel = max_vel_limit_;
277 if (limits_.has_acceleration_limits)
279 vel = hjh_.getVelocity();
280 const double delta_t = period.toSec();
281 min_vel = std::max(vel - limits_.max_acceleration * delta_t, min_vel);
282 max_vel = std::min(vel + limits_.max_acceleration * delta_t, max_vel);