Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HKG tuning #66

Open
wants to merge 29 commits into
base: master-new
Choose a base branch
from
Open

Conversation

Discountchubbs
Copy link

@Discountchubbs Discountchubbs commented Feb 17, 2025

sunnypilot/sunnypilot#636

New Feature

Custom tuning for HKG vehicles, taking into account lower, upper jerk, and comfort bands. When the user selects toggles, these plus interface tuning will be applied. Furthermore, if the user presses the button to enable smoother braking, my custom accel logic will be utilized to greatly filter and smoothen accel/braking transitions for a more chill open pilot experience.

Current issue:
--While CB calculation works great to limit rough transitions from acceleration costs. There is an error on cruiseState.Speed target that is still being ironed out. So, at this time, until that issue is completely fixed, Hyundai has the standard value of 0.0 for CB upper and lower.

Summary by Sourcery

Add custom longitudinal tuning for HKG vehicles.

New Features:

  • Introduce custom longitudinal tuning for HKG vehicles, including adjustable jerk limits, comfort bands, and smoother braking logic.
  • Add a toggle for smoother braking that utilizes custom acceleration logic to filter and smoothen acceleration and braking transitions.

Copy link

sourcery-ai bot commented Feb 17, 2025

Reviewer's Guide by Sourcery

This pull request introduces custom longitudinal tuning for HKG vehicles. It includes new classes for managing tuning parameters and applying custom acceleration logic. The changes also modify CAN message creation to incorporate jerk limits and comfort band values, and adjust default longitudinal parameters when HKG tuning is enabled.

Sequence diagram for calculating limited acceleration with HKG tuning

sequenceDiagram
    participant CarController
    participant HKGLongitudinalController
    participant HKGLongitudinalTuning
    participant CarState
    participant Actuators

    CarController->HKGLongitudinalController: calculate_limited_accel(accel, actuators, CS)
    alt HKGtuning is enabled
        HKGLongitudinalController->HKGLongitudinalTuning: calculate_limited_accel(accel, actuators, CS)
        HKGLongitudinalTuning->HKGLongitudinalTuning: make_jerk(CS, accel, actuators)
        HKGLongitudinalTuning->CarState: Access vEgo, cruiseState.speed
        HKGLongitudinalTuning->Actuators: Access accel
        HKGLongitudinalTuning->HKGLongitudinalTuning: Compute accel_delta, ramp_rate, brake_aggressiveness
        HKGLongitudinalTuning->HKGLongitudinalTuning: Apply smoothing
        HKGLongitudinalTuning->HKGLongitudinalTuning: Enforce jerk limits
        HKGLongitudinalTuning->HKGLongitudinalTuning: Gradual transition from positive accel to negative
        HKGLongitudinalTuning->HKGLongitudinalTuning: Update accel
        HKGLongitudinalTuning-->CarController: return accel
    else HKGtuning is disabled
        HKGLongitudinalController-->CarController: return accel
    end
Loading

Updated class diagram for HKGLongitudinalController and HKGLongitudinalTuning

classDiagram
    class HKGLongitudinalController {
        -CP
        -tuning
        +__init__(CP)
        +apply_tune(CP)
        +calculate_limited_accel(accel, actuators, CS)
        +get_jerk()
    }
    class HKGLongitudinalTuning {
        -CP
        -mpc
        -long_control
        -DT_CTRL
        -params
        -hkg_tuning
        -has_radar
        -last_accel
        -brake_ramp
        -accel_last
        -using_e2e
        -accel_raw
        -accel_last_jerk
        -jerk
        -jerk_count
        -jerk_upper_limit
        -jerk_lower_limit
        -cb_upper
        -cb_lower
        +__init__(CP)
        -_setup_controllers()
        -_init_state()
        +make_jerk(CS, accel, actuators)
        +calculate_limited_accel(accel, actuators, CS)
        +apply_tune(CP)
        +get_jerk()
    }
    class JerkOutput {
        +jerk_upper_limit
        +jerk_lower_limit
        +cb_upper
        +cb_lower
        +__init__(jerk_upper_limit, jerk_lower_limit, cb_upper, cb_lower)
    }

    HKGLongitudinalController -- HKGLongitudinalTuning : uses
    HKGLongitudinalTuning -- JerkOutput : returns
Loading

File-Level Changes

Change Details Files
Introduces custom longitudinal tuning for HKG vehicles, including jerk and comfort band adjustments.
  • Adds HKGLongitudinalController and HKGLongitudinalTuning classes for custom tuning logic.
  • Implements calculate_limited_accel to filter and smooth acceleration/braking transitions.
  • Adds logic to adjust jerk limits and comfort bands based on vehicle speed and acceleration.
  • Adds a new JerkOutput class to encapsulate jerk-related values.
  • Adds a new parameter HKGBraking to enable the custom acceleration logic.
  • Adds a new parameter HKGtuning to enable the custom tuning.
