- Introduced `StatLogSP` for sunnypilot-specific metrics.
- Integrated stats collection and submission pathways for sunnylink.
- Extended parameters and handlers to support additional metrics.
- Added gzip compression and base64 encoding for oversized payload handling.
- Adjusted torque tuning configuration to avoid reliance on torque controller for Hyundai angle steering.
- Simplified control logic by removing unnecessary checks for torque control type.
refactor: clean up code formatting and improve test structure for torque reduction gain
- Adjusted `slip_factor` in Hyundai CANFD safety modes for improved consistency and accuracy.
- Ensured proper representation of `slip_factor` output in test logs.
This reverts commit b95f8c5929.
Revert "Add baseline safety model and improve steering angle limiting logic"
This reverts commit b53cbb2e18.
Revert "Disable lateral accel/jerk params and ensure float consistency in angle limits"
This reverts commit 165d7c7b36.
- Introduced a baseline safety model (`GENESIS_GV80_2025`) for comparison.
- Enhanced steer angle limit calculation using both baseline and current limits for improved safety and precision.
- Reduced max lateral acceleration and jerk by 20% for smoother handling.
- Removed unused `get_safety_CP` function, simplifying `VehicleModel` initialization.
- Replaced conservative GENESIS_GV80_2025 model with IONIQ 5 PE parameters.
- Adjusted steering parameters (ratio, slip factor, wheelbase) for better lateral control performance.
Ensure `actuators.torque` uses its absolute value in the `calculate_angle_torque_reduction_gain` method to prevent sign-related issues during Hyundai steering angle control.
The parameter name "HkgTuningAngleIdleTorqueReductionGain" was updated to "HkgTuningAngleActiveTorqueReductionGain" across multiple files for better clarity and alignment with its functionality. This change ensures consistency in naming conventions and improves code readability.
Introduced `ANGLE_IDLE_TORQUE_REDUCTION_GAIN` to manage torque when the vehicle is stationary, ensuring smoother handling and better lane centering. Updated parsing, parameters, and UI settings to support this new idle torque parameter. Adjusted torque calculation logic and smoothing factor behavior for enhanced control flexibility.
Introduced a toggle for angle smoothing factor and renamed related parameters for clarity. Refactored backend settings to use new parameter names and expanded smoothing matrices for better tuning granularity. Updated UI elements to reflect these changes, emphasizing usability and consistency.
Rename methods and variables for clarity in torque reduction and override calculations. Adjust logic to streamline handling of steering inputs and improve maintainability.
Extract torque ramping and override functionality into dedicated methods within `LkasTorqueManager` to improve maintainability and reduce redundancy. Simplify `update` logic by delegating state-specific operations to new methods.
Encapsulate LKAS torque calculations, ramping, and override logic into the new `LkasTorqueManager` class to improve modularity and maintainability. Replace existing torque logic with calls to the manager.
Add handling for IMU lateral acceleration to refine steering angle limits in CAN FD configurations. Parse and utilize `IMU_LatAccelVal` signal for enhanced lateral control accuracy.
Introduced support for CAN FD angle steering, including updated parameters, signal parsing, and new tests. Refactored related steering logic for clarity, reducing unused code and enhancing maintainability.
Streamline steering angle calculations and fault avoidance logic by removing redundant comments and unused code. Simplified `round_angle` implementation for clarity and consistency.
Revised the determination of `steeringPressed` to account for both hands-on-wheel detection and torque overriding in CAN FD setups. Simplified fallback logic for non-CAN FD configurations for better code clarity and maintainability.
Adjusted the sensitivity and threshold values for `HOD_Dir_Status` in steering press updates, improving accuracy in detecting steering input. This change aligns with updated parameter requirements for better responsiveness.
Updated the condition to detect steering press by changing HOD_Dir_Status threshold from `> 2` to `>= 2`. This ensures the detection logic aligns correctly with expected behavior.
Introduced handling for the `HOD_FD_01_100ms` message when the CANFD angle steering flag is enabled. This ensures proper message parsing and extends compatibility for specific Hyundai vehicle configurations.
Adjusted the steering override frame window and incorporated new HOD_Dir_Status to improve hands-on detection. Added parsing for new signals in Hyundai CAN FD, enhancing steering override responsiveness and reliability.
Increased the minimum override angle cap from 0.01 to 0.1 and explicitly cast the maximum cap to a float. This change improves consistency and ensures proper handling of steering limits.
Reduced the override frame window and updated the angle cap logic to use MAX_ANGLE_RATE. These changes aim to enhance steering responsiveness and safety by fine-tuning steer angle limits.
The `smoothing_factor` parameter and related logic have been removed to simplify the steering angle smoothing approach. All references and usage of this parameter have been eliminated, relying solely on speed-based dynamic interpolation. This change streamlines the code while maintaining functionality.
Reduced `OVERRIDE_FRAME_WINDOW` and updated condition to properly respect override frame limits. This ensures smoother handling and more precise steering adjustments under certain driving scenarios.
Replaced `recently_overridden` with `frames_since_override` for better granularity and added dynamic override angle limits using interpolation. These changes enhance steering control accuracy during user overrides and improve overall code readability.
Adjusted logic for recently overridden steering to improve angle limits and torque smoothing. Removed unused or redundant code, optimizing the functionality and maintaining cleaner readability.
Extracted the steering angle smoothing logic into a standalone function `sp_smooth_angle` to enhance readability and reusability. Adjusted angle smoothing parameters and introduced a maximum vehicle speed threshold for applying smoothing. Minor updates improve maintainability and ensure consistent behavior across speed ranges.
Updated `STEER_THRESHOLD` to 350 and `NO_LONGER_OVERRIDING_THRESHOLD` to 150 for better alignment with Hyundai CAN FD steering behavior. These changes ensure improved compatibility and more accurate steering response.
Re-enables resetting `apply_angle_last` to `steering_angle` when steering is recently overridden. This ensures proper handling of steering angle limits during transitions.
Simplified torque ramp-up logic by combining conditions and adjusted `STEER_THRESHOLD` for CANFD angle steering. These changes aim to enhance control precision and maintain consistency in overrides.
Decrease the override timeout from 100 to 50 frames, ensuring quicker recognition of driver input override. This improves responsiveness and aligns with refined control behavior.
Removed restrictive rate limiting during recent user overrides to improve steering response. Adjusted logic to ensure correct handling of steering angle when lateral control is inactive or overridden.
Adjust steering behavior to account for recent user overrides, improving safety and control. Introduced a "recently_overridden" check to limit angle rates and torque adjustments when user intervention is detected.
Added logic to use the current steering angle when the steering wheel is pressed, ensuring smoother transitions during user overrides. Updated function parameters and implementation to reflect this enhancement.
Removed redundant `recently_overridden` logic and introduced a more robust approach for tracking user steering overrides. Added `NO_LONGER_OVERRIDING_THRESHOLD` and updated conditions to improve steer override handling. Adjustments ensure smoother torque transitions and more accurate steering state detection.
Replaced hardcoded `angle_min_active_torque` with `ANGLE_MIN_TORQUE` from params for better configurability and consistency. This ensures the torque clamping logic aligns with defined parameters.
Updated torque calculation logic with a new optional parameter for minimum active torque, streamlining control behavior. Deactivated and cleaned up references to HkgAngleLiveTuning, simplifying configuration and reducing runtime complexities. Updated relevant UI and parameter descriptions for clarity.
Increase the override window and refine torque ramp-up behavior to avoid conflicts during recent overrides. Updated steering driver allowance and threshold values for CANFD angle steering to improve compatibility and performance.
Added logic to track recent steering overrides and adjust LKAS torque behavior accordingly. This ensures smoother transitions when the steering is overridden and reduces potential conflicts with driver input. Updated CANFD-specific steering thresholds for enhanced compatibility.
This new layout visualizes actuator data, CAN steering messages, and car state variables. It provides multiple time-series plots to aid in debugging and analysis. Plugin configurations are also included for extended functionality.
Simplified control flag handling for angle steering, adjusted torque calculations for smoother ramp rates, and updated tuning parameters for the Hyundai Ioniq 5 PE. Minor adjustment to return value handling in lateral control functions.
Remove duplicate STEER_ANGLE_SATURATION_THRESHOLD import
Cleaned up an unnecessary duplicate import of STEER_ANGLE_SATURATION_THRESHOLD from latcontrol_angle_torque. This simplifies the module imports and prevents potential redundancy or confusion.
Refactor lateral control to combine torque and angle logic
Merged functionalities of LatControlTorque and LatControlAngle into a single LatControlAngleTorque class. Refactored code to utilize methods from both parent classes, reducing duplication and improving maintainability.
Add angle-torque hybrid lateral control for Hyundai CAN FD
Introduces `LatControlAngleTorque` to enable hybrid angle and torque-based steering for specific Hyundai models. Updates related logic in carcontroller, interface, and controlsd to accommodate this new lateral control method. Adjusts torque parameters for enhanced control in supported models.
Replaced direct access to `params` with instance variables for torque parameters to improve code clarity and maintainability. Updated smoothing factor description in angle tuning settings to include speed-related behavior. This enhances readability and prepares for further tuning adjustments.
Updated the value of HkgTuningOverridingCycles to a string for consistency with other parameters in the tuning configuration. This ensures proper handling and avoids potential issues with type mismatches.
Add overriding cycles parameter for torque adjustment
Introduced "HkgTuningOverridingCycles" for configurable user override torque ramp-down cycles. Updated relevant logic in torque control and UI settings to handle the new parameter. This improves flexibility in adjusting steering torque override behavior.
Introduce separate angle tuning controls for HKG vehicles, including smoothing factor, min torque, and max torque parameters. Refactor developer panel to integrate the new settings into a dedicated UI panel, enhancing modularity and customization capabilities.
Enhanced the description to clarify its effect on steering behavior. Included details on how the smoothing factor impacts steering smoothness using EMA, aiding user understanding.
Refactored the calculation and application of the steering angle to improve code clarity and ensure smoother transitions. Removed unused parameter update logic in `latcontrol_angle.py` and enhanced handling of driver overrides in `carcontroller.py`.
Replaced `self._params` with `self.params` to correctly access the parameter `HkgTuningAngleSmoothingFactor`. This ensures the smoothing factor is updated as intended during the control loop.
Introduced a dynamic smoothing factor using the `HkgTuningAngleSmoothingFactor` parameter. This allows more granular control over curvature smoothing based on customizable user input, enhancing driving smoothness. Added necessary logic to process and apply this parameter efficiently.
Introduced a new parameter, `HkgTuningAngleSmoothingFactor`, to apply exponential moving average (EMA) smoothing to steering angle changes, reducing sudden adjustments. Added associated UI controls, parameter persistence, and integration into Hyundai carcontroller logic for improved steering stability.
Wrap the pygame import in a try-except block to catch ImportError. This prevents the script from crashing and provides a clear message prompting the user to install pygame if it's missing.
Remove "inputs" package and update "pygame" dependency
The "inputs" package has been removed from the lockfile and dependency list, while "pygame" is now included universally without the "dev" extra marker. This change simplifies dependencies and ensures consistency across environments.
Update dependencies: replace 'inputs' with 'pygame'
Replaced the 'inputs' library with 'pygame' for joystickd dependencies in `pyproject.toml`. Additionally, removed a redundant 'pygame' entry from the general dependencies.
Ugly, I know, but soundd is unhappy with joystick
Allowing lat with mads
Invert steering input for joystick control
The steering axis input is now multiplied by -1 to reverse its direction. This ensures correct handling of the left stick's horizontal input, aligning behavior with expected control dynamics.
Refactor joystick control to use pygame for broader support
Replaced the `inputs` library with `pygame` for joystick handling, providing improved compatibility with Xbox and PlayStation controllers. Added initialization, adaptive mappings, deadzone handling, and enhanced event processing for robust joystick operation. Updated README with dependencies and usage information for Xbox controllers.
Updated the `filter_speed_matrox` values to improve curvature filtering behavior at different speeds. This change ensures better handling and stability across a wider range of driving conditions.
Introduced speed-based dynamic alpha adjustment using interpolation for smoother curvature filtering. This improves steering angle calculations by adapting filter sensitivity to vehicle speed, enhancing control performance.
Updated curvature breakpoints and torque scaling for improved control in sharp turns. Increased filter alpha for faster curvature response while maintaining system stability.
Updated curvature breakpoints in Hyundai carcontroller to improve torque scaling for curved driving. Slightly refined the filter coefficient in lateral control for smoother curvature filtering and more accurate steering adjustments.
Introduced dynamic torque scaling based on curvature for smoother and more adaptive steering control. Replaced raw curvature inputs with filtered curvature for enhanced stability and reduced noise in steering angle calculations. Removed unused speed scaling logic to simplify the lateral control flow.
This reverts commit ea1af879ba2905b076ccfe65993a9db701d689dd.
Revert "More improvement but still not quite"
This reverts commit ad95493c5c61b2ace7c459d2ebc151ddaa80040f.
Revert "Adjust low-speed scaling for lateral control angle"
This reverts commit 6f789ac1ebb66b0239b4028303573c2d7d386b39.
Revert "Refactor speed-based steering scaling logic."
This reverts commit 1d40735ab8db8d470ff3b287a6b42847beffff7d.
Updated the steering angle computation to use a clearer and more descriptive speed-scaling configuration. Replaced low-speed-specific logic with a generalized approach based on speed breakpoints and corresponding influence factors. This improves maintainability and ensures smoother steering adjustments at varying speeds.
Refined the low-speed scaling parameters by modifying speed breakpoints and factors. This improves handling at lower speeds for smoother and more predictable behavior.
<configurationdefault="false"name="Replay for controls + ui"type="Multirun"separateTabs="false"reuseTabsWithFailures="false"startOneByOne="true"markFailedProcess="true"hideSuccessProcess="false"delayTime="0.0">
<runConfigurationname="replay for controls"type="Native Application"/>
<configurationdefault="false"name="replay for controls"type="CLionNativeAppRunConfigurationType"focusToolWindowBeforeRun="true"PROGRAM_PARAMS=""$Prompt$" --block "sendcan,carState,carParams,carOutput,liveTracks,carParamsSP,carStateSP,bookmarkButton""REDIRECT_INPUT="false"ELEVATE="false"USE_EXTERNAL_CONSOLE="false"EMULATE_TERMINAL="true"WORKING_DIR="file://$ProjectFileDir$/tools/replay"PASS_PARENT_ENVS_2="true"PROJECT_NAME="openpilot-special"TARGET_NAME="replay"CONFIG_NAME="replay"version="1"RUN_PATH="replay">
enableHkgAngleSmoothingFactor=newExpandableToggleRow("EnableHkgTuningAngleSmoothingFactor",tr("HKG Angle Smoothing Factor"),tr("Applies EMA (Exponential Moving Average) to the desired angle steering and avoid overcorrections."),"../assets/offroad/icon_blank.png");
list->addItem(enableHkgAngleSmoothingFactor);
autofirst_row=newQHBoxLayout();
hkgTuningOverridingCycles=newOptionControlSP("HkgTuningOverridingCycles",tr("Override Ramp-Down Cycles"),tr("Number of cycles to ramp down the current amount of torque on the steering wheel.<br/>A smaller value means a faster override by the user (less effort)"),"../assets/offroad/icon_blank.png",{10,30},1);
hkgAngleMinTorque=newOptionControlSP("HkgTuningAngleMinTorqueReductionGain",tr("Override Steering Effort"),tr("Sets the steering effort percentage used when the driver is overriding lateral control.<br/>Higher values increase resistance and make the wheel feel stiffer."),"../assets/offroad/icon_blank.png",{5,60},1);
hkgAngleActiveTorque=newOptionControlSP("HkgTuningAngleActiveTorqueReductionGain",tr("Min Active Torque"),tr("Torque applied when lateral control is active but the vehicle is not turning.<br/>Used to maintain lane centering on straight paths when no user input is detected."),"../assets/offroad/icon_blank.png",{10,100},1);
hkgAngleMaxTorque=newOptionControlSP("HkgTuningAngleMaxTorqueReductionGain",tr("Max Torque Allowance"),tr("Sets the maximum torque reduction percentage the controller can apply during normal lateral control.<br/>"),"../assets/offroad/icon_blank.png",{10,100},1);
<librarycode="--[[ Helper function to create a series from arrays

 new_series: a series previously created with ScatterXY.new(name)
 prefix: prefix of the timeseries, before the index of the array
 suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.
 suffix_Y: suffix to complete the name of the series containing the Y value
 timestamp: usually the tracker_time variable
 
 Example:
 
 Assuming we have multiple series in the form:
 
 /trajectory/node.{X}/position/x
 /trajectory/node.{X}/position/y
 
 where {N} is the index of the array (integer). We can create a reactive series from the array with:
 
 new_series = ScatterXY.new("my_trajectory") 
 CreateSeriesFromArray( new_series, "/trajectory/node", "position/x", "position/y", tracker_time );
