145 num_joints_ = num_joints;
146 robot_model_ = robot_model;
147 cur_acceleration_ = Eigen::VectorXd::Zero(num_joints);
150 auto param_listener = online_signal_smoothing::ParamListener(node_);
151 params_ = param_listener.get_params();
154 auto joint_model_group = robot_model_->getJointModelGroup(params_.planning_group_name);
155 auto joint_bounds = joint_model_group->getActiveJointModelsBounds();
156 min_acceleration_limits_ = Eigen::VectorXd::Zero(num_joints);
157 max_acceleration_limits_ = Eigen::VectorXd::Zero(num_joints);
159 for (
const auto& joint_bound : joint_bounds)
161 for (
const auto& variable_bound : *joint_bound)
163 if (variable_bound.acceleration_bounded_)
165 min_acceleration_limits_[ind] = variable_bound.min_acceleration_;
166 max_acceleration_limits_[ind] = variable_bound.max_acceleration_;
170 RCLCPP_ERROR(
getLogger(),
"The robot must have acceleration joint limits specified for all joints to "
171 "use AccelerationLimitedPlugin.");
179 Eigen::SparseMatrix<double> objective_sparse(1, 1);
180 objective_sparse.insert(0, 0) = 1.0;
181 size_t num_constraints = num_joints + 1;
182 constraints_sparse_ = Eigen::SparseMatrix<double>(num_constraints, 1);
183 for (
size_t i = 0; i < num_constraints - 1; ++i)
185 constraints_sparse_.insert(i, 0) = 0;
187 constraints_sparse_.insert(num_constraints - 1, 0) = 0;
188 osqp_set_default_settings(&osqp_settings_);
189 osqp_settings_.warm_start = 0;
190 osqp_settings_.verbose = 0;
191 osqp_data_ = std::make_shared<OSQPDataWrapper>(objective_sparse, constraints_sparse_);
192 osqp_data_->q[0] = 0;
194 if (osqp_setup(&osqp_workspace_, &osqp_data_->data, &osqp_settings_) != 0)
196 osqp_settings_.verbose = 1;
198 osqp_setup(&osqp_workspace_, &osqp_data_->data, &osqp_settings_);
199 RCLCPP_ERROR(
getLogger(),
"Failed to initialize osqp problem.");
209 double min_scaling_factor = 1.0;
213 for (
const auto& joint_bound : joint_bounds)
215 for (
const auto& variable_bound : *joint_bound)
217 const auto& target_accel = accelerations(idx);
218 if (variable_bound.acceleration_bounded_ && target_accel != 0.0)
221 const auto bounded_vel =
222 std::clamp(target_accel, variable_bound.min_acceleration_, variable_bound.max_acceleration_);
223 double joint_scaling_factor = bounded_vel / target_accel;
224 min_scaling_factor = std::min(min_scaling_factor, joint_scaling_factor);
230 return min_scaling_factor;
233inline bool updateData(
const OSQPDataWrapperPtr& data, OSQPWorkspace* work,
234 Eigen::SparseMatrix<double>& constraints_sparse,
const Eigen::VectorXd& lower_bound,
235 const Eigen::VectorXd& upper_bound)
237 data->updateA(work, constraints_sparse);
238 size_t num_constraints = constraints_sparse.rows();
239 data->u.block(0, 0, num_constraints - 1, 1) = upper_bound;
240 data->l.block(0, 0, num_constraints - 1, 1) = lower_bound;
243 return 0 == osqp_update_bounds(work, data->l.data(), data->u.data());
249 const size_t num_positions = velocities.size();
250 if (num_positions != num_joints_)
252 RCLCPP_ERROR_THROTTLE(
254 "The length of the joint positions parameter is not equal to the number of joints, expected %zu got %zu.",
255 num_joints_, num_positions);
258 else if (last_positions_.size() != positions.size())
260 RCLCPP_ERROR_THROTTLE(
getLogger(), *node_->get_clock(), 1000,
261 "The length of the last joint positions not equal to the current, expected %zu got %zu. Make "
262 "sure the reset was called.",
263 last_positions_.size(), positions.size());
285 double& update_period = params_.update_period;
286 size_t num_constraints = num_joints_ + 1;
287 positions_offset_ = last_positions_ - positions;
288 velocities_offset_ = last_velocities_ - velocities;
289 for (
size_t i = 0; i < num_constraints - 1; ++i)
291 constraints_sparse_.coeffRef(i, 0) = positions_offset_[i];
293 constraints_sparse_.coeffRef(num_constraints - 1, 0) = 1;
294 Eigen::VectorXd vel_point = last_positions_ + last_velocities_ * update_period;
295 Eigen::VectorXd upper_bound = vel_point - positions + max_acceleration_limits_ * (update_period * update_period);
296 Eigen::VectorXd lower_bound = vel_point - positions + min_acceleration_limits_ * (update_period * update_period);
297 if (!
updateData(osqp_data_, osqp_workspace_, constraints_sparse_, lower_bound, upper_bound))
299 RCLCPP_ERROR_THROTTLE(
getLogger(), *node_->get_clock(), 1000,
300 "failed to set osqp_update_bounds. Make sure the robot's acceleration limits are valid");
307 positions = last_positions_;
308 velocities = last_velocities_;
310 else if (osqp_solve(osqp_workspace_) == 0 &&
314 double alpha = osqp_workspace_->solution->x[0];
315 positions = alpha * last_positions_ + (1.0 - alpha) * positions.eval();
316 velocities = (positions - last_positions_) / update_period;
320 auto joint_model_group = robot_model_->getJointModelGroup(params_.planning_group_name);
321 auto joint_bounds = joint_model_group->getActiveJointModelsBounds();
322 cur_acceleration_ = -(last_velocities_) / update_period;
324 velocities = last_velocities_ + cur_acceleration_ * update_period;
325 positions = last_positions_ + velocities * update_period;
328 last_velocities_ = velocities;
329 last_positions_ = positions;