Ejemplo n.º 1
0
    def calc_fan_flow(self, iphi=None):
        """Calculate flow angles."""
        if iphi is not None:
            self.phi = iphi
        self.psi = 2 * (1 - self.reaction - self.phi * m.tan(r(self.alpha1)))
        self.u = self.rpm / 60 * 2 * m.pi * self.radius
        self.beta1 = d(m.atan((1 / self.phi) - m.tan(r(self.alpha1))))
        self.beta2 = d(
            m.atan((2 * self.reaction - 1) / self.phi + m.tan(r(self.alpha1))))
        self.betam = d(
            m.atan((m.tan(r(self.beta1)) + m.tan(r(self.beta2))) / 2))
        self.alpha2 = d(m.atan((1 / self.phi) - m.tan(r(self.beta2))))
        self.alpham = d(
            m.atan((m.tan(r(self.alpha1)) + m.tan(r(self.alpha2))) / 2))
        self.cx = self.phi * self.u
        self.w1 = self.cx / m.cos(r(self.beta1))
        self.w2 = self.cx / m.cos(r(self.beta2))
        self.c1 = self.cx / m.cos(r(self.alpha1))
        self.c2 = self.cx / m.cos(r(self.alpha2))
        self.wt1 = self.w1 * m.sin(r(self.beta1))
        self.wt2 = self.w1 * m.sin(r(self.beta2))
        self.ct1 = self.c1 * m.sin(r(self.alpha1))
        self.ct2 = self.c2 * m.sin(r(self.alpha2))

        # Thermodynamics
        self.mach = self.cx / m.sqrt(self.GAMMA * self.R * self.t1)
        self.dt0 = self.psi * (self.u)**2 / self.CP

        self.t01 = self.t1 * (1 + ((self.GAMMA - 1) * self.mach**2) / 2)
        self.p01 = self.p1*(1 + ((self.GAMMA - 1)*self.mach**2)/2)\
            ** (self.GAMMA/(self.GAMMA - 1))
        self.t02 = self.t01 + self.dt0
        self.p02 = self.p01 * (self.t02 / self.t01)**(self.GAMMA /
                                                      (self.GAMMA - 1))
        self.t2 = self.t02 / (1 + ((self.GAMMA - 1) * self.mach**2) / 2)
        self.p2 = self.p02 / ((1 + (
            (self.GAMMA - 1) * self.mach**2) / 2)**(self.GAMMA /
                                                    (self.GAMMA - 1)))

        self.eta_p = ((self.GAMMA - 1)/self.GAMMA)\
            * m.log(self.p2/self.p1)/m.log(self.t2/self.t1)
        self.eta_c = ((self.p02/self.p01)**(self.GAMMA/(self.GAMMA - 1)) - 1)\
            / (self.dt0/self.t01)
        self.pr = (1 + (self.dt0/self.t01))\
            ** (self.GAMMA*self.eta_p/(self.GAMMA-1))
        self.cp = (self.p2 - self.p1) / (self.p01 - self.p1)
        self.work = self.CP * self.dt0
        self.torque = self.work / (self.u / self.radius)
        self.capacity = self.GAMMA/m.sqrt(self.GAMMA - 1)*self.mach\
            * (1 + (self.GAMMA - 1)/2*self.mach**2)\
            ** (-(1/2)*(self.GAMMA + 1)/(self.GAMMA - 1))
Ejemplo n.º 2
0
    def redefine_task_cs(self, translate_x, translate_y, rotate_z):
        if not (translate_x == 0 and translate_y == 0 and rotate_z == 0):
            # calculate movement vector angle
            current_foot_pos_thorax = self.get_node("foot-thorax")
            odom_cs = self.cs.parent.parent  # leg->thorax->odom
            foot_pos_odom = odom_cs.to_this(current_foot_pos_thorax)
            moved_thorax_cs = self.cs.parent.get_derivative("tmp_thorax_for_tcs_vector", translate_x, translate_y, 0, 0, 0, rotate_z)
            new_foot_pos_thorax = moved_thorax_cs.to_this(foot_pos_odom, caller="redefine_task_cs")

            dx = new_foot_pos_thorax.x - current_foot_pos_thorax.x
            dy = new_foot_pos_thorax.y - current_foot_pos_thorax.y

            angle = d(atan2(dx, dy)) - 180

            home_pos = self.home_position_thorax

            self.task_cs.redefine_tuple(home_pos.tuple, (None, None, -angle))

            self.update_swings_inwards()
        else:
            self.swings_inwards = None
