Torque converter adaptation improvements

This commit is contained in:
Ashcon Mohseninia 2023-01-02 18:28:02 +00:00
parent ec0f2a8241
commit c1fa4998d0
3 changed files with 55 additions and 130 deletions

View File

@ -501,7 +501,6 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
ESP_LOG_LEVEL(ESP_LOG_INFO, "SHIFT", "ABORTING SHIFT");
sd.shift_solenoid->write_pwm_12_bit(0);
pressure_mgr->disable_spc();
this->tcc->on_shift_complete(sensor_data.current_timestamp_ms);
vTaskDelay(250);
egs_can_hal->set_torque_request(TorqueRequest::None);
egs_can_hal->set_requested_torque(0);
@ -551,7 +550,6 @@ bool Gearbox::elapse_shift(ProfileGearChange req_lookup, AbstractProfile *profil
this->is_ramp = false;
pressure_mgr->disable_spc(); // Max pressure!
sd.shift_solenoid->write_pwm_12_bit(0); // Close SPC and Shift solenoid
this->tcc->on_shift_complete(sensor_data.current_timestamp_ms);
this->abort_shift = false;
this->sensor_data.last_shift_time = esp_timer_get_time() / 1000;

View File

@ -12,6 +12,8 @@ const int16_t tcc_learn_y_headers[1] = {1};
const int16_t tcc_learn_default_data[5] = {900, 900, 900, 900, 900};
const uint16_t TCC_MIN_LOCKING_RPM = 1100;
static const uint16_t TCC_ADJ_INTERVAL_MS = 500;
TorqueConverter::TorqueConverter(uint16_t max_gb_rating) {
tcc_learn_lockup_map = new StoredTcuMap("TCC_LOCK", 5, tcc_learn_x_headers, tcc_learn_y_headers, 5, 1, tcc_learn_default_data);
if (this->tcc_learn_lockup_map->init_status() != ESP_OK) {
@ -19,21 +21,39 @@ TorqueConverter::TorqueConverter(uint16_t max_gb_rating) {
}
int16_t* data = this->tcc_learn_lockup_map->get_current_data();
for (int i = 0; i < 5; i++) {
//data[i] = tcc_learn_default_data[i];
ESP_LOGI("TCC", "Adapt value for gear %d - %d mBar", i+1, data[i]);
}
// range of adaptation is 1/10 - 1/3 of the rating of the gearbox
// W5A330 - 33Nm - 110Nm
// W5A580 - 58Nm - 193Nm
this->high_torque_adapt_limit = max_gb_rating / 3;
// W5A330 - 33Nm - 55Nm
// W5A580 - 58Nm - 96Nm
this->high_torque_adapt_limit = max_gb_rating / 6;
this->low_torque_adapt_limit = max_gb_rating / 10;
}
inline void TorqueConverter::reset_rpm_samples(SensorData* sensors) {
//this->input_rpm_tot = this->last_input_rpm = sensors->input_rpm;
//this->engine_rpm_tot = this->last_engine_rpm = sensors->engine_rpm;
//this->rpm_samples = 1;
}
void TorqueConverter::adjust_map_cell(GearboxGear g, uint16_t new_pressure) {
// Too much slip
int16_t* modify = this->tcc_learn_lockup_map->get_current_data();
int16_t curr_v = modify[(uint8_t)(g)-1];
if (abs(this->base_tcc_pressure-curr_v) >= 20) {
ESP_LOGI("TCC", "Adjusting TCC adaptation for gear %d. Was %d mBar, now %d mBar", (uint8_t)g, curr_v, new_pressure);
modify[(uint8_t)(g)-1] = (int16_t)new_pressure;
}
}
void TorqueConverter::update(GearboxGear curr_gear, PressureManager* pm, AbstractProfile* profile, SensorData* sensors, bool is_shifting) {
if (is_shifting) { // Reset strikes when changing gears!
this->strike_count = 0;
this->adapt_lock_count = 0;
last_adj_time = sensors->current_timestamp_ms;
this->reset_rpm_samples(sensors);
this->was_shifting = true;
}
if (sensors->input_rpm <= TCC_MIN_LOCKING_RPM) { // RPM too low!
last_adj_time = sensors->current_timestamp_ms;
@ -54,9 +74,11 @@ void TorqueConverter::update(GearboxGear curr_gear, PressureManager* pm, Abstrac
this->base_tcc_pressure = 0;
}
this->curr_tcc_pressure = this->base_tcc_pressure;
this->reset_rpm_samples(sensors);
} else {
// We can lock now!
if (this->was_idle) {
if (this->was_idle || (was_shifting && !is_shifting)) {
was_shifting = false;
// We were too low, but now we can lock! (RPM increasing)
this->was_idle = false;
if (this->tcc_learn_lockup_map != nullptr) {
@ -69,17 +91,18 @@ void TorqueConverter::update(GearboxGear curr_gear, PressureManager* pm, Abstrac
this->base_tcc_pressure = TCC_PREFILL;
this->curr_tcc_pressure = TCC_PREFILL;
last_adj_time = sensors->current_timestamp_ms;
this->reset_rpm_samples(sensors);
} else {
// We are just driving, TCC is free to lockup
if (!initial_ramp_done) {
#define TCC_FAST_RAMP_STEP 10 // ~= 200mBar/sec
#define TCC_FAST_RAMP_STEP 5 // ~= 200mBar/sec
// We are in stage of ramping TCC pressure up to initial lock phase as learned by TCC
int delta = MIN(TCC_FAST_RAMP_STEP, abs((int)this->curr_tcc_target - (int)this->base_tcc_pressure));
if (delta > TCC_FAST_RAMP_STEP) {
if (abs(delta) > TCC_FAST_RAMP_STEP) {
if (this->curr_tcc_target > this->base_tcc_pressure) {
this->base_tcc_pressure += TCC_FAST_RAMP_STEP;
this->base_tcc_pressure += delta;
} else if (this->curr_tcc_target < this->base_tcc_pressure) {
this->base_tcc_pressure -= TCC_FAST_RAMP_STEP;
this->base_tcc_pressure -= delta;
}
} else {
this->base_tcc_pressure = this->curr_tcc_target;
@ -87,30 +110,29 @@ void TorqueConverter::update(GearboxGear curr_gear, PressureManager* pm, Abstrac
}
this->curr_tcc_pressure = this->base_tcc_pressure;
last_adj_time = sensors->current_timestamp_ms;
} else if (sensors->current_timestamp_ms - last_adj_time > 500) { // Allowed to adjust
this->reset_rpm_samples(sensors);
}
if (initial_ramp_done && sensors->current_timestamp_ms - last_adj_time > TCC_ADJ_INTERVAL_MS) { // Allowed to adjust
last_adj_time = sensors->current_timestamp_ms;
bool learning = false;
// Learning phase / dynamic phase
if (!is_shifting && this->tcc_learn_lockup_map != nullptr) {
// Learning phase check
if (sensors->static_torque >= this->low_torque_adapt_limit && sensors->static_torque <= this->high_torque_adapt_limit) {
// Requires:
// * torque in bounds
// * Engine RPM - Less than TCC stall speed
if (sensors->static_torque >= this->low_torque_adapt_limit && sensors->static_torque <= this->high_torque_adapt_limit && sensors->engine_rpm < 2500) {
if (sensors->tcc_slip_rpm > 0 && sensors->tcc_slip_rpm < TCC_ADAPT_CONSIDERED_LOCK) {
adapt_lock_count++;
} else {
learning = true;
this->base_tcc_pressure += 25;
this->base_tcc_pressure += 10;
}
} else {
adapt_lock_count = 0;
}
if (adapt_lock_count == 100) { // ~= 2 seconds
// Modify map
int16_t* modify = this->tcc_learn_lockup_map->get_current_data();
int16_t curr_v = modify[(uint8_t)(curr_gear)-1];
if (abs(this->base_tcc_pressure-curr_v) > 100) {
ESP_LOGI("TCC", "Adjusting TCC adaptation for gear %d. Was %d mBar, now %d mBar", (uint8_t)curr_gear, curr_v, this->base_tcc_pressure);
modify[(uint8_t)(curr_gear)-1] = (int16_t)this->base_tcc_pressure;
}
if (adapt_lock_count == 2000/TCC_ADJ_INTERVAL_MS) { // ~= 2 seconds
this->adjust_map_cell(curr_gear, this->base_tcc_pressure);
}
}
this->curr_tcc_pressure = this->base_tcc_pressure;
@ -118,128 +140,30 @@ void TorqueConverter::update(GearboxGear curr_gear, PressureManager* pm, Abstrac
if (!learning) {
if (sensors->static_torque > high_torque_adapt_limit) {
int torque_delta = sensors->static_torque - high_torque_adapt_limit;
this->curr_tcc_pressure = this->base_tcc_pressure + (6*torque_delta); // 5mBar per Nm
this->curr_tcc_pressure = this->base_tcc_pressure + (2*torque_delta); // 2mBar per Nm
} else if (sensors->static_torque < 0) {
if (this->curr_tcc_pressure > TCC_PREFILL) {
this->curr_tcc_pressure = this->base_tcc_pressure - 100;
this->curr_tcc_pressure = this->base_tcc_pressure - 50;
}
}
}
bool adj = false;
if (sensors->static_torque < 0 && sensors->tcc_slip_rpm < -200) {
this->base_tcc_pressure += 5;
adj = true;
} else if (sensors->static_torque < 0 && sensors->tcc_slip_rpm < -50) {
this->base_tcc_pressure -= 5;
if (sensors->static_torque < 0 && abs(sensors->tcc_slip_rpm) > 150) {
//this->base_tcc_pressure += 10;
//adj = true;
} else if (sensors->static_torque < 0 && abs(sensors->tcc_slip_rpm) < 20) {
this->base_tcc_pressure -= 10;
adj = true;
}
if (adj) {
// Too much slip
int16_t* modify = this->tcc_learn_lockup_map->get_current_data();
int16_t curr_v = modify[(uint8_t)(curr_gear)-1];
if (abs(this->base_tcc_pressure-curr_v) > 100) {
ESP_LOGI("TCC", "Adjusting TCC adaptation for gear %d. Was %d mBar, now %d mBar", (uint8_t)curr_gear, curr_v, this->base_tcc_pressure);
modify[(uint8_t)(curr_gear)-1] = (int16_t)this->base_tcc_pressure;
}
this->adjust_map_cell(curr_gear, this->base_tcc_pressure);
}
}
}
}
if (this->curr_tcc_pressure > 2000) {
this->curr_tcc_pressure = 2000;
}
pm->set_target_tcc_pressure(this->curr_tcc_pressure);
/*
int trq = sensors->static_torque;
if (trq < 0) {
trq *= -1;
}
// Only think about lockup on positive torque
int max_allowed_slip;
int min_allowed_slip;
float temp_time_multiplier = pm->get_tcc_temp_multiplier(sensors->atf_temp);
if (profile == nullptr) {
max_allowed_slip = MAX(100, trq);
min_allowed_slip = MAX(10, trq/2);
} else {
TccLockupBounds bounds = profile->get_tcc_lockup_bounds(sensors, curr_gear);
max_allowed_slip = bounds.max_slip_rpm;
min_allowed_slip = bounds.min_slip_rpm;
// When producing less thats 44Nm, we should always be locked
// as that is the turbines inertia force, if we are not then we trigger
// more pressure with this code
if (sensors->static_torque <= 44 && sensors->static_torque > 0) {
max_allowed_slip = 10;
min_allowed_slip = 0;
}
// This means that at 1000Rpm, we will get 0.9 the slip (More slip)
// At 2100RPM, we will get half the slip as at 1100rpm
// Dynamic slip :D
float multiplier = MIN(0.9, (float)(1000.0/MAX(1000.0, sensors->engine_rpm)));
max_allowed_slip *= multiplier;
min_allowed_slip *= multiplier;
}
int slip = abs(sensors->tcc_slip_rpm);
float rpm_multi = 2000.0/sensors->engine_rpm;
if (is_shifting || sensors->current_timestamp_ms-sensors->last_shift_time < 1500) {
this->last_inc_time = sensors->current_timestamp_ms;
strike_count = 0;
goto write_pressure;
}
if (slip > max_allowed_slip && strike_count < 20) {
strike_count++;
} else if (slip < max_allowed_slip) {
strike_count = 0;
}
// Quick activate of slip mode
if (sensors->input_rpm > 1000 && this->curr_tcc_pressure < 1100) {
this->curr_tcc_pressure = 1100;
goto write_pressure;
}
if (sensors->current_timestamp_ms - last_inc_time > 500 * rpm_multi * temp_time_multiplier && strike_count >= 10) {
if (slip > max_allowed_slip) {
if (this->curr_tcc_pressure < 1100) {
this->curr_tcc_pressure += 50; // 50mbar
} else if (this->curr_tcc_pressure >= 1200) {
this->curr_tcc_pressure += 10; // 50mbar
} else {
this->curr_tcc_pressure += 25; // 50mbar
}
this->last_inc_time = sensors->current_timestamp_ms;
} else if (sensors->tcc_slip_rpm < min_allowed_slip && this->curr_tcc_pressure >= 1100 && sensors->static_torque > 40) {
// Decrease pressure, but only if we have pedal input
this->curr_tcc_pressure -= 50; // 50mBar
this->last_inc_time = sensors->current_timestamp_ms;
}
}
write_pressure:
if (this->curr_tcc_pressure <= 0) { // Just to be safe!
this->curr_tcc_pressure = 0;
}
this->state = (slip > 200 || is_shifting) ? ClutchStatus::Slipping : ClutchStatus::Closed;
pm->set_target_tcc_pressure((uint16_t)(this->curr_tcc_pressure));
*/
}
void TorqueConverter::on_shift_complete(uint64_t now) {
}
// 1600 - lock
// 1000 - slip
// 500 - prefill
// void TorqueConverter::on_shift_start(uint64_t now, bool is_downshift, SensorData* sensors, float shift_firmness) {
// if (this->curr_tcc_pressure < 1200) {
// this->curr_tcc_pressure = 1200;
// } else if (sensors->static_torque > 0 && abs(sensors->tcc_slip_rpm) < 20) {
// uint32_t additional_reduction = scale_number(shift_firmness*10, 100, 0, 0, 100);
// this->curr_tcc_pressure -= additional_reduction;
// }
// }
ClutchStatus TorqueConverter::get_clutch_state(void) {
return this->state;
}

View File

@ -26,15 +26,16 @@ class TorqueConverter {
* @param shifting True if the car is currently transitioning to new gear
*/
void update(GearboxGear curr_gear, PressureManager* pm, AbstractProfile* profile, SensorData* sensors, bool is_shifting);
// void on_shift_start(uint64_t now, bool is_downshift, SensorData* sensors, float shift_firmness);
void on_shift_complete(uint64_t now);
ClutchStatus get_clutch_state(void);
void save() {
if (this->tcc_learn_lockup_map != nullptr) {
if (this->tcc_learn_lockup_map != nullptr && this->pending_changes) {
this->tcc_learn_lockup_map->save_to_eeprom();
}
};
void adjust_map_cell(GearboxGear g, uint16_t new_pressure);
private:
inline void reset_rpm_samples(SensorData* sensors);
bool neg_torque_zone = false;
uint16_t adapt_lock_count = 0;
uint16_t low_torque_adapt_limit = 0;
@ -54,6 +55,8 @@ class TorqueConverter {
uint16_t tmp_pressure = 0;
StoredTcuMap* tcc_learn_lockup_map;
uint64_t last_adj_time = 0;
bool pending_changes = false;
bool was_shifting = false;
};
#endif