--]]

function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )
 
 --- clear previous values
 new_series:clear()
 
 --- Append points to new_series
 index = 0
 while(true) do

 x = index;
 -- if not nil, get the X coordinate from a series
 if suffix_X ~= nil then 
 series_x = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_X) )
 if series_x == nil then break end
 x = series_x:atTime(timestamp)	 
 end
 
 series_y = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_Y) )
 if series_y == nil then break end 
 y = series_y:atTime(timestamp)
 
 new_series:push_back(x,y)
 index = index+1
 end
end

--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]

function GetSeriesNamesByPrefix(prefix)
 -- GetSeriesNames(9 is a built-in function
 all_names = GetSeriesNames()
 filtered_names = {}
 for i, name in ipairs(all_names) do
 -- check the prefix
 if name:find(prefix, 1, #prefix) then
 table.insert(filtered_names, name);
 end
 end
 return filtered_names
end

--[[ Modify an existing series, applying offsets to all their X and Y values

 series: an existing timeseries, obtained with TimeseriesView.find(name)
 delta_x: offset to apply to each x value
 delta_y: offset to apply to each y value 
 
--]]

function ApplyOffsetInPlace(series, delta_x, delta_y)
 -- use C++ indeces, not Lua indeces
 for index=0, series:size()-1 do
 x,y = series:at(index)
 series:set(index, x + delta_x, y + delta_y)
 end
end
"/>
<librarycode="--[[ Helper function to create a series from arrays

 new_series: a series previously created with ScatterXY.new(name)
 prefix: prefix of the timeseries, before the index of the array
 suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.
 suffix_Y: suffix to complete the name of the series containing the Y value
 timestamp: usually the tracker_time variable
 
 Example:
 
 Assuming we have multiple series in the form:
 
 /trajectory/node.{X}/position/x
 /trajectory/node.{X}/position/y
 
 where {N} is the index of the array (integer). We can create a reactive series from the array with:
 
 new_series = ScatterXY.new("my_trajectory") 
 CreateSeriesFromArray( new_series, "/trajectory/node", "position/x", "position/y", tracker_time );
--]]

