def get_urdf_parameters(urdf_file, base_elements=None, last_link_vector=None, base_element_type="link"):
    """
    Returns translated parameters from the given URDF file

    Parameters
    ----------
    urdf_file: str
        The path of the URDF file
    base_elements: list of strings
        List of the links beginning the chain
    last_link_vector: numpy.array
        Optional : The translation vector of the tip.
    base_element_type: str

    Returns
    -------
    list[ikpy.link.URDFLink]
    """
    tree = ET.parse(urdf_file)
    root = tree.getroot()
    base_elements = list(base_elements)
    if base_elements is None:
        base_elements = ["base_link"]
    elif base_elements is []:
        raise ValueError("base_elements can't be the empty list []")

    joints = []
    links = []
    has_next = True
    current_joint = None
    current_link = None

    # Initialize the tree traversal
    if base_element_type == "link":
        # The first element is a link, so its (virtual) parent should be a joint
        node_type = "joint"
    elif base_element_type == "joint":
        # The same as before, but swap link and joint
        node_type = "link"
    else:
        raise ValueError("Unknown type: {}".format(base_element_type))

    # Parcours récursif de la structure de la chain
    while has_next:
        if len(base_elements) != 0:
            next_element = base_elements.pop(0)
        else:
            next_element = None

        if node_type == "link":
            # Current element is a link, find child joint
            (has_next, current_joint) = find_next_joint(root, current_link, next_element)
            node_type = "joint"
            if has_next:
                joints.append(current_joint)

        elif node_type == "joint":
            # Current element is a joint, find child link
            (has_next, current_link) = find_next_link(root, current_joint, next_element)
            node_type = "link"
            if has_next:
                links.append(current_link)

    parameters = []

    # Save the joints in the good format
    for joint in joints:
        translation = [0, 0, 0]
        orientation = [0, 0, 0]
        rotation = [1, 0, 0]
        bounds = [None, None]

        origin = joint.find("origin")
        if origin is not None:
            if origin.attrib["xyz"]:
                translation = [float(x) for x in origin.attrib["xyz"].split()]
            if origin.attrib["rpy"]:
                orientation = [float(x) for x in origin.attrib["rpy"].split()]

        axis = joint.find("axis")
        if axis is not None:
            rotation = [float(x) for x in axis.attrib["xyz"].split()]

        limit = joint.find("limit")
        if limit is not None:
            if limit.attrib["lower"]:
                bounds[0] = float(limit.attrib["lower"])
            if limit.attrib["upper"]:
                bounds[1] = float(limit.attrib["upper"])

        parameters.append(lib_link.URDFLink(
            name=joint.attrib["name"],
            bounds=tuple(bounds),
            translation_vector=translation,
            orientation=orientation,
            rotation=rotation,
        ))

    # Add last_link_vector to parameters
    if last_link_vector is not None:
        parameters.append(lib_link.URDFLink(
            translation_vector=last_link_vector,
            orientation=[0, 0, 0],
            rotation=[1, 0, 0],
            name="last_joint"
        ))

    return parameters
Returns translated parameters from the given URDF file

    Parameters
    ----------
    urdf_file: str
        The path of the URDF file
    base_elements: list of strings
        List of the links beginning the chain
    last_link_vector: numpy.array
        Optional : The translation vector of the tip.
    base_element_type: str

    Returns
    -------
    list[ikpy.link.URDFLink]