def test_I_rim_only():
    'Check that wheel inertia returns rim inertia if no spoke density is given'

    w = BicycleWheel()
    w.hub = Hub(diameter=0.050, width=0.05)
    w.rim = Rim(radius=0.3,
                area=100e-6,
                I_lat=200. / 69e9,
                I_rad=100. / 69e9,
                J_tor=25. / 26e9,
                I_warp=0.0,
                young_mod=69e9,
                shear_mod=26e9,
                density=1.)

    w.lace_cross(n_spokes=36,
                 n_cross=3,
                 diameter=1.8e-3,
                 young_mod=210e9,
                 offset=0.)

    # Should return a warning that some spoke densities are not specified
    with pytest.warns(UserWarning):
        I_wheel = w.calc_rot_inertia()

    assert np.allclose(I_wheel, (2 * np.pi * 0.3 * 100e-6) * 0.3**2)
def test_I_spokes_only():
    'Check that spoke inertias are correctly calculated'

    w = BicycleWheel()
    w.hub = Hub(diameter=0.050, width=0.05)
    w.rim = Rim(radius=0.3,
                area=100e-6,
                I_lat=200. / 69e9,
                I_rad=100. / 69e9,
                J_tor=25. / 26e9,
                I_warp=0.0,
                young_mod=69e9,
                shear_mod=26e9)

    w.lace_radial(n_spokes=36,
                  diameter=1.8e-3,
                  young_mod=210e9,
                  offset=0.,
                  density=1.0)

    # Calculate inertia of a single spoke
    m_spk = np.hypot(0.3 - 0.025, 0.025) * np.pi / 4 * (1.8e-3)**2 * 1.0
    I_spk = m_spk * (0.3 - 0.025)**2 / 12. + m_spk * (0.5 * (0.025 + 0.3))**2

    # Should return a warning that the rim density is not specified
    with pytest.warns(UserWarning):
        I_wheel = w.calc_rot_inertia()

    assert np.allclose(I_wheel, 36. * I_spk)
示例#3
0
    def wheel_from_row(self, j):
        'Create a BicycleWheel object from a job row'

        # Try to un-pickle wheel object
        if 'wheel_pickle' in j:
            with open(self.out_dir + '/' + j['wheel_pickle'], 'rb') as p:
                w = pickle.load(p)

        else:
            w = BicycleWheel()
            w.hub = Hub(diam1=j['hub_diam1'], width1=j['hub_width1'])
            w.rim = Rim(radius=j['rim_radius'],
                        area=j['rim_area'],
                        I11=j['rim_I11'],
                        I22=j['rim_I22'],
                        I33=j['rim_I33'],
                        Iw=j['rim_Iw'],
                        young_mod=j['rim_young_mod'],
                        shear_mod=j['rim_shear_mod'])

            w.lace_radial(n_spokes=int(j['spk_num']),
                          diameter=j['spk_diameter'],
                          young_mod=j['spk_young_mod'])

            if 'spk_paired' in j.keys() and j['spk_paired']:
                w = convert_to_paired(w)

        return w
示例#4
0
def wheel_from_name(name):
    'Generate a wheel from a standard template'

    df = pd.read_csv('../data/wheel_properties.csv', index_col=0)

    # Find requested wheel
    if name in df:
        p = df[name]

        w = BicycleWheel()
        w.hub = Hub(diam1=float(p['hub_diameter']) / 1000.,
                    width1=float(p['hub_width']) / 2000.)
        w.rim = Rim(
            radius=float(p['rim_radius']) / 1000.,
            area=float(p['rim_area']) / 1e6,
            I11=float(p['rim_GJ']) / (float(p['rim_shear_mod']) * 1e9),
            I22=float(p['rim_EI2']) / (float(p['rim_young_mod']) * 1e9),
            I33=float(p['rim_EI1']) / (float(p['rim_young_mod']) * 1e9),
            Iw=0.0,
            young_mod=float(p['rim_young_mod']) * 1e9,
            shear_mod=float(p['rim_shear_mod']) * 1e9)

        if p['spk_pattern'] == 'radial':
            w.lace_radial(n_spokes=int(p['spk_num']),
                          diameter=float(p['spk_diameter']) / 1000.,
                          young_mod=float(p['spk_young_mod']) * 1e9,
                          offset=float(p['spk_offset']) / 1000.)
        else:
            raise KeyError('Spoke pattern {0:s} is not defined.'.format(
                p['spk_pattern']))

        return w
    else:
        raise KeyError('Wheel template {0:s} is not defined.'.format(name))