Ejemplo n.º 3
0
    def calc_joint_angles(self, target_position, best_effort):

        general_calculation = True

        position_leg_cs = self.cs.to_this(target_position)

        angle_coxa = -1 * d(atan2(position_leg_cs.x, position_leg_cs.y))
        femur_to_position_projection = 0

        femur_segment = self.segments["femur"]
        femur_length = femur_segment.length
        tibia_segment = self.segments["tibia"]
        tibia_length = tibia_segment.length
        tarsus_segment = self.segments["tarsus"]
        tarsus_length = tarsus_segment.length

        coxa_segment = self.segments["coxa"]

        if best_effort:
            tgt_tarsus = position_leg_cs.clone
            tgt_tarsus.z += tarsus_length

            femur = self.get_node("femur")

            # check if we can actually reach target_position
            distance = femur.distance_to(tgt_tarsus)

            max_dist = femur_length + tibia_length
            min_dist = third_side(femur_length, tibia_length, 180 + tibia_segment.min_angle)

            dz = femur.z - tgt_tarsus.z

            # are we too far?
            if distance > max_dist:
                # yep, too far
                # calculate femur angle to target
                femur_to_position_projection = sqrt(max_dist ** 2 - dz ** 2)
                general_calculation = False
            elif distance < min_dist:
                # we are too close
                femur_to_position_projection = sqrt(min_dist ** 2 - dz ** 2)
                general_calculation = False
            else:
                # we are not too close and not too far
                general_calculation = True

        if general_calculation:
            # works either when not best_effort or when best_effort and distance is ok
            coxa_to_position_projection = sqrt(position_leg_cs.x ** 2 + position_leg_cs.y ** 2)
            femur_to_position_projection = coxa_to_position_projection - coxa_segment.length

        distance_to_tarsus_top = sqrt(femur_to_position_projection ** 2 + (position_leg_cs.z + tarsus_length) ** 2)

        if position_leg_cs.z + tarsus_length == 0:
            angle_down_to_tarsus_top = 0
        else:
            angle_down_to_tarsus_top = 90 - angle_ab(-1 * (position_leg_cs.z + tarsus_length), distance_to_tarsus_top, femur_to_position_projection)

        angle_femur = angle_ab(femur_length, distance_to_tarsus_top, tibia_length) - angle_down_to_tarsus_top
        angle_tibia = -180 + angle_ac(femur_length, distance_to_tarsus_top, tibia_length)
        angle_tarsus = -180 + 90 - angle_femur - angle_tibia

        if coxa_segment.min_angle > angle_coxa:
            if best_effort:
                angle_coxa = coxa_segment.min_angle
            else:
                raise Exception(self.name + " coxa angle too low")
        elif coxa_segment.max_angle < angle_coxa:
            if best_effort:
                angle_coxa = coxa_segment.max_angle
            else:
                raise Exception(self.name + " coxa angle too high")

        if femur_segment.min_angle > angle_femur:
            if best_effort:
                angle_femur = femur_segment.min_angle
            else:
                raise Exception(self.name + " femur angle too low")
        elif femur_segment.max_angle < angle_femur:
            if best_effort:
                angle_femur = femur_segment.max_angle
            else:
                raise Exception(self.name + " femur angle too high")

        if tibia_segment.min_angle > angle_tibia:
            if best_effort:
                angle_tibia = tibia_segment.min_angle
            else:
                raise Exception(self.name + " tibia angle too low")
        elif tibia_segment.max_angle < angle_tibia:
            if best_effort:
                angle_tibia = tibia_segment.max_angle
            else:
                raise Exception(self.name + " tibia angle too high")

        if tarsus_segment.min_angle > angle_tarsus:
            if best_effort:
                angle_tarsus = tarsus_segment.min_angle
            else:
                raise Exception(self.name + " tarsus angle too low")
        elif tarsus_segment.max_angle < angle_tarsus:
            if best_effort:
                angle_tarsus = tarsus_segment.max_angle
            else:
                raise Exception(self.name + " tarsus angle too high")

        return angle_coxa, angle_femur, angle_tibia, angle_tarsus
