In [ ]:
# %pip install -q dimstack
import plotly
plotly.offline.init_notebook_mode()

# disable logging
import logging
logging.getLogger().disabled = True

In [ ]:
import dimstack as ds
import numpy as np
ds.display.mode("df")

m1 = ds.dim.Basic(
    nom=2.565/2,
    tol=ds.tol.SymmetricBilateral(0.05/2),
    name="Datum C Slot Size",
)
m2 = ds.dim.Basic(
    nom=0.7/2,
    tol=ds.tol.SymmetricBilateral(0.07/2),
    name="Datum C Slot Diameter",
)
m3 = ds.dim.Basic(
    nom=-np.sqrt(45.05**2 + 39.8**2),
    # tol=ds.tol.SymmetricBilateral(np.sqrt(0.3**2 + 0.27**2)),
    tol=ds.tol.SymmetricBilateral(np.sqrt(0.46**2 + 0.4**2)), # Per suppliers request
    name="Datum C Slot Location",
    desc="Relative to Datum B",
)
m4 = ds.dim.Basic(
    nom=3.065/2,
    tol=ds.tol.SymmetricBilateral(0.05/2),
    name="Datum B Hole Size",
)
m5 = ds.dim.Basic(
    nom=-2.99/2,
    tol=ds.tol.SymmetricBilateral(0.03/2),
    name="Datum B Pin Size",
)
m6 = ds.dim.Basic(
    nom=np.sqrt(45.05**2 + 39.8**2),
    tol=ds.tol.SymmetricBilateral(0.1/2), # 0.08/2 per reference design, but customer likely to be sloppy.
    name="Datum C Pin Position",
    desc="Relative to Datum B Pin",
)
m7 = ds.dim.Basic(
    nom=-2.49/2,
    tol=ds.tol.SymmetricBilateral(0.03/2),
    name="Datum C Pin Size",
)
items = [m1, m2, m3, m4, m5, m6, m7]

stack = ds.Stack(title="Datum C Pin-Slot Gap", items=items)
stack
Out[ ]:
Stack: Datum C Pin-Slot Gap
ID Name Description dir Nom. Tol. Sen. Relative Bounds Distribution Process Sigma k C_p C_pk μ σ μ_eff σ_eff Yield Probability Reject PPM
0 Datum C Slot Size Dimension + 1.2825 ± 0.025 1 [1.2575, 1.3075] Uniform
1 Datum C Slot Length Dimension + 0.35 ± 0.035 1 [0.315, 0.385] Uniform
2 Datum C Slot Location Relative to Datum B - 60.11275 ± 0.60959 1 [59.50316, 60.72234] Uniform
3 Datum B Hole Size Dimension + 1.5325 ± 0.025 1 [1.5075, 1.5575] Uniform
4 Datum B Pin Size Dimension - 1.495 ± 0.015 1 [1.48, 1.51] Uniform
5 Datum C Pin Position Relative to Datum B Pin + 60.11275 ± 0.05 1 [60.06275, 60.16275] Uniform
6 Datum C Pin Size Dimension - 1.245 ± 0.015 1 [1.23, 1.26] Uniform
In [ ]:
ds.plot.StackPlot().add(stack).show()
In [ ]:
display(stack.WC)
Dimension: Datum C Pin-Slot Gap - WC Analysis -
ID Name Description dir Nom. Tol. Sen. Relative Bounds Distribution
7 Datum C Pin-Slot Gap - WC Analysis + 0.425 ± 0.77459 1 [-0.34959, 1.19959] Uniform

Since the left side of the slot is our 0 point, we want the left size of the pin to be in the positive direction, or the bounds of the entire tolerance stack to be greater than zero.

At worst-case, the lower bound is negative, meaning the pin would not fit in the slot. It would need to grow 340 [um] in both directions to get there.

That is quite a bit. What if we don't need it to fit every time, just pretty dang close to almost every time...

