61 {
62 if (XYbounds.empty() || end_pose.empty() || obstacles_edges_num.cols() == 0 ||
63 obstacles_A.cols() == 0 || obstacles_b.cols() == 0) {
64 ADEBUG <<
"OpenSpaceTrajectoryOptimizer input data not ready";
65 AERROR << XYbounds.empty() << end_pose.empty() << obstacles_edges_num.cols()
66 << obstacles_A.cols() << obstacles_b.cols();
67 return Status(ErrorCode::PLANNING_ERROR,
68 "OpenSpaceTrajectoryOptimizer input data not ready");
69 }
70 CHECK(!stitching_trajectory.empty());
71
72 if (IsInitPointNearDestination(stitching_trajectory.back(), end_pose,
73 rotate_angle, translate_origin)) {
74 AINFO <<
"Planning init point is close to destination, skip new "
75 "trajectory generation";
76 return Status(ErrorCode::OK,
77 "Planning init point is close to destination, skip new "
78 "trajectory generation");
79 }
80
81 const auto start_timestamp = std::chrono::system_clock::now();
82
83
84 stitching_trajectory_ = stitching_trajectory;
85
86
87 const common::TrajectoryPoint trajectory_stitching_point =
88 stitching_trajectory.back();
89
90
91 double init_x = trajectory_stitching_point.path_point().x();
92 double init_y = trajectory_stitching_point.path_point().y();
93 double init_phi = trajectory_stitching_point.path_point().theta();
94 AINFO <<
"origin_point: (" << std::setprecision(9) << translate_origin.x()
95 << "," << translate_origin.y() << ")";
96 AINFO <<
"origin_heading:" << std::setprecision(9) << rotate_angle <<
",";
97 AINFO <<
"init_point: ( " << std::setprecision(9) << init_x <<
"," << init_y
98 << ")";
99 AINFO <<
"end_pose: (" << std::setprecision(9) << end_pose[0] <<
"," << end_pose[1]
100 << ")";
101
102
103 PathPointNormalizing(rotate_angle, translate_origin, &init_x, &init_y,
104 &init_phi);
105
106
107
108 HybridAStartResult result;
109
110 if (warm_start_->Plan(init_x, init_y, init_phi, end_pose[0], end_pose[1],
111 end_pose[2], XYbounds, obstacles_vertices_vec,
112 &result)) {
113 AINFO <<
"State warm start problem solved successfully!";
114 } else {
115 AERROR <<
"State warm start problem failed to solve";
116 return Status(ErrorCode::PLANNING_ERROR,
117 "State warm start problem failed to solve");
118 }
119
120
121 Eigen::MatrixXd xWS;
122 Eigen::MatrixXd uWS;
123 Eigen::MatrixXd state_result_ds;
124 Eigen::MatrixXd control_result_ds;
125 Eigen::MatrixXd time_result_ds;
126 Eigen::MatrixXd l_warm_up;
127 Eigen::MatrixXd n_warm_up;
128 Eigen::MatrixXd dual_l_result_ds;
129 Eigen::MatrixXd dual_n_result_ds;
130
131 if (FLAGS_enable_parallel_trajectory_smoothing) {
132 std::vector<HybridAStartResult> partition_trajectories;
133 if (!warm_start_->TrajectoryPartition(result, &partition_trajectories)) {
134 return Status(ErrorCode::PLANNING_ERROR,
"Hybrid Astar partition failed");
135 }
136 size_t size = partition_trajectories.size();
137 std::vector<Eigen::MatrixXd> xWS_vec;
138 std::vector<Eigen::MatrixXd> uWS_vec;
139 std::vector<Eigen::MatrixXd> state_result_ds_vec;
140 std::vector<Eigen::MatrixXd> control_result_ds_vec;
141 std::vector<Eigen::MatrixXd> time_result_ds_vec;
142 std::vector<Eigen::MatrixXd> l_warm_up_vec;
143 std::vector<Eigen::MatrixXd> n_warm_up_vec;
144 std::vector<Eigen::MatrixXd> dual_l_result_ds_vec;
145 std::vector<Eigen::MatrixXd> dual_n_result_ds_vec;
146 xWS_vec.resize(size);
147 uWS_vec.resize(size);
148 state_result_ds_vec.resize(size);
149 control_result_ds_vec.resize(size);
150 time_result_ds_vec.resize(size);
151 l_warm_up_vec.resize(size);
152 n_warm_up_vec.resize(size);
153 dual_l_result_ds_vec.resize(size);
154 dual_n_result_ds_vec.resize(size);
155
156
157 ADEBUG <<
"Trajectories size in smoother is " << size;
158 for (size_t i = 0; i < size; ++i) {
159 LoadHybridAstarResultInEigen(&partition_trajectories[i], &xWS_vec[i],
160 &uWS_vec[i]);
161 Eigen::MatrixXd last_time_u(2, 1);
162 double init_v = 0.0;
163
164
165
166 if (i == 0) {
167 const double init_steer = trajectory_stitching_point.steer();
168 const double init_a = trajectory_stitching_point.a();
169 last_time_u << init_steer, init_a;
170 init_v = trajectory_stitching_point.v();
171 } else {
172 last_time_u << 0.0, 0.0;
173 init_v = 0.0;
174 }
175
176 const auto smoother_start_timestamp = std::chrono::system_clock::now();
177 if (FLAGS_use_iterative_anchoring_smoother) {
178 AINFO <<
"use iterative anchoring smoother";
179 if (!GenerateDecoupledTraj(
180 xWS_vec[i], last_time_u(1, 0), init_v, obstacles_vertices_vec,
181 &state_result_ds_vec[i], &control_result_ds_vec[i],
182 &time_result_ds_vec[i])) {
183 AERROR <<
"Smoother fail at " << i <<
"th trajectory";
184 AERROR << i <<
"th trajectory size is " << xWS_vec[i].cols();
186 ErrorCode::PLANNING_ERROR,
187 "iterative anchoring smoothing problem failed to solve");
188 }
189 } else {
190 const double start_system_timestamp =
191 std::chrono::duration<double>(
192 std::chrono::system_clock::now().time_since_epoch())
193 .count();
194 AINFO <<
"use distance approach parallel smoother";
195 if (!GenerateDistanceApproachTraj(
196 xWS_vec[i], uWS_vec[i], XYbounds, obstacles_edges_num,
197 obstacles_A, obstacles_b, obstacles_vertices_vec, last_time_u,
198 init_v, &state_result_ds_vec[i], &control_result_ds_vec[i],
199 &time_result_ds_vec[i], &l_warm_up_vec[i], &n_warm_up_vec[i],
200 &dual_l_result_ds_vec[i], &dual_n_result_ds_vec[i])) {
201 AERROR <<
"Smoother fail at " << i
202 << "th trajectory with index starts from 0";
203 AERROR << i <<
"th trajectory size is " << xWS_vec[i].cols();
204 AERROR <<
"State matrix: " << xWS_vec[i];
205 AERROR <<
"Control matrix: " << uWS_vec[i];
206 return Status(ErrorCode::PLANNING_ERROR,
207 "distance approach smoothing problem failed to solve");
208 }
209 const auto end_system_timestamp =
210 std::chrono::duration<double>(
211 std::chrono::system_clock::now().time_since_epoch())
212 .count();
213 const auto time_diff_ms =
214 (end_system_timestamp - start_system_timestamp) * 1000;
215 ADEBUG <<
"total planning time spend: " << time_diff_ms <<
" ms.";
216 ADEBUG << i <<
"th trajectory size is " << xWS_vec[i].cols();
217 ADEBUG <<
"average time spend: " << time_diff_ms / xWS_vec[i].cols()
218 << " ms per point.";
219 ADEBUG <<
"average time spend after smooth: "
220 << time_diff_ms / state_result_ds_vec[i].cols()
221 << " ms per point.";
222 ADEBUG << i <<
"th smoothed trajectory size is "
223 << state_result_ds_vec[i].cols();
224 }
225 const auto smoother_end_timestamp = std::chrono::system_clock::now();
226 std::chrono::duration<double> smoother_diff =
227 smoother_end_timestamp - smoother_start_timestamp;
228 AINFO <<
"Open space trajectory smoothing total time: "
229 << smoother_diff.count() * 1000.0 << " ms at the " << i
230 << "th trajectory.";
231 AINFO <<
"The " << i <<
"th trajectory pre-smoothing size is "
232 << xWS_vec[i].cols() << "; post-smoothing size is "
233 << state_result_ds_vec[i].cols();
234 }
235
236
237 CombineTrajectories(xWS_vec, uWS_vec, state_result_ds_vec,
238 control_result_ds_vec, time_result_ds_vec,
239 l_warm_up_vec, n_warm_up_vec, dual_l_result_ds_vec,
240 dual_n_result_ds_vec, &xWS, &uWS, &state_result_ds,
241 &control_result_ds, &time_result_ds, &l_warm_up,
242 &n_warm_up, &dual_l_result_ds, &dual_n_result_ds);
243
244 } else {
245 AINFO <<
"use distance approach smoother";
246 LoadHybridAstarResultInEigen(&result, &xWS, &uWS);
247
248 const double init_steer = trajectory_stitching_point.steer();
249 const double init_a = trajectory_stitching_point.a();
250 Eigen::MatrixXd last_time_u(2, 1);
251 last_time_u << init_steer, init_a;
252
253 const double init_v = trajectory_stitching_point.v();
254 FLAGS_use_iterative_anchoring_smoother = false;
255 if (!GenerateDistanceApproachTraj(
256 xWS, uWS, XYbounds, obstacles_edges_num, obstacles_A, obstacles_b,
257 obstacles_vertices_vec, last_time_u, init_v, &state_result_ds,
258 &control_result_ds, &time_result_ds, &l_warm_up, &n_warm_up,
259 &dual_l_result_ds, &dual_n_result_ds)) {
260 return Status(ErrorCode::PLANNING_ERROR,
261 "distance approach smoothing problem failed to solve");
262 }
263 }
264
265
266 if (FLAGS_enable_record_debug) {
267 open_space_debug_.Clear();
268 RecordDebugInfo(trajectory_stitching_point, translate_origin, rotate_angle,
269 end_pose, xWS, uWS, l_warm_up, n_warm_up, dual_l_result_ds,
270 dual_n_result_ds, state_result_ds, control_result_ds,
271 time_result_ds, XYbounds, obstacles_vertices_vec);
272 }
273
274
275 size_t state_size = state_result_ds.cols();
276 for (size_t i = 0; i < state_size; ++i) {
277 PathPointDeNormalizing(rotate_angle, translate_origin,
278 &(state_result_ds(0, i)), &(state_result_ds(1, i)),
279 &(state_result_ds(2, i)));
280 }
281
282 LoadTrajectory(state_result_ds, control_result_ds, time_result_ds);
283
284 const auto end_timestamp = std::chrono::system_clock::now();
285 std::chrono::duration<double>
diff = end_timestamp - start_timestamp;
286 ADEBUG <<
"open space trajectory smoother total time: "
287 <<
diff.count() * 1000.0 <<
" ms.";
288 *time_latency =
diff.count() * 1000.0;
289
291}
static Status OK()
generate a success status.
void RecordDebugInfo(const common::TrajectoryPoint &trajectory_stitching_point, const common::math::Vec2d &translate_origin, const double rotate_angle, const std::vector< double > &end_pose, const Eigen::MatrixXd &xWS, const Eigen::MatrixXd &uWs, const Eigen::MatrixXd &l_warm_up, const Eigen::MatrixXd &n_warm_up, const Eigen::MatrixXd &dual_l_result_ds, const Eigen::MatrixXd &dual_n_result_ds, const Eigen::MatrixXd &state_result_ds, const Eigen::MatrixXd &control_result_ds, const Eigen::MatrixXd &time_result_ds, const std::vector< double > &XYbounds, const std::vector< std::vector< common::math::Vec2d > > &obstacles_vertices_vec)
float diff(Image< float > *I, int x1, int y1, int x2, int y2)
Dissimilarity measure between pixels