43 #include <ilqgames/cost/semiquadratic_polyline2_cost.h> 44 #include <ilqgames/cost/time_invariant_cost.h> 45 #include <ilqgames/geometry/polyline2.h> 46 #include <ilqgames/utils/types.h> 52 float SemiquadraticPolyline2Cost::Evaluate(
const VectorXf& input)
const {
53 CHECK_LT(xidx_, input.size());
54 CHECK_LT(yidx_, input.size());
57 float signed_squared_distance;
59 polyline_.ClosestPoint(Point2(input(xidx_), input(yidx_)),
nullptr,
nullptr,
60 &signed_squared_distance, &is_endpoint);
66 if (!IsActive(signed_squared_distance))
return 0.0;
69 const float signed_distance = sgn(signed_squared_distance) *
70 std::sqrt(std::abs(signed_squared_distance));
71 const float diff = signed_distance - threshold_;
72 return 0.5 * weight_ * diff * diff;
75 void SemiquadraticPolyline2Cost::Quadraticize(
const VectorXf& input,
77 VectorXf* grad)
const {
78 CHECK_LT(xidx_, input.size());
79 CHECK_LT(yidx_, input.size());
83 CHECK_EQ(input.size(), hess->rows());
84 CHECK_EQ(input.size(), hess->cols());
85 CHECK_EQ(input.size(), grad->size());
88 const Point2 current_position(input(xidx_), input(yidx_));
90 float signed_squared_distance;
93 LineSegment2 segment(Point2(0.0, 0.0), Point2(1.0, 1.0));
94 const Point2 closest_point =
95 polyline_.ClosestPoint(current_position, &is_vertex, &segment,
96 &signed_squared_distance, &is_endpoint);
99 if (!IsActive(signed_squared_distance))
return;
102 if (is_endpoint)
return;
110 float scaling = std::sqrt(std::abs(signed_squared_distance));
111 scaling = (scaling - std::abs(threshold_)) / scaling;
112 float dx = weight_ * scaling * (current_position.x() - closest_point.x());
113 float dy = weight_ * scaling * (current_position.y() - closest_point.y());
115 const Point2 relative = current_position - segment.FirstPoint();
116 const Point2& unit_segment = segment.UnitDirection();
119 ddx = weight_ * unit_segment.y() * unit_segment.y();
120 ddy = weight_ * unit_segment.x() * unit_segment.x();
122 const float cross_term = -weight_ * unit_segment.x() * unit_segment.y();
127 const float w_cross =
128 weight_ * (relative.x() * unit_segment.y() -
129 relative.y() * unit_segment.x() - threshold_);
131 dx = w_cross * unit_segment.y();
132 dy = -w_cross * unit_segment.x();
135 (*grad)(xidx_) += dx;
136 (*grad)(yidx_) += dy;
138 (*hess)(xidx_, xidx_) += ddx;
139 (*hess)(yidx_, yidx_) += ddy;
140 (*hess)(xidx_, yidx_) += dxdy;
141 (*hess)(yidx_, xidx_) += dxdy;