function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )
 
 --- clear previous values
 new_series:clear()
 
 --- Append points to new_series
 index = 0
 while(true) do

 x = index;
 -- if not nil, get the X coordinate from a series
 if suffix_X ~= nil then 
 series_x = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_X) )
 if series_x == nil then break end
 x = series_x:atTime(timestamp)	 
 end
 
 series_y = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_Y) )
 if series_y == nil then break end 
 y = series_y:atTime(timestamp)
 
 new_series:push_back(x,y)
 index = index+1
 end
end

--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]

function GetSeriesNamesByPrefix(prefix)
 -- GetSeriesNames(9 is a built-in function
 all_names = GetSeriesNames()
 filtered_names = {}
 for i, name in ipairs(all_names) do
 -- check the prefix
 if name:find(prefix, 1, #prefix) then
 table.insert(filtered_names, name);
 end
 end
 return filtered_names
end

--[[ Modify an existing series, applying offsets to all their X and Y values

 series: an existing timeseries, obtained with TimeseriesView.find(name)
 delta_x: offset to apply to each x value
 delta_y: offset to apply to each y value 
 
--]]

function ApplyOffsetInPlace(series, delta_x, delta_y)
 -- use C++ indeces, not Lua indeces
 for index=0, series:size()-1 do
 x,y = series:at(index)
 series:set(index, x + delta_x, y + delta_y)
 end
end
"/>
<scripts/>
</plugin>
<pluginID="CSV Exporter"/>
</Plugins>
<!------------------>
<previouslyLoaded_Datafiles>
<fileInfofilename="../tmpgh9xhmjb.rlog"prefix="">
<selected_datasourcesvalue=""/>
</fileInfo>
</previouslyLoaded_Datafiles>
<!------------------>
<customMathEquations>
<snippetname="Angle Staturation">
<global></global>
<function>if value > .3 then
return 1
end
return 0</function>
<linked_source>Angle Error</linked_source>
</snippet>
<snippetname="ang_cmd rate">
<global>firstX = 0
firstY = 0
is_first = true
secondX = 0
secondY = 0
is_second = false</global>
<function>-- Wait for initial values
if (is_first) then
is_first = false
is_second = true
firstX = time
firstY = value
end
if (is_second) then
is_second = false
secondX = time
secondY = value
end
-- Central derivative: dy/dx ~= f(x+delta_x)-f(x-delta_x)/(2*delta_x)
<librarycode="--[[ Helper function to create a series from arrays

 new_series: a series previously created with ScatterXY.new(name)
 prefix: prefix of the timeseries, before the index of the array
 suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.
 suffix_Y: suffix to complete the name of the series containing the Y value
 timestamp: usually the tracker_time variable
 
 Example:
 
 Assuming we have multiple series in the form:
 
 /trajectory/node.{X}/position/x
 /trajectory/node.{X}/position/y
 
 where {N} is the index of the array (integer). We can create a reactive series from the array with:
 
 new_series = ScatterXY.new("my_trajectory") 
 CreateSeriesFromArray( new_series, "/trajectory/node", "position/x", "position/y", tracker_time );
--]]

