Exemplo n.º 1
0
Arquivo: ml.py Projeto: cactode/ammp
    def predict_one(self, conditions):
        # evaluate
        T = T_lin(conditions, *self.params)
        F = F_lin(conditions, *self.params)

        # repack and return
        return Prediction(*conditions.unpack(), T, F)
Exemplo n.º 2
0
 def loss(self, prediction: Prediction):
     """
     Find the "loss" for this problem.
     Loss is defined as the inverse of (optimality * failure metric).
     This is boosted by 1e8 to deal with floating point precision.
     """
     return -(1e8 * (optimality(prediction.conditions())) *
              self.failure(prediction))
Exemplo n.º 3
0
def deflection_load(D_a,
                    prediction: Prediction,
                    machinechar: MachineChar,
                    E_e=650e9):
    """
    Calculates ratio of tool deflection to allowed deflection.
    Uses FEA model described in doi:10.1016/j.ijmachtools.2005.09.009.
    Also includes machine deflection if it is defined.

    Args:
        D_a: Allowed deflection (m)
        prediction: A prediction object 
        E_e: Modulus of elasticity (default is for Carbide) (Pa)

    Returns:
        Ratio of tool deflection to allowed deflection
    """
    _, _, _, _, endmill, _, F = prediction.unpack()
    K_machine = machinechar.K_machine
    Fy = F[1]
    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
    l_1 = l_c * 1e3
    l_2 = (l_s + l_c) * 1e3
    E = E_e * 1e-6  # convert to MPa

    # set constants
    C = None
    G = None
    if N == 4:
        C = 9.05
        G = 0.950
    elif N == 3:
        C = 8.30
        G = 0.965
    elif N == 2:
        C = 7.93
        G = 0.974
    else:
        raise ValueError("Flute count must be between 2-4")

    # calculate tool bending
    D_t = C * (Fy / E) * ((l_1**3 / d_1**4) +
                          ((l_2**3 - l_1**3) / d_2**4))**G * 1e-3

    # calculate machine deflection
    D_m = Fy / K_machine

    return (D_t + D_m) / D_a
Exemplo n.º 4
0
def motor_torque_load(prediction: Prediction, machinechar: MachineChar):
    """
    Calculates ratio of current motor torque to max motor torque.

    Args:
        prediction: A prediction object.
        machinechar: A machinechar object.
    Returns:
        Ratio of current motor torque to max achievable torque
    """
    _, _, _, _, _, T, _ = prediction.unpack()
    r_e, K_T, _, _, I_max, T_nom, _, _, _ = machinechar.unpack()
    T_m = (T + T_nom) / r_e
    # store K_V for convenience
    # max torque is either determined by max current that can be supplied
    return T_m / (K_T * I_max)
Exemplo n.º 5
0
def motor_speed_load(prediction: Prediction, machinechar: MachineChar):
    """
    Calculates ratio of motor speed to maximum motor speed
    Args:
        prediction: A prediction object
        machinechar: A machinechar object

    Returns:
        Ratio of current motor speed to max achievable speed
    """
    _, _, _, w, _, T, _ = prediction.unpack()
    r_e, K_T, R_w, V_max, _, T_nom, _, _, _ = machinechar.unpack()
    w_m = w * r_e
    T_m = (T + T_nom) / r_e
    # store K_V for convenience
    K_V = 1 / K_T
    # max speed is affected by winding resistive voltage drop along with backemf
    return w_m / (K_V * (V_max - T_m * R_w / K_T))
