16 #ifndef NAV2_CONSTRAINED_SMOOTHER__SMOOTHER_COST_FUNCTION_HPP_
17 #define NAV2_CONSTRAINED_SMOOTHER__SMOOTHER_COST_FUNCTION_HPP_
22 #include <unordered_map>
27 #include "ceres/ceres.h"
28 #include "ceres/cubic_interpolation.h"
30 #include "nav2_costmap_2d/costmap_2d.hpp"
31 #include "nav2_constrained_smoother/options.hpp"
32 #include "nav2_constrained_smoother/utils.hpp"
34 namespace nav2_constrained_smoother
56 const Eigen::Vector2d & original_pos,
57 double next_to_last_length_ratio,
60 const std::shared_ptr<ceres::BiCubicInterpolator<ceres::Grid2D<unsigned char>>> &
63 double costmap_weight_sqrt)
64 : original_pos_(original_pos),
65 next_to_last_length_ratio_(next_to_last_length_ratio),
66 reversing_(reversing),
68 costmap_weight_sqrt_(costmap_weight_sqrt),
69 costmap_origin_(costmap->getOriginX(), costmap->getOriginY()),
70 costmap_resolution_(costmap->getResolution()),
71 costmap_interpolator_(costmap_interpolator)
75 ceres::CostFunction * AutoDiff()
77 return new ceres::AutoDiffCostFunction<SmootherCostFunction, 6, 2, 2, 2>(
this);
80 void setCostmapWeightSqrt(
double costmap_weight_sqrt)
82 costmap_weight_sqrt_ = costmap_weight_sqrt;
85 double getCostmapWeightSqrt()
87 return costmap_weight_sqrt_;
100 const T *
const pt,
const T *
const pt_next,
const T *
const pt_prev,
101 T * pt_residual)
const
103 Eigen::Map<const Eigen::Matrix<T, 2, 1>> xi(pt);
104 Eigen::Map<const Eigen::Matrix<T, 2, 1>> xi_next(pt_next);
105 Eigen::Map<const Eigen::Matrix<T, 2, 1>> xi_prev(pt_prev);
106 Eigen::Map<Eigen::Matrix<T, 6, 1>> residual(pt_residual);
110 addSmoothingResidual<T>(
111 params_.smooth_weight_sqrt, xi, xi_next, xi_prev, residual[0],
113 addCurvatureResidual<T>(params_.curvature_weight_sqrt, xi, xi_next, xi_prev, residual[2]);
114 addDistanceResidual<T>(
115 params_.distance_weight_sqrt, xi,
116 original_pos_.template cast<T>(), residual[3], residual[4]);
117 addCostResidual<T>(costmap_weight_sqrt_, xi, xi_next, xi_prev, residual[5]);
133 const double & weight_sqrt,
134 const Eigen::Matrix<T, 2, 1> & pt,
135 const Eigen::Matrix<T, 2, 1> & pt_next,
136 const Eigen::Matrix<T, 2, 1> & pt_prev,
137 T & r1, T & r2)
const
139 Eigen::Matrix<T, 2, 1> d_next = pt_next - pt;
140 Eigen::Matrix<T, 2, 1> d_prev = pt - pt_prev;
141 Eigen::Matrix<T, 2, 1> d_diff = next_to_last_length_ratio_ * d_next - d_prev;
142 r1 += (T)weight_sqrt * d_diff(0, 0);
143 r2 += (T)weight_sqrt * d_diff(1, 0);
157 const double & weight_sqrt,
158 const Eigen::Matrix<T, 2, 1> & pt,
159 const Eigen::Matrix<T, 2, 1> & pt_next,
160 const Eigen::Matrix<T, 2, 1> & pt_prev,
163 Eigen::Matrix<T, 2, 1> center = arcCenter(
164 pt_prev, pt, pt_next,
165 next_to_last_length_ratio_ < 0);
166 if (CERES_ISINF(center[0])) {
169 T turning_rad = (pt - center).norm();
170 T ki_minus_kmax = (T)1.0 / turning_rad - params_.max_curvature;
172 if (ki_minus_kmax <= (T)EPSILON) {
176 r += (T)weight_sqrt * ki_minus_kmax;
188 const double & weight_sqrt,
189 const Eigen::Matrix<T, 2, 1> & xi,
190 const Eigen::Matrix<T, 2, 1> & xi_original,
191 T & r1, T & r2)
const
193 Eigen::Matrix<T, 2, 1> diff = xi - xi_original;
194 r1 += (T)weight_sqrt * diff(0, 0);
195 r2 += (T)weight_sqrt * diff(1, 0);
207 const double & weight_sqrt,
208 const Eigen::Matrix<T, 2, 1> & pt,
209 const Eigen::Matrix<T, 2, 1> & pt_next,
210 const Eigen::Matrix<T, 2, 1> & pt_prev,
213 if (params_.cost_check_points.empty()) {
214 Eigen::Matrix<T, 2, 1> interp_pos =
215 (pt - costmap_origin_.template cast<T>()) / (T)costmap_resolution_;
217 costmap_interpolator_->Evaluate(interp_pos[1] - (T)0.5, interp_pos[0] - (T)0.5, &value);
218 r += (T)weight_sqrt * value;
220 Eigen::Matrix<T, 2, 1> dir = tangentDir(
221 pt_prev, pt, pt_next,
222 next_to_last_length_ratio_ < 0);
224 if (((pt_next - pt).dot(dir) < (T)0) != reversing_) {
227 Eigen::Matrix<T, 3, 3> transform;
228 transform << dir[0], -dir[1], pt[0],
229 dir[1], dir[0], pt[1],
231 for (
size_t i = 0; i < params_.cost_check_points.size(); i += 3) {
232 Eigen::Matrix<T, 3, 1> ccpt((T)params_.cost_check_points[i],
233 (T)params_.cost_check_points[i + 1], (T)1);
234 auto ccpt_world = (transform * ccpt).
template block<2, 1>(0, 0);
236 1> interp_pos = (ccpt_world - costmap_origin_.template cast<T>()) /
237 (T)costmap_resolution_;
239 costmap_interpolator_->Evaluate(interp_pos[1] - (T)0.5, interp_pos[0] - (T)0.5, &value);
241 r += (T)weight_sqrt * (T)params_.cost_check_points[i + 2] * value;
246 const Eigen::Vector2d original_pos_;
247 double next_to_last_length_ratio_;
250 double costmap_weight_sqrt_;
251 Eigen::Vector2d costmap_origin_;
252 double costmap_resolution_;
253 std::shared_ptr<ceres::BiCubicInterpolator<ceres::Grid2D<unsigned char>>> costmap_interpolator_;
Cost function for path smoothing with multiple terms including curvature, smoothness,...
bool operator()(const T *const pt, const T *const pt_next, const T *const pt_prev, T *pt_residual) const
Smoother cost function evaluation.
void addCostResidual(const double &weight_sqrt, const Eigen::Matrix< T, 2, 1 > &pt, const Eigen::Matrix< T, 2, 1 > &pt_next, const Eigen::Matrix< T, 2, 1 > &pt_prev, T &r) const
Cost function term for steering away from costs.
void addSmoothingResidual(const double &weight_sqrt, const Eigen::Matrix< T, 2, 1 > &pt, const Eigen::Matrix< T, 2, 1 > &pt_next, const Eigen::Matrix< T, 2, 1 > &pt_prev, T &r1, T &r2) const
Cost function term for smooth paths.
void addCurvatureResidual(const double &weight_sqrt, const Eigen::Matrix< T, 2, 1 > &pt, const Eigen::Matrix< T, 2, 1 > &pt_next, const Eigen::Matrix< T, 2, 1 > &pt_prev, T &r) const
Cost function term for maximum curved paths.
SmootherCostFunction(const Eigen::Vector2d &original_pos, double next_to_last_length_ratio, bool reversing, const nav2_costmap_2d::Costmap2D *costmap, const std::shared_ptr< ceres::BiCubicInterpolator< ceres::Grid2D< unsigned char >>> &costmap_interpolator, const SmootherParams ¶ms, double costmap_weight_sqrt)
A constructor for nav2_constrained_smoother::SmootherCostFunction.
void addDistanceResidual(const double &weight_sqrt, const Eigen::Matrix< T, 2, 1 > &xi, const Eigen::Matrix< T, 2, 1 > &xi_original, T &r1, T &r2) const
Cost function derivative term for steering away changes in pose.
A 2D costmap provides a mapping between points in the world and their associated "costs".