mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-02-06 23:41:53 +08:00
90 lines
3.0 KiB
C++
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));
|
|
}
|