示例#1
0
    def followWpp(self, w, p, newpath):
        """
        followWpp implements waypoint following via connected straight-line
        paths.

        Inputs:
            w = 3xn matrix of waypoints in NED (m)
            p = position of MAV in NED (m)
            newpath = flag to initialize the algorithm or define new waypoints

        Outputs
            r = origin of straight-line path in NED (m)
            q = direction of straight-line path in NED (m)

        Example Usage;
            r, q = followWpp(w, p, newpath)

        Reference: Beard, Small Unmanned Aircraft, Chapter 11, Algorithm 5
        Copyright 2018 Utah State University
        """

        if self.i is None:
            self.i = 0

        if newpath:
            # initialize index
            self.i = 1

        # check sizes
        m, N = w.shape
        assert N >= 3
        assert m == 3

        # calculate the q vector
        r = w[:, self.i - 1]
        qi1 = s_norm(w[:, self.i], -w[:, self.i - 1])

        # Calculate the origin of the current path
        qi = s_norm(w[:, self.i + 1], -w[:, self.i])

        # Calculate the unit normal to define the half plane
        ni = s_norm(qi1, qi)

        # Check if the MAV has crossed the half-plane
        if in_half_plane(p, w[:, self.i], ni):
            if self.i < (N - 2):
                self.i += 1
        q = qi1

        return r, q
示例#2
0
    def followWppDubins(self, W, Chi, p, R, newpath):
        """
        followWppDubins implements waypoint following via Dubins paths

        Inputs:
            W = list of waypoints in NED (m)
            Chi = list of course angles at waypoints in NED (rad)
            p = mav position in NED (m)
            R = fillet radius (m)
            newpath = flag to initialize the algorithm or define new waypoints

        Outputs
            flag = flag for straight line path (1) or orbit (2)
            r = origin of straight-line path in NED (m)
            q = direction of straight-line path in NED (m)
            c = center of orbit in NED (m)
            rho = radius of orbit (m)
            lamb = direction or orbit, 1 clockwise, -1 counter clockwise
            self.i = waypoint number
            dp = dubins path parameters

        Example Usage
            flag, r, q, c, rho, lamb = followWppDubins(W, Chi, p, R, newpath)

        Reference: Beard, Small Unmanned Aircraft, Chapter 11, Algorithm 8
        Copyright 2018 Utah State University
        """

        # TODO Algorithm 8 goes here
        # state = 0
        if not self.i:  # checks if i is empty
            self.i = 0
            self.state = 0
        if newpath:
            self.i = 1
            self.state = 1
            m, N = W.shape
            assert N >= 3
            assert m == 3
        else:
            m, N = W.shape
            assert N >= 3
            assert m == 3
        dp = self.findDubinsParameters(W[:, self.i - 1], Chi[self.i - 1, :],
                                       W[:, self.i], Chi[self.i, :], R)
        if self.state == 1:
            # Follow start orbit until on the correct side of H1
            flag = 2
            c = dp.c_s
            rho = R
            lamb = dp.lamb_s
            r = np.empty((3, 1))
            r[:] = np.nan
            q = np.empty((3, 1))
            q[:] = np.nan
            if in_half_plane(p, dp.z_1, -dp.q_12):
                self.state = 2
        elif self.state == 2:
            # Continue following the start orbit until in H1
            flag = 2
            c = dp.c_s
            rho = R
            lamb = dp.lamb_s
            r = np.empty((3, 1))
            r[:] = np.nan  # if nothing else works, tryo to put 'zeros' in place of 'nan'
            q = np.empty((3, 1))
            q[:] = np.nan
            if in_half_plane(p, dp.z_1, dp.q_12):
                self.state = 3
        elif self.state == 3:
            # Transition to straight-line path until in H2
            flag = 1
            r = dp.z_1
            q = dp.q_12
            c = np.empty((3, 1))
            c[:] = np.nan
            rho = np.nan
            lamb = np.nan
            if in_half_plane(p, dp.z_2, dp.q_12):
                self.state = 4
        elif self.state == 4:
            flag = 2
            c = dp.c_e
            rho = R
            lamb = dp.lamb_e
            r = np.empty((3, 1))
            r[:] = np.nan
            q = np.empty((3, 1))
            q[:] = np.nan
            if in_half_plane(p, dp.z_3, -dp.q_3):
                self.state = 5
        else:  # state == 5
            # Continue following the end orbit until in H3
            flag = 2
            c = dp.c_e
            rho = R
            lamb = dp.lamb_e
            r = np.empty((3, 1))
            r[:] = np.nan
            q = np.empty((3, 1))
            q[:] = np.nan
            if in_half_plane(p, dp.z_3, dp.q_3):
                self.state = 1
                self.i = self.i + 1
                if self.i >= N:
                    self.i = N

        return flag, r, q, c, rho, lamb, self.i, dp
