Apollo 11.0
自动驾驶开放平台
lon_plus_controller.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
17
18#include <algorithm>
19#include <utility>
20
21#include "absl/strings/str_cat.h"
22
23#include "modules/control/control_component/proto/pid_conf.pb.h"
24
25#include "cyber/common/log.h"
26#include "cyber/time/clock.h"
27#include "cyber/time/time.h"
31
32namespace apollo {
33namespace control {
34
43using apollo::planning::StopReasonCode;
44
45constexpr double GRA_ACC = 9.8;
46
47LonPlusController::LonPlusController() : name_("PID-basesd Longitudinal Plus Controller") {
48 // node_.reset(new apollo::cyber::Node("lon_plus_controller"));
49 if (FLAGS_enable_csv_debug) {
50 time_t rawtime;
51 char name_buffer[80];
52 std::time(&rawtime);
53 std::tm time_tm;
54 localtime_r(&rawtime, &time_tm);
55 strftime(name_buffer, 80, "/tmp/speed_log__%F_%H%M%S.csv", &time_tm);
56 speed_log_file_ = fopen(name_buffer, "w");
57 if (speed_log_file_ == nullptr) {
58 AERROR << "Fail to open file:" << name_buffer;
59 FLAGS_enable_csv_debug = false;
60 }
61 if (speed_log_file_ != nullptr) {
62 fprintf(speed_log_file_,
63 "station_reference,"
64 "station_error,"
65 "station_error_limited,"
66 "preview_station_error,"
67 "speed_reference,"
68 "speed_error,"
69 "speed_error_limited,"
70 "preview_speed_reference,"
71 "preview_speed_error,"
72 "preview_acceleration_reference,"
73 "acceleration_cmd_closeloop,"
74 "acceleration_cmd,"
75 "acceleration_lookup,"
76 "acceleration_lookup_limit,"
77 "speed_lookup,"
78 "calibration_value,"
79 "throttle_cmd,"
80 "brake_cmd,"
81 "is_full_stop,"
82 "\r\n");
83
84 fflush(speed_log_file_);
85 }
86 AINFO << name_ << " used.";
87 }
88}
89
90void LonPlusController::CloseLogFile() {
91 if (FLAGS_enable_csv_debug) {
92 if (speed_log_file_ != nullptr) {
93 fclose(speed_log_file_);
94 speed_log_file_ = nullptr;
95 }
96 }
97}
99 CloseLogFile();
100}
101
103 CloseLogFile();
104}
105
106Status LonPlusController::Init(std::shared_ptr<DependencyInjector> injector) {
107 if (!ControlTask::LoadConfig<LonBasedPidPlusControllerConf>(&lon_based_pidcontroller_conf_)) {
108 AERROR << "failed to load control default conf";
109 return Status(ErrorCode::CONTROL_INIT_ERROR, "failed to load lon control_conf");
110 }
111
112 if (!ControlTaskExtend::LoadParamsPipelineConfig<ParamsPipeline>(&params_pipeline_)) {
113 AERROR << "failed to load lon pid params pipeline config";
114 return Status(ErrorCode::CONTROL_INIT_ERROR, "failed to load lon pid params pipeline config");
115 }
116
117 if (!LoadParams(&params_pipeline_)) {
118 AERROR << "failed to load lon pid controller params.";
119 return Status(ErrorCode::CONTROL_INIT_ERROR, "failed to load lon pid params pipeline config");
120 }
121
122 injector_ = injector;
123
124 station_pid_controller_.InitPID();
125 speed_pid_controller_.InitPID();
126
127 station_leadlag_controller_.InitLeadlag();
128 speed_leadlag_controller_.InitLeadlag();
129
130 vehicle_param_.CopyFrom(common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param());
131
132 SetDigitalFilterPitchAngle();
133
134 controller_initialized_ = true;
135
136 return Status::OK();
137}
138
139bool LonPlusController::LoadParams(ParamsPipeline *params_pipeline) {
140 for (int i = 0; i < params_pipeline->params_declare_size(); i++) {
141 LonBasedPidPlusControllerConf param_config;
142 auto param_config_path = params_pipeline->params_declare(i).config_path();
143 std::string param_config_path_relative = absl::StrCat("conf", "/", param_config_path);
144 AINFO << "Param config_path_relative is " << param_config_path_relative;
145 std::string param_config_path_absolute
147 "apollo::control::LonPlusController", param_config_path_relative);
148 AINFO << "Param config_path_absolute is " << param_config_path_absolute;
149 if (!apollo::cyber::common::GetProtoFromFile(param_config_path_absolute, &param_config)) {
150 AERROR << "Load config: " << params_pipeline->params_declare(i).config_name() << " param failed!";
151 return false;
152 }
153 AINFO << "Load the config file successfully, param file name: " << param_config_path;
154 params_list_.push_back(std::make_pair(params_pipeline->params_declare(i).config_name(), param_config));
155 }
156 for (int i = 0; i < params_pipeline->calibration_table_declare_size(); i++) {
157 calibration_table calibration_table_conf;
158 auto calibration_table_path = params_pipeline->calibration_table_declare(i).config_path();
159 if (!LoadCalibrationTable(calibration_table_path, &calibration_table_conf)) {
160 AERROR << "Load config: " << params_pipeline->calibration_table_declare(i).config_name()
161 << " calibration table failed!";
162 return false;
163 }
164 AINFO << "Load the calibration table successfully, calibration table file name: " << calibration_table_path;
165 calibration_table_list_.push_back(
166 std::make_pair(params_pipeline->calibration_table_declare(i).config_name(), calibration_table_conf));
167 for (const auto &calibration_table : calibration_table_list_) {
168 AINFO << "calibration table name is " << calibration_table.first;
169 InitControlCalibrationTable(calibration_table.second);
170 }
171 }
172
173 return true;
174}
175
176void LonPlusController::SetDigitalFilterPitchAngle() {
177 double cutoff_freq = lon_based_pidcontroller_conf_.pitch_angle_filter_conf().cutoff_freq();
178 double ts = lon_based_pidcontroller_conf_.ts();
179 SetDigitalFilter(ts, cutoff_freq, &digital_filter_pitch_angle_);
180}
181
182void LonPlusController::InitControlCalibrationTable(calibration_table calibration_table) {
183 AINFO << "Control calibration table size is " << calibration_table.calibration_size();
185 for (const auto &calibration : calibration_table.calibration()) {
186 xyz.push_back(std::make_tuple(calibration.speed(), calibration.acceleration(), calibration.command()));
187 }
188 control_interpolation_.reset(new Interpolation2D);
189 ACHECK(control_interpolation_->Init(xyz)) << "Fail to load control calibration table";
190}
191
192bool LonPlusController::SetCurrentParam(
193 const std::string param_config_name,
194 LonBasedPidPlusControllerConf &current_lon_based_pidcontroller_conf) {
195 bool set_success = false;
196 for (const auto &param : params_list_) {
197 if (param.first == param_config_name) {
198 current_lon_based_pidcontroller_conf.CopyFrom(param.second);
199 set_success = true;
200 ADEBUG << "find the right params, set the currernt param_config_name is " << param_config_name;
201 break;
202 }
203 }
204 if (!set_success) {
205 AERROR << "Fail to find lon current param[" << param_config_name << "]";
206 }
207 return set_success;
208}
209
210bool LonPlusController::ChooseCurrentParam(
211 const planning::ADCTrajectory *trajectory_msg,
212 const double vehicle_speed,
213 LonBasedPidPlusControllerConf &current_lon_based_pidcontroller_conf) {
214 std::string param_config_name = "";
215
216 if (trajectory_msg->trajectory_type() != ADCTrajectory::OPEN_SPACE) {
217 param_config_name = "public_road_forward_param";
218 } else {
219 if (!IsForwardModel()) {
220 param_config_name = "open_space_backward_param";
221 } else {
222 param_config_name = "open_space_forward_param";
223 }
224 }
225
226 if (current_lon_based_pidcontroller_conf.use_check_pit()
227 && CheckInPit(
228 lon_based_pidcontroller_conf_.pit_replan_check_time(),
229 lon_based_pidcontroller_conf_.pit_replan_check_count(),
230 std::fabs(vehicle_speed),
231 trajectory_message_->is_replan())) {
232 if (!IsForwardModel()) {
233 param_config_name = "pit_backward_param";
234 } else {
235 param_config_name = "pit_forward_param";
236 }
237 }
238
239 if (trajectory_msg->trajectory_type() == ADCTrajectory::OPEN_SPACE
240 && trajectory_msg->debug().planning_data().scenario().scenario_plugin_type() == "PRECISE_PARKING") {
241 if (!IsForwardModel()) {
242 param_config_name = "precise_backward_param";
243 } else {
244 param_config_name = "precise_forward_param";
245 }
246 }
247
248 if (trajectory_msg->debug().planning_data().scenario().scenario_plugin_type() == "ZONE_COVER") {
249 if (!IsForwardModel()) {
250 param_config_name = "zone_cover_backward_param";
251 } else {
252 param_config_name = "zone_cover_forward_param";
253 }
254 }
255
256 if (!SetCurrentParam(param_config_name, current_lon_based_pidcontroller_conf)) {
257 AERROR << "Failed to set current lon param config: " << param_config_name;
258 return false;
259 } else {
260 if (param_config_name != current_param_config_name_) {
261 AINFO << "Update the current lon param config name is " << param_config_name;
262 current_param_config_name_ = param_config_name;
263 }
264 return true;
265 }
266}
267
268bool LonPlusController::SetCurrentCalibrationTable(
269 const std::string calibration_table_config_name,
270 calibration_table &current_calibration_table_conf) {
271 bool set_success = false;
272 for (const auto &calibration_table : calibration_table_list_) {
273 if (calibration_table.first == calibration_table_config_name) {
274 current_calibration_table_conf.CopyFrom(calibration_table.second);
275 set_success = true;
276 break;
277 }
278 }
279 if (!set_success) {
280 AERROR << "Fail to find lon current calibration table[" << calibration_table_config_name << "]";
281 }
282 return set_success;
283}
284
285bool LonPlusController::ChooseCurrentCalibrationTable(calibration_table &current_calibration_table_conf) {
286 std::string calibration_table_config_name = "default_calibration_table";
287 if (chassis_->battery_soc_percentage() > current_lon_based_pidcontroller_conf_.battery_threshold()) {
288 calibration_table_config_name = "high_battery_calibration_table";
289 } else {
290 calibration_table_config_name = "normal_battery_calibration_table";
291 }
292
293 if (!SetCurrentCalibrationTable(calibration_table_config_name, current_calibration_table_conf)) {
294 AERROR << "Failed to set current calibration table: " << calibration_table_config_name;
295 return false;
296 } else {
297 if (calibration_table_config_name != current_calibration_table_config_name_) {
298 AINFO << "Update the current calibration table config name is " << calibration_table_config_name;
299 current_calibration_table_config_name_ = calibration_table_config_name;
300 }
301 return true;
302 }
303}
304
306 const localization::LocalizationEstimate *localization,
307 const canbus::Chassis *chassis,
308 const planning::ADCTrajectory *planning_published_trajectory,
310 localization_ = localization;
311 chassis_ = chassis;
312 trajectory_message_ = planning_published_trajectory;
313
314 auto debug = cmd->mutable_debug()->mutable_simple_lon_debug();
315 debug->Clear();
316 auto lon_debug_info = injector_->mutable_control_debug_info()->mutable_simple_lon_debug();
317 lon_debug_info->Clear();
318
319 // speed filter
320 double vehicle_speed_ori = injector_->vehicle_state()->linear_velocity();
321 lon_debug_info->set_vehicle_speed(vehicle_speed_ori);
322
323 double current_speed = GetVehicleSpeed(injector_, FLAGS_use_speed_filter, FLAGS_speed_smoothing_factor);
324 lon_debug_info->set_vehicle_speed_filter(current_speed);
325
326 if (!VehicleStatusIdentificationUpdate(localization_, chassis_, trajectory_message_)) {
327 AERROR << "Fail to update the vehicle status identification!";
328 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Fail to update the vehicle status identification!");
329 }
330
331 if (trajectory_analyzer_ == nullptr
332 || trajectory_analyzer_->seq_num() != trajectory_message_->header().sequence_num()) {
333 trajectory_analyzer_.reset(new TrajectoryAnalyzer(trajectory_message_));
334 }
335
336 if (!ChooseCurrentParam(trajectory_message_, current_speed, current_lon_based_pidcontroller_conf_)) {
337 AERROR << "Fail to load current lon control param!";
338 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Fail to load current lon control param!");
339 }
340
341 if (!ChooseCurrentCalibrationTable(calibration_table_)) {
342 AERROR << "Fail to load the current lon control calibration table!";
343 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Fail to load the current lon control calibration table!!");
344 }
345
346 if (calibration_table_.calibration_size() != previous_calibration_table_size_) {
347 AINFO << "Update the calibration table, init the new calibration table.";
348 InitControlCalibrationTable(calibration_table_);
349 previous_calibration_table_size_ = calibration_table_.calibration_size();
350 }
351
352 if (!control_interpolation_) {
353 AERROR << "Fail to initialize calibration table.";
354 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, "Fail to initialize calibration table.");
355 }
356
357 double brake_cmd = 0.0;
358 double throttle_cmd = 0.0;
359 double ts = current_lon_based_pidcontroller_conf_.ts();
360 double preview_time = current_lon_based_pidcontroller_conf_.preview_window() * ts;
361 bool enable_leadlag = current_lon_based_pidcontroller_conf_.enable_reverse_leadlag_compensation();
362
363 standstill_narmal_acceleration_
364 = -std::fabs(current_lon_based_pidcontroller_conf_.standstill_narmal_acceleration());
365 stop_gain_acceleration_ = -std::fabs(current_lon_based_pidcontroller_conf_.stop_gain_acceleration());
366
367 if (preview_time < 0.0) {
368 const auto error_msg = absl::StrCat("Preview time set as: ", preview_time, " less than 0");
369 AERROR << error_msg;
370 return Status(ErrorCode::CONTROL_COMPUTE_ERROR, error_msg);
371 }
372
373 station_leadlag_controller_.SetLeadlagConf(current_lon_based_pidcontroller_conf_.speed_leadlag_conf());
374 speed_leadlag_controller_.SetLeadlagConf(current_lon_based_pidcontroller_conf_.speed_leadlag_conf());
375
376 CheckFinishToElse(planning_published_trajectory);
377 ComputeLongitudinalErrors(trajectory_analyzer_.get(), preview_time, ts, current_speed, debug);
378
379 double station_error_limit = current_lon_based_pidcontroller_conf_.station_error_limit();
380 double station_error_limited = 0.0;
381 if (current_lon_based_pidcontroller_conf_.enable_speed_station_preview()) {
382 station_error_limited
383 = common::math::Clamp(debug->preview_station_error(), -station_error_limit, station_error_limit);
384 } else {
385 station_error_limited = common::math::Clamp(debug->station_error(), -station_error_limit, station_error_limit);
386 }
387
388 auto station_pid_conf = current_lon_based_pidcontroller_conf_.station_pid_conf();
389 CalcultePidParams(std::fabs(current_speed), station_pid_conf);
390 station_pid_controller_.SetPID(station_pid_conf);
391 auto speed_pid_conf = current_lon_based_pidcontroller_conf_.speed_pid_conf();
392 CalcultePidParams(std::fabs(current_speed), speed_pid_conf);
393 speed_pid_controller_.SetPID(speed_pid_conf);
394
395 current_trajectory_timestamp_ = planning_published_trajectory->header().timestamp_sec();
396 if ((current_trajectory_timestamp_ - pre_trajectory_timestamp_ > 1e-4)
397 && planning_published_trajectory->is_replan()) {
398 station_pid_controller_.Reset_integral();
399 speed_pid_controller_.Reset_integral();
400 ADEBUG << "Reset the pid controller integral because of re-planning.";
401 }
402 pre_trajectory_timestamp_ = current_trajectory_timestamp_;
403
404 double speed_offset = station_pid_controller_.Control(station_error_limited, ts);
405 if (enable_leadlag) {
406 speed_offset = station_leadlag_controller_.Control(speed_offset, ts);
407 }
408
409 double speed_controller_input = 0.0;
410 double speed_controller_input_limit = current_lon_based_pidcontroller_conf_.speed_controller_input_limit();
411 double speed_controller_input_limited = 0.0;
412 if (current_lon_based_pidcontroller_conf_.enable_speed_station_preview()) {
413 speed_controller_input = speed_offset + debug->preview_speed_error();
414 } else {
415 speed_controller_input = speed_offset + debug->speed_error();
416 }
417 speed_controller_input_limited
418 = common::math::Clamp(speed_controller_input, -speed_controller_input_limit, speed_controller_input_limit);
419
420 double acceleration_cmd_closeloop = 0.0;
421
422 acceleration_cmd_closeloop = speed_pid_controller_.Control(speed_controller_input_limited, ts);
423 debug->set_pid_saturation_status(speed_pid_controller_.IntegratorSaturationStatus());
424 if (enable_leadlag) {
425 acceleration_cmd_closeloop = speed_leadlag_controller_.Control(acceleration_cmd_closeloop, ts);
426 debug->set_leadlag_saturation_status(speed_leadlag_controller_.InnerstateSaturationStatus());
427 }
428
430 speed_pid_controller_.Reset_integral();
431 station_pid_controller_.Reset_integral();
432 }
433
434 double vehicle_pitch_rad = injector_->vehicle_state()->pitch();
435 double vehicle_pitch = vehicle_pitch_rad * 180 / M_PI + FLAGS_pitch_offset_deg;
436 ADEBUG << "[LON]vehicle_pitch is " << vehicle_pitch;
437 debug->set_vehicle_pitch(vehicle_pitch);
438 // TODO(ALL): confirm the slope_offset_compensation whether is positive or not
439 // when vehicle move uphill
440 // Resume: uphill: + , downhill: -
441 double slope_offset_compensation = current_lon_based_pidcontroller_conf_.use_opposite_slope_compensation() * GRA_ACC
442 * std::sin(vehicle_pitch_rad + FLAGS_pitch_offset_deg * M_PI / 180);
443
444 if (std::isnan(slope_offset_compensation)) {
445 slope_offset_compensation = 0;
446 }
447
448 debug->set_slope_offset_compensation(slope_offset_compensation);
449 double acceleration_cmd = acceleration_cmd_closeloop + debug->preview_acceleration_reference();
450
451 // Check the steer command in reverse trajectory if the current steer target
452 // is larger than previous target, free the acceleration command, wait for
453 // the current steer target
454 double current_steer_interval = cmd->steering_target() - chassis->steering_percentage();
455 if (current_lon_based_pidcontroller_conf_.use_steering_check()
456 && (trajectory_message_->trajectory_type() == apollo::planning::ADCTrajectory::UNKNOWN)
457 && std::abs(current_steer_interval) > current_lon_based_pidcontroller_conf_.steer_cmd_interval()) {
458 ADEBUG << "steering_target is " << cmd->steering_target() << " steering_percentage is "
459 << chassis->steering_percentage();
460 ADEBUG << "Steer cmd interval is larger than " << current_lon_based_pidcontroller_conf_.steer_cmd_interval();
461
462 speed_pid_controller_.Reset_integral();
463 station_pid_controller_.Reset_integral();
464 acceleration_cmd = 0;
465 debug->set_is_wait_steer(true);
466 } else {
467 debug->set_is_wait_steer(false);
468 }
469 debug->set_current_steer_interval(current_steer_interval);
470
471 // At near-stop stage, replace the brake control command with the standstill
472 // acceleration if the former is even softer than the latter
473 debug->set_is_full_stop(false);
474 debug->set_is_full_stop_soft(false);
475 // previous_full_stop will determine whether the max path remain will be added.
476 auto previous_full_stop = injector_->Get_previous_lon_debug_info()->is_full_stop()
477 || injector_->Get_previous_lon_debug_info()->is_full_stop_soft();
478 GetPathRemain(debug);
479 IsStopByDestination(debug);
480 IsPedestrianStopLongTerm(debug);
481 if (current_lon_based_pidcontroller_conf_.use_preview_reference_check()
482 && (std::fabs(debug->preview_acceleration_reference()) <= FLAGS_max_acceleration_when_stopped)
483 && std::fabs(debug->preview_speed_reference()) <= vehicle_param_.max_abs_speed_when_stopped()
484 && trajectory_message_->trajectory_type() != ADCTrajectory::OPEN_SPACE) {
485 if (debug->is_stop_reason_by_destination() || debug->is_stop_reason_by_prdestrian()) {
486 debug->set_is_full_stop(true);
487 ADEBUG << "Into full stop within preview acc and reference speed, " << "is_full_stop is "
488 << debug->is_full_stop();
489 } else {
490 debug->set_is_full_stop_soft(true);
491 ADEBUG << "Into full stop soft within preview acc and reference speed, " << "is_full_stop_soft is "
492 << debug->is_full_stop_soft();
493 }
494 }
495
496 double path_remain_add = 0.0;
497 if (vehicle_pitch < current_lon_based_pidcontroller_conf_.pitch_path_remain_param_min()
498 && fabs(current_speed) > current_lon_based_pidcontroller_conf_.downhill_full_stop_min_speed()
499 && trajectory_message_->trajectory_type() != ADCTrajectory::OPEN_SPACE) {
500 path_remain_add = fabs(
501 sin(vehicle_pitch * M_PI / 180) * current_lon_based_pidcontroller_conf_.pitch_path_remain_param());
502 }
503
504 if (!previous_full_stop) {
505 max_path_remain_when_stopped_ = current_lon_based_pidcontroller_conf_.path_remain() + path_remain_add;
506 } else {
507 max_path_remain_when_stopped_ = current_lon_based_pidcontroller_conf_.path_remain()
508 + current_lon_based_pidcontroller_conf_.full_stop_path_remain_gain() + path_remain_add;
509 }
510 ADEBUG << "current max_path_remain_when_stopped_ is " << max_path_remain_when_stopped_;
511
512 if (((IsForwardModel() && debug->path_remain() < max_path_remain_when_stopped_)
513 || (!IsForwardModel() && debug->path_remain() > -max_path_remain_when_stopped_))) {
514 ADEBUG << "Into full stop decision by path remain.";
515 if (debug->is_stop_reason_by_destination() || debug->is_stop_reason_by_prdestrian()) {
516 debug->set_is_full_stop(true);
517 ADEBUG << "Current path remain distance: " << debug->path_remain()
518 << " is within max_path_remain threshold: " << max_path_remain_when_stopped_
519 << ", into full stop because vehicle is in destination: " << debug->is_stop_reason_by_destination()
520 << " or pedestrian is in long time stop: " << debug->is_stop_reason_by_prdestrian()
521 << "is_full_stop flag: " << debug->is_full_stop();
522 } else {
523 debug->set_is_full_stop_soft(true);
524 ADEBUG << "Current path remain distance: " << debug->path_remain()
525 << " is within max_path_remain threshold: " << max_path_remain_when_stopped_
526 << ", but not into full stop because stop not in destination: "
527 << debug->is_stop_reason_by_destination()
528 << " or pedestrian is not long time stop: " << debug->is_stop_reason_by_prdestrian()
529 << "is_full_stop_soft flag: " << debug->is_full_stop_soft();
530 }
531 if ((std::fabs(current_speed) < vehicle_param_.max_abs_speed_when_stopped())
532 && debug->is_stop_reason_by_prdestrian()) {
533 ADEBUG << "Current stop is for long time pedestrian stop, " << debug->is_stop_reason_by_prdestrian();
534 debug->set_is_full_stop(true);
535 }
536 } else {
537 ADEBUG << "Not into full stop decision by path remain.";
538 }
539
540 if (!debug->is_full_stop() && !debug->is_full_stop_soft()) {
541 is_full_stop_wait_time_diff_ = 0;
542 ResetNewFullStop();
543 } else {
544 if (!previous_is_full_stop_ && (debug->is_full_stop() || debug->is_full_stop_soft())) {
545 ADEBUG << "from go into full stop";
546 previous_is_full_stop_ = true;
547 form_go_to_full_stop_ = true;
548 }
549 }
550
551 double throttle_lowerbound = std::max(
552 vehicle_param_.throttle_deadzone(), current_lon_based_pidcontroller_conf_.throttle_minimum_action());
553 double brake_lowerbound
554 = std::max(vehicle_param_.brake_deadzone(), current_lon_based_pidcontroller_conf_.brake_minimum_action());
555 double calibration_value = 0.0;
556 double acceleration_lookup = (!IsForwardModel()) ? -acceleration_cmd : acceleration_cmd;
557
558 double acceleration_lookup_limited = vehicle_param_.max_acceleration()
559 + current_lon_based_pidcontroller_conf_.enable_slope_offset() * debug->slope_offset_compensation();
560 double acceleration_lookup_limit = 0.0;
561
562 if (current_lon_based_pidcontroller_conf_.use_acceleration_lookup_limit()) {
563 acceleration_lookup_limit = (acceleration_lookup > acceleration_lookup_limited) ? acceleration_lookup_limited
564 : acceleration_lookup;
565 }
566
567 if (FLAGS_use_preview_speed_for_table) {
568 if (current_lon_based_pidcontroller_conf_.use_acceleration_lookup_limit()) {
569 calibration_value = control_interpolation_->Interpolate(
570 std::make_pair(debug->preview_speed_reference(), acceleration_lookup_limit));
571 } else {
572 calibration_value = control_interpolation_->Interpolate(
573 std::make_pair(debug->preview_speed_reference(), acceleration_lookup));
574 }
575 } else {
576 if (current_lon_based_pidcontroller_conf_.use_acceleration_lookup_limit()) {
577 calibration_value = control_interpolation_->Interpolate(
578 std::make_pair(std::fabs(current_speed), acceleration_lookup_limit));
579 } else {
580 calibration_value = control_interpolation_->Interpolate(
581 std::make_pair(std::fabs(current_speed), acceleration_lookup));
582 }
583 }
584
585 if (acceleration_lookup >= 0) {
586 if (calibration_value >= 0) {
587 throttle_cmd = std::max(calibration_value, throttle_lowerbound);
588 } else {
589 throttle_cmd = throttle_lowerbound;
590 }
591 brake_cmd = 0.0;
592 } else {
593 throttle_cmd = 0.0;
594 if (calibration_value >= 0) {
595 brake_cmd = brake_lowerbound;
596 } else {
597 brake_cmd = std::max(-calibration_value, brake_lowerbound);
598 }
599 }
600
601 if (form_go_to_full_stop_ && (debug->is_full_stop() || debug->is_full_stop_soft())) {
602 ADEBUG << "from go to full stop in to control";
603 ADEBUG << "now brake = " << cmd->brake();
604 throttle_cmd = 0.0;
605 openspace_speed_control_throttle_cmd_ = 0.0;
606 if (debug->acceleration_reference() < current_lon_based_pidcontroller_conf_.emergency_quit_fullstop_mindec()) {
607 ADEBUG << "[NewFullStop] emergency stop, use acc before fullstop.";
608 } else {
609 if (((std::fabs(current_speed) < current_lon_based_pidcontroller_conf_.release_end_brake_speed())
610 || (std::fabs(debug->path_remain()) < current_lon_based_pidcontroller_conf_.fullstop_pathremain()))
611 && !begin_end_brake_) {
612 begin_end_brake_ = true;
613 fullstop_in_brake_ = cmd->brake();
614 double start_brake = current_lon_based_pidcontroller_conf_.full_stop_pitch_brake_param()
615 * fabs(std::sin(vehicle_pitch_rad + FLAGS_pitch_offset_deg * M_PI / 180));
616 if (start_brake > fullstop_in_brake_) {
617 fullstop_in_brake_ = start_brake;
618 }
619 hillup_fullstop_brake_rate_ = std::max(
620 current_lon_based_pidcontroller_conf_.full_stop_max_brake()
621 / (current_lon_based_pidcontroller_conf_.fullstop_window()
622 - current_lon_based_pidcontroller_conf_.full_stop_pitch_window_param()
623 * fabs(std::sin(vehicle_pitch_rad + FLAGS_pitch_offset_deg * M_PI / 180))),
624 0.0);
625 ADEBUG << "======brake rate = " << hillup_fullstop_brake_rate_;
626 ADEBUG << "brake cal window = "
627 << current_lon_based_pidcontroller_conf_.fullstop_window()
628 - fabs(std::sin(vehicle_pitch_rad + FLAGS_pitch_offset_deg * M_PI / 180));
629 }
630 if (IsForwardModel()) {
631 double station_err = (debug->station_error() < 0) ? debug->station_error() : 0.0;
632 hillup_fullstop_brake_rate_ = hillup_fullstop_brake_rate_
633 + fabs(station_err) * current_lon_based_pidcontroller_conf_.full_stop_station_err_rate();
634 if (hillup_fullstop_brake_rate_
635 > current_lon_based_pidcontroller_conf_.max_brk_downhill_change_rate()) {
636 hillup_fullstop_brake_rate_ = current_lon_based_pidcontroller_conf_.max_brk_downhill_change_rate();
637 }
638 }
639
640 if (begin_end_brake_) {
641 fullstop_in_brake_ = fullstop_in_brake_ + hillup_fullstop_brake_rate_;
642 if ((fullstop_window_count_ > current_lon_based_pidcontroller_conf_.fullstop_window())
643 && (fullstop_in_brake_ > current_lon_based_pidcontroller_conf_.full_stop_max_brake()
644 + current_lon_based_pidcontroller_conf_.full_stop_pitch_brake_param()
645 * fabs(std::sin(vehicle_pitch_rad + FLAGS_pitch_offset_deg * M_PI / 180)))) {
646 hillup_fullstop_brake_rate_ = 0;
647 }
648 if (fullstop_in_brake_ >= 100.0) {
649 fullstop_in_brake_ = 100.0;
650 }
651 brake_cmd = fullstop_in_brake_;
652 ADEBUG << "=======now brkcmd===AL== = " << fullstop_in_brake_;
653 fullstop_window_count_++;
654 }
655 }
656
657 speed_pid_controller_.Reset_integral();
658 station_pid_controller_.Reset_integral();
659 }
660
661 if (FLAGS_use_vehicle_epb) {
662 ADEBUG << "Into use vehicle epb.";
663 if ((debug->is_full_stop() && IsFullStopLongTerm(debug))
664 || (debug->is_full_stop() && debug->is_stop_reason_by_prdestrian())) {
665 cmd->set_parking_brake(true);
666 if (chassis->parking_brake()) {
667 brake_cmd = 0.0;
668 ResetNewFullStop();
669 }
670 } else {
671 cmd->set_parking_brake(false);
672 if (chassis->parking_brake()) {
673 ADEBUG << "Into park brake release.";
674 SetParkingBrake(&current_lon_based_pidcontroller_conf_, cmd);
675 }
676 }
677 }
678
679 // if the car is driven by acceleration, disgard the cmd->throttle and brake
680
681 bool is_previous_replan = injector_->previous_control_debug_mutable()->mutable_replan_debug()->is_need_replan();
682 if (is_previous_replan) {
683 ADEBUG << "NEED REPLAN";
684 }
685 if ((trajectory_message_->trajectory_type() != ADCTrajectory::OPEN_SPACE) || debug->is_full_stop()
686 || debug->is_full_stop_soft() || is_previous_replan) {
687 openspace_speed_control_throttle_cmd_ = 0.0;
688 openspace_count_ = 0;
689 }
690
691 if ((trajectory_message_->trajectory_type() == ADCTrajectory::OPEN_SPACE)
692 && current_lon_based_pidcontroller_conf_.use_parking_speed_control()
693 && std::fabs(debug->path_remain()) > current_lon_based_pidcontroller_conf_.speed_path_remain()) {
695 && (debug->acceleration_reference()
696 <= (-1) * current_lon_based_pidcontroller_conf_.speed_itfc_dcc_emergency()))
698 && (debug->acceleration_reference()
699 >= current_lon_based_pidcontroller_conf_.speed_itfc_dcc_emergency()))) {
700 // use speed control
701 ADEBUG << "=======use speed control.";
702 openspace_count_++;
703 if (std::fabs(current_speed) <= current_lon_based_pidcontroller_conf_.openspace_r_std_v()) {
704 openspace_speed_control_throttle_cmd_ = openspace_speed_control_throttle_cmd_
705 + current_lon_based_pidcontroller_conf_.openspace_cmd_change();
706 }
707 if (std::fabs(current_speed) >= current_lon_based_pidcontroller_conf_.openspace_r_std_v()
708 + current_lon_based_pidcontroller_conf_.openspace_r_err()) {
709 if ((openspace_speed_control_throttle_cmd_
710 >= current_lon_based_pidcontroller_conf_.openspace_start_throttle())
711 && current_lon_based_pidcontroller_conf_.use_maintain_throttle()) {
712 openspace_speed_control_throttle_cmd_
713 = current_lon_based_pidcontroller_conf_.openspace_maintain_throttle();
714 } else {
715 openspace_speed_control_throttle_cmd_ = openspace_speed_control_throttle_cmd_
716 - current_lon_based_pidcontroller_conf_.openspace_cmd_change();
717 }
718 }
719 if ((std::fabs(current_speed) >= current_lon_based_pidcontroller_conf_.openspace_r_std_v()
720 - current_lon_based_pidcontroller_conf_.openspace_r_err())
721 && (std::fabs(current_speed) <= current_lon_based_pidcontroller_conf_.openspace_r_std_v()
722 + current_lon_based_pidcontroller_conf_.openspace_r_err())
723 && current_lon_based_pidcontroller_conf_.use_maintain_throttle()) {
724 openspace_speed_control_throttle_cmd_
725 = current_lon_based_pidcontroller_conf_.openspace_maintain_throttle();
726 }
727 if (vehicle_pitch <= current_lon_based_pidcontroller_conf_.speed_control_pitch_thres()
728 && openspace_speed_control_throttle_cmd_ < current_lon_based_pidcontroller_conf_.pitch_start_throttle()
729 && std::fabs(current_speed) < current_lon_based_pidcontroller_conf_.speed_control_min_speed()
730 && openspace_count_ < current_lon_based_pidcontroller_conf_.openspace_start_num()) {
731 openspace_speed_control_brake_cmd_ = current_lon_based_pidcontroller_conf_.epb_brake();
732 } else {
733 if (std::fabs(current_speed) >= current_lon_based_pidcontroller_conf_.openspace_r_std_v()
734 + current_lon_based_pidcontroller_conf_.openspace_r_err_big()) {
735 openspace_speed_control_brake_cmd_ = openspace_speed_control_brake_cmd_
736 + current_lon_based_pidcontroller_conf_.openspace_brk_change();
737 if (openspace_speed_control_brake_cmd_
738 > current_lon_based_pidcontroller_conf_.openspace_max_brk()) {
739 openspace_speed_control_brake_cmd_ = current_lon_based_pidcontroller_conf_.openspace_max_brk();
740 }
741 } else {
742 openspace_speed_control_brake_cmd_ = 0.0;
743 }
744 }
745
746 if (openspace_speed_control_throttle_cmd_ <= 0.0) {
747 openspace_speed_control_throttle_cmd_ = 0.0;
748 }
749
750 brake_cmd = openspace_speed_control_brake_cmd_;
751 if (brake_cmd > 0.0) {
752 throttle_cmd = 0.0;
753 } else {
754 throttle_cmd = openspace_speed_control_throttle_cmd_;
755 }
756 }
757 }
758
759 if (trajectory_message_->trajectory_type() == ADCTrajectory::OPEN_SPACE) {
760 if (brake_cmd > current_lon_based_pidcontroller_conf_.full_stop_max_brake()) {
761 brake_cmd = current_lon_based_pidcontroller_conf_.full_stop_max_brake();
762 }
763 }
764
765 // a logic to keep car safe,when the chassis gear is different with traj gear.
766 if (chassis->gear_location() != trajectory_message_->gear()) {
767 speed_pid_controller_.Reset_integral();
768 station_pid_controller_.Reset_integral();
769 throttle_cmd = 0.0;
770 brake_cmd = current_lon_based_pidcontroller_conf_.epb_brake();
771 }
772
773 debug->set_throttle_cmd(throttle_cmd);
774 debug->set_brake_cmd(brake_cmd);
775
776 throttle_cmd = ThrottleCmdFilter(FLAGS_use_throttle_filter, FLAGS_throttle_smoothing_factor, throttle_cmd);
777 lon_debug_info->set_throttle_cmd_filter(throttle_cmd);
778
779 cmd->set_throttle(throttle_cmd);
780 cmd->set_brake(brake_cmd);
781 if (current_lon_based_pidcontroller_conf_.use_acceleration_lookup_limit()) {
782 cmd->set_acceleration(acceleration_lookup_limit);
783 previous_acc_output_ = acceleration_lookup_limit;
784 } else {
785 cmd->set_acceleration(acceleration_cmd);
786 previous_acc_output_ = acceleration_cmd;
787 }
788
789 if (std::fabs(current_speed) <= vehicle_param_.max_abs_speed_when_stopped()
790 || chassis->gear_location() == trajectory_message_->gear()
792 cmd->set_gear_location(trajectory_message_->gear());
793 } else {
794 cmd->set_gear_location(chassis->gear_location());
795 }
796
797 if (current_lon_based_pidcontroller_conf_.use_speed_itfc()) {
798 reference_spd_cmd_ = reference_spd_ + debug->speed_offset();
799 if ((reference_spd_ <= current_lon_based_pidcontroller_conf_.speed_itfc_full_stop_speed())
800 && (chassis->gear_location() == canbus::Chassis::GEAR_DRIVE)) {
801 if ((debug->path_remain() >= current_lon_based_pidcontroller_conf_.speed_itfc_path_remain_min())
802 && (debug->preview_acceleration_reference()
803 >= current_lon_based_pidcontroller_conf_.speed_itfc_dcc_emergency())
804 && (debug->path_remain() <= current_lon_based_pidcontroller_conf_.speed_itfc_path_remain_max())) {
805 if (debug->preview_acceleration_reference()
806 <= current_lon_based_pidcontroller_conf_.speed_itfc_acc_thres()) {
807 if (reference_spd_ > current_lon_based_pidcontroller_conf_.speed_itfc_stop_speed()) {
808 reference_spd_cmd_ = current_lon_based_pidcontroller_conf_.speed_itfc_speed_cmd();
809 }
810 }
811 }
812 }
813 cmd->set_speed(reference_spd_cmd_);
814 if ((debug->is_full_stop() || debug->is_full_stop_soft())
815 && trajectory_message_->trajectory_type() == ADCTrajectory::OPEN_SPACE) {
816 cmd->set_speed(0.0);
817 }
818 }
819
820 debug->set_station_error_limited(station_error_limited);
821 debug->set_speed_offset(speed_offset);
822 debug->set_speed_controller_input_limited(speed_controller_input_limited);
823 debug->set_acceleration_cmd(acceleration_cmd);
824 debug->set_acceleration_lookup(acceleration_lookup);
825 debug->set_acceleration_lookup_limit(acceleration_lookup_limit);
826 debug->set_speed_lookup(current_speed);
827 debug->set_calibration_value(calibration_value);
828 debug->set_acceleration_cmd_closeloop(acceleration_cmd_closeloop);
829
830 lon_debug_info->set_path_remain_add(path_remain_add);
831 lon_debug_info->set_max_path_remain_when_stopped(max_path_remain_when_stopped_);
832 lon_debug_info->set_form_go_to_full_stop(form_go_to_full_stop_);
833 lon_debug_info->set_begin_end_brake(begin_end_brake_);
834 lon_debug_info->set_hillup_fullstop_brake_rate(hillup_fullstop_brake_rate_);
835 lon_debug_info->set_control_task_name(name_);
836
837 if (FLAGS_enable_csv_debug && speed_log_file_ != nullptr) {
838 fprintf(speed_log_file_,
839 "%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f,"
840 "%.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %d,\r\n",
841 debug->station_reference(),
842 debug->station_error(),
843 station_error_limited,
844 debug->preview_station_error(),
845 debug->speed_reference(),
846 debug->speed_error(),
847 speed_controller_input_limited,
848 debug->preview_speed_reference(),
849 debug->preview_speed_error(),
850 debug->preview_acceleration_reference(),
851 acceleration_cmd_closeloop,
852 acceleration_cmd,
853 debug->acceleration_lookup(),
854 debug->acceleration_lookup_limit(),
855 debug->speed_lookup(),
856 calibration_value,
857 throttle_cmd,
858 brake_cmd,
859 debug->is_full_stop());
860 }
861
862 return Status::OK();
863}
864
866 speed_pid_controller_.Reset();
867 station_pid_controller_.Reset();
868 is_full_stop_wait_time_diff_ = 0;
869 wait_time_diff_ = 0;
870 from_finish_to_else_ = false;
871 previous_is_finish_ = false;
872 is_need_restart_pedestrian_init_time_ = true;
873 return Status::OK();
874}
875
876std::string LonPlusController::Name() const {
877 return name_;
878}
879
881 const TrajectoryAnalyzer *trajectory_analyzer,
882 const double preview_time,
883 const double ts,
884 const double vehicle_speed,
886 // the decomposed vehicle motion onto Frenet frame
887 // s: longitudinal accumulated distance along reference trajectory
888 // s_dot: longitudinal velocity along reference trajectory
889 // d: lateral distance w.r.t. reference trajectory
890 // d_dot: lateral distance change rate, i.e. dd/dt
891 double s_matched = 0.0;
892 double s_dot_matched = 0.0;
893 double d_matched = 0.0;
894 double d_dot_matched = 0.0;
895
896 auto vehicle_state = injector_->vehicle_state();
897 auto matched_point = trajectory_analyzer->QueryMatchedPathPoint(vehicle_state->x(), vehicle_state->y());
898
899 trajectory_analyzer->ToTrajectoryFrame(
900 vehicle_state->x(),
901 vehicle_state->y(),
902 vehicle_state->heading(),
903 vehicle_speed,
904 matched_point,
905 &s_matched,
906 &s_dot_matched,
907 &d_matched,
908 &d_dot_matched);
909
910 // double current_control_time = Time::Now().ToSecond();
911 double current_control_time
912 = FLAGS_sim_by_record ? chassis_->header().timestamp_sec() : (::apollo::cyber::Clock::NowInSeconds());
913 double preview_control_time = current_control_time + preview_time;
914
915 TrajectoryPoint reference_point = trajectory_analyzer->QueryNearestPointByAbsoluteTime(current_control_time);
916 TrajectoryPoint preview_point = trajectory_analyzer->QueryNearestPointByAbsoluteTime(preview_control_time);
917
918 debug->mutable_current_matched_point()->mutable_path_point()->set_x(matched_point.x());
919 debug->mutable_current_matched_point()->mutable_path_point()->set_y(matched_point.y());
920 debug->mutable_current_reference_point()->mutable_path_point()->set_x(reference_point.path_point().x());
921 debug->mutable_current_reference_point()->mutable_path_point()->set_y(reference_point.path_point().y());
922 debug->mutable_preview_reference_point()->mutable_path_point()->set_x(preview_point.path_point().x());
923 debug->mutable_preview_reference_point()->mutable_path_point()->set_y(preview_point.path_point().y());
924
925 ADEBUG << "matched point:" << matched_point.DebugString();
926 ADEBUG << "reference point:" << reference_point.DebugString();
927 ADEBUG << "preview point:" << preview_point.DebugString();
928
929 double heading_error = common::math::NormalizeAngle(vehicle_state->heading() - matched_point.theta());
930 double lon_speed = vehicle_speed * std::cos(heading_error);
931 double lon_acceleration = vehicle_state->linear_acceleration() * std::cos(heading_error);
932 double one_minus_kappa_lat_error
933 = 1 - reference_point.path_point().kappa() * vehicle_speed * std::sin(heading_error);
934
935 debug->set_station_reference(reference_point.path_point().s());
936 debug->set_current_station(s_matched);
937 debug->set_station_error(reference_point.path_point().s() - s_matched);
938 debug->set_speed_reference(reference_point.v());
939 debug->set_current_speed(lon_speed);
940 debug->set_speed_error(reference_point.v() - s_dot_matched);
941 debug->set_acceleration_reference(reference_point.a());
942 debug->set_current_acceleration(lon_acceleration);
943 debug->set_acceleration_error(reference_point.a() - lon_acceleration / one_minus_kappa_lat_error);
944 double jerk_reference = (debug->acceleration_reference() - previous_acceleration_reference_) / ts;
945 double lon_jerk = (debug->current_acceleration() - previous_acceleration_) / ts;
946 debug->set_jerk_reference(jerk_reference);
947 debug->set_current_jerk(lon_jerk);
948 debug->set_jerk_error(jerk_reference - lon_jerk / one_minus_kappa_lat_error);
949 previous_acceleration_reference_ = debug->acceleration_reference();
950 previous_acceleration_ = debug->current_acceleration();
951
952 debug->set_preview_station_error(preview_point.path_point().s() - s_matched);
953 debug->set_preview_speed_error(preview_point.v() - s_dot_matched);
954 debug->set_preview_speed_reference(preview_point.v());
955 debug->set_preview_acceleration_reference(preview_point.a());
956 if (current_lon_based_pidcontroller_conf_.use_speed_itfc()) {
957 reference_spd_ = reference_point.v();
958 }
959}
960
961void LonPlusController::SetDigitalFilter(double ts, double cutoff_freq, common::DigitalFilter *digital_filter) {
962 std::vector<double> denominators;
963 std::vector<double> numerators;
964 common::LpfCoefficients(ts, cutoff_freq, &denominators, &numerators);
965 digital_filter->set_coefficients(denominators, numerators);
966}
967
968// TODO(all): Refactor and simplify
970 int stop_index = 0;
971 static constexpr double kSpeedThreshold = 1e-3;
972 static constexpr double kForwardAccThreshold = -1e-2;
973 static constexpr double kBackwardAccThreshold = 1e-1;
974 static constexpr double kParkingSpeed = 0.1;
975
976 if (trajectory_message_->gear() == canbus::Chassis::GEAR_DRIVE) {
977 while (stop_index < trajectory_message_->trajectory_point_size()) {
978 auto &current_trajectory_point = trajectory_message_->trajectory_point(stop_index);
979 if (std::fabs(current_trajectory_point.v()) < kSpeedThreshold
980 && current_trajectory_point.a() > kForwardAccThreshold && current_trajectory_point.a() < 0.0) {
981 break;
982 }
983 ++stop_index;
984 }
985 } else {
986 while (stop_index < trajectory_message_->trajectory_point_size()) {
987 auto &current_trajectory_point = trajectory_message_->trajectory_point(stop_index);
988 if (current_trajectory_point.v() > -kSpeedThreshold && current_trajectory_point.a() < kBackwardAccThreshold
989 && current_trajectory_point.a() > 0.0) {
990 break;
991 }
992 ++stop_index;
993 }
994 }
995 ADEBUG << "stop_index is, " << stop_index;
996 if (stop_index == trajectory_message_->trajectory_point_size()) {
997 --stop_index;
998 if (std::fabs(trajectory_message_->trajectory_point(stop_index).v()) < kParkingSpeed) {
999 ADEBUG << "the last point is selected as parking point";
1000 } else {
1001 ADEBUG << "the last point found in path and speed > speed_deadzone";
1002 }
1003 }
1004 debug->set_path_remain(
1005 trajectory_message_->trajectory_point(stop_index).path_point().s() - debug->current_station());
1006}
1007
1008bool LonPlusController::IsStopByDestination(SimpleLongitudinalDebug *debug) {
1009 auto stop_reason = trajectory_message_->decision().main_decision().stop();
1010 ADEBUG << "Current stop reason is \n" << stop_reason.DebugString();
1011 ADEBUG << "Planning command status msg is \n" << injector_->get_planning_command_status()->ShortDebugString();
1012
1013 StopReasonCode stop_reason_code = stop_reason.reason_code();
1014
1015 if (stop_reason_code == StopReasonCode::STOP_REASON_SIGNAL
1016 || stop_reason_code == StopReasonCode::STOP_REASON_REFERENCE_END
1017 || injector_->get_planning_command_status()->status() == CommandStatusType::FINISHED
1018 || trajectory_message_->decision().main_decision().has_mission_complete()) {
1019 ADEBUG << "[IsStopByDestination]Current stop reason is in destination.";
1020 debug->set_is_stop_reason_by_destination(true);
1021 return true;
1022 }
1023 debug->set_is_stop_reason_by_destination(false);
1024 return false;
1025}
1026
1027bool LonPlusController::IsPedestrianStopLongTerm(SimpleLongitudinalDebug *debug) {
1028 auto stop_reason = trajectory_message_->decision().main_decision().stop();
1029 ADEBUG << "Current stop reason is \n" << stop_reason.DebugString();
1030 StopReasonCode stop_reason_code = stop_reason.reason_code();
1031 // const auto control_debug_info = injector_->control_debug_info();
1032
1033 if (stop_reason_code == StopReasonCode::STOP_REASON_PEDESTRIAN
1034 || stop_reason_code == StopReasonCode::STOP_REASON_OBSTACLE) {
1035 ADEBUG << "[IsPedestrianStopLongTerm]Stop reason for pedestrian.";
1036 is_stop_by_pedestrian_ = true;
1037 } else {
1038 is_stop_by_pedestrian_ = false;
1039 }
1040
1041 ADEBUG << "Current is_stop_by_pedestrian: " << is_stop_by_pedestrian_
1042 << ", is_stop_by_pedestrian_previous: " << is_stop_by_pedestrian_previous_;
1043 ADEBUG << "is_need_restart_pedestrian_init_time_ is " << is_need_restart_pedestrian_init_time_;
1044 if (is_stop_by_pedestrian_) {
1045 if (!(is_stop_by_pedestrian_ && is_stop_by_pedestrian_previous_) || is_need_restart_pedestrian_init_time_
1046 || from_finish_to_else_) {
1048 ADEBUG << "Stop reason for pedestrian, start time(s) is " << start_time_;
1049 is_need_restart_pedestrian_init_time_ = false;
1050 } else {
1051 ADEBUG << "Last time stop is already pedestrian, skip start_time init.";
1052 }
1053 double end_time = ::apollo::cyber::Clock::NowInSeconds();
1054 ADEBUG << "Stop reason for pedestrian, current time(s) is " << end_time;
1055 wait_time_diff_ = end_time - start_time_;
1056 } else {
1057 start_time_ = 0.0;
1058 wait_time_diff_ = 0.0;
1059 }
1060
1061 is_stop_by_pedestrian_previous_ = is_stop_by_pedestrian_;
1062
1063 if (wait_time_diff_ > current_lon_based_pidcontroller_conf_.pedestrian_stop_time()) {
1064 ADEBUG << "Current pedestrian stop lasting time(s) is " << wait_time_diff_
1065 << ", larger than threshold: " << current_lon_based_pidcontroller_conf_.pedestrian_stop_time();
1066 debug->set_is_stop_reason_by_prdestrian(true);
1067 return true;
1068 } else {
1069 ADEBUG << "Current pedestrian stop lasting time(s) is " << wait_time_diff_
1070 << ", not reach the threshold: " << current_lon_based_pidcontroller_conf_.pedestrian_stop_time();
1071 debug->set_is_stop_reason_by_prdestrian(false);
1072 return false;
1073 }
1074}
1075
1076bool LonPlusController::IsFullStopLongTerm(SimpleLongitudinalDebug *debug) {
1077 if (debug->is_full_stop()) {
1078 is_full_stop_wait_time_diff_++;
1079 } else {
1080 is_full_stop_wait_time_diff_ = 0;
1081 }
1082
1083 if (is_full_stop_wait_time_diff_ > current_lon_based_pidcontroller_conf_.full_stop_long_time()) {
1084 ADEBUG << "Current full stop lasting time(s) is " << is_full_stop_wait_time_diff_
1085 << ", larger than threshold: " << current_lon_based_pidcontroller_conf_.full_stop_long_time();
1086 return true;
1087 } else {
1088 ADEBUG << "Current full stop lasting time(s) is " << is_full_stop_wait_time_diff_
1089 << ", not reach the threshold: " << current_lon_based_pidcontroller_conf_.full_stop_long_time();
1090 return false;
1091 }
1092}
1093
1094void LonPlusController::SetParkingBrake(
1095 const LonBasedPidPlusControllerConf *conf,
1096 control::ControlCommand *control_command) {
1097 if (control_command->parking_brake()) {
1098 // epb on, parking brake: 0 -> 1
1099 if (epb_on_change_switch_) {
1100 ADEBUG << "Epb on, first set parking brake false.";
1101 control_command->set_parking_brake(false);
1102 ++epb_change_count_;
1103 if (epb_change_count_ >= conf->epb_change_count()) {
1104 epb_on_change_switch_ = false;
1105 epb_change_count_ = 0;
1106 ADEBUG << "Epb on, first stage has been done.";
1107 }
1108 } else {
1109 ADEBUG << "Epb on, second set parking brake true.";
1110 control_command->set_parking_brake(true);
1111 ++epb_change_count_;
1112 if (epb_change_count_ >= conf->epb_change_count()) {
1113 epb_on_change_switch_ = true;
1114 epb_change_count_ = 0;
1115 ADEBUG << "Epb on, second stage has been done.";
1116 }
1117 }
1118 } else {
1119 // epb off, parking brake: 1 -> 0
1120 if (epb_off_change_switch_) {
1121 ADEBUG << "Epb off, first set praking brake true.";
1122 control_command->set_parking_brake(true);
1123 ++epb_change_count_;
1124 if (epb_change_count_ >= conf->epb_change_count()) {
1125 epb_off_change_switch_ = false;
1126 epb_change_count_ = 0;
1127 ADEBUG << "Epb off, first stage has been done.";
1128 }
1129 } else {
1130 ADEBUG << "Epb off, second set parking brake false.";
1131 control_command->set_parking_brake(false);
1132 ++epb_change_count_;
1133 if (epb_change_count_ >= conf->epb_change_count()) {
1134 epb_off_change_switch_ = true;
1135 epb_change_count_ = 0;
1136 ADEBUG << "Epb off, second stage has been done.";
1137 }
1138 }
1139 }
1140}
1141
1142void LonPlusController::CalcultePidParams(const double &speed, PidPlusConf &pid_plus_conf) {
1143 double kp = pid_plus_conf.pid_conf().kp()
1145 speed, pid_plus_conf.speed_input(), pid_plus_conf.kp_speed_gain_output());
1146 pid_plus_conf.mutable_pid_conf()->set_kp(kp);
1147 double ki = pid_plus_conf.pid_conf().ki()
1149 speed, pid_plus_conf.speed_input(), pid_plus_conf.ki_speed_gain_output());
1150 pid_plus_conf.mutable_pid_conf()->set_ki(ki);
1151 double kd = pid_plus_conf.pid_conf().kd()
1153 speed, pid_plus_conf.speed_input(), pid_plus_conf.kd_speed_gain_output());
1154 pid_plus_conf.mutable_pid_conf()->set_kd(kd);
1155 ADEBUG << "Current pid params: kp: " << kp << ", ki: " << ki << ", kd: " << kd;
1156}
1157
1158void LonPlusController::ResetNewFullStop() {
1159 previous_is_full_stop_ = false;
1160 form_go_to_full_stop_ = false;
1161 begin_end_brake_ = false;
1162 fullstop_in_brake_ = 0.0;
1163 fullstop_window_count_ = 0;
1164 hillup_fullstop_brake_rate_ = 0.0;
1165}
1166
1167void LonPlusController::CheckFinishToElse(const planning::ADCTrajectory *trajectory_message) {
1168 if (previous_is_finish_
1169 && !(injector_->get_planning_command_status()->status() == CommandStatusType::FINISHED
1170 || trajectory_message->decision().main_decision().has_mission_complete())) {
1171 from_finish_to_else_ = true;
1172 ADEBUG << "From finish to else!!!";
1173 } else {
1174 from_finish_to_else_ = false;
1175 }
1176 ADEBUG << "from_finish_to_else_: " << from_finish_to_else_;
1177 if (injector_->get_planning_command_status()->status() == CommandStatusType::FINISHED
1178 || trajectory_message->decision().main_decision().has_mission_complete()) {
1179 previous_is_finish_ = true;
1180 } else {
1181 previous_is_finish_ = false;
1182 }
1183 ADEBUG << "previous_is_finish_: " << previous_is_finish_;
1184}
1185
1186} // namespace control
1187} // namespace apollo
The DigitalFilter class is used to pass signals with a frequency lower than a certain cutoff frequenc...
void set_coefficients(const std::vector< double > &denominators, const std::vector< double > &numerators)
set denominators and numerators
A general class to denote the return status of an API call.
Definition status.h:43
static Status OK()
generate a success status.
Definition status.h:60
double ThrottleCmdFilter(const bool &use_filter, const double &filter_coeff, const double &throttle)
bool VehicleStatusIdentificationUpdate(const localization::LocalizationEstimate *localization, const canbus::Chassis *chassis, const planning::ADCTrajectory *trajectory)
bool LoadCalibrationTable(const std::string &calibration_table_path, calibration_table *calibration_table_conf)
bool CheckInPit(double pit_replan_check_time, double pit_replan_check_count, double vehicle_speed, bool replan)
double GetVehicleSpeed(std::shared_ptr< DependencyInjector > injector, const bool &use_filter, const double &filter_coeff)
std::vector< std::tuple< double, double, double > > DataType
static double interpolation_1d(const double &value, const google::protobuf::RepeatedField< double > &input_vector, const google::protobuf::RepeatedField< double > &output_vector)
int InnerstateSaturationStatus() const
get saturation status
virtual double Control(const double error, const double dt)
compute control value based on the error
void SetLeadlagConf(const LeadlagConf &leadlag_conf)
alpha, beta and tau
void InitLeadlag()
initialize lead/lag controller
bool LoadParams(ParamsPipeline *params_pipeline)
std::shared_ptr< DependencyInjector > injector_
void ComputeLongitudinalErrors(const TrajectoryAnalyzer *trajectory, const double preview_time, const double ts, const double vehicle_speed, SimpleLongitudinalDebug *debug)
common::Status ComputeControlCommand(const localization::LocalizationEstimate *localization, const canbus::Chassis *chassis, const planning::ADCTrajectory *trajectory, control::ControlCommand *cmd) override
compute brake / throttle values based on current vehicle status and target trajectory
common::Status Reset() override
reset longitudinal controller
std::string Name() const override
longitudinal controller name
void GetPathRemain(SimpleLongitudinalDebug *debug)
common::Status Init(std::shared_ptr< DependencyInjector > injector) override
initialize Longitudinal Controller
void Stop() override
stop longitudinal controller
void Reset_integral()
reset integral for pid controller
void Reset()
reset variables for pid controller
virtual double Control(const double error, const double dt)
compute control value based on the error
int IntegratorSaturationStatus() const
get saturation status
void InitPID()
initialize pid controller
void SetPID(const PidPlusConf &pid_plus_conf)
set pid controller coefficients for the proportional, integral, and derivative
process point query and conversion related to trajectory
common::PathPoint QueryMatchedPathPoint(const double x, const double y) const
query a point on trajectory that its position is closest to the given position.
common::TrajectoryPoint QueryNearestPointByAbsoluteTime(const double t) const
query a point of trajectory that its absolute time is closest to the give time.
void ToTrajectoryFrame(const double x, const double y, const double theta, const double v, const common::PathPoint &matched_point, double *ptr_s, double *ptr_s_dot, double *ptr_d, double *ptr_d_dot) const
convert a position with theta and speed to trajectory frame,
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
Cyber has builtin time type Time.
Definition time.h:31
std::string GetPluginConfPath(const std::string &class_name, const std::string &conf_name)
get plugin configuration file location
static PluginManager * Instance()
get singleton instance of PluginManager
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
Defines the LonPlusController class.
T Clamp(const T value, T bound1, T bound2)
Clamp a value between two bounds.
Definition math_utils.h:155
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53
void LpfCoefficients(const double ts, const double cutoff_freq, std::vector< double > *denominators, std::vector< double > *numerators)
Get low-pass coefficients for digital filter.
constexpr double GRA_ACC
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
class register implement
Definition arena_queue.h:37
optional GearPosition gear_location
optional apollo::common::Header header
optional float steering_percentage
Definition chassis.proto:88
optional bool parking_brake
Definition chassis.proto:94
optional int32 battery_soc_percentage
optional uint32 sequence_num
Definition header.proto:16
optional double timestamp_sec
Definition header.proto:9
repeated apollo::common::TrajectoryPoint trajectory_point
optional TrajectoryType trajectory_type
optional apollo::canbus::Chassis::GearPosition gear
optional apollo::common::Header header
optional apollo::planning::DecisionResult decision