Ejemplo n.º 4
0
def create_coord_file(filename: str,
                      plot: bool,
                      xc,
                      yc,
                      kc,
                      bc,
                      xt,
                      yt,
                      kt,
                      bt,
                      cle,
                      cte,
                      wte,
                      rle=0):  # pylint: disable=W0613
    """Generate airfoil coordinate file."""
    bp = {
        'x': {
            'LET': [0, 0, bt, xt],
            'TET': [
                xt, 2 * xt - bt,
                1 + (0 - (1.5 * kt * (xt - bt)**2 + yt)) * ut.cot(r(wte)), 1
            ],
            'LEC': [
                0, bc * ut.cot(r(cle)), xc - ((2 * (bc - yc)) / (3 * kc))**0.5,
                xc
            ],
            'TEC': [
                xc, xc + ((2 * (bc - yc)) / (3 * kc))**0.5,
                1 + (0 - bc) * ut.cot(r(cte)), 1
            ]
        },
        'y': {
            'LET': [0, (1.5 * kt * (xt - bt)**2 + yt), yt, yt],
            'TET': [yt, yt, (1.5 * kt * (xt - bt)**2 + yt), 0],
            'LEC': [0, bc, yc, yc],
            'TEC': [yc, yc, bc, 0]
        }
    }
    c = {'x': [], 'yC': [], 'yT': []}
    dc = {'xC': [], 'xT': [], 'yC': [], 'yT': []}

    # x, y coordinates and slopes for LE and TE of T and C bezier curves
    n_points = 80
    for i in range(0, n_points + 1):
        x = (1 - m.cos(i * m.pi / n_points)) / 2
        c['x'].append(x)
        for j in ['C', 'T']:
            if j == 'C':
                xmax = xc
            elif j == 'T':
                xmax = xt
            if x <= xmax:
                loc = 'LE'
                bp_xi = bp['x'][loc + j]
            elif x > xmax:
                loc = 'TE'
                bp_xi = bp['x'][loc + j]

            u_x = [
                -bp_xi[0] + 3 * bp_xi[1] - 3 * bp_xi[2] + bp_xi[3],
                3 * bp_xi[0] - 6 * bp_xi[1] + 3 * bp_xi[2],
                -3 * bp_xi[0] + 3 * bp_xi[1], bp_xi[0] - x
            ]
            u = [
                root.real for root in np.roots(u_x)
                if root.imag == 0 and 0 <= root <= (1 + 1 / (20 * n_points))
            ]
            u = u[0]
            c['y' + j].append(bp['y'][loc + j][0] * (1 - u)**3 +
                              3 * bp['y'][loc + j][1] * (u) * (1 - u)**2 +
                              3 * bp['y'][loc + j][2] * (u)**2 * (1 - u) +
                              bp['y'][loc + j][3] * (u)**3)
            for k in ['x', 'y']:
                dc[k +
                   j].append(bp[k][loc + j][0] * (-3 * (1 - u)**2) +
                             3 * bp[k][loc + j][1] * (3 * u**2 - 4 * u + 1) +
                             3 * bp[k][loc + j][2] * (-3 * u**2 + 2 * u) +
                             bp[k][loc + j][3] * (3 * u**2))

    theta = []
    xu = []
    yu = []
    xl = []
    yl = []
    lines = []
    for i in range(0, len(c['x'])):  # theta[0] is a divide by 0 error
        theta.append(d(m.atan(dc['yC'][i] / dc['xC'][i])))
        xu.append(c['x'][i] - c['yT'][i] * m.sin(r(theta[i])))
        yu.append(c['yC'][i] + c['yT'][i] * m.cos(r(theta[i])))
        xl.append(c['x'][i] + c['yT'][i] * m.sin(r(theta[i])))
        yl.append(c['yC'][i] - c['yT'][i] * m.cos(r(theta[i])))
        lines.append([(xu[i], yu[i]), (xl[i], yl[i])])

    # Organize coordinates so that xfoil can read them
    xcoord = list(reversed(xu))[:-1] + xl
    ycoord = list(reversed(yu))[:-1] + yl
    # Create airfoil file for xfoil
    os.chdir('Input')
    with open(filename, 'w') as datafile:
        for i, _ in enumerate(xcoord):
            datafile.write(f'     {xcoord[i]:.6f}    {ycoord[i]:.6f}\n')
    os.chdir('..')

    if plot:
        lc = mc.LineCollection(lines)
        _, ax = plt.subplots()
        ax.add_collection(lc)
        plt.scatter(c['x'], c['yC'], color='red', marker='^')
        plt.scatter(c['x'], c['yT'], color='blue', marker='^')
        plt.scatter(xu, yu, color='green')
        plt.scatter(xl, yl, color='green')
        plt.axis('equal')
        plt.show()