示例#3
0
    def followWppFillet(self, w, p, R, newpath):
        """
        followWppFillet implements waypoint following via straightline paths
        connected by fillets

        Inputs:
            W = 3xn matrix of waypoints in NED (m)
            p = position of MAV in NED (m)
            R = fillet radius (m)
            newpath = flag to initialize the algorithm or define new waypoints

        Outputs
            flag = flag for straight line path (1) or orbit (2)
            r = origin of straight-line path in NED (m)
            q = direction of straight-line path in NED (m)
            c = center of orbit in NED (m)
            rho = radius of orbit (m)
            lamb = direction or orbit, 1 clockwise, -1 counter clockwise

        Example Usage
            [flag, r, q, c, rho, lamb] = followWppFillet( w, p, R, newpath )

        Reference: Beard, Small Unmanned Aircraft, Chapter 11, Algorithm 6
        Copyright 2018 Utah State University
        """

        if self.i is None:
            self.i = 0
            self.state = 0
        if newpath:
            # Initialize the waypoint index
            self.i = 2
            self.state = 1

            # Check size of waypoints matrix
            m, N = W.shape  # Where 'N' is the number of waypoints and 'm' dimensions
            assert N >= 3
            assert m == 3
        else:
            [m, N] = W.shape
            assert N >= 3
            assert m == 3
        # Calculate the q vector and fillet angle
        qi1 = mat(s_norm(w[:, self.i], -w[:, self.i - 1]))
        qi = mat(s_norm(w[:, self.i + 1], -w[:, self.i]))
        e = acos(-qi1.T * qi)

        # Determine if the MAV is on a straight or orbit path
        if self.state == 1:
            c = mat([0, 0, 0]).T
            rho = 0
            lamb = 0

            flag = 1
            r = w[:, self.i - 1]
            q = q1
            z = w[:, self.i] - (R / (np.tan(e / 2))) * qi1
            if in_half_plane(p, z, qi1):
                self.state = 2

        elif self.state == 2:
            r = [0, 0, 0]
            q = [0, 0, 0]

            flag = 2
            c = w[:, self.i] - (R / (np.sin(e / 2))) * s_norm(qi1, -qi)
            rho = R
            lamb = np.sign(qi1(1) * qi(2) - qi1(2) * qi(1))
            z = w[:, self.i] + (R / (np.tan(e / 2))) * qi

            if in_half_plane(p, z, qi):
                if self.i < (N - 1):
                    self.i = self.i + 1
                self.state = 1

        else:
            # Fly north as default
            flag = -1
            r = p
            q = mat([1, 0, 0]).T
            c = np.nan(3, 1)
            rho = np.nan
            lamb = np.nan

        return flag, r, q, c, rho, lamb