function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )
 
 --- clear previous values
 new_series:clear()
 
 --- Append points to new_series
 index = 0
 while(true) do

 x = index;
 -- if not nil, get the X coordinate from a series
 if suffix_X ~= nil then 
 series_x = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_X) )
 if series_x == nil then break end
 x = series_x:atTime(timestamp)	 
 end
 
 series_y = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_Y) )
 if series_y == nil then break end 
 y = series_y:atTime(timestamp)
 
 new_series:push_back(x,y)
 index = index+1
 end
end

--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]

function GetSeriesNamesByPrefix(prefix)
 -- GetSeriesNames(9 is a built-in function
 all_names = GetSeriesNames()
 filtered_names = {}
 for i, name in ipairs(all_names) do
 -- check the prefix
 if name:find(prefix, 1, #prefix) then
 table.insert(filtered_names, name);
 end
 end
 return filtered_names
end

--[[ Modify an existing series, applying offsets to all their X and Y values

 series: an existing timeseries, obtained with TimeseriesView.find(name)
 delta_x: offset to apply to each x value
 delta_y: offset to apply to each y value 
 
--]]

function ApplyOffsetInPlace(series, delta_x, delta_y)
 -- use C++ indeces, not Lua indeces
 for index=0, series:size()-1 do
 x,y = series:at(index)
 series:set(index, x + delta_x, y + delta_y)
 end
end
"/>
<scripts/>
</plugin>
<pluginID="CSV Exporter"/>
</Plugins>
<!------------------>
<previouslyLoaded_Datafiles>
<fileInfoprefix=""filename="../tmpa_e8kwpj.rlog">
<selected_datasourcesvalue=""/>
</fileInfo>
</previouslyLoaded_Datafiles>
<!------------------>
<customMathEquations>
<snippetname="zero">
<global>min=0
max=250
max_from_speed=96
rate_lim = 500
la_deadzone = 0.38
k1=200
k2=20
k3=1.0
k4=1
k5=10
old = 0
function sign(number)
return number > 0 and 1 or (number == 0 and 0 or -1)
end
function apply_rate_limit(old, new, limit)
return math.min(math.max(new, old - limit), old + limit)
end
function apply_deadzone(val, deadzone)
if math.abs(val) <= deadzone then
return 0.0
elseif val < 0.0 then
return val + deadzone
else
return val - deadzone
end
end</global>
<function>return 0</function>
<linked_source>/carState/aEgo</linked_source>
</snippet>
<snippetname="max torque lj adj">
<global>min=0
max=250
max_from_speed=96
k1=200
k2=30
k3=1
k4=1
k5=10
function sign(number)
return number > 0 and 1 or (number == 0 and 0 or -1)
<librarycode="--[[ Helper function to create a series from arrays

 new_series: a series previously created with ScatterXY.new(name)
 prefix: prefix of the timeseries, before the index of the array
 suffix_X: suffix to complete the name of the series containing the X value. If [nil], use the index of the array.
 suffix_Y: suffix to complete the name of the series containing the Y value
 timestamp: usually the tracker_time variable
 
 Example:
 
 Assuming we have multiple series in the form:
 
 /trajectory/node.{X}/position/x
 /trajectory/node.{X}/position/y
 
 where {N} is the index of the array (integer). We can create a reactive series from the array with:
 
 new_series = ScatterXY.new("my_trajectory") 
 CreateSeriesFromArray( new_series, "/trajectory/node", "position/x", "position/y", tracker_time );
--]]