Ejemplo n.º 5
0
    def calcairfoil(self,
                    stage,
                    blade: str,
                    station: str,
                    plot_airfoil=False,
                    plot_ploar=False,
                    plot_cp=False,
                    plot_sv=False):
        """Calculate Bezier-PARSEC variables and airfoil properties."""
        avle, avte, rvle, rvte, v1, v2, radius = ut.get_vars(stage=stage,
                                                             blade=blade,
                                                             station=station)
        cx = v1 * m.cos(r(avle))
        u = stage.rpm / 60 * 2 * m.pi * radius
        betam = d(m.atan((m.tan(r(avle)) + m.tan(r(avte))) / 2))

        self.dh = v2 / v1
        self.space = (2 * m.pi * radius) / self.z
        # self.chord = stage.span/self.ar
        # self.sigma = self.chord/self.space
        # self.df = ((1 - m.cos(r(avle))/m.cos(r(avte)))
        #            + ((m.cos(r(avle))*(m.tan(r(avle)) - m.tan(r(avte))))
        #               / (2*self.sigma)))
        self.sigma = ((m.cos(r(avle)) * (m.tan(r(avle)) - m.tan(r(avte)))) /
                      (2 * (m.cos(r(avle)) / m.cos(r(avte)) - 1 + self.df)))
        self.chord = self.sigma * self.space

        # Incidence, deviation, and blade angle calculation
        self.deflection = abs(avle - avte)
        self.incidence, _n_slope = ut.calcincidence(thickness=2 * self.yt,
                                                    solidity=self.sigma,
                                                    relative_inlet_angle=rvle)
        self.deviation, _m_slope = ut.calcdeviation(thickness=2 * self.yt,
                                                    solidity=self.sigma,
                                                    relative_inlet_angle=rvle)
        self.blade_angle_i = avle - self.incidence
        self.blade_angle_e = avte - self.deviation
        self.camber = abs(self.blade_angle_i - self.blade_angle_e)
        # Compare to:
        # self.camber2 = (self.deflection
        #                 - (self.incidence
        #                    - self.deviation))/(1 - m_slope + n_slope)
        # self.blade_angle_e2 = self.blade_angle_i + self.camber2

        # Assumes double circular arc airfoil to estimate stagger
        self.stagger = (self.blade_angle_i * self.xcr + self.blade_angle_e *
                        (1 - self.xcr))
        self.aoa = abs(self.stagger - avle)
        # Redefine blade angles to sw blade angles (stagger independent)
        self.cle = self.blade_angle_i - self.stagger
        self.cte = self.stagger - self.blade_angle_e

        # Assume NACA 4 definition of wedge angle and leading edge radius
        self.rle = 1.1019 * (2 * self.yt)**2
        self.wte = 2 * d(m.atan(1.16925 *
                                (2 * self.yt)))  # TE radius done in sw

        # Calculate natural xc,yc from cle and cte using ycr altitutde ratio
        self.xc = m.tan(r(
            self.cte)) / (m.tan(r(self.cle)) + m.tan(r(self.cte)))
        # self.ycr = (self.xc + 1)/2
        self.yc = self.ycr * self.xc * abs(m.tan(r(self.cle)))

        # Assume NACA 4 curvature
        self.kc, self.kt = ut.curvatures(xc=self.xc,
                                         yc=self.yc,
                                         xt=self.xt,
                                         yt=self.yt)

        self.bc, self.bt = ut.beziers(xc=self.xc,
                                      yc=self.yc,
                                      kc=self.kc,
                                      xt=self.xt,
                                      yt=self.yt,
                                      kt=self.kt,
                                      cle=self.cle,
                                      cte=self.cte,
                                      rle=self.rle,
                                      blade=blade,
                                      station=station)
        airfoil_name = blade + '_' + station
        wf.create_coord_file(filename=airfoil_name,
                             plot=plot_airfoil,
                             xc=self.xc,
                             yc=self.yc,
                             kc=self.kc,
                             bc=self.bc,
                             xt=self.xt,
                             yt=self.yt,
                             kt=self.kt,
                             bt=self.bt,
                             cle=self.cle,
                             cte=self.cte,
                             wte=self.wte,
                             rle=self.rle)

        self.Re = self.rho * v1 * self.chord / self.mu
        self.polar = xf.find_coefficients(airfoil=airfoil_name,
                                          indir='Input',
                                          outdir='Output',
                                          alpha=self.aoa,
                                          Reynolds=self.Re,
                                          iteration=500,
                                          echo=False,
                                          delete=False,
                                          NACA=False,
                                          PANE=True)
        self.cp = xf.find_pressure_coefficients(airfoil=airfoil_name,
                                                alpha=self.aoa,
                                                indir='Input',
                                                outdir='Output',
                                                Reynolds=self.Re,
                                                iteration=500,
                                                echo=False,
                                                NACA=False,
                                                chord=1.,
                                                PANE=True,
                                                delete=False)
        self.sv = {'x': list(), 'y': list(), 'v': list()}
        for i in range(len(self.cp['Cp'])):
            self.sv['x'].append(self.cp['x'][i])
            # self.sv['y'].append(self.cp['y'][i])
            self.sv['v'].append(m.sqrt(1 - self.cp['Cp'][i]))

        if plot_cp:
            plt.plot(self.cp['x'], self.cp['Cp'])
            plt.show()

        if plot_sv:
            plt.plot(self.sv['x'], self.sv['v'])
            plt.show()

        if plot_ploar:
            # Gather multiple angles of attack for airfoil and get polars
            alphas = list(range(-30, 30))
            polars = xf.find_coefficients(airfoil=airfoil_name,
                                          alpha=alphas,
                                          Reynolds=self.Re,
                                          iteration=500,
                                          delete=True,
                                          echo=False,
                                          NACA=False,
                                          PANE=True)
            # Plot airfoil
            plt.plot(polars['alpha'], polars['CL'])
            plt.show()

        try:
            cl = self.polar['CL']
            cd = self.polar['CD']
            gamma = m.atan(cd / cl)
            self._psi = (((cx / u) / 2) * ut.sec(r(betam)) * self.sigma *
                         (cl + cd * m.tan(r(betam))))
            self.psi_opt = (((cx / u) / m.sqrt(2)) * self.sigma * (cl + cd))

            self.dX = ((self.rho * cx**2 * self.chord * cl /
                        (2 * m.cos(r(betam))**2)) * m.sin(r(betam) - gamma) /
                       m.cos(gamma))
            self.dTau = (
                (self.rho * cx**2 * self.chord * cl * self.z * radius /
                 (2 * m.cos(r(betam))**2)) * m.cos(r(betam) - gamma) /
                m.cos(gamma))
            self.delta_p = cl * ((self.rho * cx**2 * self.chord /
                                  (2 * self.space * m.cos(r(betam))**2)) *
                                 m.sin(r(betam) - gamma) / m.cos(gamma))
            self.delta_T = (cl / 1.005) * (
                (u * cx * self.chord / (2 * self.space * m.cos(r(betam))**2)) *
                m.cos(r(betam) - gamma) / m.cos(gamma))
            self.efficiency = (cx/u)*m.tan(r(betam) - gamma)\
                + cx*m.tan(r(rvte))/(2*u)
        except TypeError:
            print('Design point did not converge in xfoil.')
            # pass

        print(f'{station} {blade} Performance')
        print(f'    DF: {self.df:.2f} (<=0.6)')
        print(f'    DH: {self.dh:.2f} (>=0.72)')
        print(f'    i : {self.incidence:.2f} deg')
        print(f'    d : {self.deviation:.2f} deg')
        print('\n')
Ejemplo n.º 6
0
 def chk(x):
     nonlocal nums
     return sum([d(n/x) for n in nums])