示例#5
0
    def _build_wheel():
        w = BicycleWheel()
        w.hub = Hub(diameter=0.050, width=0.05)
        w.rim = Rim(radius=0.3,
                    area=100e-6,
                    I_lat=200. / 69e9,
                    I_rad=100. / 69e9,
                    J_tor=25. / 26e9,
                    I_warp=0.0,
                    young_mod=69e9,
                    shear_mod=26e9)

        return w
示例#6
0
def create_wheel_from_lm(l, mu):
    """Create a wheel with arbitrary values of lambda and mu.

    Since the reverse problem of generating a wheel with a specified lambda
    and mu is not unique, some constraints must be applied:

    - wheel dimensions are R=300m, d_hub=50mm, w_hub=25mm
    - radial spokes, E=200 GPa
    - number and diameter of spokes are chosen to ensure that Pn_lat = 2
    """

    wheel = BicycleWheel()

    wheel.hub = Hub(diam1=0.05, width1=0.025)

    wheel.rim = Rim(radius=0.3,
                    area=100e-6,
                    I11=1000e-12 * (69. / 26.) * mu,
                    I22=1000e-12,
                    I33=1000e-12,
                    Iw=0.0e-12,
                    young_mod=69.0e9,
                    shear_mod=26.0e9)

    alpha = np.arctan(wheel.hub.width1 /
                      (wheel.rim.radius - wheel.hub.diam1 / 2))

    ls = np.sqrt(wheel.hub.width1**2 +
                 (wheel.rim.radius - wheel.hub.diam1 / 2)**2)

    # Calculate n_s by requiring that Pn_lat = 2.0 and round up to next even
    n_s = 1.5 * (8 * np.pi / np.power(4, 0.25)) * np.power(
        l * (mu + 1) / mu, 0.25)
    n_s = 2 * int(np.ceil(n_s / 2))

    # Calculate spoke diameter based on requirement on lambda
    k_uu = l * wheel.rim.young_mod * wheel.rim.I22 / (wheel.rim.radius**4)
    A_s = 2 * np.pi * wheel.rim.radius * ls * k_uu / (n_s * 200e9 *
                                                      np.sin(alpha)**2)
    d_s = np.sqrt(4 * A_s / np.pi)

    # Create spokes
    wheel.lace_radial(n_spokes=n_s, diameter=d_s, young_mod=200e9)

    return wheel
示例#7
0
    def _build_wheel(n_cross=0):
        w = BicycleWheel()
        w.hub = Hub(diameter=0.050, width=0.05)
        w.rim = Rim(radius=0.3,
                    area=100e-6,
                    I_lat=200. / 69e9,
                    I_rad=100. / 69e9,
                    J_tor=25. / 26e9,
                    I_warp=0.0,
                    young_mod=69e9,
                    shear_mod=26e9)

        w.lace_cross(n_spokes=36,
                     n_cross=n_cross,
                     diameter=1.8e-3,
                     young_mod=210e9,
                     offset=0.)

        return w
def test_I_wheel_less_than_max():
    'Check that rotational inertia is less than theoretical maximum'

    w = BicycleWheel()
    w.hub = Hub(diameter=0.050, width=0.05)
    w.rim = Rim(radius=0.3,
                area=100e-6,
                J_tor=25. / 26e9,
                I_lat=200. / 69e9,
                I_rad=100. / 69e9,
                I_warp=0.0,
                young_mod=69e9,
                shear_mod=26e9,
                density=1.0)

    w.lace_radial(n_spokes=36,
                  diameter=1.8e-3,
                  young_mod=210e9,
                  offset=0.,
                  density=1.0)

    I_wheel = w.calc_rot_inertia()

    assert I_wheel < w.calc_mass() * w.rim.radius**2
