Apollo 11.0
自动驾驶开放平台
apollo::planning::TrajectoryStitcher类 参考

#include <trajectory_stitcher.h>

apollo::planning::TrajectoryStitcher 的协作图:

Public 成员函数

 TrajectoryStitcher ()=delete
 

静态 Public 成员函数

static void TransformLastPublishedTrajectory (const double x_diff, const double y_diff, const double theta_diff, PublishableTrajectory *prev_trajectory)
 
static std::vector< common::TrajectoryPointComputeStitchingTrajectory (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::TrajectoryPointComputeReinitStitchingTrajectory (const double planning_cycle_time, const common::VehicleState &vehicle_state)
 
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 bool need_replan_by_control_interactive (const double current_timestamp, std::string *replan_reason, const control::ControlInteractiveMsg &control_interactive_msg)
 
static std::vector< common::TrajectoryPointComputeControlInteractiveStitchingTrajectory (const double planning_cycle_time, const common::VehicleState &vehicle_state, const common::TrajectoryPoint &time_match_point, const control::ControlInteractiveMsg &control_interactive_msg)
 

详细描述

在文件 trajectory_stitcher.h37 行定义.

构造及析构函数说明

◆ TrajectoryStitcher()

apollo::planning::TrajectoryStitcher::TrajectoryStitcher ( )
delete

成员函数说明

◆ ComputeControlInteractiveStitchingTrajectory()

std::vector< common::TrajectoryPoint > apollo::planning::TrajectoryStitcher::ComputeControlInteractiveStitchingTrajectory ( const double  planning_cycle_time,
const common::VehicleState vehicle_state,
const common::TrajectoryPoint time_match_point,
const control::ControlInteractiveMsg control_interactive_msg 
)
static

在文件 trajectory_stitcher.cc357 行定义.

360 {
361 if (control_interactive_msg.replan_req_reason_code() ==
363 control_interactive_msg.replan_req_reason_code() ==
365 AINFO << "control_interactive_msg replan, all replan";
366 return ComputeReinitStitchingTrajectory(planning_cycle_time, vehicle_state);
367 } else {
368 AINFO << "control_interactive_msg replan, speed replan";
369 VehicleState vehicle_state_tmp = vehicle_state;
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());
373 vehicle_state_tmp.set_heading(time_match_point.path_point().theta());
374 vehicle_state_tmp.set_kappa(time_match_point.path_point().kappa());
375 return ComputeReinitStitchingTrajectory(planning_cycle_time,
376 vehicle_state_tmp);
377 }
378}
static std::vector< common::TrajectoryPoint > ComputeReinitStitchingTrajectory(const double planning_cycle_time, const common::VehicleState &vehicle_state)
#define AINFO
Definition log.h:42

◆ ComputeReinitStitchingTrajectory()

std::vector< TrajectoryPoint > apollo::planning::TrajectoryStitcher::ComputeReinitStitchingTrajectory ( const double  planning_cycle_time,
const common::VehicleState vehicle_state 
)
static

在文件 trajectory_stitcher.cc59 行定义.

60 {
61 TrajectoryPoint reinit_point;
62 static constexpr double kEpsilon_v = 0.1;
63 static constexpr double kEpsilon_a = 0.4;
64 // TODO(Jinyun/Yu): adjust kEpsilon if corrected IMU acceleration provided
65 if (std::abs(vehicle_state.linear_velocity()) < kEpsilon_v &&
66 std::abs(vehicle_state.linear_acceleration()) < kEpsilon_a) {
67 reinit_point = ComputeTrajectoryPointFromVehicleState(planning_cycle_time,
68 vehicle_state);
69 } else {
70 VehicleState predicted_vehicle_state;
71 predicted_vehicle_state =
72 VehicleModel::Predict(planning_cycle_time, vehicle_state);
73 reinit_point = ComputeTrajectoryPointFromVehicleState(
74 planning_cycle_time, predicted_vehicle_state);
75 }
76
77 return std::vector<TrajectoryPoint>(1, reinit_point);
78}
static VehicleState Predict(const double predicted_time_horizon, const VehicleState &cur_vehicle_state)

◆ ComputeStitchingTrajectory()

std::vector< TrajectoryPoint > apollo::planning::TrajectoryStitcher::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

在文件 trajectory_stitcher.cc119 行定义.

