Beispiel #1
0
def get_aircraft_name(aircraft, tixi):
    """
    Extract the aircraft name from CPACS and add it to the aircraft model

    Args:
        :aircraft: Aircraft model
        :tixi: Tixi handle
    """

    if tixi.checkElement(XPATHS.MODEL):
        aircraft_uid = parse_str(tixi.getTextAttribute(XPATHS.MODEL, 'uID'))
        logger.debug(f"Aircraft name: '{aircraft.uid}'")
    else:
        logger.warning(f"Could not find path '{XPATHS.MODEL}'")
        aircraft_uid = 'NAME_NOT_FOUND'

    aircraft.uid = aircraft_uid
Beispiel #2
0
def get_aircraft_wings(aircraft, settings, tixi, tigl):
    """
    Extract aircraft wings including airfoils and controls

    Args:
        :aircraft: Aircraft model
        :tixi: Tixi handle
        :tigl: Tigl handle
    """

    logger.info("Loading aircraft wings...")
    if not tixi.checkElement(XPATHS.WINGS):
        err_msg = f"""
        Could not find path '{XPATHS.WINGS}'.
        The aircraft must have at least one wing.
        """
        logger.error(err_msg)
        raise ValueError(err_msg)

    # ---------- Iterate through wings ----------
    num_wings = tixi.getNamedChildrenCount(XPATHS.WINGS, 'wing')
    for idx_wing in range(1, num_wings + 1):
        xpath_wing = XPATHS.WINGS + f"/wing[{idx_wing}]"

        try:
            wing_uid = parse_str(tixi.getTextAttribute(xpath_wing, 'uID'))
        except tixiwrapper.TixiException:
            wing_uid = f'WING{idx_wing:02}'

        logger.debug(f"Wing name: '{wing_uid}'")

        aircraft.add_wing(wing_uid)
        aircraft.wings[wing_uid].symmetry = tigl.wingGetSymmetry(idx_wing)

        # For each wing we set segment and control data
        get_aircraft_wing_segments(aircraft, settings, xpath_wing, wing_uid,
                                   idx_wing, tixi, tigl)
        get_aircraft_controls(aircraft, wing_uid, idx_wing, tixi, tigl)
Beispiel #3
0
def get_aircraft_airfoils(aircraft, settings, tigl, wing_uid, segment_uid,
                          idx_wing, idx_segment):
    """
    Extract the aircraft airfoils

    Args:
        :aircraft: Aircraft model
        :settings: Settings object
        :tigl: Tigl handle
        :segment_uid: Name of the segment
        :idx_wing: Index of the wing
        :idx_segment: Index of the segment
    """

    for position in ['inner', 'outer']:
        if position == 'inner':
            tigl_func = tigl.wingGetInnerSectionAndElementIndex
        else:
            tigl_func = tigl.wingGetOuterSectionAndElementIndex

        idx_section, idx_elem = tigl_func(idx_wing, idx_segment)
        name_airfoil = parse_str(
            tigl.wingGetProfileName(idx_wing, idx_section, idx_elem))
        if not name_airfoil:
            err_msg = f"""
            CPACS error: Could not extract {position} airfoil name
            * Wing: {idx_wing}
            * Segment: {idx_section}
            * Element: {idx_elem}
            """
            raise ValueError(err_msg)

        file_airfoil = join_paths(settings.paths('root'),
                                  PATHS.FILES.AIRFOIL(name_airfoil))
        aircraft.wings[wing_uid].segments[segment_uid].airfoils[
            position] = str(file_airfoil)