function CreateSeriesFromArray( new_series, prefix, suffix_X, suffix_Y, timestamp )
 
 --- clear previous values
 new_series:clear()
 
 --- Append points to new_series
 index = 0
 while(true) do

 x = index;
 -- if not nil, get the X coordinate from a series
 if suffix_X ~= nil then 
 series_x = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_X) )
 if series_x == nil then break end
 x = series_x:atTime(timestamp)	 
 end
 
 series_y = TimeseriesView.find( string.format( "%s.%d/%s", prefix, index, suffix_Y) )
 if series_y == nil then break end 
 y = series_y:atTime(timestamp)
 
 new_series:push_back(x,y)
 index = index+1
 end
end

--[[ Similar to the built-in function GetSeriesNames(), but select only the names with a give prefix. --]]

function GetSeriesNamesByPrefix(prefix)
 -- GetSeriesNames(9 is a built-in function
 all_names = GetSeriesNames()
 filtered_names = {}
 for i, name in ipairs(all_names) do
 -- check the prefix
 if name:find(prefix, 1, #prefix) then
 table.insert(filtered_names, name);
 end
 end
 return filtered_names
end

--[[ Modify an existing series, applying offsets to all their X and Y values

 series: an existing timeseries, obtained with TimeseriesView.find(name)
 delta_x: offset to apply to each x value
 delta_y: offset to apply to each y value 
 
--]]

function ApplyOffsetInPlace(series, delta_x, delta_y)
 -- use C++ indeces, not Lua indeces
 for index=0, series:size()-1 do
 x,y = series:at(index)
 series:set(index, x + delta_x, y + delta_y)
 end
end
"/>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.