opendbc/car/hyundai/carcontroller.py
opendbc/car/hyundai/hyundaican.py
opendbc/car/hyundai/hyundaicanfd.py
opendbc/car/hyundai/interface.py
opendbc/sunnypilot/car/hyundai/longitudinal_tuning.py
Modifies CAN message creation to include jerk limits and comfort band values.
  • Updates create_acc_commands in hyundaican.py to include jerk upper/lower limits, and comfort band values.
  • Updates create_acc_control in hyundaicanfd.py to include jerk upper/lower limits.
  • Passes jerk values from the controller to the CAN message creation functions.
opendbc/car/hyundai/hyundaican.py
opendbc/car/hyundai/hyundaicanfd.py
Adjusts default longitudinal parameters when HKG tuning is enabled.
  • Modifies _get_params in interface.py to apply custom tuning parameters when HKGtuning is enabled, such as vEgoStopping, vEgoStarting, stoppingDecelRate, and startAccel.
opendbc/car/hyundai/interface.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Discountchubbs - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider adding a more descriptive name than HKGLongitudinalController to better reflect its purpose.
  • It might be cleaner to encapsulate the logic that determines whether to use the custom acceleration logic within the HKGLongitudinalTuning class.
Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

self.cb_upper = self.cb_lower = 0.0


def make_jerk(self, CS, accel, actuators):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider refactoring complex tuning logic into smaller, testable helper methods.

Consider refactoring parts of the tuning logic into small helper methods. For example, the nested conditionals in make_jerk could be separated into a helper that computes the jerk limits and comfort bands. This makes the code easier to read and test. Some suggestions:

  1. Extract the CANFD/non-CANFD logic into its own method:
def _compute_jerk_limits(self, v_error, current_jerk, accel):
    jerk_max = 5.0
    if self.CP.flags & HyundaiFlags.CANFD.value:
        if v_error < 3.0:
            jerk_reduction = interp(v_error, [0.0, 1.0, 3.0], [0.3, 0.5, 1.0])
            jerk_max *= jerk_reduction
        jerk_upper = min(max(0.5, current_jerk * 2.0), jerk_max)
        jerk_lower = min(max(1.0, -current_jerk * 4.0), jerk_max)
        cb_upper = cb_lower = 0.0
    else:
        jerk_upper = min(max(0.5, current_jerk * 2.0), jerk_max)
        jerk_lower = min(max(1.0, -current_jerk * 2.0), jerk_max)
        error_factor = interp(v_error, [0.0, 0.5, 1.0, 5.0], [0.0, 0.1, 0.5, 1.0])
        accel_factor = interp(abs(accel), [0.0, 1.0], [0.2, 0.1])
        if accel >= 0:
            cb_upper = clip(0.8 * error_factor + accel * accel_factor, 0, 1.0)
            cb_lower = clip(0.6 * error_factor + accel * accel_factor, 0, 0.8)
        else:
            cb_upper = clip(1.0 * error_factor + accel * accel_factor, 0, 1.2)
            cb_lower = clip(0.8 * error_factor + accel * accel_factor, 0, 1.2)
    return jerk_upper, jerk_lower, cb_upper, cb_lower
  1. Use this helper inside make_jerk to simplify that method:
def make_jerk(self, CS, accel, actuators):
    state = getattr(actuators, "longControlState", LongCtrlState.pid)

    if not CS.out.cruiseState.enabled:
        self.jerk_upper_limit = 0.0
        self.jerk_lower_limit = 0.0
        self.cb_upper = self.cb_lower = 0.0
        self.accel_last_jerk = 0.0
        return 0.0

    if state == LongCtrlState.stopping:
        self.jerk = 1.75 / 2 - CS.out.aEgo
        return self.jerk
    else:
        current_accel = clip(actuators.accel, CarControllerParams.ACCEL_MIN, CarControllerParams.ACCEL_MAX)
        self.jerk = (current_accel - self.accel_last_jerk) / self.DT_CTRL
        self.accel_last_jerk = current_accel

    v_error = abs(CS.out.vEgo - CS.out.cruiseState.speed)
    self.jerk_upper_limit, self.jerk_lower_limit, self.cb_upper, self.cb_lower = \
        self._compute_jerk_limits(v_error, self.jerk, accel)
    return self.jerk
  1. Consider similar extraction in calculate_limited_accel for the brake ramp and smoothing logic.

These changes keep all functionality intact while reducing complexity and improving testability.

18Feb2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants