Skip to content

Commit

Permalink
Be more specific about pressure calculations in shifts
Browse files Browse the repository at this point in the history
  • Loading branch information
rnd-ash committed Apr 3, 2024
1 parent b308273 commit 0e1782a
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 44 deletions.
5 changes: 5 additions & 0 deletions src/diag/diag_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ DATA_PRESSURES get_pressure_data(Gearbox* gb_ptr) {
ret.corrected_mpc_pressure = gb_ptr->pressure_mgr->get_corrected_modulating_pressure();
ret.tcc_pressure = gb_ptr->pressure_mgr->get_targ_tcc_pressure();
ret.ss_flag = gb_ptr->pressure_mgr->get_active_shift_circuits();
ShiftPressures p = gb_ptr->pressure_mgr->get_shift_pressures_now();
ret.overlap_mod = p.overlap_mod;
ret.overlap_shift = p.overlap_shift;
ret.on_clutch_pressure = p.on_clutch;
ret.off_clutch_pressure = p.off_clutch;
}
return ret;
}
Expand Down
6 changes: 6 additions & 0 deletions src/diag/diag_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ typedef struct {
uint16_t corrected_mpc_pressure;

uint16_t tcc_pressure;

// Shifting pressures
uint16_t on_clutch_pressure;
uint16_t off_clutch_pressure;
uint16_t overlap_mod;
uint16_t overlap_shift;
} __attribute__ ((packed)) DATA_PRESSURES;

// Solenoid command struct
Expand Down
123 changes: 79 additions & 44 deletions src/gearbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,21 +367,23 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
float phase_total_time = 100;

// Current Y values
float current_shift_pressure = 0;
float current_modulating_pressure = 0;
ShiftPressures p_now = {};


// Previous stage Y values (Set at end of stage)
float prev_modulating_pressure = 0;
float prev_shift_pressure = 0;
ShiftPressures p_prev = {};

memset(&p_now, 0, sizeof(ShiftPressures));
memset(&p_prev, 0, sizeof(ShiftPressures));

uint32_t total_elapsed = 0;
uint32_t phase_elapsed = 0;

uint32_t prefill_adapt_flags = this->shift_adapter->check_prefill_adapt_conditions_start(&this->sensor_data, req_lookup);
AdaptPrefillData adapt_prefill = this->shift_adapter->get_prefill_adapt_data(req_lookup);
prefill_data.fill_pressure_on_clutch += adapt_prefill.pressure_offset_on_clutch;
prefill_data.fill_time += adapt_prefill.timing_offset;

pressure_manager->register_shift_pressure_data(&p_now);
/**
* Precomputed variables
*/
Expand Down Expand Up @@ -430,7 +432,6 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
pressure_manager->set_shift_stage(current_stage);
Clutch applying = get_clutch_to_apply(req_lookup);
Clutch releasing = get_clutch_to_apply(req_lookup);
int off_clutch_pressure = 0;
int clutch_merge_rpm = 0;
bool enable_torque_request = true;
int trq_req_start_time = 100 + prefill_data.fill_time;
Expand Down Expand Up @@ -469,7 +470,10 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
SPC_GAIN = 1.993;
}
int MOD_MAX = this->pressure_mgr->get_max_solenoid_pressure();
int DYNAMIC_SHIFT_THRESHOLD = gearboxConfig.max_torque / 4;

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 DYNAMIC_SHIFT_THRESHOLD = fill_p_torque_max_on_clutch;

