Files
ODrive/Firmware/MotorControl/thermistor.cpp
2021-04-14 19:01:05 -04:00

90 lines
3.0 KiB
C++

#include "odrive_main.h"
#include "low_level.h"
ThermistorCurrentLimiter::ThermistorCurrentLimiter(uint16_t adc_channel,
const float* const coefficients,
size_t num_coeffs,
const float& temp_limit_lower,
const float& temp_limit_upper,
const bool& enabled) :
adc_channel_(adc_channel),
coefficients_(coefficients),
num_coeffs_(num_coeffs),
temperature_(NAN),
temp_limit_lower_(temp_limit_lower),
temp_limit_upper_(temp_limit_upper),
enabled_(enabled)
{
}
void ThermistorCurrentLimiter::update() {
const float normalized_voltage = get_adc_relative_voltage_ch(adc_channel_);
float raw_temperature_ = horner_poly_eval(normalized_voltage, coefficients_, num_coeffs_);
constexpr float tau = 0.1f; // [sec]
float k = current_meas_period / tau;
float val = raw_temperature_;
for (float& lpf_val : lpf_vals_) {
lpf_val += k * (val - lpf_val);
val = lpf_val;
}
if (is_nan(val)) {
lpf_vals_.fill(0.0f);
}
temperature_ = lpf_vals_.back();
}
bool ThermistorCurrentLimiter::do_checks() {
if (enabled_ && temperature_ >= temp_limit_upper_ + 5) {
return false;
}
return true;
}
float ThermistorCurrentLimiter::get_current_limit(float base_current_lim) const {
if (!enabled_) {
return base_current_lim;
}
const float temp_margin = temp_limit_upper_ - temperature_;
const float derating_range = temp_limit_upper_ - temp_limit_lower_;
float thermal_current_lim = base_current_lim * (temp_margin / derating_range);
if (thermal_current_lim < 0.0f || is_nan(thermal_current_lim)) {
thermal_current_lim = 0.0f;
}
return std::min(thermal_current_lim, base_current_lim);
}
OnboardThermistorCurrentLimiter::OnboardThermistorCurrentLimiter(uint16_t adc_channel, const float* const coefficients, size_t num_coeffs) :
ThermistorCurrentLimiter(adc_channel,
coefficients,
num_coeffs,
config_.temp_limit_lower,
config_.temp_limit_upper,
config_.enabled)
{
}
OffboardThermistorCurrentLimiter::OffboardThermistorCurrentLimiter() :
ThermistorCurrentLimiter(UINT16_MAX,
&config_.thermistor_poly_coeffs[0],
num_coeffs_,
config_.temp_limit_lower,
config_.temp_limit_upper,
config_.enabled)
{
decode_pin();
}
bool OffboardThermistorCurrentLimiter::apply_config() {
config_.parent = this;
decode_pin();
return true;
}
void OffboardThermistorCurrentLimiter::decode_pin() {
adc_channel_ = channel_from_gpio(get_gpio(config_.gpio_pin));
}