Skip to content

Commit

Permalink
Experiment with torque transfer calculations in shift
Browse files Browse the repository at this point in the history
  • Loading branch information
rnd-ash committed Apr 6, 2024
1 parent 0e1782a commit be685b3
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 79 deletions.
1 change: 1 addition & 0 deletions src/common_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ struct ShiftData{
float pressure_multi_spc;
float pressure_multi_mpc;
int16_t mpc_pressure_spring_reduction;
float centrifugal_factor_off_clutch;
};

#define RAT_1_IDX 0
Expand Down
131 changes: 53 additions & 78 deletions src/gearbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
int clutch_merge_rpm = 0;
bool enable_torque_request = true;
int trq_req_start_time = 100 + prefill_data.fill_time;
int overlap_phase_2_time = INT_MAX;
switch (req_lookup) {
case ProfileGearChange::ONE_TWO:
enable_torque_request = SBS_CURRENT_SETTINGS.trq_req_1_2_enable;
Expand Down Expand Up @@ -471,7 +472,7 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
}
int MOD_MAX = this->pressure_mgr->get_max_solenoid_pressure();

int fill_p_torque_max_on_clutch = pressure_manager->calc_max_torque_for_clutch(this->target_gear, applying, prefill_data.fill_pressure_on_clutch) / 2;
int fill_p_torque_max_on_clutch = gearboxConfig.max_torque/4;
int DYNAMIC_SHIFT_THRESHOLD = fill_p_torque_max_on_clutch;