示例#4
0
    def pathFollower(self, flag, r, q, p, chi, chi_inf, k_path, c, rho, lamb,
                     k_orbit):
        """
        Input:
            flag = 1 for straight line, 2 for orbit
            r = origin of straight-line path in NED (m)
            q = direction of straight-line path in NED (m)
            p = current position of uav in NED (m)
            chi = course angle of UAV (rad)
            chi_inf = straight line path following parameter
            k_path = straight line path following parameter
            c = center of orbit in NED (m)
            rho = radius of orbit (m)
            lamb = direction of orbit, 1 clockwise, -1 counter-clockwise
            k_orbit = orbit path following parameter

        Outputs:
            e_crosstrack = crosstrack error (m)
            chi_c = commanded course angle (rad)
            h_c = commanded altitude (m)

        Example Usage
            e_crosstrack, chi_c, h_c = pathFollower(path)

        Reference: Beard, Small Unmanned Aircraft, Chapter 10, Algorithms 3 and 4
        Copyright 2018 Utah State University
        """

        # Unpackaging variables
        r_n = r[0][0]
        r_e = r[1][0]
        r_d = r[2][0]
        p_n = p[0][0]
        p_e = p[1][0]
        p_d = p[2][0]
        k_i = np.array([0, 0, 1])
        e_i_p = np.array([[p_n - r_n], [p_e - r_e], [p_d - r_d]])  # 3x1
        normal = (np.cross(q.T, k_i) /
                  (np.linalg.norm(np.cross(q.T, k_i)))).T  # 3x1
        s_i = np.subtract(e_i_p, (np.dot(e_i_p.T, normal) * normal))  # 3x1
        s_n = s_i[0]
        s_e = s_i[1]
        # s_d =
        q_n = q[0]
        q_e = q[1]
        q_d = q[2]
        chi_q = np.arctan2(q_e, q_n)
        chi = chi

        c_n = c[0][0]
        c_e = c[1][0]
        c_d = c[2][0]
        lamb = lamb
        k_orbit = 3.6
        rho = 55

        if flag == 1:  # straight line
            pass
            # TODO Algorithm 3 goes here
            h_d = -r_d + np.sqrt(s_n**2 + s_e**2) * (
                q_d / np.sqrt(q_n**2 + q_e**2))  #equation 10.5
            chi_q = np.arctan2(q_e, q_n)
            while (chi_q - chi) < -np.pi:
                chi_q = chi_q + 2 * np.pi
            while (chi_q - chi) > np.pi:
                chi_q = chi_q - 2 * np.pi
            e_py = -np.sin(chi_q) * (p_n - r_n) + np.cos(chi_q) * (p_e - r_e)
            e_crosstrack = e_py
            chi_c = chi_q - chi_inf * 2 / np.pi * np.arctan(k_path * e_py)
            h_c = h_d
        elif flag == 2:  # orbit following
            pass
            # TODO Algorithm 4 goes here
            h_c = -c_d
            d = np.sqrt((p_n - c_n)**2 + (p_e - c_e)**2)
            psi = np.arctan2(p_e - c_e, p_n - c_n)
            while (psi - chi) < -np.pi:
                psi = psi + 2 * np.pi
            while (psi - chi) > np.pi:
                psi = psi - 2 * np.pi
            chi_c = 0.6 + psi + lamb * (np.pi / 2 + np.arctan(k_orbit * (
                (d - rho) / rho)))
            e_crosstrack = d - rho
        else:
            raise Exception("Invalid path type")

        return e_crosstrack, chi_c, h_c

        # followWpp algorithm left here for reference
        # It is not used in the final implementation
        #     def followWpp(self, w, p, newpath):
        """
        followWpp implements waypoint following via connected straight-line
        paths.

        Inputs:
            w = 3xn matrix of waypoints in NED (m)
            p = position of MAV in NED (m)
            newpath = flag to initialize the algorithm or define new waypoints

        Outputs
            r = origin of straight-line path in NED (m)
            q = direction of straight-line path in NED (m)

        Example Usage;
            r, q = followWpp(w, p, newpath)

        Reference: Beard, Small Unmanned Aircraft, Chapter 11, Algorithm 5
        Copyright 2018 Utah State University
        """

        if self.i is None:
            self.i = 0

        if newpath:
            # initialize index
            self.i = 1

        # check sizes
        m, N = W.shape
        assert N >= 3
        assert m == 3

        # calculate the q vector
        r = w[:, self.i - 1]
        qi1 = s_norm(w[:, self.i], -w[:, self.i - 1])

        # Calculate the origin of the current path
        qi = s_norm(w[:, self.i + 1], -w[:, self.i])

        # Calculate the unit normal to define the half plane
        ni = s_norm(qi1, qi)

        # Check if the MAV has crossed the half-plane
        if in_half_plane(p, w[:, self.i], ni):
            if self.i < (N - 2):
                self.i += 1
        q = qi1
        return r, q
