26#include "modules/common/vehicle_state/proto/vehicle_state.pb.h"
44 const std::string& config_dir,
const std::string& name,
45 const std::shared_ptr<DependencyInjector>& injector) {
50 if (!Task::LoadConfig<OpenSpaceTrajectoryProviderConfig>(&config_)) {
67 is_generation_thread_stop_.store(
true);
68 if (thread_init_flag_) {
71 trajectory_updated_.store(
false);
72 trajectory_error_.store(
false);
73 trajectory_skipped_.store(
false);
74 optimizer_thread_counter = 0;
75 last_trajctory_point.Clear();
81 is_generation_thread_stop_.store(
true);
82 if (thread_init_flag_) {
85 is_generation_thread_stop_.store(
false);
86 thread_init_flag_ =
false;
87 trajectory_updated_.store(
false);
88 trajectory_error_.store(
false);
89 trajectory_skipped_.store(
false);
90 optimizer_thread_counter = 0;
95Status OpenSpaceTrajectoryProvider::Process() {
96 ADEBUG <<
"trajectory provider";
97 auto trajectory_data =
102 ->mutable_planning_status()
103 ->mutable_park_and_go()
104 ->in_check_stage()) {
105 ADEBUG <<
"ParkAndGo Stage Check.";
106 GenerateStopTrajectory(trajectory_data);
111 if (FLAGS_change_end_pose) {
112 AINFO <<
"Restart OpenSpaceTrajectoryProvider!";
113 FLAGS_calculate_next_trajectory =
true;
119 task_future_ = cyber::Async(
120 &OpenSpaceTrajectoryProvider::GenerateTrajectoryThread,
this);
121 thread_init_flag_ =
true;
123 bool need_replan =
false;
126 auto* previous_frame =
injector_->frame_history()->Latest();
128 std::vector<TrajectoryPoint> stitching_trajectory;
129 bool is_stop_due_to_fallback =
false;
130 if (previous_frame &&
131 IsVehicleStopDueToFallBack(
132 previous_frame->open_space_info().fallback_flag(), vehicle_state)) {
133 is_stop_due_to_fallback =
true;
135 if (!is_planned_ || is_stop_due_to_fallback) {
136 AINFO <<
"need to fallback: is_planned" << is_planned_
137 <<
"is_stop_due_to_fallback" << is_stop_due_to_fallback;
138 const double planning_cycle_time =
139 1.0 /
static_cast<double>(FLAGS_planning_loop_rate);
141 planning_cycle_time, vehicle_state);
142 if (FLAGS_calculate_next_trajectory &&
143 last_trajctory_point.has_path_point() && !is_stop_due_to_fallback) {
144 last_trajctory_point.mutable_path_point()->set_s(0.0);
145 last_trajctory_point.set_v(0.1);
146 last_trajctory_point.set_relative_time(0.1);
147 stitching_trajectory =
148 std::vector<TrajectoryPoint>(1, last_trajctory_point);
150 for (
auto& trajectorypoint : stitching_trajectory) {
151 AINFO <<
"stitching_trajectory: " << trajectorypoint.DebugString();
155 ->mutable_planning_status()
156 ->mutable_open_space()
157 ->set_position_init(
false);
164 ADEBUG <<
"Open space plan in multi-threads mode";
166 if (is_generation_thread_stop_) {
167 GenerateStopTrajectory(trajectory_data);
168 return Status(ErrorCode::OK,
"Parking finished");
172 std::vector<double> temp_target =
174 if (open_space_info.target_parking_spot_id() !=
"") {
175 double angle = open_space_info.open_space_end_pose()[2];
176 temp_target[0] = straight_trajectory_length_ *
cos(angle) +
177 open_space_info.open_space_end_pose()[0];
178 temp_target[1] = straight_trajectory_length_ *
sin(angle) +
179 open_space_info.open_space_end_pose()[1];
181 std::lock_guard<std::mutex> lock(open_space_mutex_);
183 thread_data_.
end_pose = temp_target;
184 thread_data_.
rotate_angle = open_space_info.origin_heading();
187 thread_data_.
obstacles_A = open_space_info.obstacles_A();
188 thread_data_.
obstacles_b = open_space_info.obstacles_b();
190 open_space_info.obstacles_vertices_vec();
191 thread_data_.
XYbounds = open_space_info.ROI_xy_boundary();
192 data_ready_.store(
true);
195 std::lock_guard<std::mutex> lock(open_space_mutex_);
196 data_ready_.store(
false);
200 if (IsVehicleNearDestination(
201 vehicle_state, open_space_info.open_space_end_pose(),
202 open_space_info.origin_heading(), open_space_info.origin_point())) {
203 GenerateStopTrajectory(trajectory_data);
205 AINFO <<
"Vehicle is near to destination";
206 return Status(ErrorCode::OK,
"Vehicle is near to destination");
210 if (trajectory_updated_) {
211 std::lock_guard<std::mutex> lock(open_space_mutex_);
212 LoadResult(trajectory_data);
213 if (FLAGS_enable_record_debug) {
216 open_space_trajectory_optimizer_->UpdateDebugInfo(
217 ptr_debug->mutable_planning_data()->mutable_open_space());
222 AINFO <<
"Trajectory Update" << trajectory_data->size();
223 data_ready_.store(
false);
224 trajectory_updated_.store(
false);
228 if (trajectory_error_) {
230 ++optimizer_thread_counter;
231 std::lock_guard<std::mutex> lock(open_space_mutex_);
232 trajectory_error_.store(
false);
237 if (optimizer_thread_counter > 1000) {
238 return Status(ErrorCode::PLANNING_ERROR,
239 "open_space_optimizer failed too many times");
243 if (previous_frame &&
244 previous_frame->open_space_info().open_space_provider_success() &&
246 ReuseLastFrameResult(previous_frame, trajectory_data);
247 if (FLAGS_enable_record_debug) {
249 ReuseLastFrameDebug(previous_frame);
252 AINFO <<
"ReuseLastFrameResult";
253 return Status(ErrorCode::OK,
254 "Waiting for open_space_trajectory_optimizer in "
255 "open_space_trajectory_provider");
257 AINFO <<
"Stop due to computation not finished";
258 if (previous_frame && !previous_frame->open_space_info()
259 .stitched_trajectory_result()
262 previous_frame->open_space_info().stitched_trajectory_result();
264 GenerateStopTrajectory(trajectory_data);
266 return Status(ErrorCode::OK,
"Stop due to computation not finished");
269 const auto& end_pose = open_space_info.open_space_end_pose();
270 const auto& rotate_angle = open_space_info.origin_heading();
271 const auto& translate_origin = open_space_info.origin_point();
272 const auto& obstacles_edges_num = open_space_info.obstacles_edges_num();
273 const auto& obstacles_A = open_space_info.obstacles_A();
274 const auto& obstacles_b = open_space_info.obstacles_b();
275 const auto& obstacles_vertices_vec =
276 open_space_info.obstacles_vertices_vec();
277 const auto& XYbounds = open_space_info.ROI_xy_boundary();
280 if (IsVehicleNearDestination(vehicle_state, end_pose, rotate_angle,
282 GenerateStopTrajectory(trajectory_data);
283 return Status(ErrorCode::OK,
"Vehicle is near to destination");
288 Status status = open_space_trajectory_optimizer_->Plan(
289 stitching_trajectory, end_pose, XYbounds, rotate_angle,
290 translate_origin, obstacles_edges_num, obstacles_A, obstacles_b,
291 obstacles_vertices_vec, &time_latency);
296 LoadResult(trajectory_data);
302 return Status(ErrorCode::PLANNING_ERROR);
305void OpenSpaceTrajectoryProvider::GenerateTrajectoryThread() {
306 while (!is_generation_thread_stop_) {
307 if (!trajectory_updated_ && data_ready_) {
308 OpenSpaceTrajectoryThreadData thread_data;
310 std::lock_guard<std::mutex> lock(open_space_mutex_);
311 thread_data = thread_data_;
314 Status status = open_space_trajectory_optimizer_->Plan(
315 thread_data.stitching_trajectory, thread_data.end_pose,
316 thread_data.XYbounds, thread_data.rotate_angle,
317 thread_data.translate_origin, thread_data.obstacles_edges_num,
318 thread_data.obstacles_A, thread_data.obstacles_b,
319 thread_data.obstacles_vertices_vec, &time_latency);
322 std::lock_guard<std::mutex> lock(open_space_mutex_);
323 trajectory_updated_.store(
true);
326 std::lock_guard<std::mutex> lock(open_space_mutex_);
327 trajectory_skipped_.store(
true);
329 std::lock_guard<std::mutex> lock(open_space_mutex_);
330 trajectory_error_.store(
true);
337bool OpenSpaceTrajectoryProvider::IsVehicleNearDestination(
338 const common::VehicleState& vehicle_state,
339 const std::vector<double>& end_pose,
double rotate_angle,
340 const Vec2d& translate_origin) {
341 CHECK_EQ(end_pose.size(), 4U);
342 Vec2d end_pose_to_world_frame = Vec2d(end_pose[0], end_pose[1]);
344 end_pose_to_world_frame.SelfRotate(rotate_angle);
345 end_pose_to_world_frame += translate_origin;
347 double end_theta_to_world_frame = end_pose[2];
348 end_theta_to_world_frame += rotate_angle;
349 const double max_adc_stop_speed = common::VehicleConfigHelper::Instance()
352 .max_abs_speed_when_stopped();
353 if (std::fabs(vehicle_state.linear_velocity()) > max_adc_stop_speed) {
356 double distance_to_vehicle =
357 std::sqrt((vehicle_state.x() - end_pose_to_world_frame.x()) *
358 (vehicle_state.x() - end_pose_to_world_frame.x()) +
359 (vehicle_state.y() - end_pose_to_world_frame.y()) *
360 (vehicle_state.y() - end_pose_to_world_frame.y()));
363 vehicle_state.heading(), end_theta_to_world_frame));
364 ADEBUG <<
"theta_to_vehicle" << theta_to_vehicle <<
"end_theta_to_world_frame"
365 << end_theta_to_world_frame <<
"rotate_angle" << rotate_angle;
366 ADEBUG <<
"near_destination_threshold"
370 ADEBUG <<
"is_near_destination_theta_threshold"
380 ADEBUG <<
"vehicle reach end_pose";
388bool OpenSpaceTrajectoryProvider::IsVehicleStopDueToFallBack(
389 const bool is_on_fallback,
const common::VehicleState& vehicle_state) {
390 if (!is_on_fallback) {
393 static constexpr double kEpsilon = 1.0e-1;
394 const double adc_speed = vehicle_state.linear_velocity();
395 if (std::abs(adc_speed) < kEpsilon) {
396 AINFO <<
"ADC stops due to fallback trajectory";
399 AINFO <<
"set fallback but adc not stop" << adc_speed;
403void OpenSpaceTrajectoryProvider::GenerateStopTrajectory(
404 DiscretizedTrajectory*
const trajectory_data) {
405 double relative_time = 0.0;
407 static constexpr int stop_trajectory_length = 10;
408 static constexpr double relative_stop_time = 0.1;
409 static constexpr double vEpsilon = 0.00001;
410 double standstill_acceleration =
414 trajectory_data->clear();
415 for (
size_t i = 0; i < stop_trajectory_length; i++) {
416 TrajectoryPoint point;
420 point.mutable_path_point()->set_s(0.0);
421 point.mutable_path_point()->set_kappa(0.0);
422 point.set_relative_time(relative_time);
424 point.set_a(standstill_acceleration);
425 trajectory_data->emplace_back(point);
426 relative_time += relative_stop_time;
430void OpenSpaceTrajectoryProvider::LoadResult(
431 DiscretizedTrajectory*
const trajectory_data) {
433 trajectory_data->clear();
434 auto optimizer_trajectory_ptr =
436 auto stitching_trajectory_ptr =
438 open_space_trajectory_optimizer_->GetOptimizedTrajectory(
439 optimizer_trajectory_ptr);
440 open_space_trajectory_optimizer_->GetStitchingTrajectory(
441 stitching_trajectory_ptr);
443 size_t optimizer_trajectory_size = optimizer_trajectory_ptr->size();
444 double stitching_point_relative_time =
445 stitching_trajectory_ptr->back().relative_time();
446 double stitching_point_relative_s =
447 stitching_trajectory_ptr->back().path_point().s();
448 for (
size_t i = 0; i < optimizer_trajectory_size; ++i) {
449 optimizer_trajectory_ptr->at(i).set_relative_time(
450 optimizer_trajectory_ptr->at(i).relative_time() +
451 stitching_point_relative_time);
452 optimizer_trajectory_ptr->at(i).mutable_path_point()->set_s(
453 optimizer_trajectory_ptr->at(i).path_point().s() +
454 stitching_point_relative_s);
458 double distance = straight_trajectory_length_;
460 double t = distance / v * 2;
462 double start_x = optimizer_trajectory_ptr->back().path_point().x();
463 double start_y = optimizer_trajectory_ptr->back().path_point().y();
464 double start_time = optimizer_trajectory_ptr->back().relative_time();
465 std::vector<double> end_pose =
467 double unit_x = -
cos(optimizer_trajectory_ptr->back().path_point().theta());
468 double unit_y = -
sin(optimizer_trajectory_ptr->back().path_point().theta());
469 for (
size_t i = 1; i <= t / 0.1; i++) {
470 double x = 0, y = 0, v_now = 0, a_now = 0;
471 v_now = v - a * i * 0.1;
473 double scale = (v + v_now) / 2 * i * 0.1;
476 ADEBUG << start_x + x <<
", " << start_y + y <<
", "
477 << start_time + 0.1 * i <<
", " << v_now <<
", " << a_now;
478 TrajectoryPoint point;
479 point.mutable_path_point()->set_x(start_x + x);
480 point.mutable_path_point()->set_y(start_y + y);
481 point.mutable_path_point()->set_theta(
482 optimizer_trajectory_ptr->back().path_point().theta());
483 point.mutable_path_point()->set_s(0.0);
484 point.mutable_path_point()->set_kappa(0.0);
485 point.set_relative_time(start_time + 0.1 * i);
488 optimizer_trajectory_ptr->push_back(point);
491 *(trajectory_data) = *(optimizer_trajectory_ptr);
498 trajectory_data->PrependTrajectoryPoints(
503void OpenSpaceTrajectoryProvider::ReuseLastFrameResult(
504 const Frame* last_frame, DiscretizedTrajectory*
const trajectory_data) {
506 last_frame->open_space_info().stitched_trajectory_result();
510void OpenSpaceTrajectoryProvider::ReuseLastFrameDebug(
const Frame* last_frame) {
513 ptr_debug->mutable_planning_data()->mutable_open_space()->MergeFrom(
514 last_frame->open_space_info()
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
Implements a class of 2-dimensional vectors.
a singleton clock that can be used to get the current timestamp.
const OpenSpaceInfo & open_space_info() const
const common::VehicleState & vehicle_state() const
OpenSpaceInfo * mutable_open_space_info()
void set_destination_reached(const bool flag)
apollo::planning_internal::Debug * mutable_debug_instance()
const std::vector< common::TrajectoryPoint > & stitching_trajectory_data() const
void sync_debug_instance()
const std::vector< double > & open_space_end_pose() const
const std::string target_parking_spot_id() const
std::vector< common::TrajectoryPoint > * mutable_stitching_trajectory_data()
void set_time_latency(double time_latency)
void set_open_space_provider_success(const bool flag)
void set_openspace_planning_finish(const bool flag)
DiscretizedTrajectory * mutable_optimizer_trajectory_data()
DiscretizedTrajectory * mutable_stitched_trajectory_result()
apollo::planning_internal::Debug * mutable_debug()
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
~OpenSpaceTrajectoryProvider()
std::shared_ptr< DependencyInjector > injector_
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
static std::vector< common::TrajectoryPoint > ComputeReinitStitchingTrajectory(const double planning_cycle_time, const common::VehicleState &vehicle_state)
Planning module main class.
double AngleDiff(const double from, const double to)
Calculate the difference between angle from and to
optional double linear_velocity
optional PlannerOpenSpaceConfig planner_open_space_config
optional bool enable_open_space_planner_thread
optional double open_space_standstill_acceleration
optional OpenSpaceTrajectoryOptimizerConfig open_space_trajectory_optimizer_config
optional double open_space_straight_trajectory_length
apollo::common::math::Vec2d translate_origin
Eigen::MatrixXi obstacles_edges_num
std::vector< double > end_pose
Eigen::MatrixXd obstacles_b
Eigen::MatrixXd obstacles_A
std::vector< common::TrajectoryPoint > stitching_trajectory
std::vector< double > XYbounds
std::vector< std::vector< common::math::Vec2d > > obstacles_vertices_vec
optional double near_destination_threshold
optional double is_near_destination_theta_threshold