Beispiel #4
0
def write_airfoil_files(settings, tixi):
    """
    Extract airfoil data from CPACS and write airfoil files

    Args:
        :settings: Settings object
        :tixi: Tixi handle
    """

    logger.debug("Extracting airfoil data...")
    num_airfoils = tixi.getNumberOfChilds(XPATHS.AIRFOILS)
    for i in range(1, num_airfoils + 1):
        node_airfoil = XPATHS.AIRFOILS + f"/wingAirfoil[{i}]"
        node_data = node_airfoil + "/pointList"

        try:
            name_airfoil = parse_str(
                tixi.getTextElement(node_airfoil + '/name'))
        except tixiwrapper.TixiException:
            name_airfoil = f'AIRFOIL{i:02d}'

        file_airfoil = join_paths(settings.paths('root'),
                                  PATHS.FILES.AIRFOIL(name_airfoil))

        # Convert string to numpy array
        coords_x = np.fromstring(tixi.getTextElement(node_data + '/x'),
                                 sep=';')
        coords_z = np.fromstring(tixi.getTextElement(node_data + '/z'),
                                 sep=';')
        coords = np.transpose([coords_x, coords_z])

        logger.info(f"Copying airfoil {name_airfoil} to file...")
        np.savetxt(file_airfoil,
                   coords,
                   header=f"{name_airfoil}",
                   fmt=COORD_FORMAT)
Beispiel #5
0
def get_aircraft_wing_segments(aircraft, settings, xpath_wing, wing_uid,
                               idx_wing, tixi, tigl):
    """
    Extract a wing segment for a given wing

    Args:
        :aircraft: Aircraft model
        :settings: Settings object
        :xpath_wing: CPACS wing path
        :idx_wing: Wing index
        :tixi: Tixi handle
        :tigl: Tigl handle
    """

    xpath_segments = xpath_wing + '/segments'
    if not tixi.checkElement(xpath_segments):
        err_msg = f"Could not find path '{xpath_segments}'"
        logger.error(err_msg)
        raise ValueError(err_msg)

    logger.debug(f"Loading segments of wing '{wing_uid}'...")

    # ---------- Iterate through segments of given wing ----------
    num_segments = tixi.getNamedChildrenCount(xpath_segments, 'segment')
    for idx_segment in range(1, num_segments + 1):
        node_segment = xpath_segments + f"/segment[{idx_segment}]"

        try:
            segment_uid = parse_str(tixi.getTextAttribute(node_segment, 'uID'))
        except tixiwrapper.TixiException:
            segment_uid = f"{wing_uid}_SEGMENT{idx_segment:02}"

        logger.debug(f"Loading segment '{segment_uid}'...")

        aircraft.wings[wing_uid].add_segment(segment_uid)

        # Get the absolute segment vertices
        a = get_segment_mid_point(tigl, idx_wing, idx_segment, eta=0, xsi=0)
        b = get_segment_mid_point(tigl, idx_wing, idx_segment, eta=1, xsi=0)
        c = get_segment_mid_point(tigl, idx_wing, idx_segment, eta=1, xsi=1)
        d = get_segment_mid_point(tigl, idx_wing, idx_segment, eta=0, xsi=1)

        #########################################################################
        # TODO: Put this in "objects.aircraft!?"
        #########################################################################
        # Re-order vertices
        # * A, D should be at root and B, C at tip
        # * This is done so that the segments (thus panel normals point in the correct direction)
        if b[1] - a[1] < 0.0 or (b[1] == a[1] and b[2] - a[2] < 0.0):
            a, b, c, d = b, a, c, d
        if c[1] - d[1] < 0.0 or (c[1] == d[1] and c[2] - d[2] < 0.0):
            a, b, c, d = a, b, d, c
        if d[0] - a[0] < 0.0:
            a, b, c, d = d, b, c, a
        if c[0] - b[0] < 0.0:
            a, b, c, d = a, c, b, d
        #########################################################################
        #########################################################################
        #########################################################################

        aircraft.wings[wing_uid].segments[segment_uid].vertices['a'] = a
        aircraft.wings[wing_uid].segments[segment_uid].vertices['b'] = b
        aircraft.wings[wing_uid].segments[segment_uid].vertices['c'] = c
        aircraft.wings[wing_uid].segments[segment_uid].vertices['d'] = d

        # ----- Set airfoils -----
        get_aircraft_airfoils(aircraft, settings, tigl, wing_uid, segment_uid,
                              idx_wing, idx_segment)