示例#5
0
    def followWppDubins(self, W, Chi, p, R, newpath):
        """
        followWppDubins implements waypoint following via Dubins paths

        Inputs:
            W = list of waypoints in NED (m)
            Chi = list of course angles at waypoints in NED (rad)
            p = mav position in NED (m)
            R = fillet radius (m)
            newpath = flag to initialize the algorithm or define new waypoints

        Outputs
            flag = flag for straight line path (1) or orbit (2)
            r = origin of straight-line path in NED (m)
            q = direction of straight-line path in NED (m)
            c = center of orbit in NED (m)
            rho = radius of orbit (m)
            lamb = direction or orbit, 1 clockwise, -1 counter clockwise
            self.i = waypoint number
            dp = dubins path parameters

        Example Usage
            flag, r, q, c, rho, lamb = followWppDubins(W, Chi, p, R, newpath)

        Reference: Beard, Small Unmanned Aircraft, Chapter 11, Algorithm 8
        Copyright 2018 Utah State University
        """

        if self.i is None:
            self.i = 0
            self.state = 0
        if newpath:
            # Initialize the waypoint index
            self.i = 1
            self.state = 1

            # Check size of waypoints matrix
            m, N = W.shape  # 'N' is number of waypoints and 'm' dimensions
            assert N >= 3
            assert m == 3
        else:
            [m, N] = W.shape
            assert N >= 3
            assert m == 3

        #print("Calculating Start Position...")
        # Determine the Dubins path parameters
        p_s = mat([[W[0, self.i - 1]], [W[1, self.i - 1]], [W[2,
                                                              self.i - 1]]]).T
        #print("Calculating Start Attitude...")
        chi_s = Chi[self.i - 1],
        #print("Calculating End Position...")
        p_e = mat([[W[0, self.i]], [W[1, self.i]], [W[2, self.i]]]).T
        #print("Calculating End Attitude...")
        chi_e = Chi[self.i]
        #print("W = ", W)

        #print("Finding Dubins Parameters...\n")
        dp = self.findDubinsParameters(p_s, chi_s, p_e, chi_e, R)
        #print("Dubins Parameters found\n")

        r = mat([[0], [0], [0]]).T
        q = mat([[0], [0], [0]]).T
        c = mat([[0], [0], [0]]).T
        rho = 0
        lamb = 0

        print("state = ", self.state)

        # ... Follow start orbit until on the correct side of H1
        if self.state == 1:
            flag = 2
            c = dp.c_s
            rho = R
            lamb = dp.lamb_s
            if in_half_plane(p, dp.z_1, -dp.q_1):
                self.state = 2

        # ... Continue following the start orbit until in H1
        elif self.state == 2:
            flag = 2
            c = dp.c_s
            rho = R
            lamb = dp.lamb_s
            if in_half_plane(p, dp.z_1, dp.q_1):
                self.state = 3

        # ... Transition to straight-line path until H2
        elif self.state == 3:
            flag = 1
            r = dp.z_1
            q = dp.q_1
            if in_half_plane(p, dp.z_2, dp.q_1):
                self.state = 4

        # ... Follow the end orbit until on the correct side of H3
        elif self.state == 4:
            flag = 2
            c = dp.c_e
            rho = R
            lamb = dp.lamb_e
            if in_half_plane(p, dp.z_3, -dp.q_3):
                self.state = 5

        # state = 5
        else:
            flag = 2
            c = dp.c_e
            rho = R
            lamb = dp.lamb_e
            # ... Continue following the end oribit until in H3
            if in_half_plane(p, dp.z_3, dp.q_3):
                self.state = 1
                if (self.i < N):
                    self.i = self.i + 1
                dp = self.findDubinsParameters(p_s, chi_s, p_e, chi_e, R)

        return flag, r, q, c, rho, lamb, self.i, dp