#ComputeLongitudinalErrors主函数
void LonController::ComputeLongitudinalErrors(
const TrajectoryAnalyzer *trajectory_analyzer, const double preview_time,
const double ts, SimpleLongitudinalDebug *debug) {
// the decomposed vehicle motion onto Frenet frame
// s: longitudinal accumulated distance along reference trajectory
// s_dot: longitudinal velocity along reference trajectory
// d: lateral distance w.r.t. reference trajectory
// d_dot: lateral distance change rate, i.e. dd/dt
double s_matched = 0.0;
double s_dot_matched = 0.0;
double d_matched = 0.0;
double d_dot_matched = 0.0;
//转到函数1
auto matched_point = trajectory_analyzer->QueryMatchedPathPoint(
VehicleStateProvider::Instance()->x(),
VehicleStateProvider::Instance()->y());
//转到函数3
trajectory_analyzer->ToTrajectoryFrame(
VehicleStateProvider::Instance()->x(),
VehicleStateProvider::Instance()->y(),
VehicleStateProvider::Instance()->heading(),
VehicleStateProvider::Instance()->linear_velocity(), matched_point,
&s_matched, &s_dot_matched, &d_matched, &d_dot_matched);
//当前控制时间和未来控制时间
double current_control_time = Clock::NowInSeconds();
double preview_control_time = current_control_time + preview_time;
//转到函数4
TrajectoryPoint reference_point =
trajectory_analyzer->QueryNearestPointByAbsoluteTime(
current_control_time);
TrajectoryPoint preview_point =
trajectory_analyzer->QueryNearestPointByAbsoluteTime(
preview_control_time);
debug->mutable_current_matched_point()->mutable_path_point()->set_x(
matched_point.x());
debug->mutable_current_matched_point()->mutable_path_point()->set_y(
matched_point.y());
debug->mutable_current_reference_point()->mutable_path_point()->set_x(
reference_point.path_point().x());
debug->mutable_current_reference_point()->mutable_path_point()->set_y(
reference_point.path_point().y());
debug->mutable_preview_reference_point()->mutable_path_point()->set_x(
preview_point.path_point().x());
debug->mutable_preview_reference_point()->mutable_path_point()->set_y(
preview_point.path_point().y());
ADEBUG << "matched point:" << matched_point.DebugString();
ADEBUG << "reference point:" << reference_point.DebugString();
ADEBUG << "preview point:" << preview_point.DebugString();
double heading_error = common::math::NormalizeAngle(
VehicleStateProvider::Instance()->heading() - matched_point.theta());
double lon_speed = VehicleStateProvider::Instance()->linear_velocity() *
std::cos(heading_error);
double lon_acceleration =
VehicleStateProvider::Instance()->linear_acceleration() *
std::cos(heading_error);
double one_minus_kappa_lat_error =
1 - reference_point.path_point().kappa() *
VehicleStateProvider::Instance()->linear_velocity() *
std::sin(heading_error);
debug->set_station_reference(reference_point.path_point().s());
debug->set_current_station(s_matched);
debug->set_station_error(reference_point.path_point().s() - s_matched);
debug->set_speed_reference(reference_point.v());
debug->set_current_speed(lon_speed);
debug->set_speed_error(reference_point.v() - s_dot_matched);
debug->set_acceleration_reference(reference_point.a());
debug->set_current_acceleration(lon_acceleration);
debug->set_acceleration_error(reference_point.a() -
lon_acceleration / one_minus_kappa_lat_error);
double jerk_reference =
(debug->acceleration_reference() - previous_acceleration_reference_) / ts;
double lon_jerk =
(debug->current_acceleration() - previous_acceleration_) / ts;
debug->set_jerk_reference(jerk_reference);
debug->set_current_jerk(lon_jerk);
debug->set_jerk_error(jerk_reference - lon_jerk / one_minus_kappa_lat_error);
previous_acceleration_reference_ = debug->acceleration_reference();
previous_acceleration_ = debug->current_acceleration();
debug->set_preview_station_error(preview_point.path_point().s() - s_matched);
debug->set_preview_speed_error(preview_point.v() - s_dot_matched);
debug->set_preview_speed_reference(preview_point.v());
debug->set_preview_acceleration_reference(preview_point.a());
}
QueryMatchedPathPoint()函数1
PathPoint TrajectoryAnalyzer::QueryMatchedPathPoint(const double x,
const double y) const {
CHECK_GT(trajectory_points_.size(), 0);
//PointDistanceSquare,求两个点之间的距离
double d_min = PointDistanceSquare(trajectory_points_.front(), x, y);
size_t index_min = 0;
for (size_t i = 1; i < trajectory_points_.size(); ++i) {
double d_temp = PointDistanceSquare(trajectory_points_[i], x, y);
if (d_temp < d_min) {
d_min = d_temp;
index_min = i;
}
}
size_t index_start = index_min == 0 ? index_min : index_min - 1;
size_t index_end =
index_min + 1 == trajectory_points_.size() ? index_min : index_min + 1;
const double kEpsilon = 0.001;
if (index_start == index_end ||
std::fabs(trajectory_points_[index_start].path_point().s() -
trajectory_points_[index_end].path_point().s()) <= kEpsilon) {
return TrajectoryPointToPathPoint(trajectory_points_[index_start]);
}
//转到函数2
return FindMinDistancePoint(trajectory_points_[index_start],
trajectory_points_[index_end], x, y);
}
FindMinDistancePoint()函数2
PathPoint TrajectoryAnalyzer::FindMinDistancePoint(const TrajectoryPoint &p0,
const TrajectoryPoint &p1,
const double x,
const double y) const {
// given the fact that the discretized trajectory is dense enough,
// we assume linear trajectory between consecutive trajectory points.
auto dist_square = [&p0, &p1, &x, &y](const double s) {
double px = common::math::lerp(p0.path_point().x(), p0.path_point().s(),
p1.path_point().x(), p1.path_point().s(), s);
double py = common::math::lerp(p0.path_point().y(), p0.path_point().s(),
p1.path_point().y(), p1.path_point().s(), s);
double dx = px - x;
double dy = py - y;
return dx * dx + dy * dy;
};
PathPoint p = p0.path_point();
double s = common::math::GoldenSectionSearch(dist_square, p0.path_point().s(),
p1.path_point().s());
p.set_s(s);
p.set_x(common::math::lerp(p0.path_point().x(), p0.path_point().s(),
p1.path_point().x(), p1.path_point().s(), s));
p.set_y(common::math::lerp(p0.path_point().y(), p0.path_point().s(),
p1.path_point().y(), p1.path_point().s(), s));
p.set_theta(common::math::slerp(p0.path_point().theta(), p0.path_point().s(),
p1.path_point().theta(), p1.path_point().s(),
s));
// approximate the curvature at the intermediate point
p.set_kappa(common::math::lerp(p0.path_point().kappa(), p0.path_point().s(),
p1.path_point().kappa(), p1.path_point().s(),
s));
return p;
}
函数3
// reference: Optimal trajectory generation for dynamic street scenarios in a
// Frenét Frame,
// Moritz Werling, Julius Ziegler, Sören Kammel and Sebastian Thrun, ICRA 2010
// similar to the method in this paper without the assumption the "normal"
// vector
// (from vehicle position to ref_point position) and reference heading are
// perpendicular.
void TrajectoryAnalyzer::ToTrajectoryFrame(const double x, const double y,
const double theta, const double v,
const PathPoint &ref_point,
double *ptr_s, double *ptr_s_dot,
double *ptr_d,
double *ptr_d_dot) const {
double dx = x - ref_point.x();
double dy = y - ref_point.y();
double cos_ref_theta = std::cos(ref_point.theta());
double sin_ref_theta = std::sin(ref_point.theta());
// the sin of diff angle between vector (cos_ref_theta, sin_ref_theta) and
// (dx, dy)
double cross_rd_nd = cos_ref_theta * dy - sin_ref_theta * dx;
*ptr_d = cross_rd_nd;
// the cos of diff angle between vector (cos_ref_theta, sin_ref_theta) and
// (dx, dy)
double dot_rd_nd = dx * cos_ref_theta + dy * sin_ref_theta;
*ptr_s = ref_point.s() + dot_rd_nd;
double delta_theta = theta - ref_point.theta();
double cos_delta_theta = std::cos(delta_theta);
double sin_delta_theta = std::sin(delta_theta);
*ptr_d_dot = v * sin_delta_theta;
double one_minus_kappa_r_d = 1 - ref_point.kappa() * (*ptr_d);
if (one_minus_kappa_r_d <= 0.0) {
AERROR << "TrajectoryAnalyzer::ToTrajectoryFrame "
"found fatal reference and actual difference. "
"Control output might be unstable:"
<< " ref_point.kappa:" << ref_point.kappa()
<< " ref_point.x:" << ref_point.x()
<< " ref_point.y:" << ref_point.y() << " car x:" << x
<< " car y:" << y << " *ptr_d:" << *ptr_d
<< " one_minus_kappa_r_d:" << one_minus_kappa_r_d;
// currently set to a small value to avoid control crash.
one_minus_kappa_r_d = 0.01;
}
*ptr_s_dot = v * cos_delta_theta / one_minus_kappa_r_d;
}
QueryNearestPointByAbsoluteTime()函数4
TrajectoryPoint TrajectoryAnalyzer::QueryNearestPointByAbsoluteTime(
const double t) const {
return QueryNearestPointByRelativeTime(t - header_time_);
}
TrajectoryPoint TrajectoryAnalyzer::QueryNearestPointByRelativeTime(
const double t) const {
auto func_comp = [](const TrajectoryPoint &point,
const double relative_time) {
return point.relative_time() < relative_time;
};
auto it_low = std::lower_bound(trajectory_points_.begin(),
trajectory_points_.end(), t, func_comp);
if (it_low == trajectory_points_.begin()) {
return trajectory_points_.front();
}
if (it_low == trajectory_points_.end()) {
return trajectory_points_.back();
}
if (FLAGS_query_forward_time_point_only) {
return *it_low;
} else {
auto it_lower = it_low - 1;
if (it_low->relative_time() - t < t - it_lower->relative_time()) {
return *it_low;
}
return *it_lower;
}
}
版权声明:本文为qq_42589654原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。