Commit fa2497ae authored by Chetan Sharma's avatar Chetan Sharma
Browse files

Saving progress

parent 61bc7546
%% Cell type:markdown id: tags:
# Data Verification
%% Cell type:code id: tags:
``` python
import numpy as np
import time
import shelve
import logging
import queue
from collect_data import DataPoint, RawDataPacket
# from collect_data import DataPoint, RawDataPacket
from matplotlib import pyplot as plt
from scipy.signal import medfilt
TEST_NAMES = ['6']
results = list()
with shelve.open('results') as db:
for test_name in TEST_NAMES:
results += db[test_name]
data_points = list(map(lambda x: x.decompose_packet(), results))
print(data_points[0].W)
x = list(map(lambda x: x.f_r, data_points))
y = list(map(lambda x: x.T, data_points))
plt.figure()
plt.plot(x, y)
```
%%%% Output: stream
0.003175
%%%% Output: execute_result
[<matplotlib.lines.Line2D at 0x7f9bf7983e50>]
%%%% Output: display_data
%%%% Output: error
![](data:image/png;base64,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)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
~/anaconda3/envs/ampd/lib/python3.8/shelve.py in __getitem__(self, key)
110 try:
--> 111 value = self.cache[key]
112 except KeyError:
KeyError: '6'
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
<ipython-input-2-aae045e25021> in <module>
13 with shelve.open('results') as db:
14 for test_name in TEST_NAMES:
---> 15 results += db[test_name]
16
17 data_points = list(map(lambda x: x.decompose_packet(), results))
~/anaconda3/envs/ampd/lib/python3.8/shelve.py in __getitem__(self, key)
112 except KeyError:
113 f = BytesIO(self.dict[key.encode(self.keyencoding)])
--> 114 value = Unpickler(f).load()
115 if self.writeback:
116 self.cache[key] = value
AttributeError: Can't get attribute 'RawDataPacket' on <module '__main__'>
%% Cell type:code id: tags:
``` python
%matplotlib notebook
new_data = list(map(lambda x: RawDataPacket(x.D, x.W, x.R, x.N, x.f_r, x.w, x.measurements), results))
data_points = list(map(lambda x: x.decompose_packet_sorta(), new_data))
plt.figure()
last_time = 0
for tTs, tFys, Ts, Fys in data_points:
times = [t + last_time for t in tTs]
stuff = Ts
filter_size = 3
fc = int((filter_size + 1) / 2)
plt.plot(times[fc: -fc], medfilt(stuff, filter_size)[fc: -fc])
last_time = times[-1]
```
%%%% Output: display_data
%%%% Output: display_data
%% Cell type:markdown id: tags:
## Plan
We have three datasets. Two variables are tweaked across dataset. We want to perform some kind of regression to figure out our cutting force coefficients.
Regression is linear if we only vary feed, but becomes nonlinear once we incorporate WOC.
First, maybe just try using a linear regressor for both?
%% Cell type:code id: tags:
``` python
from scipy.optimize import least_squares
def single_residual(d, K_tc, K_te, p):
return T_exp_lin(d.D, d.N, d.R, d.W, d.f_r, d.w, K_tc, K_te, p) - d.T
def gen_train_pairs():
X = [[d.D, d.N, d.R, d.W, d.f_r, d.w] for d in data_points]
y = [d.T for d in data_points]
return (X, y)
residual_array = np.vectorize(single_residual)
def objective(x):
K_tc = x[0]
K_te = x[1]
p = x[2]
return residual_array(data_points, K_tc, K_te, p)
class NonLinRegressor:
def fit(self, X, Y):
self.coef = least_squares(lambda coef: [self.evaluate(x, coef) - y for x, y in zip(X, Y)], self.coef).x
return self
def predict(self, X):
return [self.evaluate(x, self.coef) for x in X]
def get_params(self, deep=True):
return {}
def set_params(self, **params):
...
def score(self, X, Y):
u = sum([(y_true - y_pred) ** 2 for y_true, y_pred in zip(Y, self.predict(X))])
y_true_mean = np.mean(Y)
v = sum([(y_true - y_true_mean) ** 2 for y_true in Y])
return (1 - u/v)
class TRegressor(NonLinRegressor):
def __init__(self):
self.coef = [0,0,1]
def evaluate(self, x, coef):
return T_exp_lin(*x, coef[0], coef[1], coef[2])
class FRegressor(NonLinRegressor):
def __init__(self):
self.coef = [0,0,0,0, 0, 0]
def evaluate(self, x, coef):
return F_exp_lin(*x, *coef)[0][1]
estimator = TRegressor()
regressor = RANSACRegressor(base_estimator = estimator, min_samples = 5)
X, y = gen_train_pairs()
# y = [d.Fy * 9.81 ** 2 for d in data_points]
regressor.fit(X, y)
# K_tc, K_te, K_rc, K_re, p, q = regressor.estimator_.coef
K_tc, K_te, p = regressor.estimator_.coef
```
%% Cell type:code id: tags:
``` python
# print(K_tc, K_te, K_rc, K_re, p, q)
y_est = list(map(lambda d : T_exp_lin(d.D, d.N, d.R, d.W, d.f_r, d.w, K_tc, K_te, p), data_points))
# y_est = list(map(lambda d : F_exp_lin(d.D, d.N, d.R, d.W, d.f_r, d.w, K_tc, K_te, K_rc, K_re, p, q), data_points))
# y_est = np.array(y_est)
# y_est = np.squeeze(y_est)[:, 1]
# print(y_est)
plt.figure()
plt.plot(x, y)
plt.plot(x, y_est)
```
%%%% Output: execute_result
[<matplotlib.lines.Line2D at 0x7fc984255c10>]
%%%% Output: display_data
![](data:image/png;base64,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)
%% Cell type:code id: tags:
``` python
from sklearn.linear_model import RANSACRegressor, LinearRegression
from models import T_x_vector, T_lin, T_exp_lin, calc_h_a, calc_f_t, F_exp_lin
def dataPoint_to_X(d):
return T_x_vector(d.D, d.N, d.R, d.W, d.f_r, d.w)
def single_residual(d, K_tc, K_te, p):
return T_exp_lin(d.D, d.N, d.R, d.W, d.f_r, d.w, K_tc, K_te, p) - d.T
residual_array = np.vectorize(single_residual)
def objective(x):
K_tc = x[0]
K_te = x[1]
p = x[2]
return residual_array(data_points, K_tc, K_te, p)
X = list(map(dataPoint_to_X, data_points))
estimator = LinearRegression(fit_intercept=False)
regressor = RANSACRegressor(base_estimator = estimator)
regressor.fit(X, y)
K_tc, K_te = regressor.estimator_.coef_
print("K_tc = ", K_tc, ", K_te = ", K_te)
x_h_a = np.linspace(0.1e-3, 4e-3, 100)
y_h_a = [calc_h_a(6.35e-3 / 2 , x, calc_f_t(3, 0.0016, 500)) for x in x_h_a]
```
%%%% Output: stream
K_tc = 858494934.9591976 , K_te = -696.3150933941946
%% Cell type:markdown id: tags:
Now we check if we actually fit anything useful
%% Cell type:code id: tags:
``` python
y_est = list(map(lambda d : T_lin(d.D, d.N, d.R, d.W, d.f_r, d.w, K_tc, K_te), data_points))
plt.figure()
plt.plot(x, y)
plt.plot(x, y_est)
plt.figure()
plt.plot(x_h_a, y_h_a)
plt.plot([0.00079375, 0.0015875, 0.003175], [0,0,0], 'd')
```
%%%% Output: execute_result
[<matplotlib.lines.Line2D at 0x7f22f8fe0640>]
%%%% Output: display_data
![](data:image/png;base64,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)
%%%% Output: display_data
![](data:image/png;base64,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)
......
from ml import LinearModel
from fake_cut import Fake_Cut
from objects import EndMill, Conditions
PARAMS = [858494934.9591976, -696.3150933941946, 858494934.9591976, -696.3150933941946]
# ERROR = [0.01, 0.01]
# NOISE = [0.1, 0.1]
ERROR = [0, 0]
NOISE = [0, 0]
CONDITIONS = Conditions(1e-3, 3.175e-3, 5e-3, 5000, EndMill(3, 3.175e-3, 3.175e-3, 10e-3, 10e-3))
model = LinearModel()
cut = Fake_Cut(PARAMS, ERROR, NOISE)
data = cut.cut(CONDITIONS)
model.ingest_datum(data)
print("{0:.20f}".format(model.params[1]))
\ No newline at end of file
......@@ -62,10 +62,11 @@ class Cut:
self._logger.info("Layer prepared for clearing")
def cut(self, W, f_r, w):
def cut(self, conditions):
"""
Performs a stroke of facing. Returns a data blob.
"""
_, W, f_r, w, _ = conditions.unpack()
X_START = x_cut - self.endmill.r_c + W
if X_START > self.X_END:
raise MachineCrash("Cutting too far in X direction: X = " + str(X_START))
......
from models import T_lin, F_lin
from objects import Conditions, Data
import numpy as np
class Fake_Cut:
def __init__(self, params, error, noise):
"""
Args:
params: list of format [K_tc, K_te, K_rc, K_re]
error: list of standard deviations of format [o_T, o_Fy]. Simulates the sensor being "wrong" sometimes.
error: list of standard deviations of format [o_T, o_Fy]. Simulates the sensor being noisy.
"""
self.params = params
self.error = error
self.noise = noise
def cut(self, conditions : Conditions):
# use prediction as output
T = T_lin(conditions, *self.params[:2])
_, Fy = F_lin(conditions, *self.params)
# add sensor error
T_error = np.random.normal(T, self.error[0])
Fy_error = np.random.normal(Fy, self.error[1])
# add sensor noise
T_noisy = np.random.normal(T_error, self.noise[0], (100))
Fy_noisy = np.random.normal(Fy_error, self.noise[1], (100))
# generate fake times
t = np.linspace(0, 1, 100)
# return fake reading
return Data(*conditions.unpack(), np.array([t, T_noisy]), np.stack([t, Fy_noisy]))
\ No newline at end of file
......@@ -5,7 +5,7 @@ from sklearn import linear_model
from matplotlib import pyplot as plt
from models import T_lin, F_lin, T_x_vector, Fy_x_vector
from objects import Data, Reading, EndMill, Prediction
from objects import Data, Conditions, EndMill, Prediction
class Model(abc.ABC):
"""
......@@ -40,19 +40,21 @@ class LinearModel(Model):
self.training_T_y = list()
self.training_Fy_x = list()
self.training_Fy_y = list()
self.regressor_T = linear_model.Lasso(fit_intercept = False, warm_start=True)
self.regressor_Fy = linear_model.Lasso(fit_intercept = False, warm_start=True)
self.regressor_T = linear_model.LinearRegression(fit_intercept = False)
self.regressor_Fy = linear_model.LinearRegression(fit_intercept = False)
self.params = np.array([0,0,0,0])
def ingest_datum(self, datum):
# decompose
D, W, f_r, w, endmill, Ts, Fys = datum.D, datum.W, datum.f_r, datum.w, datum.endmill, datum.Ts, datum.Fys
R, N = endmill.R, endmill, N
T, Fy = np.median(Ts[:, 1]), np.median(Fys[:, 1])
_, _, _, _, _, Ts, Fys = datum.unpack()
T, Fy = np.median(Ts[1, :]), np.median(Fys[1, :])
# get linear coefficients
T_x = T_x_vector(D, N, R, W, f_r, w)
Fy_x = Fy_x_vector(D, N, R, W, f_r, w)
T_x = T_x_vector(datum.conditions())
Fy_x = Fy_x_vector(datum.conditions())
print("T", T)
print("coef times real K_tc", T_x[1] * 858494934.9591976)
# add to training set
self.training_T_x.append(T_x)
......@@ -68,24 +70,25 @@ class LinearModel(Model):
# calculate best fit from data
self.regressor_T.fit(self.training_T_x, self.training_T_y)
K_tc, K_te = self.regressor.coef_
K_tc, K_te = self.regressor_T.coef_
print(K_tc, K_te)
self.params[0], self.params[1] = K_tc, K_te
# transform Fy into a smaller linear problem and fit
intercepts = training_Fy_x @ np.array([K_tc, K_te, 0, 0])[np.newaxis].T
training_Fy_y_no_intercepts = training_Fy_y - intercepts
self.regressor_Fy.fit(training_Fy_x[:, 2:], training_Fy_y_no_intercepts)
K_rc, K_re = self.regressor_Fy.coef_
self.params[0], self.params[1] = K_rc, K_re
def predict_one(self, conditions):
# decompose
D, W, f_r, w, endmill = conditions.D, conditions.W, conditions.f_r, conditions.w, conditions.endmill
R, N = endmill.R, endmill, N
# evaluate
T = T_lin(D, N, R, W, f_r, w, self.params[0], self.params[1])
F = F_lin(D, N, R, W, f_r, w, *self.params)
T = T_lin(conditions, *self.params[:2])
F = F_lin(conditions, *self.params)
# repack and return
return Prediction(D, W, f_r, w, endmill, T, F)
return Prediction(conditions, T, F)
import numpy as np
def calc_h_a(R, W, f_t):
from objects import Conditions, Data, Prediction, MachineChar
def calc_f_t(conditions : Conditions):
D, W, f_r, w, endmill = conditions.unpack()
N = endmill.N
return (2 * np.pi * f_r) / (N * w)
def calc_h_a(conditions : Conditions):
D, W, f_r, w, endmill = conditions.unpack()
R = endmill.r_c
f_t = calc_f_t(conditions)
phi_st = np.pi - np.arccos(1 - W / R)
phi_ex = np.pi
return -f_t * (np.cos(phi_ex) - np.cos(phi_st)) / (phi_ex - phi_st)
def calc_f_t(N, f_r, w):
return (2 * np.pi * f_r) / (N * w)
# exponential models, account for strange decrease in cutting forces as chip thickness increases.
def T_exp_lin(D, N, R, W, f_r, w, K_TC, K_te, p):
f_t = calc_f_t(N, f_r, w)
h_a = calc_h_a(R, W, f_t)
def T_exp_lin(conditions : Conditions, K_TC, K_te, p):
D, W, f_r, w, endmill = conditions.unpack()
N, R, _, _, _ = endmill.unpack()
f_t = calc_f_t(conditions)
h_a = calc_h_a(conditions)
K_tc = K_TC * h_a ** -p
return ((D * N) * (K_te * R * np.arccos(1 - W/R) + K_tc * W * f_t)) / (2 * np.pi)
def F_exp_lin(D, N, R, W, f_r, w, K_TC, K_te, K_RC, K_re, p, q):
f_t = calc_f_t(N, f_r, w)
h_a = calc_h_a(R, W, f_t)
def F_exp_lin(conditions : Conditions, K_TC, K_te, K_RC, K_re, p, q):
D, W, f_r, w, endmill = conditions.unpack()
N, R, _, _, _ = endmill.unpack()
f_t = calc_f_t(conditions)
h_a = calc_h_a(conditions)
K_tc = K_TC * h_a ** -p
K_rc = K_RC * h_a ** -q
Fx = - ((D*N*(K_tc*W**2*f_t + K_rc*W**(3/2)*f_t*(2*R - W)**(1/2)))/4 - (D*N*R*(2*K_tc*W*f_t - 2*K_re*W + 2*K_te*W**(1/2)*(2*R - W)**(1/2) + K_rc*W**(1/2)*f_t*(2*R - W)**(1/2)))/4)/(R**2*np.pi) - (D*K_rc*N*f_t*np.arccos((R - W)/R))/(4*np.pi)
......@@ -26,36 +38,42 @@ def F_exp_lin(D, N, R, W, f_r, w, K_TC, K_te, K_RC, K_re, p, q):
# linear models, easier to fit and more simple
def T_lin(D, N, R, W, f_r, w, K_tc, K_te):
f_t = calc_f_t(N, f_r, w)
def T_lin(conditions, K_tc, K_te):
D, W, f_r, w, endmill = conditions.unpack()
N, R, _, _, _ = endmill.unpack()
f_t = calc_f_t(conditions)
return ((D * N) * (K_te * R * np.arccos(1 - W/R) + K_tc * W * f_t)) / (2 * np.pi)
def F_lin(D, N, R, W, f_r, w, K_tc, K_te, K_rc, K_re):
f_t = calc_f_t(N, f_r, w)
def F_lin(conditions, K_tc, K_te, K_rc, K_re):
D, W, f_r, w, endmill = conditions.unpack()
N, R, _, _, _ = endmill.unpack()
f_t = calc_f_t(conditions)
Fx = - ((D*N*(K_tc*W**2*f_t + K_rc*W**(3/2)*f_t*(2*R - W)**(1/2)))/4 - (D*N*R*(2*K_tc*W*f_t - 2*K_re*W + 2*K_te*W**(1/2)*(2*R - W)**(1/2) + K_rc*W**(1/2)*f_t*(2*R - W)**(1/2)))/4)/(R**2*np.pi) - (D*K_rc*N*f_t*np.arccos((R - W)/R))/(4*np.pi)
Fy = (D*K_tc*N*f_t*np.arccos((R - W)/R))/(4*np.pi) - ((D*N*(K_rc*W**2*f_t - K_tc*W**(3/2)*f_t*(2*R - W)**(1/2)))/4 - (D*N*R*(2*K_te*W + 2*K_rc*W*f_t + 2*K_re*W**(1/2)*(2*R - W)**(1/2) - K_tc*W**(1/2)*f_t*(2*R - W)**(1/2)))/4)/(R**2*np.pi)
return np.array([Fx, Fy])
# coefficient calculators for linear regression
def T_x_vector(D, N, R, W, f_r, w):
def T_x_vector(conditions : Conditions):
"""
Outputs vector that corresponds to coefficients in order:
K_tc, K_te
"""
f_t = calc_f_t(N, f_r, w)
K_tc_C = (D * N * W * f_t) / (2 * np.pi)
K_te_C = (D * N * R * np.arccos(1 - (W / R))) / (2 * np.pi)
return [K_tc_C, K_te_C]
D, W, f_r, w, endmill = conditions.unpack()
N, R, _, _, _ = endmill.unpack()
f_t = calc_f_t(conditions)
return[(D * N * W * f_t) / (2 * np.pi), (D * N * R * np.arccos(1 - (W / R))) / (2 * np.pi)]
def Fy_x_vector(D, N, R, W, f_r, w):
f_t = calc_f_t(N, f_r, w)
def Fy_x_vector(conditions : Conditions):
D, W, f_r, w, endmill = conditions.unpack()
N, R, _, _, _ = endmill.unpack()
f_t = calc_f_t(conditions)
return [(D*N*f_t*(W**(3/2)*(2*R - W)**(1/2) + R**2*np.arccos((R - W)/R) - R*W**(1/2)*(2*R - W)**(1/2)))/(4*R**2*np.pi), (D*N*W)/(2*R*np.pi), (D*N*W*f_t*(2*R - W))/(4*R**2*np.pi), (D*N*W**(1/2)*(2*R - W)**(1/2))/(2*R*np.pi)]
def deflection_load(D_a, F, endmill, E_e = 650e9):
def deflection_load(D_a, prediction : Prediction, E_e = 650e9):
"""
Calculates ratio of tool deflection to allowed deflection.
Uses FEA model described in doi:10.1016/j.ijmachtools.2005.09.009.
......@@ -67,11 +85,10 @@ def deflection_load(D_a, F, endmill, E_e = 650e9):
Returns:
Ratio of tool deflection to allowed deflection
"""
r_c = endmill.r_c
r_s = endmill.r_s
l_c = endmill.l_c
l_s = endmill.l_s
N = endmill.N
D, W, f_r, w, endmill, T, F = prediction.unpack()
F = np.norm(F)
N, r_c, r_s, l_c, l_s = endmill.unpack()
# prepare variables, this must be done since the FEA model has arbitrary constants defined for certain units
d_1 = r_c * 2 * 1e3 # convert to diameter in mm
d_2 = r_s * 2 * 1e3
......@@ -98,7 +115,7 @@ def deflection_load(D_a, F, endmill, E_e = 650e9):
D_m = C * (F / E) * ((l_1 ** 3 / d_1 ** 4) + ((l_2 ** 3 - l_1 ** 3) / d_2 ** 4)) ** G * 1e-3
return D_m / D_a
def failure_prob_milling(F, T, endmill, D, roughing = False, m = 4, o = 1500e6, a_c = 0.8):
def failure_prob_milling(prediction : Prediction, roughing = False, m = 4, o = 1500e6, a_c = 0.8):
"""
Calculates failure probability according to Weibull distribution. Method adapted from https://doi.org/10.1016/S0007-8506(07)62072-1
Args:
......@@ -113,11 +130,10 @@ def failure_prob_milling(F, T, endmill, D, roughing = False, m = 4, o = 1500e6,