Exemplo n.º 6
0
def failure_prob_milling(prediction: Prediction, 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:
        prediction: A prediction object
        roughing: Whether or not the cutter has roughing serrations (true/false)
        m: Weibull parameter for carbide tooling (dimensionless)
        o: Weibull parameter for carbide tooling (N)
        a_c: Compensated cutter diameter due to helical flutes (dimensionless)

    Returns:
        Probability of failure
    """
    D, _, _, _, endmill, T, F = prediction.unpack()
    F = np.linalg.norm(F)
    _, r_c, r_s, l_c, l_s = endmill.unpack()  # establish base variables

    r_ceq = r_c * a_c  # equivalent cutter radius
    I_ceq = np.pi / 4 * r_ceq**4  # equivalent cutter 2nd inertia
    I_s = np.pi / 4 * r_s**4  # shank 2nd inertia
    J_ceq = np.pi * r_ceq**4 / 2  # equivalent cutter polar inertia

    # reusable expression to get peak stress in cutter
    def stress_tensile(r, l, I):
        return (F * r * (l - D / 2)) / I

    # finding surface stress at cutter-shank interface at the depth of the cutter edge
    stress_c = stress_tensile(r_c, l_c, I_ceq)
    # finding surface stress at shaft-collet interface
    stress_s = stress_tensile(r_s, l_c + l_s, I_s)
    # adjusting torsion to compensate for shear-tensile difference
    stress_t = 1 / 0.577 * T * r_c / J_ceq

    # unknown if von mises stress criterion makes any sense for weibull analysis, taking max of all stresses instead
    stress_peak = max(stress_c, stress_s, stress_t)

    # cdf for weibull distribution
    failure_prob = 1 - np.exp(-(stress_peak / o)**m)
    return failure_prob
Exemplo n.º 7
0
def deflection_load_simple(prediction: Prediction,
                           machinechar: MachineChar,
                           E_e=600e9,
                           a_c=0.8):
    """
    Calculates ratio of deflection to allowable deflection.
    Uses simple approximation that assumes endmill cutter can be approx. as 0.8 of its diameter.

    Args:
        D_a: Allowed deflection (m)
        prediction: Prediction of force
        machinechar: Characterization of machine
        E_e: Modulus of elasticity for endmill
        a_c: Diameter reduction of cutter for cantilever beam model of endmill.

    Returns:
        Ratio of tool deflection to allowed deflection along y axis (since this is the only axis that matters for milling a face)
    """
    D, _, _, _, endmill, _, F = prediction.unpack()
    _, _, _, _, _, _, _, K_machine, D_a = machinechar.unpack()
    F_y = F[1]
    _, r_c, r_s, l_c, l_s = endmill.unpack()

    # calculate basic params
    D_m = F_y / K_machine
    r_ceq = r_c * a_c  # equivalent cutter radius
    I_ceq = np.pi / 4 * r_ceq**4  # equivalent cutter 2nd inertia
    I_s = np.pi / 4 * r_s**4  # shank 2nd inertia

    M_s = F_y * (l_c - D / 2)  # find moment at end of shank
    D_s = (M_s * l_s ** 2) / (2 * E_e * I_s) + (F_y * l_s ** 3) / \
        (3 * E_e * I_s)  # deflection of shank from moment and force
    theta_s = (M_s * l_s) / (E_e * I_s)  # slope at end of shank
    D_c = (F_y * (l_c - D / 2)**2 * (3 * l_c - (l_c - D / 2))) / (
        6 * E_e * I_ceq
    ) + D_s + theta_s * l_c  # deflection at cutter tip from everything

    return (D_m + D_c) / D_a
Exemplo n.º 8
0
MACHINE_PORT = '/dev/ttyS25'
SPINDLE_PORT = '/dev/ttyS33'
TFD_PORT = '/dev/ttyS36'

D = 1e-3
W = 1e-3
f_r = 0.001
w = 100
D_A = 0.1e-3
N = 100
CONFIDENCE_RATE = np.linspace(0.2, 1, 10)

MACHINE = MachineChar(r_e=1,
                      K_T=0.10281,
                      R_w=0.188,
                      V_max=48,
                      I_max=10,
                      T_nom=0.12,
                      f_r_max=0.010,
                      K_machine=5e6,
                      D_a=D_A)

ENDMILL = EndMill(3, 3.175e-3, 3.175e-3, 19.05e-3, 1e-3)

FIXED_CONDITIONS = Conditions(D=D, W=W, f_r=f_r, w=w, endmill=ENDMILL)
print(
    deflection_load_simple(
        D_A, Prediction(*FIXED_CONDITIONS.unpack(), 0.1, [100, 100]), MACHINE))
print(
    deflection_load(D_A, Prediction(*FIXED_CONDITIONS.unpack(), 0.1,
                                    [100, 100]), MACHINE))