WeldingSpotPerformance/src/OptAlgorithm/OptTimeCalculator.py

247 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from numpy import sqrt, arcsin, arccos, cos, sin
from src.OptAlgorithm.AutoConfigClass import AutoConfigClass
from src.OptAlgorithm.ConstantCalculator import ConstantCalculator
class OptTimeCalculator(AutoConfigClass):
params_list = []
def __init__(self, operator_config : dict, system_config : dict):
cCalculator = ConstantCalculator(operator_config, system_config)
super().__init__(OptTimeCalculator.params_list, operator_config, system_config, cCalculator.calc())
self.allTimes = {}
def tGrowNominal(self, F : float) -> float:
return arcsin(F/(self.Ftogrow)) * sqrt(self.mass_1/self.k_hardness_1)
def Tclose(self, h1: float, h2: float) -> None:
v0q = min(sqrt(2 * self.a_max_1 * h1), self.v_max_1)
v0 = min(v0q, sqrt(1/(self.k_hardness_1*self.mass_1))* self.Ftogrow)
t1 = v0 / self.a_max_1
t2t = max(0, (h1 - (self.a_max_1 * t1 * t1 /2)) / v0q)
T1 = t1 + t2t
t21 = sqrt(h2/self.a_max_2)
t21 = min(self.v_max_2/self.a_max_2, t21)
t22 = max(0, (h2 - (self.a_max_2 * t21 * t21)) / self.v_max_2)
T2 = t22 + 2 * t21
Tclose = max(T1, T2)
tclose_1_acc, tclose_1_speed = self.calcFirstClose(Tclose, h1)
tclose_2_acc, tclose_2_speed = self.calcSecondClose(Tclose, h2)
self.allTimes["tclose_1_acc"] = tclose_1_acc
self.allTimes["tclose_1_speed"] = tclose_1_speed
self.allTimes["tclose_2_acc"] = tclose_2_acc
self.allTimes["tclose_2_speed"] = tclose_2_speed
self.allTimes["tclose"] = Tclose
def Topen(self, s1 : float, s2 : float, l1 : float, l2 : float, Fs1 : float, Fs2 : float = 0) -> None:
t11 = sqrt((l1 + Fs1)/self.a_max_1)
t11 = min(self.v_max_1/self.a_max_1, t11)
t12 = max(0, ((l1+Fs1) - (self.a_max_1 * t11 * t11)) / self.v_max_1)
T1 = t12 + 2 * t11
offset = self.calcSecondOpenOffset(t11, t12, Fs1)
t21 = sqrt(l2/self.a_max_2)
t21 = min(self.v_max_2/self.a_max_2, t21)
t22 = max(0, (l2 - (self.a_max_2 * t21 * t21)) / self.v_max_2)
T2 = t22 + 2 * t21 + offset
topen_1_acc, topen_1_speed = self.calcFirstOpen(T1, l1+Fs1)
offset = self.calcSecondOpenOffset(topen_1_acc, topen_1_speed, Fs1)
topen_2_acc, topen_2_speed = self.calcSecondOpen(T2 - offset, l2)
self.allTimes["topen_1_acc"] = topen_1_acc
self.allTimes["topen_2_offset"] = offset
self.allTimes["topen_1_acc"] = topen_1_acc
self.allTimes["topen_1_speed"] = topen_1_speed
self.allTimes["topen_2_acc"] = topen_2_acc
self.allTimes["topen_2_speed"] = topen_2_speed
if s1 >= l1:
raise Exception("""S1 >= L1 - недопустимый сценарий,
проверьте dist_open_after_1, dist_close_end_1""")
if s2 >= l2:
raise Exception("""S2 >= L2 - недопустимый сценарий,
проверьте dist_open_after_2, dist_close_end_2""")
s1 += Fs1
topen_1_mark = sqrt(2 * s1 / self.a_max_1)
if topen_1_mark > topen_1_acc:
s1 -= topen_1_acc ** 2 * self.a_max_1 / 2
v1 = topen_1_acc * self.a_max_1
if s1 > topen_1_speed * v1:
s1 -= topen_1_speed * v1
topen_1_mark = 2*topen_1_acc + topen_1_speed - sqrt(topen_1_acc**2 - 2*s1 / self.a_max_1)
else:
topen_1_mark = topen_1_acc + s1 / v1
topen_2_mark = sqrt(2 * s2 / self.a_max_2)
if topen_2_mark > topen_2_acc:
s2 -= topen_2_acc ** 2 * self.a_max_2 / 2
v2 = topen_2_acc * self.a_max_2
if s2 > topen_2_speed * v2:
s2 -= topen_2_speed * v2
topen_2_mark = 2*topen_2_acc + topen_2_speed - sqrt(topen_2_acc**2 - 2*s2 / self.a_max_2)
else:
topen_2_mark = topen_2_acc + s2 / v2
self.allTimes["topen_1_mark"] = topen_1_mark
self.allTimes["topen_2_mark"] = topen_2_mark
def Tgrow(self) -> None:
v0 = self.allTimes["tclose_1_acc"] * self.a_max_1
vF0 = v0 * self.k_hardness_1
vFmax = min(self.v_max_1 * self.k_hardness_1, sqrt(self.k_hardness_1/(self.mass_1))* self.Ftogrow)
L = sqrt(self.k_hardness_1 / self.mass_1 * self.eff_control ** 2 + vF0*vF0)
tspeed = sqrt(self.mass_1/self.k_hardness_1) * (arcsin(vFmax / L) - arccos(sqrt(self.k_hardness_1 / self.mass_1) * self.eff_control / L))
Fspeed = - self.eff_control * cos(self.freq * tspeed) + self.eff_control + 1/self.freq * vF0 * sin(self.freq * tspeed)
eps = 1e1
if self.freq**2 * self.Ftogrow**2 - vFmax**2 < -eps:
raise Exception("""Номинальная траектория набора усилия не может быть достигнута, максимальная скорость превысила скорость траектории
, проверьте параметры k_hardness_1, mass_1, k_prop""")
Fmeet = 1/self.freq * sqrt(self.freq**2 * self.Ftogrow**2 - vFmax**2 + eps)
Fstart_prop = self.Fstart_prop
if Fmeet > Fstart_prop:
raise Exception("""Номинальная траектория набора усилия была достигнута на фазе подпора
, проверьте параметры v_max_1, k_prop""")
tmeet = (Fmeet - Fspeed)/vFmax
tend = self.tGrowNominal(Fstart_prop) - self.tGrowNominal(Fmeet)
vp = 1/sqrt(self.k_hardness_1 * self.mass_1) * sqrt(self.Ftogrow**2 - self.Fstart_prop**2)
ap = Fstart_prop / self.mass_1
tprop = 2*vp / ap
self.allTimes["tspeed"] = tspeed
self.allTimes["tmeet"] = tmeet
self.allTimes["tend"] = tend
self.allTimes["tprop"] = tprop
self.allTimes["tgrow"] = tspeed + tmeet + tend + tprop
def T(self, h1 : float, h2 : float, s1 : float, s2 : float, l1 : float, l2 : float) -> dict:
self.Tclose(h1, h2)
self.Tgrow()
self.Topen(s1, s2, l1, l2, self.force_target / self.k_hardness_1, 0)
return self.allTimes
def Tmovement(self, closeAlgo, tmark) -> None:
contact = [self.dist_open_start_1 + self.position_start_1, self.dist_open_start_2 + self.position_start_2]
v0s = []
pos0s = []
for i in range(1,3):
if tmark < 0:
raise Exception("""Отрицательное время этапа раскрытия,
проверьте dist_open_after_{1,2}, time_command""")
v0 = closeAlgo("V"+str(i), "Open", tmark)
v0s.append(v0)
x0 = closeAlgo("X"+str(i), "Open", tmark)
x1 = contact[i-1] - self.__dict__["dist_close_end_"+str(i)]
x = x1 - x0
pos0s.append(closeAlgo("X"+str(i), "Open", tmark))
Tfull = self.time_robot_movement
L = self.__dict__["dist_open_end_"+str(i)]
maxL = contact[i-1] - L - x0
self.Tmovementi(i, x, Tfull, v0, maxL)
return pos0s, v0s
def Tmovementi(self, i, Sfull, Tfull, v0, maxL) -> None:
v0 = abs(v0)
vmax = self.__dict__["v_max_"+str(i)]
a = self.__dict__["a_max_"+str(i)]
t3 = (Tfull + v0 / a) / 2
sqrtval = a**2 * (a**2 * (Tfull+2*t3)**2 - 8 * a * Sfull + 2 * a* v0 * (Tfull+2*t3) - 3 *v0**2)
if sqrtval < 0:
raise Exception("""Невозможно с S_{i} добраться но H*_{i} за указанное время,
проверьте dist_open_after_{i}, dist_close_end_{i}, time_command, time_robot_movement""")
t1max = ((Tfull+2*t3) + v0/a)/(2) - sqrt(sqrtval) * sqrt(2)/(4*a**2)
t1 = min(t1max, (vmax- abs(v0))/a)
t1 = max(0, min(t1, -v0/a + sqrt(v0**2 / (a**2) + (abs(maxL)-v0*v0/a)/a)))
t31 = v0/a + t1
t5max = (Tfull - v0/a)/2 - t1
v1 = v0 + a * t1
S1 = v0*t1 + a*t1*t1/2 + v1*t31 - a*t31*t31/2
S2max = Sfull + S1
t5 = min(t5max, (vmax)/a, sqrt(S2max / a))
t3 = abs(v0)/a + t1 + t5
t32 = t5
v1 = abs(v0+t1*a)
v3 = abs(v0 + t1*a - t3*a)
timeleft = Tfull - t1 - t5 - t3
sq = -v0*t1 - a*t1**2/2 - v1 * t3 + a*t3**2/2 + v3*t5 - a*t5**2/2
Sleft = Sfull - sq
t2max = (timeleft - Sleft/v3) / (1 + v1/v3)
Smovement = -v0 * t1 - a/2 * t1**2 - v1 * t31 + a/2*t31**2
t2 = max(0, min(t2max, (abs(maxL) - abs(Smovement))/v1))
t4 = max(0, Sleft/v3 + v1/v3 * t2)
tstay = max(0, Tfull - t1 - t2 - t3 - t4 - t5)
self.allTimes["tmovement_"+str(i)+"_acc"] = t1
self.allTimes["tmovement_"+str(i)+"_speed"] = t2
self.allTimes["tmovement_"+str(i)+"_slow"] = t31
self.allTimes["tmovement_"+str(i)+"_stay"] = tstay
self.allTimes["tmovement_"+str(i)] = t1 + t2 + t31 + tstay
self.allTimes["tpreclose_"+str(i)+"_slow"] = t32
self.allTimes["tpreclose_"+str(i)+"_speed"] = t4
self.allTimes["tpreclose_"+str(i)+"_acc"] = t5
self.allTimes["tpreclose_"+str(i)] = t32 + t4 + t5
T = Tfull
self.allTimes["tmovement"] = T
def calcFirstClose(self, T : float, s : float) -> tuple[float, float]:
t1 = T - sqrt(max(0, T**2 - 2 * s / self.a_max_1))
t1 = min(t1, self.v_max_1 / self.a_max_1)
t2 = sqrt(max(0, T**2 - 2 * s / self.a_max_1))
return t1, t2
def calcFirstOpen(self, T : float, s : float) -> tuple[float, float]:
t1 = T / 2 - sqrt(max(0, T**2 - 4 * s / self.a_max_1)) / 2
t1 = min(t1, self.v_max_1 / self.a_max_1)
t2 = sqrt(max(0, T * T - 4 * s / self.a_max_1))
return t1, t2
def calcSecondOpen(self, T : float, s : float) -> tuple[float, float]:
t1 = T / 2 - sqrt(max(0, T**2 - 4 * s / self.a_max_2)) / 2
t1 = min(t1, self.v_max_2 / self.a_max_2)
t2 = sqrt(max(0, T * T - 4 * s / self.a_max_2))
return t1, t2
def calcSecondClose(self, T : float, s : float) -> tuple[float, float]:
t1 = T / 2 - sqrt(max(0, T**2 - 4 * s / self.a_max_2)) / 2
t1 = min(t1, self.v_max_2 / self.a_max_2)
t2 = sqrt(max(0, T * T - 4 * s / self.a_max_2))
return t1, t2
def calcSecondOpenOffset(self, t1 : float, t2 : float, sq : float) -> float:
s = sq * 1
offset = sqrt(2 * s / self.a_max_1)
if offset > t1:
s -= t1 ** 2 * self.a_max_1 / 2
v1 = t1 * self.a_max_1
if s > t2 * v1:
s -= t2 * v1
offset = 2*t1 + t2 - sqrt(t1**2 - 2*s / self.a_max_1)
else:
offset = t1 + s / v1
return offset