Skip to content

Commit

Permalink
feat(pid_longitudinal_controller): add new slope compensation mode tr…
Browse files Browse the repository at this point in the history
…ajectory_goal_adaptive (#9705)

Signed-off-by: yuki-takagi-66 <[email protected]>
  • Loading branch information
yuki-takagi-66 authored Dec 20, 2024
1 parent a7314b6 commit 4c03b8d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 12 deletions.
2 changes: 2 additions & 0 deletions control/autoware_pid_longitudinal_controller/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ There are two sources of the slope information, which can be switched by a param
- Cons: z-coordinates of high-precision map is needed.
- Cons: Does not support free space planning (for now)

We also offer the options to switch between these, depending on driving conditions.

**Notation:** This function works correctly only in a vehicle system that does not have acceleration feedback in the low-level control system.

This compensation adds gravity correction to the target acceleration, resulting in an output value that is no longer equal to the target acceleration that the autonomous driving system desires. Therefore, it conflicts with the role of the acceleration feedback in the low-level controller.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@

# slope compensation
lpf_pitch_gain: 0.95
slope_source: "raw_pitch" # raw_pitch, trajectory_pitch or trajectory_adaptive
slope_source: "trajectory_goal_adaptive" # raw_pitch, trajectory_pitch, trajectory_adaptive or trajectory_goal_adaptive
adaptive_trajectory_velocity_th: 1.0
max_pitch_rad: 0.1
min_pitch_rad: -0.1
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,12 @@ class PidLongitudinalController : public trajectory_follower::LongitudinalContro
double m_max_acc_cmd_diff;

// slope compensation
enum class SlopeSource { RAW_PITCH = 0, TRAJECTORY_PITCH, TRAJECTORY_ADAPTIVE };
enum class SlopeSource {
RAW_PITCH = 0,
TRAJECTORY_PITCH,
TRAJECTORY_ADAPTIVE,
TRAJECTORY_GOAL_ADAPTIVE
};
SlopeSource m_slope_source{SlopeSource::RAW_PITCH};
double m_adaptive_trajectory_velocity_th;
std::shared_ptr<LowpassFilter1d> m_lpf_pitch{nullptr};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ PidLongitudinalController::PidLongitudinalController(
m_slope_source = SlopeSource::TRAJECTORY_PITCH;
} else if (slope_source == "trajectory_adaptive") {
m_slope_source = SlopeSource::TRAJECTORY_ADAPTIVE;
} else if (slope_source == "trajectory_goal_adaptive") {
m_slope_source = SlopeSource::TRAJECTORY_GOAL_ADAPTIVE;
} else {
RCLCPP_ERROR(logger_, "Slope source is not valid. Using raw_pitch option as default");
m_slope_source = SlopeSource::RAW_PITCH;
Expand Down Expand Up @@ -529,35 +531,44 @@ PidLongitudinalController::ControlData PidLongitudinalController::getControlData
// NOTE: getPitchByTraj() calculates the pitch angle as defined in
// ../media/slope_definition.drawio.svg while getPitchByPose() is not, so `raw_pitch` is reversed
const double raw_pitch = (-1.0) * longitudinal_utils::getPitchByPose(current_pose.orientation);
m_lpf_pitch->filter(raw_pitch);
const double traj_pitch = longitudinal_utils::getPitchByTraj(
control_data.interpolated_traj, control_data.target_idx, m_wheel_base);

if (m_slope_source == SlopeSource::RAW_PITCH) {
control_data.slope_angle = m_lpf_pitch->filter(raw_pitch);
control_data.slope_angle = m_lpf_pitch->getValue();
} else if (m_slope_source == SlopeSource::TRAJECTORY_PITCH) {
control_data.slope_angle = traj_pitch;
} else if (m_slope_source == SlopeSource::TRAJECTORY_ADAPTIVE) {
} else if (
m_slope_source == SlopeSource::TRAJECTORY_ADAPTIVE ||
m_slope_source == SlopeSource::TRAJECTORY_GOAL_ADAPTIVE) {
// if velocity is high, use target idx for slope, otherwise, use raw_pitch
if (control_data.current_motion.vel > m_adaptive_trajectory_velocity_th) {
control_data.slope_angle = traj_pitch;
m_lpf_pitch->filter(raw_pitch);
} else {
control_data.slope_angle = m_lpf_pitch->filter(raw_pitch);
}
const bool is_vel_slow = control_data.current_motion.vel < m_adaptive_trajectory_velocity_th &&
m_slope_source == SlopeSource::TRAJECTORY_ADAPTIVE;

const double goal_dist = autoware::motion_utils::calcSignedArcLength(
control_data.interpolated_traj.points, current_pose.position,
control_data.interpolated_traj.points.size() - 1);
const bool is_close_to_trajectory_end =
goal_dist < m_wheel_base && m_slope_source == SlopeSource::TRAJECTORY_GOAL_ADAPTIVE;

control_data.slope_angle =
(is_close_to_trajectory_end || is_vel_slow) ? m_lpf_pitch->getValue() : traj_pitch;

if (m_previous_slope_angle.has_value()) {
constexpr double gravity_const = 9.8;
control_data.slope_angle = std::clamp(
control_data.slope_angle,
m_previous_slope_angle.value() + m_min_jerk * control_data.dt / gravity_const,
m_previous_slope_angle.value() + m_max_jerk * control_data.dt / gravity_const);
}
m_previous_slope_angle = control_data.slope_angle;
} else {
RCLCPP_ERROR_THROTTLE(
logger_, *clock_, 3000, "Slope source is not valid. Using raw_pitch option as default");
control_data.slope_angle = m_lpf_pitch->filter(raw_pitch);
control_data.slope_angle = m_lpf_pitch->getValue();
}

m_previous_slope_angle = control_data.slope_angle;
updatePitchDebugValues(control_data.slope_angle, traj_pitch, raw_pitch, m_lpf_pitch->getValue());

return control_data;
Expand Down

0 comments on commit 4c03b8d

Please sign in to comment.