示例#9
0
def build_wheel_from_UI():
    'Create a BicycleWheel object from UI inputs'

    w = BicycleWheel()

    # Hub
    w.hub = Hub(diameter=float(hub_diam.value)/1000.,
                width_nds=np.abs(float(hub_width.value[0]))/1000.,
                width_ds=np.abs(float(hub_width.value[1]))/1000.)

    # Rim
    r_matl = list(RIM_MATLS)[rim_matl.active]
    radius = RIM_SIZES[rim_size.value]['radius']
    density = RIM_MATLS[r_matl]['density']
    mass = float(rim_mass.value) / 1000.
    area = mass / (2*np.pi*radius*density)
    rim_young_mod = RIM_MATLS[r_matl]['young_mod']
    rim_shear_mod = RIM_MATLS[r_matl]['shear_mod']

    w.rim = Rim(radius=radius,
                area=area,
                I11=float(rim_GJ.value) / rim_shear_mod,
                I22=float(rim_EI2.value) / rim_young_mod,
                I33=float(rim_EI1.value) / rim_young_mod, Iw=0.0,
                young_mod=rim_young_mod, shear_mod=rim_shear_mod)

    # Drive-side
    if spk_pat_ds.value == 'Radial':
        n_cross_ds = 0
    elif spk_pat_ds.value.endswith('-cross'):
        n_cross_ds = int(spk_pat_ds.value[0])
    else:
        raise ValueError('Undefined drive-side spoke pattern: {:s}'.format(spk_pat_ds.value))

    s_matl_ds = list(SPK_MATLS)[spk_matl_ds.active]
    w.lace_cross_ds(n_spokes=int(spk_num.value)//2,
                    n_cross=n_cross_ds,
                    diameter=float(spk_diam_ds.value)/1000.,
                    young_mod=SPK_MATLS[s_matl_ds]['young_mod'],
                    offset=0.)  # Implement this later

    # Non-drive-side
    if spk_pat_nds.value == 'Radial':
        n_cross_nds = 0
    elif spk_pat_nds.value.endswith('-cross'):
        n_cross_nds = int(spk_pat_nds.value[0])
    else:
        raise ValueError('Undefined drive-side spoke pattern: {:s}'.format(spk_pat_nds.value))

    s_matl_nds = list(SPK_MATLS)[spk_matl_nds.active]
    w.lace_cross_nds(n_spokes=int(spk_num.value)//2,
                     n_cross=n_cross_nds,
                     diameter=float(spk_diam_nds.value)/1000.,
                     young_mod=SPK_MATLS[s_matl_nds]['young_mod'],
                     offset=0.)  # Implement this later


    if (spk_pat_ds.value == 'Radial' and spk_pat_nds.value == 'Radial'
        and float(spk_T_ds.value) == 0.):
        # Apply a vanishingly small tension to make stiffness matrix invertable
        w.apply_tension(T_avg=w.spokes[0].EA*1e-6)
    else:
        w.apply_tension(T_right=9.81*float(spk_T_ds.value))

    return w
示例#10
0
from bikewheelcalc import BicycleWheel, Rim, Hub, ModeMatrix
import matplotlib.pyplot as plt
import numpy as np

# Create an example wheel and rim
wheel = BicycleWheel()
wheel.hub = Hub(width=0.05, diameter=0.05)
wheel.rim = Rim(radius=0.3,
                area=100e-6,
                I_lat=200. / 69e9,
                I_rad=100. / 69e9,
                J_tor=25. / 26e9,
                I_warp=0.0,
                young_mod=69e9,
                shear_mod=26e9)
wheel.lace_cross(n_spokes=36, n_cross=3, diameter=2.0e-3, young_mod=210e9)

# Create a ModeMatrix model with 24 modes
mm = ModeMatrix(wheel, N=24)

# Create a 500 Newton pointing radially inwards at theta=0
F_ext = mm.F_ext(0., np.array([0., 500., 0., 0.]))

# Calculate stiffness matrix
K = mm.K_rim(tension=False) + mm.K_spk(smeared_spokes=False, tension=False)

# Solve for the mode coefficients
dm = np.linalg.solve(K, F_ext)

# Get radial deflection
theta = np.linspace(-np.pi, np.pi, 100)