compute brake / throttle values based on current vehicle status and target trajectory
173 {
174 localization_ = localization;
175 chassis_ = chassis;
176 trajectory_message_ = planning_published_trajectory;
177
178 if (!control_interpolation_) {
179 AERROR <<
"Fail to initialize calibration table.";
180 return Status(ErrorCode::CONTROL_COMPUTE_ERROR,
181 "Fail to initialize calibration table.");
182 }
183
184 if (trajectory_analyzer_ == nullptr ||
185 trajectory_analyzer_->seq_num() !=
187 trajectory_analyzer_.reset(new TrajectoryAnalyzer(trajectory_message_));
188 }
189
190 auto debug = cmd->mutable_debug()->mutable_simple_lon_debug();
191 debug->Clear();
192
193 double brake_cmd = 0.0;
194 double throttle_cmd = 0.0;
195 double ts = lon_based_pidcontroller_conf_.ts();
196 double preview_time = lon_based_pidcontroller_conf_.preview_window() * ts;
197 bool enable_leadlag =
198 lon_based_pidcontroller_conf_.enable_reverse_leadlag_compensation();
199
200 if (preview_time < 0.0) {
201 const auto error_msg =
202 absl::StrCat("Preview time set as: ", preview_time, " less than 0");
204 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, error_msg);
205 }
207 debug);
208
209 double station_error_limit =
210 lon_based_pidcontroller_conf_.station_error_limit();
211 double station_error_limited = 0.0;
212 if (lon_based_pidcontroller_conf_.enable_speed_station_preview()) {
213 station_error_limited =
215 -station_error_limit, station_error_limit);
216 } else {
218 debug->station_error(), -station_error_limit, station_error_limit);
219 }
220
223 injector_->vehicle_state()->linear_velocity(),
226 station_pid_controller_.
SetPID(
227 lon_based_pidcontroller_conf_.pit_station_pid_conf());
228 speed_pid_controller_.
SetPID(
229 lon_based_pidcontroller_conf_.pit_speed_pid_conf());
230 } else {
231 station_pid_controller_.
SetPID(
232 lon_based_pidcontroller_conf_.reverse_station_pid_conf());
233 speed_pid_controller_.
SetPID(
234 lon_based_pidcontroller_conf_.reverse_speed_pid_conf());
235 }
236 if (enable_leadlag) {
238 lon_based_pidcontroller_conf_.reverse_station_leadlag_conf());
240 lon_based_pidcontroller_conf_.reverse_speed_leadlag_conf());
241 }
242 }
else if (
injector_->vehicle_state()->linear_velocity() <=
243 lon_based_pidcontroller_conf_.switch_speed()) {
245 injector_->vehicle_state()->linear_velocity(),
248 station_pid_controller_.
SetPID(
249 lon_based_pidcontroller_conf_.pit_station_pid_conf());
250 speed_pid_controller_.
SetPID(
251 lon_based_pidcontroller_conf_.pit_speed_pid_conf());
252 } else {
253 station_pid_controller_.
SetPID(
254 lon_based_pidcontroller_conf_.station_pid_conf());
255 speed_pid_controller_.
SetPID(
256 lon_based_pidcontroller_conf_.low_speed_pid_conf());
257 }
258 } else {
259 station_pid_controller_.
SetPID(
260 lon_based_pidcontroller_conf_.station_pid_conf());
261 speed_pid_controller_.
SetPID(
262 lon_based_pidcontroller_conf_.high_speed_pid_conf());
263 }
264
265 double speed_offset =
266 station_pid_controller_.
Control(station_error_limited, ts);
267 if (enable_leadlag) {
268 speed_offset = station_leadlag_controller_.
Control(speed_offset, ts);
269 }
270
271 double speed_controller_input = 0.0;
272 double speed_controller_input_limit =
273 lon_based_pidcontroller_conf_.speed_controller_input_limit();
274 double speed_controller_input_limited = 0.0;
275 if (lon_based_pidcontroller_conf_.enable_speed_station_preview()) {
276 speed_controller_input = speed_offset + debug->preview_speed_error();
277 } else {
278 speed_controller_input = speed_offset + debug->speed_error();
279 }
280 speed_controller_input_limited =
282 speed_controller_input_limit);
283
284 double acceleration_cmd_closeloop = 0.0;
285
286 acceleration_cmd_closeloop =
287 speed_pid_controller_.
Control(speed_controller_input_limited, ts);
288 debug->set_pid_saturation_status(
290 if (enable_leadlag) {
291 acceleration_cmd_closeloop =
292 speed_leadlag_controller_.
Control(acceleration_cmd_closeloop, ts);
293 debug->set_leadlag_saturation_status(
295 }
296
300 }
301
302 double vehicle_pitch_rad =
303 digital_filter_pitch_angle_.
Filter(
injector_->vehicle_state()->pitch());
304 double vehicle_pitch =
305 vehicle_pitch_rad * 180 / M_PI + FLAGS_pitch_offset_deg;
306 ADEBUG <<
"[LON]vehicle_pitch is " << vehicle_pitch;
307 debug->set_vehicle_pitch(vehicle_pitch);
308
309
310
311 double slope_offset_compensation =
312 lon_based_pidcontroller_conf_.use_opposite_slope_compensation() *
314 std::sin(vehicle_pitch_rad + FLAGS_pitch_offset_deg * M_PI / 180);
315
316 if (std::isnan(slope_offset_compensation)) {
317 slope_offset_compensation = 0;
318 }
319
320 debug->set_slope_offset_compensation(slope_offset_compensation);
321
322 double acceleration_cmd =
323 acceleration_cmd_closeloop + debug->preview_acceleration_reference() +
324 lon_based_pidcontroller_conf_.enable_slope_offset() *
325 debug->slope_offset_compensation();
326
327
328
329
330 double current_steer_interval =
331 cmd->steering_target() - chassis->steering_percentage();
332 if (lon_based_pidcontroller_conf_.use_steering_check() &&
335 std::abs(current_steer_interval) >
336 lon_based_pidcontroller_conf_.steer_cmd_interval()) {
337 ADEBUG <<
"steering_target is " << cmd->steering_target()
338 << " steering_percentage is " << chassis->steering_percentage();
339 ADEBUG <<
"Steer cmd interval is larger than "
340 << lon_based_pidcontroller_conf_.steer_cmd_interval();
341
344 acceleration_cmd = 0;
345 debug->set_is_wait_steer(true);
346 } else {
347 debug->set_is_wait_steer(false);
348 }
349 debug->set_current_steer_interval(current_steer_interval);
350
351
352
353 debug->set_is_full_stop(false);
354 debug->set_is_full_stop_soft(false);
355 auto previous_full_stop =
356 injector_->Get_previous_lon_debug_info()->is_full_stop();
358 IsStopByDestination(debug);
359 IsPedestrianStopLongTerm(debug);
360 if (lon_based_pidcontroller_conf_.use_preview_reference_check() &&
361 (std::fabs(debug->preview_acceleration_reference()) <=
362 FLAGS_max_acceleration_when_stopped) &&
363 std::fabs(debug->preview_speed_reference()) <=
366 if (debug->is_stop_reason_by_destination() ||
367 debug->is_stop_reason_by_prdestrian()) {
368 debug->set_is_full_stop(true);
369 ADEBUG <<
"Into full stop within preview acc and reference speed, "
370 << "is_full_stop is " << debug->is_full_stop();
371 } else {
372 debug->set_is_full_stop_soft(true);
373 ADEBUG <<
"Into full stop soft within preview acc and reference speed, "
374 << "is_full_stop_soft is " << debug->is_full_stop_soft();
375 }
376 }
377
378 if (!previous_full_stop) {
379 max_path_remain_when_stopped_ = FLAGS_max_path_remain_when_stopped;
380 } else {
381 max_path_remain_when_stopped_ =
382 FLAGS_max_path_remain_when_stopped +
383 lon_based_pidcontroller_conf_.full_stop_path_remain_gain();
384 }
385
387 debug->path_remain() < max_path_remain_when_stopped_) ||
389 debug->path_remain() > -max_path_remain_when_stopped_)) {
390 ADEBUG <<
"Into full stop decision by path remain.";
391 if (debug->is_stop_reason_by_destination() ||
392 debug->is_stop_reason_by_prdestrian()) {
393 debug->set_is_full_stop(true);
394 ADEBUG <<
"Current path remain distance: " << debug->path_remain()
395 << " is within max_path_remain threshold: "
396 << max_path_remain_when_stopped_
397 << ", into full stop because vehicle is in destination: "
398 << debug->is_stop_reason_by_destination()
399 << " or pedestrian is in long time stop: "
400 << debug->is_stop_reason_by_prdestrian()
401 << "is_full_stop flag: " << debug->is_full_stop();
402 } else {
403 debug->set_is_full_stop_soft(true);
404 ADEBUG <<
"Current path remain distance: " << debug->path_remain()
405 << " is within max_path_remain threshold: "
406 << max_path_remain_when_stopped_
407 << ", but not into full stop because stop not in destination: "
408 << debug->is_stop_reason_by_destination()
409 << " or pedestrian is not long time stop: "
410 << debug->is_stop_reason_by_prdestrian()
411 << "is_full_stop_soft flag: " << debug->is_full_stop_soft();
412 }
413 if (
injector_->vehicle_state()->linear_velocity() <
415 debug->is_stop_reason_by_prdestrian()) {
416 ADEBUG <<
"Current stop is for long time pedestrian stop, "
417 << debug->is_stop_reason_by_prdestrian();
418 debug->set_is_full_stop(true);
419 }
420 } else {
421 ADEBUG <<
"Not into full stop decision by path remain.";
422 }
423
424 if (debug->is_full_stop()) {
425 acceleration_cmd =
427 ? std::max(acceleration_cmd,
428 -lon_based_pidcontroller_conf_.standstill_acceleration())
429 :
std::min(acceleration_cmd,
430 lon_based_pidcontroller_conf_.standstill_acceleration());
433 }
434
435 if (debug->is_full_stop_soft()) {
437 acceleration_cmd =
438 (acceleration_cmd >= 0) ? standstill_narmal_acceleration_
439 : (debug->path_remain() >= 0) ? acceleration_cmd
440 : (trajectory_message_->trajectory_type() != ADCTrajectory::
NORMAL)
441 ? (acceleration_cmd + stop_gain_acceleration_)
442 : (acceleration_cmd + standstill_narmal_acceleration_);
443 } else {
444 acceleration_cmd =
445 (acceleration_cmd <= 0) ? -standstill_narmal_acceleration_
446 : (debug->path_remain() <= 0) ? acceleration_cmd
447 : (trajectory_message_->trajectory_type() != ADCTrajectory::
NORMAL)
448 ? (acceleration_cmd - stop_gain_acceleration_)
449 : (acceleration_cmd - standstill_narmal_acceleration_);
450 }
453 }
454
455 double throttle_lowerbound =
457 lon_based_pidcontroller_conf_.throttle_minimum_action());
458 double brake_lowerbound =
460 lon_based_pidcontroller_conf_.brake_minimum_action());
461 double calibration_value = 0.0;
462 double acceleration_lookup =
464 ? -acceleration_cmd
465 : acceleration_cmd;
466
467 double acceleration_lookup_limited =
469 lon_based_pidcontroller_conf_.enable_slope_offset() *
470 debug->slope_offset_compensation();
471 double acceleration_lookup_limit = 0.0;
472
473 if (lon_based_pidcontroller_conf_.use_acceleration_lookup_limit()) {
474 acceleration_lookup_limit =
475 (acceleration_lookup > acceleration_lookup_limited)
476 ? acceleration_lookup_limited
477 : acceleration_lookup;
478 }
479
480 if (FLAGS_use_preview_speed_for_table) {
481 if (lon_based_pidcontroller_conf_.use_acceleration_lookup_limit()) {
482 calibration_value = control_interpolation_->Interpolate(
483 std::make_pair(std::fabs(debug->preview_speed_reference()),
484 acceleration_lookup_limit));
485 } else {
486 calibration_value = control_interpolation_->Interpolate(std::make_pair(
487 std::fabs(debug->preview_speed_reference()), acceleration_lookup));
488 }
489 } else {
490 if (lon_based_pidcontroller_conf_.use_acceleration_lookup_limit()) {
491 calibration_value = control_interpolation_->Interpolate(std::make_pair(
492 std::fabs(
injector_->vehicle_state()->linear_velocity()),
493 acceleration_lookup_limit));
494 } else {
495 calibration_value = control_interpolation_->Interpolate(std::make_pair(
496 std::fabs(
injector_->vehicle_state()->linear_velocity()),
497 acceleration_lookup));
498 }
499 }
500
501 if (acceleration_lookup >= 0) {
502 if (calibration_value >= 0) {
503 throttle_cmd = std::max(calibration_value, throttle_lowerbound);
504 } else {
505 throttle_cmd = throttle_lowerbound;
506 }
507 brake_cmd = 0.0;
508 } else {
509 throttle_cmd = 0.0;
510 if (calibration_value >= 0) {
511 brake_cmd = brake_lowerbound;
512 } else {
513 brake_cmd = std::max(-calibration_value, brake_lowerbound);
514 }
515 }
516
517 if (FLAGS_use_vehicle_epb) {
518 ADEBUG <<
"Into use vehicle epb.";
519 if (acceleration_lookup >= 0) {
520 if (debug->slope_offset_compensation() > 0) {
521 if (acceleration_lookup > debug->slope_offset_compensation()) {
522 parking_release_ = true;
523 }
524 } else {
525 parking_release_ = true;
526 }
527 if (chassis->parking_brake() && parking_release_) {
528 ADEBUG <<
"Into park brake release.";
529 cmd->set_parking_brake(false);
530 SetParkingBrake(&lon_based_pidcontroller_conf_, cmd);
531 }
532 } else {
533 cmd->set_parking_brake(false);
534 if (debug->is_full_stop() && IsFullStopLongTerm(debug)) {
535 ADEBUG <<
"Into park brake trigger.";
536 cmd->set_parking_brake(true);
537 if (chassis->parking_brake()) {
538 brake_cmd = 0.0;
539 }
540 }
541 }
542 }
543
544 debug->set_station_error_limited(station_error_limited);
545 debug->set_speed_offset(speed_offset);
546 debug->set_speed_controller_input_limited(speed_controller_input_limited);
547 debug->set_acceleration_cmd(acceleration_cmd);
548 debug->set_throttle_cmd(throttle_cmd);
549 debug->set_brake_cmd(brake_cmd);
550 debug->set_acceleration_lookup(acceleration_lookup);
551 debug->set_acceleration_lookup_limit(acceleration_lookup_limit);
552 debug->set_speed_lookup(
injector_->vehicle_state()->linear_velocity());
553 debug->set_calibration_value(calibration_value);
554 debug->set_acceleration_cmd_closeloop(acceleration_cmd_closeloop);
555
556 if (FLAGS_enable_csv_debug && speed_log_file_ != nullptr) {
557 fprintf(speed_log_file_,
558 "%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f,"
559 "%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %d,\r\n",
560 debug->station_reference(), debug->station_error(),
561 station_error_limited, debug->preview_station_error(),
562 debug->speed_reference(), debug->speed_error(),
563 speed_controller_input_limited, debug->preview_speed_reference(),
564 debug->preview_speed_error(),
565 debug->preview_acceleration_reference(), acceleration_cmd_closeloop,
566 acceleration_cmd, debug->acceleration_lookup(),
567 debug->acceleration_lookup_limit(), debug->speed_lookup(),
568 calibration_value, throttle_cmd, brake_cmd, debug->is_full_stop());
569 }
570
571
572 cmd->set_throttle(throttle_cmd);
573 cmd->set_brake(brake_cmd);
574 if (lon_based_pidcontroller_conf_.use_acceleration_lookup_limit()) {
575 cmd->set_acceleration(acceleration_lookup_limit);
576 } else {
577 cmd->set_acceleration(acceleration_cmd);
578 }
579
580 if (std::fabs(
injector_->vehicle_state()->linear_velocity()) <=
582 chassis->gear_location() == trajectory_message_->
gear() ||
584 cmd->set_gear_location(trajectory_message_->
gear());
585 } else {
586 cmd->set_gear_location(chassis->gear_location());
587 }
588
589 if (lon_based_pidcontroller_conf_.use_speed_itfc()) {
590 reference_spd_cmd_ = reference_spd_ + debug->speed_offset();
591 if ((reference_spd_ <=
592 lon_based_pidcontroller_conf_.speed_itfc_full_stop_speed()) &&
594 if ((debug->path_remain() >=
595 lon_based_pidcontroller_conf_.speed_itfc_path_remain_min()) &&
596 (debug->preview_acceleration_reference() >=
597 lon_based_pidcontroller_conf_.speed_itfc_dcc_emergency()) &&
598 (debug->path_remain() <=
599 lon_based_pidcontroller_conf_.speed_itfc_path_remain_max())) {
600 if (debug->preview_acceleration_reference() <=
601 lon_based_pidcontroller_conf_.speed_itfc_acc_thres()) {
602 reference_spd_cmd_ =
603 lon_based_pidcontroller_conf_.speed_itfc_speed_cmd();
604 }
605 }
606 }
607 cmd->set_speed(reference_spd_cmd_);
608 }
609
611}
double Filter(const double x_insert)
Processes a new measurement with the filter.
static Status OK()
generate a success status.
static bool CheckInPit(SimpleLongitudinalDebug *debug, const LonBasedPidControllerConf *conf, double speed, bool replan)
void SetLeadlag(const LeadlagConf &leadlag_conf)
alpha, beta and tau
int InnerstateSaturationStatus() const
get saturation status
virtual double Control(const double error, const double dt)
compute control value based on the error
void GetPathRemain(SimpleLongitudinalDebug *debug)
void ComputeLongitudinalErrors(const TrajectoryAnalyzer *trajectory, const double preview_time, const double ts, SimpleLongitudinalDebug *debug)
std::shared_ptr< DependencyInjector > injector_
void Reset_integral()
reset integral for pid controller
void SetPID(const PidConf &pid_conf)
set pid controller coefficients for the proportional, integral, and derivative
virtual double Control(const double error, const double dt)
compute control value based on the error
int IntegratorSaturationStatus() const
get saturation status
T Clamp(const T value, T bound1, T bound2)
Clamp a value between two bounds.
optional double throttle_deadzone
optional double max_acceleration
optional float max_abs_speed_when_stopped
optional double brake_deadzone
optional TrajectoryType trajectory_type
optional apollo::canbus::Chassis::GearPosition gear
optional apollo::common::Header header