85 lines
1.9 KiB
Python
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
|
|
|
|
|
|
|
|
|