124 {
125 // 1.check replan not by offset
126 size_t time_matched_index = 0;
127 if (need_replan_by_necessary_check(vehicle_state, current_timestamp,
128 prev_trajectory, replan_reason,
129 &time_matched_index)) {
130 return ComputeReinitStitchingTrajectory(planning_cycle_time, vehicle_state);
131 }
132
133 // 2. check replan by GEAR switch
134 if (vehicle_chassis.has_gear_location()) {
135 static canbus::Chassis::GearPosition gear_pos =
137 if (gear_pos == canbus::Chassis::GEAR_NEUTRAL &&
138 vehicle_chassis.gear_location() == canbus::Chassis::GEAR_DRIVE) {
139 gear_pos = vehicle_chassis.gear_location();
140 const std::string msg =
141 "gear change from n to d, replan to avoid large station error";
142 AERROR << msg;
143 *replan_reason = msg;
144 return ComputeReinitStitchingTrajectory(planning_cycle_time,
145 vehicle_state);
146 }
147 gear_pos = vehicle_chassis.gear_location();
148 }
149
150 auto time_matched_point = prev_trajectory->TrajectoryPointAt(
151 static_cast<uint32_t>(time_matched_index));
152
153 // 3.check replan by control_interactive_msg
154 if (need_replan_by_control_interactive(current_timestamp, replan_reason,
155 control_interactive_msg)) {
157 planning_cycle_time, vehicle_state, time_matched_point,
158 control_interactive_msg);
159 }
160
161 size_t position_matched_index = prev_trajectory->QueryNearestPointWithBuffer(
162 {vehicle_state.x(), vehicle_state.y()}, 1.0e-6);
163
164 auto frenet_sd = ComputePositionProjection(
165 vehicle_state.x(), vehicle_state.y(),
166 prev_trajectory->TrajectoryPointAt(
167 static_cast<uint32_t>(position_matched_index)));
168
169 // 4.check replan by offset
170 if (replan_by_offset) {
171 if (vehicle_chassis.has_parking_brake()) {
172 static bool parking_brake = true;
173 if (parking_brake && !vehicle_chassis.parking_brake()) {
174 parking_brake = vehicle_chassis.parking_brake();
175 const std::string msg =
176 "parking brake off, ego move, replan to avoid large station error";
177 AERROR << msg;
178 *replan_reason = msg;
179 return ComputeReinitStitchingTrajectory(planning_cycle_time,
180 vehicle_state);
181 }
182 parking_brake = vehicle_chassis.parking_brake();
183 }
184
185 auto lon_diff = time_matched_point.path_point().s() - frenet_sd.first;
186 auto lat_diff = frenet_sd.second;
187 double time_diff =
188 time_matched_point.relative_time() -
189 prev_trajectory
190 ->TrajectoryPointAt(static_cast<uint32_t>(position_matched_index))
191 .relative_time();
192
193 ADEBUG << "Control lateral diff: " << lat_diff
194 << ", longitudinal diff: " << lon_diff
195 << ", time diff: " << time_diff;
196
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 = ",
201 lat_diff);
202 AERROR << msg;
203 *replan_reason = msg;
204 return ComputeReinitStitchingTrajectory(planning_cycle_time,
205 vehicle_state);
206 }
207
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 = ",
212 lon_diff);
213 AERROR << msg;
214 *replan_reason = msg;
215 return ComputeReinitStitchingTrajectory(planning_cycle_time,
216 vehicle_state);
217 }
218
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 = ",
224 time_diff);
225 AERROR << msg;
226 *replan_reason = msg;
227 return ComputeReinitStitchingTrajectory(planning_cycle_time,
228 vehicle_state);
229 }
230 } else {
231 ADEBUG << "replan according to certain amount of "
232 << "lat、lon and time offset is disabled";
233 }
234
235 // 4.stitching_trajectory
236 double forward_rel_time =
237 current_timestamp - prev_trajectory->header_time() + planning_cycle_time;
238
239 size_t forward_time_index =
240 prev_trajectory->QueryLowerBoundPoint(forward_rel_time);
241
242 ADEBUG << "Position matched index:\t" << position_matched_index;
243 ADEBUG << "Time matched index:\t" << time_matched_index;
244
245 auto matched_index = std::min(time_matched_index, position_matched_index);
246
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();
252
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";
257 return ComputeReinitStitchingTrajectory(planning_cycle_time,
258 vehicle_state);
259 }
260 tp.set_relative_time(tp.relative_time() + prev_trajectory->header_time() -
261 current_timestamp);
262 tp.mutable_path_point()->set_s(tp.path_point().s() - zero_s);
263 }
264 return stitching_trajectory;
265}
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 bool need_replan_by_control_interactive(const double current_timestamp, std::string *replan_reason, const control::ControlInteractiveMsg &control_interactive_msg)
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44