while(process_shift) {
bool stationary_shift = this->is_stationary();
bool skip_phase = false;
Expand Down Expand Up @@ -622,8 +626,7 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
if (phase_elapsed >= phase_total_time && current_stage <= ShiftStage::Overlap) {
current_stage = next_shift_stage(current_stage);
pressure_manager->set_shift_stage(current_stage);
prev_modulating_pressure = current_modulating_pressure;
prev_shift_pressure = current_shift_pressure;
p_prev = p_now;
// New stage
phase_elapsed = 0;
// One time phase initial code
Expand Down Expand Up @@ -654,64 +657,72 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
}

if (current_stage == ShiftStage::Bleed) {
float end_spc = (prefill_data.fill_pressure_on_clutch + spring_pressure_on_clutch - centrifugal_force_on_clutch);
current_shift_pressure = interpolate_float(phase_elapsed, SPC_MAX, end_spc, 0, 100, InterpType::Linear);
current_modulating_pressure = (end_spc*sd.pressure_multi_spc/SPC_GAIN)+((wp_old_clutch + spring_pressure_off_clutch - centrifugal_force_off_clutch)*sd.pressure_multi_mpc)+sd.mpc_pressure_spring_reduction; // To add to working pressure for maximum filling effect
float end_spc = prefill_data.fill_pressure_on_clutch + spring_pressure_on_clutch;
p_now.on_clutch = 0;
p_now.off_clutch = wp_old_clutch;
p_now.overlap_shift = interpolate_float(phase_elapsed, SPC_MAX, end_spc, 0, 100, InterpType::Linear);
p_now.overlap_mod = wp_old_clutch + spring_pressure_off_clutch - centrifugal_force_off_clutch;
p_now.shift_sol_req = p_now.overlap_shift/SPC_GAIN;
p_now.mod_sol_req = ((end_spc-centrifugal_force_on_clutch)*sd.pressure_multi_spc/SPC_GAIN)+(p_now.overlap_mod*sd.pressure_multi_mpc)+sd.mpc_pressure_spring_reduction;
} else if (current_stage == ShiftStage::Fill) {
bool was_adapting = prefill_adapt_flags == 0;
if (was_adapting && prefill_adapt_flags != 0) {
ESP_LOGW("SHIFT", "Adapting was cancelled. Reason flag: 0x%08X", (int)prefill_adapt_flags);
}
if (phase_elapsed < prefill_data.fill_time) { // Hold 1 (Same for all shift types)
current_shift_pressure = (spring_pressure_on_clutch + prefill_data.fill_pressure_on_clutch - centrifugal_force_on_clutch);
off_clutch_pressure = wp_old_clutch + spring_pressure_off_clutch;
p_now.off_clutch = wp_old_clutch;
p_now.on_clutch = prefill_data.fill_pressure_on_clutch;
} else if (phase_elapsed < prefill_data.fill_time + FILL_RAMP_TIME) { // Ramp phase (Hold 1 -> Hold 2)
if (filling_torque > DYNAMIC_SHIFT_THRESHOLD) { // Dynamic mode (Trq req starts here)
current_shift_pressure = spring_pressure_on_clutch - centrifugal_force_on_clutch + interpolate_float(
p_now.on_clutch = interpolate_float(
phase_elapsed - prefill_data.fill_time,
prefill_data.fill_pressure_on_clutch,
prefill_data.low_fill_pressure_on_clutch,
0,
FILL_RAMP_TIME,
InterpType::Linear
);
off_clutch_pressure = interpolate_float(
p_now.off_clutch = interpolate_float(
total_elapsed - prefill_data.fill_time - 100,
wp_old_clutch+spring_pressure_off_clutch,
spring_pressure_off_clutch,
wp_old_clutch,
0,
0,
FILL_RAMP_TIME+FILL_LP_HOLD_TIME+chars.target_shift_time/2,
InterpType::Linear
);
} else { // Comfort shift
current_shift_pressure = spring_pressure_on_clutch - centrifugal_force_on_clutch + interpolate_float(
p_now.on_clutch = interpolate_float(
phase_elapsed - prefill_data.fill_time,
prefill_data.fill_pressure_on_clutch,
0,
0,
FILL_RAMP_TIME,
InterpType::Linear
);
off_clutch_pressure = wp_old_clutch+spring_pressure_off_clutch;
p_now.off_clutch = wp_old_clutch;
}
} else { // Hold 2
if (filling_torque > DYNAMIC_SHIFT_THRESHOLD) { // Dynamic
current_shift_pressure = (spring_pressure_on_clutch + prefill_data.low_fill_pressure_on_clutch - centrifugal_force_on_clutch);
off_clutch_pressure = interpolate_float(
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+spring_pressure_off_clutch,
wp_old_clutch,
0,
0,
FILL_RAMP_TIME+FILL_LP_HOLD_TIME+chars.target_shift_time/2,
InterpType::Linear
);
} else { // Comfort
current_shift_pressure = (spring_pressure_on_clutch - centrifugal_force_on_clutch);
off_clutch_pressure = wp_old_clutch+spring_pressure_off_clutch;
p_now.on_clutch = 0;
p_now.off_clutch = wp_old_clutch;
}
}
pre_overlap_torque = sensor_data.input_torque;
current_modulating_pressure = (current_shift_pressure*sd.pressure_multi_spc/SPC_GAIN)+((off_clutch_pressure - centrifugal_force_off_clutch)*sd.pressure_multi_mpc)+sd.mpc_pressure_spring_reduction;

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;

if (mpc_released && !prefill_protection_active && prefill_adapt_flags == 0x0000) {
// Do adapting for prefill
Expand All @@ -723,56 +734,80 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
this->tcc->on_shift_ending();
}
if (filling_torque > DYNAMIC_SHIFT_THRESHOLD) {
off_clutch_pressure = interpolate_float(
total_elapsed - prefill_data.fill_time - 100,
wp_old_clutch+spring_pressure_off_clutch,
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,
FILL_RAMP_TIME+FILL_LP_HOLD_TIME+chars.target_shift_time/2,
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
);
} else {
off_clutch_pressure = interpolate_float(phase_elapsed, wp_old_clutch+spring_pressure_off_clutch, spring_pressure_off_clutch, 0, chars.target_shift_time, InterpType::Linear);
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);
current_shift_pressure = spring_pressure_on_clutch + prefill + spc_delta - centrifugal_force_on_clutch;
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);
current_shift_pressure = spring_pressure_on_clutch + prefill_data.low_fill_pressure_on_clutch + spc_delta - centrifugal_force_on_clutch;
p_now.on_clutch = prefill_data.low_fill_pressure_on_clutch + spc_delta;
// No movement
} else {
// Clutch moving, hold pressure here!
current_shift_pressure = spring_pressure_on_clutch + prefill_data.low_fill_pressure_on_clutch + spc_delta - centrifugal_force_on_clutch;
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;
current_shift_pressure = spring_pressure_on_clutch + prefill_data.low_fill_pressure_on_clutch + spc_delta - centrifugal_force_on_clutch;
p_now.on_clutch = prefill_data.low_fill_pressure_on_clutch + spc_delta;
}
}
current_modulating_pressure = (current_shift_pressure*sd.pressure_multi_spc/SPC_GAIN)+((off_clutch_pressure-centrifugal_force_off_clutch)*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);
if (phase_elapsed < maxp.ramp_time) {
current_shift_pressure = interpolate_float(phase_elapsed, prev_shift_pressure, MOD_MAX, 0, maxp.ramp_time, InterpType::Linear);
p_now.on_clutch = interpolate_float(phase_elapsed, p_prev.on_clutch, MOD_MAX, 0, maxp.ramp_time, InterpType::Linear);
p_now.overlap_shift = p_now.on_clutch;
p_now.shift_sol_req = p_now.overlap_shift / SPC_GAIN;
} else {
// Hold phase. Mod at 0, Shift at full
current_shift_pressure = MOD_MAX;
p_now.on_clutch = MOD_MAX;
p_now.overlap_shift = MOD_MAX;
p_now.shift_sol_req = MOD_MAX/SPC_GAIN;
}
// Merge working pressure slowly
current_modulating_pressure = interpolate_float(phase_elapsed, prev_modulating_pressure, wp_new_gear, 0, maxp.ramp_time, InterpType::Linear);
p_now.off_clutch = 0;
p_now.overlap_mod = 0;
p_now.mod_sol_req = interpolate_float(phase_elapsed, p_prev.mod_sol_req, wp_new_gear, 0, maxp.ramp_time, InterpType::Linear);
}

pressure_mgr->set_target_modulating_pressure(current_modulating_pressure);
pressure_mgr->set_target_shift_pressure(current_shift_pressure);
pressure_mgr->set_target_modulating_pressure(p_now.mod_sol_req);
pressure_mgr->set_target_shift_pressure(p_now.shift_sol_req);
pressure_mgr->update_pressures(current_stage == ShiftStage::MaxPressure ? this->target_gear : this->actual_gear);

// Timeout checking (Only in overlap)
Expand All @@ -783,7 +818,7 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
skip_phase = true;
sr.detect_shift_end_ts = (uint16_t)(GET_CLOCK_TIME() - shift_start_time);
if (prefill_adapt_flags == 0) {
this->shift_adapter->record_shift_end(current_stage, phase_elapsed, current_modulating_pressure, current_shift_pressure);
this->shift_adapter->record_shift_end(current_stage, phase_elapsed, p_now.off_clutch, p_now.on_clutch);
}
}
} else if (stationary_shift && phase_elapsed > 1000) {
Expand Down
1 change: 1 addition & 0 deletions src/pressure_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ uint16_t PressureManager::find_working_mpc_pressure(GearboxGear curr_g) {
void PressureManager::notify_shift_end() {
this->c_gear = 0;
this->t_gear = 0;
this->ptr_shift_pressures = nullptr;
}

ShiftData PressureManager::get_basic_shift_data(GearboxConfiguration* cfg, ProfileGearChange shift_request, ShiftCharacteristics chars) {
Expand Down
30 changes: 30 additions & 0 deletions src/pressure_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ typedef struct {
uint16_t ramp_time;
} PressureStageTiming;

struct ShiftPressures {
// At the applying clutch
float on_clutch;
// At the releasing clutch
float off_clutch;
// Pressure on the modulating side of the overlap slider
float overlap_mod;
// Pressure on the shift side of the overlap slider
float overlap_shift;
// At the shift solenoid
float shift_sol_req;
// At the modulating solenoid
float mod_sol_req;
};

class PressureManager {

public:
Expand Down Expand Up @@ -104,6 +119,20 @@ class PressureManager {
uint16_t get_shift_regulator_pressure(void);

float calculate_centrifugal_force_for_clutch(Clutch clutch, uint16_t input, uint16_t rear_sun);

void register_shift_pressure_data(ShiftPressures* p) {
this->ptr_shift_pressures = p;
}

ShiftPressures get_shift_pressures_now() {
ShiftPressures ret{};
if (nullptr == this->ptr_shift_pressures) {
memset(&ret, 0x00, sizeof(ShiftPressures));
} else {
memcpy(&ret, this->ptr_shift_pressures, sizeof(ShiftPressures));
}
return ret;
}
private:

uint16_t calc_working_pressure(GearboxGear current_gear, uint16_t in_mpc, uint16_t in_spc);
Expand Down Expand Up @@ -152,6 +181,7 @@ class PressureManager {
ShiftStage shift_stage;
bool init_ss_recovery = false;
uint64_t last_ss_on_time = 0;
ShiftPressures* ptr_shift_pressures = nullptr;
};

extern PressureManager* pressure_manager;
Expand Down

0 comments on commit 0e1782a

Please sign in to comment.