In [ ]:
display(stack.RSS)
display(stack.SixSigma(at=1))
display(stack.SixSigma(at=2))
display(stack.SixSigma(at=4.5))
Dimension: Datum C Pin-Slot Gap - RSS Analysis - (assuming inputs with Normal Distribution & ± 3σ)
ID Name Description dir Nom. Tol. Sen. Relative Bounds Distribution Process Sigma k C_p C_pk μ σ μ_eff σ_eff Yield Probability Reject PPM
15 Datum C Pin-Slot Gap - RSS Analysis (assuming inputs with Normal Distribution & ± 3σ) + 0.425 ± 0.61402 1 [-0.18902, 1.03902] Normal ± 3σ 0 1.0 1.0 0.425 0.20467 0.425 0.20467 99.73002039 2699.8
Dimension: Datum C Pin-Slot Gap - '6 Sigma' Analysis - (assuming inputs with Normal Distribution)
ID Name Description dir Nom. Tol. Sen. Relative Bounds Distribution Process Sigma k C_p C_pk μ σ μ_eff σ_eff Yield Probability Reject PPM
23 Datum C Pin-Slot Gap - '6 Sigma' Analysis (assuming inputs with Normal Distribution) + 0.425 ± 0.20467 1 [0.22033, 0.62967] Normal ± 1σ 0 0.33333 0.33333 0.425 0.20467 0.425 0.20467 68.26894921 317310.51
Dimension: Datum C Pin-Slot Gap - '6 Sigma' Analysis - (assuming inputs with Normal Distribution)
ID Name Description dir Nom. Tol. Sen. Relative Bounds Distribution Process Sigma k C_p C_pk μ σ μ_eff σ_eff Yield Probability Reject PPM
31 Datum C Pin-Slot Gap - '6 Sigma' Analysis (assuming inputs with Normal Distribution) + 0.425 ± 0.40935 1 [0.01565, 0.83435] Normal ± 2σ 0 0.66667 0.66667 0.425 0.20467 0.425 0.20467 95.44997361 45500.26
Dimension: Datum C Pin-Slot Gap - '6 Sigma' Analysis - (assuming inputs with Normal Distribution)
ID Name Description dir Nom. Tol. Sen. Relative Bounds Distribution Process Sigma k C_p C_pk μ σ μ_eff σ_eff Yield Probability Reject PPM
39 Datum C Pin-Slot Gap - '6 Sigma' Analysis (assuming inputs with Normal Distribution) + 0.425 ± 0.92104 1 [-0.49604, 1.34604] Normal ± 4.5σ 0 1.5 1.5 0.425 0.20467 0.425 0.20467 99.99932047 6.8

Let say we want +/-1sigma, the part has a (100%-68%=) 32% chance of actually hitting these bounds. Thats not very good. But the bound is pretty far from our limits (limit > 0) so lets up the deviation.

If look at +/-2sigma, the lower bounds is barely in the positive region. This is our process capability. Therefore, the current slot length will only fit 95% of the time.

If we wanted to target W.C, RSS, +/-3sigma, or +/-4.5sigma, we would have to rework the dimensions to keep the bounds within the positive region for those capabilities

Let's lengthen the slot to 1.2 mm. Because this stackup is large and will likely never get to where each part is at worst tolerance on the worst direction in the assembly, we will proceed with RSS analysis.

In [ ]:
m2 = ds.dim.Basic(
    nom=0.7/2 + 0.5/2, # grow the entire slot by 500 [um]
    tol=ds.tol.SymmetricBilateral(0.07/2),
    name="Datum C Slot Length",
)
items = [m1, m2, m3, m4, m5, m6, m7]
stack = ds.Stack(title="Datum C Pin-Slot Gap", items=items)
display(stack.WC)
display(stack.RSS)
ds.plot.StackPlot().add(stack.RSS).add(stack.WC).show()
Dimension: Datum C Pin-Slot Gap - WC Analysis -
ID Name Description dir Nom. Tol. Sen. Relative Bounds Distribution
67 Datum C Pin-Slot Gap - WC Analysis + 0.675 ± 0.77459 1 [-0.09959, 1.44959] Uniform
Dimension: Datum C Pin-Slot Gap - RSS Analysis - (assuming inputs with Normal Distribution & ± 3σ)
ID Name Description dir Nom. Tol. Sen. Relative Bounds Distribution Process Sigma k C_p C_pk μ σ μ_eff σ_eff Yield Probability Reject PPM
75 Datum C Pin-Slot Gap - RSS Analysis (assuming inputs with Normal Distribution & ± 3σ) + 0.675 ± 0.61402 1 [0.06098, 1.28902] Normal ± 3σ 0 1.0 1.0 0.675 0.20467 0.675 0.20467 99.73002039 2699.8
In [ ]:
spec = ds.Spec("stack spec", "", dim=stack.RSS, LL=0.0, UL=99)
spec
Out[ ]:
Spec: stack spec
Name Description Dimension Spec. Limits Median Yield Probability Reject PPM
stack spec 100: Datum C Pin-Slot Gap - RSS Analysis (assuming inputs with Normal Distribution & ± 3σ) +0.675 ± 0.61402 @ ± 3σ & k=0 [0.0, 99] 49.5 99.95129784 487.02

This means the assembly will be maufactured to the allowable bounds 99.95% of the time if the slot was increased to 1.2 mm

In [ ]:
gap_nom = m1.nominal + m2.nominal - m7.nominal
stack.WC.nominal - gap_nom
Out[ ]:
0.037500000000001865