apc_calc/mot.py

85 lines
1.9 KiB
Python

from dataclasses import dataclass
from functools import cached_property
import math
from scipy import optimize
from apc_perf import RPM, ApcPerfdata
VOLT_DUTY_MAX = 0.97
@dataclass(frozen=True)
class MotorOppoint:
voltage: float
current: float
rpm: float
torque: float
@cached_property
def rot_speed(self) -> float:
return self.rpm * RPM
@property
def power_in(self) -> float:
return self.voltage * self.current
@property
def power_out(self) -> float:
return self.torque * self.rot_speed
@property
def efficiency(self) -> float:
return self.power_out/self.power_in
@dataclass(frozen=True)
class MotorData:
mot_kv: float
mot_ir: float
mot_idle_i: float
@cached_property
def mot_kv_si(self) -> float:
return self.mot_kv * RPM
@property
def effective_ir(self) -> float:
return self.mot_ir*1.5
return self.mot_ir
def mot_full_pizda(self, rpm: float, voltage: float) -> MotorOppoint:
rotspd = rpm * RPM
voltage = VOLT_DUTY_MAX * voltage
u_active = (rotspd / self.mot_kv_si)
u_heat = voltage - u_active
current = u_heat / self.effective_ir
torq = (current-self.mot_idle_i) / self.mot_kv_si
return MotorOppoint(
voltage = voltage,
current = current,
rpm = rpm,
torque = torq,
)
def op_full_pizda(mot: MotorData, prop: ApcPerfdata, speed: float, volt: float):
def f(rpm):
return prop.get_op_interp(rpm, speed).torque - mot.mot_full_pizda(rpm, volt).torque
opt = optimize.root_scalar(f, bracket = prop.rpm_range_at_speed(speed))
# print(opt)
rpm = opt.root
p_op = prop.get_op_interp(rpm, speed)
m_op = mot.mot_full_pizda(rpm, volt)
# print(p_op)
# print(m_op)
return p_op, m_op