223 lines
8.1 KiB
Python
223 lines
8.1 KiB
Python
|
|
from OptTimeCalculator import OptTimeCalculator
|
|||
|
|
from Params import Params
|
|||
|
|
from numpy import cos, sin, sqrt, cbrt, arcsin, linspace
|
|||
|
|
|
|||
|
|
class OptAlgorithm():
|
|||
|
|
|
|||
|
|
paramsPath = "."
|
|||
|
|
paramsFile = "params.json"
|
|||
|
|
def __init__(self, useMins = True, s1 = 0, s2 = 0):
|
|||
|
|
self.p = Params(OptAlgorithm.paramsPath, OptAlgorithm.paramsFile)
|
|||
|
|
calc = OptTimeCalculator(self.p)
|
|||
|
|
if useMins:
|
|||
|
|
s1 = self.p.smin1t
|
|||
|
|
s2 = self.p.smin2t
|
|||
|
|
calc.T(s = s1, s2 = s2)
|
|||
|
|
self.Ts = calc.Ts
|
|||
|
|
self.TStartOpen = sqrt(self.p.flon / self.p.k * 2 / self.p.a)
|
|||
|
|
self.T2 = calc.calcSecond(Tstart = self.TStartOpen, s2 = s2)
|
|||
|
|
|
|||
|
|
self.x1Contact = s1 + self.p.x10
|
|||
|
|
self.x2Contact = s2 + self.p.x20
|
|||
|
|
|
|||
|
|
def V1Close(self, t: float):
|
|||
|
|
if t < self.Ts["t1"]:
|
|||
|
|
return self.p.a * t
|
|||
|
|
else:
|
|||
|
|
return self.p.a * self.Ts["t1"]
|
|||
|
|
|
|||
|
|
def X1Close(self, t: float):
|
|||
|
|
t1 = min(t, self.Ts["t1"])
|
|||
|
|
x0 = self.p.a * t1 * t1 / 2
|
|||
|
|
|
|||
|
|
t2 = max(t - self.Ts["t1"], 0)
|
|||
|
|
x1 = self.p.a * self.Ts["t1"] * t2
|
|||
|
|
|
|||
|
|
return x0 + x1 + self.p.x10
|
|||
|
|
|
|||
|
|
def V2Close(self, t: float):
|
|||
|
|
if t < self.T2["t1"]:
|
|||
|
|
return self.p.a2 * t
|
|||
|
|
t -= self.T2["t1"]
|
|||
|
|
if t < self.T2["t2"]:
|
|||
|
|
return self.p.a2 * self.T2["t1"]
|
|||
|
|
t -= self.T2["t2"]
|
|||
|
|
return self.p.a2 * self.T2["t1"] - self.p.a2 * t
|
|||
|
|
|
|||
|
|
def X2Close(self, t: float):
|
|||
|
|
t1 = min(t, self.T2["t1"])
|
|||
|
|
x0 = self.p.a2 * t1 * t1 / 2
|
|||
|
|
|
|||
|
|
t2 = max(min(t - self.T2["t1"], self.T2["t2"]), 0)
|
|||
|
|
x1 = self.p.a2 * self.T2["t1"] * t2
|
|||
|
|
|
|||
|
|
t3 = max(min(t - self.T2["t2"]- self.T2["t1"], self.T2["t1"]), 0)
|
|||
|
|
x2 = self.p.a2 * self.T2["t1"] * t3 - self.p.a2 * t3 * t3 / 2
|
|||
|
|
|
|||
|
|
return x0 + x1 + x2 + self.p.x20
|
|||
|
|
|
|||
|
|
def FClose(self, t: float):
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
def V1Grow(self, t: float):
|
|||
|
|
F = self.FGrow(t)
|
|||
|
|
dF0 = self.p.a * self.Ts["t1"] * self.p.k
|
|||
|
|
if t < self.Ts["tm"]:
|
|||
|
|
dF = sqrt(self.p.k / self.p.m) * self.p.umax / self.p.l * sin(sqrt(self.p.k / self.p.m) * t) + dF0 * cos(sqrt(self.p.k / self.p.m) * t)
|
|||
|
|
return dF / self.p.k
|
|||
|
|
if t < self.Ts["tend"]:
|
|||
|
|
return sqrt(self.p.k/self.p.m)*sqrt((self.p.Fd-self.p.Fprop)**2 - F**2) / self.p.k
|
|||
|
|
v0 = sqrt(self.p.k/self.p.m)*sqrt((self.p.Fd-self.p.Fprop)**2 - self.p.Fq**2)
|
|||
|
|
b = (1/3 * v0 / cbrt((self.p.Fd - self.p.Fq))**2)**3
|
|||
|
|
dF = 3.0*b*cbrt((F -self.p.Fd)/b)**2
|
|||
|
|
return dF / self.p.k
|
|||
|
|
|
|||
|
|
def X1Grow(self, t: float):
|
|||
|
|
F = self.FGrow(t)
|
|||
|
|
x = F / self.p.k
|
|||
|
|
return x + self.x1Contact
|
|||
|
|
|
|||
|
|
def V2Grow(self, t: float):
|
|||
|
|
"""Считается, что верхний электрод не влияет на набор усилия, функция не реализована!, возвращает 0. Устанавливайте kturn = 0
|
|||
|
|
"""
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
def X2Grow(self, t: float):
|
|||
|
|
"""Считается, что верхний электрод не влияет на набор усилия, функция не реализована!, возвращает 0. Устанавливайте kturn = 0
|
|||
|
|
"""
|
|||
|
|
return self.x2Contact
|
|||
|
|
|
|||
|
|
def FGrow(self, t: float):
|
|||
|
|
v0 = self.p.a * self.Ts["t1"]
|
|||
|
|
dF0 = self.p.a * self.Ts["t1"] * self.p.k
|
|||
|
|
Fm = (self.p.Ftg**2 - self.p.m/self.p.k*dF0**2)/(2 * self.p.awork * self.p.m)
|
|||
|
|
if t < self.Ts["tm"]:
|
|||
|
|
return - self.p.umax / self.p.l * cos(sqrt(self.p.k / self.p.m) * t) + self.p.umax / self.p.l + sqrt(self.p.m / self.p.k) * dF0 * sin(sqrt(self.p.k / self.p.m) * t)
|
|||
|
|
t -= self.Ts["tm"]
|
|||
|
|
if t < self.Ts["tend"]:
|
|||
|
|
tm = arcsin(Fm/(self.p.Ftg)) * sqrt(self.p.m/self.p.k)
|
|||
|
|
return self.p.Ftg * sin(sqrt(self.p.k / self.p.m)*(t + tm))
|
|||
|
|
t -= self.Ts["tend"]
|
|||
|
|
|
|||
|
|
|
|||
|
|
a = self.p.Fd
|
|||
|
|
v0 = sqrt(self.p.k/self.p.m)*sqrt((self.p.Fd-self.p.Fprop)**2 - self.p.Fq**2)
|
|||
|
|
b = (1/3 * v0 / cbrt((self.p.Fd - self.p.Fq))**2)**3
|
|||
|
|
q = self.p.Fq
|
|||
|
|
|
|||
|
|
return 3 * t**2 * cbrt(b*b*(q-a)) + 3 * t * cbrt(q-a)**2 * cbrt(b) + b * t**3 + q
|
|||
|
|
|
|||
|
|
def V1Open(self, t: float):
|
|||
|
|
if t < self.Ts["to1"]:
|
|||
|
|
return -self.p.a * t
|
|||
|
|
t -= self.Ts["to1"]
|
|||
|
|
if t < self.Ts["to2"]:
|
|||
|
|
return -self.p.a * self.Ts["to1"]
|
|||
|
|
t -= self.Ts["to2"]
|
|||
|
|
if t < self.Ts["to1"]:
|
|||
|
|
return -self.p.a * self.Ts["to1"] + self.p.a * t
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
def X1Open(self, t: float):
|
|||
|
|
xm = self.p.Fd / self.p.k
|
|||
|
|
t1 = min(t, self.Ts["to1"])
|
|||
|
|
x0 = -self.p.a * t1 * t1 / 2
|
|||
|
|
|
|||
|
|
t2 = max(min(t - self.Ts["to1"], self.Ts["to2"]), 0)
|
|||
|
|
x1 = -self.p.a * self.Ts["to1"] * t2
|
|||
|
|
|
|||
|
|
t3 = max(min(t - self.Ts["to2"]- self.Ts["to1"], self.Ts["to1"]), 0)
|
|||
|
|
x2 = -self.p.a * self.Ts["to1"] * t3 + self.p.a * t3 * t3 / 2
|
|||
|
|
|
|||
|
|
return xm + x0 + x1 + x2 + self.x1Contact
|
|||
|
|
|
|||
|
|
def V2Open(self, t: float):
|
|||
|
|
|
|||
|
|
t = max(t-self.TStartOpen , 0)
|
|||
|
|
if t < self.T2["to1"]:
|
|||
|
|
return -self.p.a2 * t
|
|||
|
|
t -= self.T2["to1"]
|
|||
|
|
if t < self.T2["to2"]:
|
|||
|
|
return -self.p.a2 * self.T2["to1"]
|
|||
|
|
t -= self.T2["to2"]
|
|||
|
|
if t < self.T2["to1"]:
|
|||
|
|
return -self.p.a2 * self.T2["to1"] + self.p.a2 * t
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
def X2Open(self, t: float):
|
|||
|
|
t = max(t-self.TStartOpen , 0)
|
|||
|
|
t1 = min(t, self.T2["to1"])
|
|||
|
|
x0 = -self.p.a2 * t1 * t1 / 2
|
|||
|
|
|
|||
|
|
t2 = max(min(t - self.T2["to1"], self.T2["to2"]), 0)
|
|||
|
|
x1 = -self.p.a2 * self.T2["to1"] * t2
|
|||
|
|
|
|||
|
|
t3 = max(min(t - self.T2["to2"]- self.T2["to1"], self.T2["to1"]), 0)
|
|||
|
|
x2 = -self.p.a2 * self.T2["to1"] * t3 + self.p.a2 * t3 * t3 / 2
|
|||
|
|
|
|||
|
|
return x0 + x1 + x2 + self.x2Contact
|
|||
|
|
|
|||
|
|
def FOpen(self, t: float):
|
|||
|
|
x1 = self.X1Open(t)
|
|||
|
|
x2 = self.X2Open(t)
|
|||
|
|
F = self.p.k * max(0, (x1 + x2 - self.x1Contact - self.x2Contact))
|
|||
|
|
return F
|
|||
|
|
|
|||
|
|
def calcPhaseClose(self, t: float):
|
|||
|
|
return self.X1Close(t), self.X2Close(t), self.V1Close(t), self.V2Close(t), self.FClose(t)
|
|||
|
|
|
|||
|
|
def calcPhaseGrow(self, t: float):
|
|||
|
|
return self.X1Grow(t), self.X2Grow(t), self.V1Grow(t), self.V2Grow(t), self.FGrow(t)
|
|||
|
|
|
|||
|
|
def calcPhaseOpen(self, t: float):
|
|||
|
|
return self.X1Open(t), self.X2Open(t), self.V1Open(t), self.V2Open(t), self.FOpen(t)
|
|||
|
|
|
|||
|
|
def getSpecific(self, param : str, phase : str, t : float):
|
|||
|
|
"""Получить значение величины в определенную фазу в момент времени t (с начала фазы)
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
param (str): Значение из списка X1 | X2 | V1 | V2 | F
|
|||
|
|
phase (str): Значение из списка: Close | Grow | Open
|
|||
|
|
t (float): Время
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
Значение величины
|
|||
|
|
"""
|
|||
|
|
funcName = param + phase
|
|||
|
|
try:
|
|||
|
|
func = getattr(self, funcName)
|
|||
|
|
except:
|
|||
|
|
print("Wrong param or phase name")
|
|||
|
|
return 0
|
|||
|
|
return func(t)
|
|||
|
|
|
|||
|
|
def getVar(self, param : str, t : float):
|
|||
|
|
if t < self.Ts["tclose"]:
|
|||
|
|
return self.getSpecific(param, "Close", t)
|
|||
|
|
t -= self.Ts["tclose"]
|
|||
|
|
if t < self.Ts["tgrow"] :
|
|||
|
|
return self.getSpecific(param, "Grow", t)
|
|||
|
|
t -= self.Ts["tgrow"]
|
|||
|
|
return self.getSpecific(param, "Open", t)
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
opt = OptAlgorithm()
|
|||
|
|
import matplotlib.pyplot as plt
|
|||
|
|
from matplotlib import use
|
|||
|
|
|
|||
|
|
print(opt.Ts)
|
|||
|
|
print(opt.calcPhaseClose(opt.Ts["tclose"]))
|
|||
|
|
print(opt.calcPhaseGrow(opt.Ts["tgrow"]))
|
|||
|
|
print(opt.calcPhaseOpen(opt.Ts["topen"]))
|
|||
|
|
print(opt.getSpecific("X1", "Close", 0))
|
|||
|
|
|
|||
|
|
|
|||
|
|
use("GTK4Agg", force = True)
|
|||
|
|
t = linspace(0, 0.5, 50000)
|
|||
|
|
V1 = [opt.getVar("V1", tt) for tt in t]
|
|||
|
|
V2 = [opt.getVar("V2", tt) for tt in t]
|
|||
|
|
plt.plot(t, V2)
|
|||
|
|
plt.plot(t, V1)
|
|||
|
|
#plt.legend()
|
|||
|
|
plt.show()
|
|||
|
|
|