25#include "absl/strings/str_cat.h"
43TrajectoryPoint TrajectoryStitcher::ComputeTrajectoryPointFromVehicleState(
44 const double planning_cycle_time,
const VehicleState& vehicle_state) {
45 TrajectoryPoint point;
46 point.mutable_path_point()->set_s(0.0);
47 point.mutable_path_point()->
set_x(vehicle_state.x());
48 point.mutable_path_point()->set_y(vehicle_state.y());
49 point.mutable_path_point()->set_z(vehicle_state.z());
50 point.mutable_path_point()->set_theta(vehicle_state.heading());
51 point.mutable_path_point()->set_kappa(vehicle_state.kappa());
52 point.set_v(vehicle_state.linear_velocity());
53 point.set_a(vehicle_state.linear_acceleration());
54 point.set_relative_time(planning_cycle_time);
58std::vector<TrajectoryPoint>
60 const double planning_cycle_time,
const VehicleState& vehicle_state) {
62 static constexpr double kEpsilon_v = 0.1;
63 static constexpr double kEpsilon_a = 0.4;
67 reinit_point = ComputeTrajectoryPointFromVehicleState(planning_cycle_time,
71 predicted_vehicle_state =
73 reinit_point = ComputeTrajectoryPointFromVehicleState(
74 planning_cycle_time, predicted_vehicle_state);
77 return std::vector<TrajectoryPoint>(1, reinit_point);
82 const double x_diff,
const double y_diff,
const double theta_diff,
84 if (!prev_trajectory) {
89 double cos_theta = std::cos(theta_diff);
90 double sin_theta = -std::sin(theta_diff);
93 auto tx = -(cos_theta * x_diff - sin_theta * y_diff);
94 auto ty = -(sin_theta * x_diff + cos_theta * y_diff);
96 std::for_each(prev_trajectory->begin(), prev_trajectory->end(),
97 [&cos_theta, &sin_theta, &tx, &ty,
99 auto x = p.path_point().x();
100 auto y = p.path_point().y();
101 auto theta = p.path_point().theta();
103 auto x_new = cos_theta * x - sin_theta * y + tx;
104 auto y_new = sin_theta * x + cos_theta * y + ty;
106 common::math::NormalizeAngle(theta - theta_diff);
108 p.mutable_path_point()->set_x(x_new);
109 p.mutable_path_point()->set_y(y_new);
110 p.mutable_path_point()->set_theta(theta_new);
121 const double current_timestamp,
const double planning_cycle_time,
122 const size_t preserved_points_num,
const bool replan_by_offset,
126 size_t time_matched_index = 0;
128 prev_trajectory, replan_reason,
129 &time_matched_index)) {
134 if (vehicle_chassis.has_gear_location()) {
140 const std::string msg =
141 "gear change from n to d, replan to avoid large station error";
143 *replan_reason = msg;
151 static_cast<uint32_t
>(time_matched_index));
155 control_interactive_msg)) {
157 planning_cycle_time, vehicle_state, time_matched_point,
158 control_interactive_msg);
162 {vehicle_state.
x(), vehicle_state.
y()}, 1.0e-6);
164 auto frenet_sd = ComputePositionProjection(
165 vehicle_state.
x(), vehicle_state.
y(),
167 static_cast<uint32_t
>(position_matched_index)));
170 if (replan_by_offset) {
171 if (vehicle_chassis.has_parking_brake()) {
172 static bool parking_brake =
true;
175 const std::string msg =
176 "parking brake off, ego move, replan to avoid large station error";
178 *replan_reason = msg;
185 auto lon_diff = time_matched_point.path_point().s() - frenet_sd.first;
186 auto lat_diff = frenet_sd.second;
188 time_matched_point.relative_time() -
193 ADEBUG <<
"Control lateral diff: " << lat_diff
194 <<
", longitudinal diff: " << lon_diff
195 <<
", time diff: " << time_diff;
197 if (std::fabs(lat_diff) > FLAGS_replan_lateral_distance_threshold) {
198 const std::string msg = absl::StrCat(
199 "the distance between matched point and actual position is too "
200 "large. Replan is triggered. lat_diff = ",
203 *replan_reason = msg;
208 if (std::fabs(lon_diff) > FLAGS_replan_longitudinal_distance_threshold) {
209 const std::string msg = absl::StrCat(
210 "the distance between matched point and actual position is too "
211 "large. Replan is triggered. lon_diff = ",
214 *replan_reason = msg;
219 if (std::fabs(time_diff) > FLAGS_replan_time_threshold) {
220 const std::string msg = absl::StrCat(
221 "the difference between time matched point relative time and "
222 "actual position corresponding relative time is too "
223 "large. Replan is triggered. time_diff = ",
226 *replan_reason = msg;
231 ADEBUG <<
"replan according to certain amount of "
232 <<
"lat、lon and time offset is disabled";
236 double forward_rel_time =
237 current_timestamp - prev_trajectory->
header_time() + planning_cycle_time;
239 size_t forward_time_index =
242 ADEBUG <<
"Position matched index:\t" << position_matched_index;
243 ADEBUG <<
"Time matched index:\t" << time_matched_index;
245 auto matched_index = std::min(time_matched_index, position_matched_index);
247 std::vector<TrajectoryPoint> stitching_trajectory(
248 prev_trajectory->begin() +
249 std::max(0,
static_cast<int>(matched_index - preserved_points_num)),
250 prev_trajectory->begin() + forward_time_index + 1);
251 ADEBUG <<
"stitching_trajectory size: " << stitching_trajectory.size();
253 const double zero_s = stitching_trajectory.back().path_point().s();
254 for (
auto& tp : stitching_trajectory) {
255 if (!tp.has_path_point()) {
256 *replan_reason =
"replan for previous trajectory missed path point";
260 tp.set_relative_time(tp.relative_time() + prev_trajectory->
header_time() -
262 tp.mutable_path_point()->set_s(tp.path_point().s() - zero_s);
264 return stitching_trajectory;
267std::pair<double, double> TrajectoryStitcher::ComputePositionProjection(
272 std::pair<double, double> frenet_sd;
273 frenet_sd.first = v.InnerProd(n) + p.
path_point().
s();
274 frenet_sd.second = v.CrossProd(n);
281 size_t* time_matched_index) {
282 if (!FLAGS_enable_trajectory_stitcher) {
283 *replan_reason =
"stitch is disabled by gflag.";
286 if (!prev_trajectory) {
287 *replan_reason =
"replan for no previous trajectory.";
292 *replan_reason =
"replan for manual mode.";
296 size_t prev_trajectory_size = prev_trajectory->
NumOfPoints();
298 if (prev_trajectory_size == 0) {
300 <<
"] size is zero! Previous planning not exist or failed. Use "
301 "origin car status instead.";
302 *replan_reason =
"replan for empty previous trajectory.";
306 const double veh_rel_time =
307 current_timestamp - prev_trajectory->
header_time();
311 if (*time_matched_index == 0 &&
312 veh_rel_time < prev_trajectory->StartPoint().relative_time()) {
313 AWARN <<
"current time smaller than the previous trajectory's first time";
315 "replan for current time smaller than the previous trajectory's first "
320 if (*time_matched_index + 1 >= prev_trajectory_size) {
321 AWARN <<
"current time beyond the previous trajectory's last time";
323 "replan for current time beyond the previous trajectory's last time";
328 static_cast<uint32_t
>(*time_matched_index));
330 if (!time_matched_point.has_path_point()) {
331 *replan_reason =
"replan for previous trajectory missed path point";
338 const double current_timestamp, std::string* replan_reason,
340 const double rel_time =
342 if (rel_time > 0.5) {
343 AINFO <<
"control_interactive_msg time out, skip replay by control "
347 if (control_interactive_msg.has_replan_request() &&
349 *replan_reason =
"replan for control_interactive_msg, " +
356std::vector<common::TrajectoryPoint>
365 AINFO <<
"control_interactive_msg replan, all replan";
368 AINFO <<
"control_interactive_msg replan, speed replan";
370 vehicle_state_tmp.set_x(time_match_point.
path_point().
x());
371 vehicle_state_tmp.set_y(time_match_point.
path_point().
y());
372 vehicle_state_tmp.set_z(time_match_point.
path_point().
z());
Defines the templated Angle class.
static VehicleState Predict(const double predicted_time_horizon, const VehicleState &cur_vehicle_state)
Implements a class of 2-dimensional vectors.
void set_x(const double x)
Setter for x component
size_t QueryNearestPointWithBuffer(const common::math::Vec2d &position, const double buffer) const
const common::TrajectoryPoint & TrajectoryPointAt(const size_t index) const
size_t NumOfPoints() const
virtual size_t QueryLowerBoundPoint(const double relative_time, const double epsilon=1.0e-5) const
double header_time() const
static std::vector< common::TrajectoryPoint > ComputeStitchingTrajectory(const canbus::Chassis &vehicle_chassis, const common::VehicleState &vehicle_state, const double current_timestamp, const double planning_cycle_time, const size_t preserved_points_num, const bool replan_by_offset, const PublishableTrajectory *prev_trajectory, std::string *replan_reason, const control::ControlInteractiveMsg &control_interactive_msg)
static std::vector< common::TrajectoryPoint > ComputeControlInteractiveStitchingTrajectory(const double planning_cycle_time, const common::VehicleState &vehicle_state, const common::TrajectoryPoint &time_match_point, const control::ControlInteractiveMsg &control_interactive_msg)
static bool need_replan_by_necessary_check(const common::VehicleState &vehicle_state, const double current_timestamp, const PublishableTrajectory *prev_trajectory, std::string *replan_reason, size_t *time_matched_index)
static std::vector< common::TrajectoryPoint > ComputeReinitStitchingTrajectory(const double planning_cycle_time, const common::VehicleState &vehicle_state)
static void TransformLastPublishedTrajectory(const double x_diff, const double y_diff, const double theta_diff, PublishableTrajectory *prev_trajectory)
static bool need_replan_by_control_interactive(const double current_timestamp, std::string *replan_reason, const control::ControlInteractiveMsg &control_interactive_msg)
Planning module main class.
@ REPLAN_REQ_STATION_REPLAN
Contains a number of helper functions related to quaternions.
optional GearPosition gear_location
optional bool parking_brake
optional double relative_time
optional PathPoint path_point
optional apollo::canbus::Chassis::DrivingMode driving_mode
optional double linear_velocity
optional double linear_acceleration
optional apollo::common::Header header
optional string replan_request_reason
optional ReplanRequestReasonCode replan_req_reason_code
optional bool replan_request