while(process_shift) {
Expand All @@ -495,7 +496,7 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil


//bool allow_mpc_reduction_below_min = current_stage == ShiftStage::Overlap || current_stage == ShiftStage::Synchronize;
int wp_old_clutch = MAX(pressure_manager->find_working_pressure_for_clutch(a_gear, releasing, torque_to_use, false), prefill_data.fill_pressure_off_clutch);
int wp_old_clutch = pressure_manager->find_working_pressure_for_clutch(a_gear, releasing, torque_to_use, false);
int wp_new_clutch = pressure_manager->find_working_pressure_for_clutch(t_gear, applying, torque_to_use);
int centrifugal_force_on_clutch = 0;
int centrifugal_force_off_clutch = 0;
Expand Down Expand Up @@ -528,7 +529,7 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
} else {
flaring = false;
}
if (now_cs.off_clutch_speed == 0) {
if (now_cs.off_clutch_speed < 100) {
pre_cs = now_cs;
target_c_on = pre_cs.on_clutch_speed / MAX(100, chars.target_shift_time);
}
Expand Down Expand Up @@ -572,7 +573,6 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
if (target_reduction_torque == -1) {
target_reduction_torque = calc_torque_limit(req_lookup, chars.target_shift_time);
}
float d_trq = (torque_req_upper_torque-target_reduction_torque) / (chars.target_shift_time/2 + 80);
int torque = interpolate_float(
total_elapsed,
torque_req_upper_torque,
Expand Down Expand Up @@ -682,14 +682,7 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
FILL_RAMP_TIME,
InterpType::Linear
);
p_now.off_clutch = interpolate_float(
total_elapsed - prefill_data.fill_time - 100,
wp_old_clutch,
0,
0,
FILL_RAMP_TIME+FILL_LP_HOLD_TIME+chars.target_shift_time/2,
InterpType::Linear
);
p_now.off_clutch = wp_old_clutch;
} else { // Comfort shift
p_now.on_clutch = interpolate_float(
phase_elapsed - prefill_data.fill_time,
Expand All @@ -704,89 +697,71 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
} else { // Hold 2
if (filling_torque > DYNAMIC_SHIFT_THRESHOLD) { // Dynamic
p_now.on_clutch = prefill_data.low_fill_pressure_on_clutch;
p_now.off_clutch = interpolate_float(
total_elapsed - prefill_data.fill_time - 100,
wp_old_clutch,
0,
0,
FILL_RAMP_TIME+FILL_LP_HOLD_TIME+chars.target_shift_time/2,
InterpType::Linear
);
p_now.off_clutch = wp_old_clutch;
} else { // Comfort
p_now.on_clutch = 0;
p_now.off_clutch = wp_old_clutch;
}
}
pre_overlap_torque = sensor_data.input_torque;

p_now.overlap_mod = p_now.off_clutch + spring_pressure_off_clutch - centrifugal_force_off_clutch;
p_now.overlap_shift = p_now.on_clutch + spring_pressure_on_clutch - centrifugal_force_on_clutch;
p_now.shift_sol_req = p_now.overlap_shift/SPC_GAIN;
p_now.mod_sol_req = (p_now.overlap_shift*sd.pressure_multi_spc/SPC_GAIN)+(p_now.overlap_mod*sd.pressure_multi_mpc)+sd.mpc_pressure_spring_reduction;
p_now.overlap_mod = MAX(p_now.off_clutch + spring_pressure_off_clutch - centrifugal_force_off_clutch, 0);
p_now.overlap_shift = MAX(p_now.on_clutch + spring_pressure_on_clutch - centrifugal_force_on_clutch, 0);
p_now.shift_sol_req = MAX(p_now.overlap_shift/SPC_GAIN, 0);
p_now.mod_sol_req = MAX((p_now.overlap_shift*sd.pressure_multi_spc/SPC_GAIN)+(p_now.overlap_mod*sd.pressure_multi_mpc)+sd.mpc_pressure_spring_reduction, 0);

if (mpc_released && !prefill_protection_active && prefill_adapt_flags == 0x0000) {
// Do adapting for prefill
ESP_LOGI("SHIFT", "Prefill Adapt running");
prefill_adapt_flags = 0x1000;
}
} else if (current_stage == ShiftStage::Overlap) {
if (!stationary_shift && now_cs.off_clutch_speed > now_cs.on_clutch_speed) {
this->tcc->on_shift_ending();
}
if (filling_torque > DYNAMIC_SHIFT_THRESHOLD) {
p_now.off_clutch = interpolate_float(
phase_elapsed,
wp_old_clutch,
0,
0,
chars.target_shift_time/2,
InterpType::Linear
);
p_now.overlap_mod = interpolate_float(
phase_elapsed,
spring_pressure_off_clutch,
0,
0,
chars.target_shift_time/2,
InterpType::Linear
) + p_now.off_clutch - centrifugal_force_off_clutch;
} else { // Comfort
p_now.off_clutch = interpolate_float(
phase_elapsed,
wp_old_clutch,
0,
0,
chars.target_shift_time/2,
InterpType::Linear
if (phase_elapsed > 500 || now_cs.off_clutch_speed > 100) {
// Stronger overlap phase (Clutch has released)
if (INT_MAX == overlap_phase_2_time) {
// Set p_prev to be memory pressures at the end of the releasing overlap phase
p_prev = p_now;
overlap_phase_2_time = phase_elapsed;
pre_cs = now_cs; // Snapshot clutch speeds for interpolation formula!
}
int elapsed_in_phase = phase_elapsed - 500;
// Phase 2 is harder, we have to monitor the clutch release and apply speed, and adjust pressures to get the desired
// ramping speeds from both clutches

// Add input torque to the pre-shift torque. This gives us a rough placeholder for target pressures
int decel_torque = torque_to_use + abs(sensor_data.input_torque);

int target_pressure = MAX(
prefill_data.fill_pressure_on_clutch,
pressure_manager->find_working_pressure_for_clutch(target_gear, applying, decel_torque, false)
);
p_now.overlap_mod = p_now.off_clutch + spring_pressure_off_clutch - centrifugal_force_off_clutch;
}
if (filling_torque > DYNAMIC_SHIFT_THRESHOLD) { // Dynamic mode
float spc_overlap_step = (float)(wp_new_clutch) / (float)(chars.target_shift_time / SHIFT_DELAY_MS);
spc_delta += spc_overlap_step;
int prefill = interpolate_float(torque_to_use, DYNAMIC_SHIFT_THRESHOLD, gearboxConfig.max_torque, prefill_data.low_fill_pressure_on_clutch, prefill_data.fill_pressure_on_clutch, InterpType::Linear);
p_now.on_clutch = prefill + spc_delta;
} else { // Comfort mode
if (phase_elapsed < chars.target_shift_time) {
if (now_cs.off_clutch_speed < 100) {
float spc_overlap_step = (float)(prefill_data.fill_pressure_on_clutch-prefill_data.low_fill_pressure_on_clutch) / (float)(chars.target_shift_time / 2 / SHIFT_DELAY_MS);
spc_delta += spc_overlap_step;
spc_delta = MIN(spc_delta, prefill_data.fill_pressure_on_clutch-prefill_data.low_fill_pressure_on_clutch);
p_now.on_clutch = prefill_data.low_fill_pressure_on_clutch + spc_delta;
// No movement
} else {
// Clutch moving, hold pressure here!
p_now.on_clutch = prefill_data.low_fill_pressure_on_clutch + spc_delta;
}
} else {
float spc_overlap_step = (float)(MAX(wp_new_clutch, prefill_data.fill_pressure_on_clutch)) / (float)(chars.target_shift_time / 2 / SHIFT_DELAY_MS);
spc_delta += spc_overlap_step;
p_now.on_clutch = prefill_data.low_fill_pressure_on_clutch + spc_delta;

float step = (float)target_pressure / ((float)chars.target_shift_time / (float)SHIFT_DELAY_MS);
spc_delta += step;

p_now.on_clutch = p_prev.on_clutch + spc_delta;
p_now.overlap_shift = p_now.on_clutch + spring_pressure_on_clutch - centrifugal_force_on_clutch;
p_now.shift_sol_req = p_now.overlap_shift / SPC_GAIN;

int torque_held_by_new_clutch = pressure_manager->calc_max_torque_for_clutch(target_gear, applying, p_now.on_clutch);
p_now.off_clutch = MAX(pressure_manager->find_working_pressure_for_clutch(actual_gear, releasing, (MAX(torque_to_use - torque_held_by_new_clutch, 0)), false), 0);
p_now.overlap_mod = MAX(p_now.off_clutch + spring_pressure_off_clutch - centrifugal_force_off_clutch, 0);
p_now.mod_sol_req = (p_now.overlap_shift * sd.pressure_multi_spc / SPC_GAIN) + ((p_now.overlap_mod*sd.pressure_multi_mpc)) + sd.mpc_pressure_spring_reduction;
} else {
// Phase 1. Release phase.
// This part of the overlap phase should start the disengagement of the off clutch.
if (filling_torque > DYNAMIC_SHIFT_THRESHOLD) { // Dynamic mode
p_now.on_clutch = interpolate_float(phase_elapsed, 0, wp_new_clutch, 0, 500, InterpType::Linear) + prefill_data.low_fill_pressure_on_clutch;
} else { // Comfort mode
p_now.on_clutch = interpolate_float(phase_elapsed, 0, wp_new_clutch, 0, 500, InterpType::Linear);
}
p_now.overlap_shift = MAX(spring_pressure_on_clutch + p_now.on_clutch - centrifugal_force_on_clutch, p_prev.overlap_shift);
p_now.shift_sol_req = p_now.overlap_shift / SPC_GAIN;
int torque_held_by_new_clutch = pressure_manager->calc_max_torque_for_clutch(target_gear, applying, p_now.on_clutch);
p_now.off_clutch = MAX(pressure_manager->find_working_pressure_for_clutch(actual_gear, releasing, (MAX(torque_to_use - torque_held_by_new_clutch, 0)), false), 0);
p_now.overlap_mod = MAX(p_now.off_clutch + spring_pressure_off_clutch - centrifugal_force_off_clutch, 0);
p_now.mod_sol_req = (p_now.overlap_shift * sd.pressure_multi_spc / SPC_GAIN) + ((p_now.overlap_mod*sd.pressure_multi_mpc)) + sd.mpc_pressure_spring_reduction;
}
p_now.overlap_shift = spring_pressure_on_clutch + p_now.on_clutch - centrifugal_force_on_clutch;
p_now.shift_sol_req = p_now.overlap_shift / SPC_GAIN;
p_now.mod_sol_req = (p_now.overlap_shift * sd.pressure_multi_spc / SPC_GAIN) + ((p_now.overlap_mod*sd.pressure_multi_mpc)) + sd.mpc_pressure_spring_reduction;
} else if (current_stage == ShiftStage::MaxPressure) {
// Ramp time is always 250ms
int wp_new_gear = pressure_manager->find_working_mpc_pressure(this->target_gear);
Expand Down
6 changes: 5 additions & 1 deletion src/pressure_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ uint16_t PressureManager::calc_max_torque_for_clutch(GearboxGear gear, Clutch cl
InterpType::Linear
);
float friction_val = MECH_PTR->friction_map[(gear_idx*6)+(uint8_t)clutch];
float calc = (friction_val / friction_coefficient) * (float) pressure;
float calc = ((float)pressure*(float)friction_coefficient) / friction_val;
return calc;
}

Expand All @@ -336,6 +336,9 @@ void PressureManager::notify_shift_end() {
this->ptr_shift_pressures = nullptr;
}

// TODO pull this from calibration tables
const float C_C_FACTOR[8] = {0.15, 0.25, 1.0, 1.0, 1.0, 1.0, 1.0, 0.8};

ShiftData PressureManager::get_basic_shift_data(GearboxConfiguration* cfg, ProfileGearChange shift_request, ShiftCharacteristics chars) {
ShiftData sd;
uint8_t lookup_valve_info = 0;
Expand Down Expand Up @@ -384,6 +387,7 @@ ShiftData PressureManager::get_basic_shift_data(GearboxConfiguration* cfg, Profi
sd.pressure_multi_mpc = (float)HYDR_PTR->overlap_circuit_factor_mpc[lookup_valve_info]/1000.0;
sd.pressure_multi_spc = (float)HYDR_PTR->overlap_circuit_factor_spc[lookup_valve_info]/1000.0;
sd.mpc_pressure_spring_reduction = HYDR_PTR->overlap_circuit_spring_pressure[lookup_valve_info];
sd.centrifugal_factor_off_clutch = C_C_FACTOR[lookup_valve_info];
// Shift start notify for pm internal algo
this->c_gear = sd.curr_g;
this->t_gear = sd.targ_g;
Expand Down

0 comments on commit be685b3

Please sign in to comment.