◆ need_replan_by_control_interactive()

bool apollo::planning::TrajectoryStitcher::need_replan_by_control_interactive ( const double  current_timestamp,
std::string *  replan_reason,
const control::ControlInteractiveMsg control_interactive_msg 
)
static

在文件 trajectory_stitcher.cc337 行定义.

339 {
340 const double rel_time =
341 current_timestamp - control_interactive_msg.header().timestamp_sec();
342 if (rel_time > 0.5) {
343 AINFO << "control_interactive_msg time out, skip replay by control "
344 "interactive";
345 return false;
346 }
347 if (control_interactive_msg.has_replan_request() &&
348 control_interactive_msg.replan_request() == true) {
349 *replan_reason = "replan for control_interactive_msg, " +
350 control_interactive_msg.replan_request_reason();
351 return true;
352 }
353 return false;
354}

◆ need_replan_by_necessary_check()

bool apollo::planning::TrajectoryStitcher::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

在文件 trajectory_stitcher.cc278 行定义.

281 {
282 if (!FLAGS_enable_trajectory_stitcher) {
283 *replan_reason = "stitch is disabled by gflag.";
284 return true;
285 }
286 if (!prev_trajectory) {
287 *replan_reason = "replan for no previous trajectory.";
288 return true;
289 }
290
291 if (vehicle_state.driving_mode() != canbus::Chassis::COMPLETE_AUTO_DRIVE) {
292 *replan_reason = "replan for manual mode.";
293 return true;
294 }
295
296 size_t prev_trajectory_size = prev_trajectory->NumOfPoints();
297
298 if (prev_trajectory_size == 0) {
299 ADEBUG << "Projected trajectory at time [" << prev_trajectory->header_time()
300 << "] size is zero! Previous planning not exist or failed. Use "
301 "origin car status instead.";
302 *replan_reason = "replan for empty previous trajectory.";
303 return true;
304 }
305
306 const double veh_rel_time =
307 current_timestamp - prev_trajectory->header_time();
308
309 *time_matched_index = prev_trajectory->QueryLowerBoundPoint(veh_rel_time);
310
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";
314 *replan_reason =
315 "replan for current time smaller than the previous trajectory's first "
316 "time.";
317 return true;
318 }
319
320 if (*time_matched_index + 1 >= prev_trajectory_size) {
321 AWARN << "current time beyond the previous trajectory's last time";
322 *replan_reason =
323 "replan for current time beyond the previous trajectory's last time";
324 return true;
325 }
326
327 auto time_matched_point = prev_trajectory->TrajectoryPointAt(
328 static_cast<uint32_t>(*time_matched_index));
329
330 if (!time_matched_point.has_path_point()) {
331 *replan_reason = "replan for previous trajectory missed path point";
332 return true;
333 }
334 return false;
335}
#define AWARN
Definition log.h:43

◆ TransformLastPublishedTrajectory()

void apollo::planning::TrajectoryStitcher::TransformLastPublishedTrajectory ( const double  x_diff,
const double  y_diff,
const double  theta_diff,
PublishableTrajectory prev_trajectory 
)
static

在文件 trajectory_stitcher.cc81 行定义.

83 {
84 if (!prev_trajectory) {
85 return;
86 }
87
88 // R^-1
89 double cos_theta = std::cos(theta_diff);
90 double sin_theta = -std::sin(theta_diff);
91
92 // -R^-1 * t
93 auto tx = -(cos_theta * x_diff - sin_theta * y_diff);
94 auto ty = -(sin_theta * x_diff + cos_theta * y_diff);
95
96 std::for_each(prev_trajectory->begin(), prev_trajectory->end(),
97 [&cos_theta, &sin_theta, &tx, &ty,
98 &theta_diff](common::TrajectoryPoint& p) {
99 auto x = p.path_point().x();
100 auto y = p.path_point().y();
101 auto theta = p.path_point().theta();
102
103 auto x_new = cos_theta * x - sin_theta * y + tx;
104 auto y_new = sin_theta * x + cos_theta * y + ty;
105 auto theta_new =
106 common::math::NormalizeAngle(theta - theta_diff);
107
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);
111 });
112}

该类的文档由以下文件生成: