def __init__(self):
        self.PI = 3.14159
        self.desiredState = np.zeros((12, 1))
        self.desiredState[0] = 3
        self.desiredState[1] = 5
        self.desiredState[2] = 10
        self.desiredState[8] = self.PI / 2

        WaypointGeneration = WaypointGen()
        self.waypoints, self.desVel, self.desAcc, self.timeVec = WaypointGeneration.waypoint_calculation(
        )
        self.desiredPos = WaypointGeneration.desiredPos
        self.desiredTimes = WaypointGeneration.desiredTimes
示例#2
0
    def __init__(self):
        self.mpcPublisher = rospy.Publisher("/hummingbird/command/motor_speed",
                                            Actuators,
                                            queue_size=1)

        self.receivedImuQuat = Quaternion()

        self.thrustConstant = 8.54858e-06
        self.momentConstant = 1.6e-2
        self.g = 9.81  # [m/s^2]
        self.m = 0.716  # [kg]
        Ixx = 0.007  # [kg*m^2]
        Iyy = 0.007  # [kg*m^2]
        Izz = 0.012  # [kg*m^2]
        gamma = self.thrustConstant / self.momentConstant
        dt = 0.1  # [sec]
        L = 0.17  # [m]
        # state update matrix
        self.A = np.array([[1, 0, 0, dt, 0, 0, 0, 0, 0, 0, 0, 0],
                           [0, 1, 0, 0, dt, 0, 0, 0, 0, 0, 0, 0],
                           [0, 0, 1, 0, 0, dt, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 1, 0, 0, 0, dt * self.g, 0, 0, 0, 0],
                           [0, 0, 0, 0, 1, 0, -dt * self.g, 0, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
                           [0, 0, 0, 0, 0, 0, 1, 0, 0, dt, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, dt, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, dt],
                           [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
                           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]])
        # input matrix
        self.B = np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
                           [0, 0, 0, 0], [0, 0, 0, 0], [dt / self.m, 0, 0, 0],
                           [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
                           [0, dt / Ixx, 0, 0], [0, 0, dt / Iyy, 0],
                           [0, 0, 0, dt / Izz]])
        # gravity component of input
        self.Bg = np.array([0, 0, 0, 0, 0, -self.g * dt, 0, 0, 0, 0, 0, 0])

        self.equilibriumInput = np.zeros((4))
        self.equilibriumInput[0] = self.m * self.g
        self.PI = 3.14159
        self.speedAllocationMatrix = np.array([[
            self.thrustConstant, self.thrustConstant, self.thrustConstant,
            self.thrustConstant
        ], [0, L * self.thrustConstant, 0, (-1) * L * self.thrustConstant],
                                               [(-1) * L * self.thrustConstant,
                                                0, L * self.thrustConstant, 0],
                                               [
                                                   self.momentConstant,
                                                   (-1) * self.momentConstant,
                                                   self.momentConstant,
                                                   (-1) * self.momentConstant
                                               ]])

        QMult = 1
        self.Q = QMult * np.eye(12)
        self.Q[2][2] = 500 / QMult
        self.R = 1000 * np.array([[1, 0, 0, 0], [0, 5, 0, 0], [0, 0, 5, 0],
                                  [0, 0, 0, 1]])

        self.Uinf = linalg.solve_discrete_are(self.A, self.B, self.Q, self.R,
                                              None, None)
        self.dlqrGain = np.dot(
            np.linalg.inv(self.R +
                          np.dot(self.B.T, np.dot(self.Uinf, self.B))),
            np.dot(self.B.T, np.dot(self.Uinf, self.A)))

        # time now subtracted by start time
        self.startTime = rospy.get_time()
        # generate the waypoints
        WaypointGeneration = WaypointGen()
        self.waypoints, self.desVel, self.desAcc, self.timeVec = WaypointGeneration.waypoint_calculation(
        )
        self.desiredPos = WaypointGeneration.desiredPos
        self.desiredTimes = WaypointGeneration.desiredTimes

        self.mpcHorizon = 2
        # number of inputs
        self.nu = 4
        # number of states
        self.nx = 12
        self.u = cv.Variable((self.nu, self.mpcHorizon))
        self.x = cv.Variable((self.nx, self.mpcHorizon + 1))

        # set up the MPC constraints
        D2R = self.PI / 180
        minVal, maxVal = self.find_min_max_waypoints()
        posTolerance = 0.5  # [m]
        angTolerance = 5 * D2R  # [rad]
        self.xmin = np.array(([
            minVal[0] - posTolerance, minVal[1] - posTolerance,
            minVal[2] - posTolerance, -np.Inf, -np.Inf, -np.Inf, -np.Inf,
            -np.Inf, minVal[3] - angTolerance, -np.Inf, -np.Inf, -np.Inf
        ]))
        self.xmax = np.array(([
            maxVal[0] + posTolerance, maxVal[1] + posTolerance,
            maxVal[2] + posTolerance, np.Inf, np.Inf, np.Inf, np.Inf, np.Inf,
            maxVal[3] + angTolerance, np.Inf, np.Inf, np.Inf
        ]))
        self.umin = np.array(([-self.m * self.g, -0.5, -0.5, -0.5]))
        self.umax = np.array(([1.5 * self.m * self.g, 0.5, 0.5, 0.5]))
    def __init__(self):
        self.dlqrPublisher = rospy.Publisher(
            "/hummingbird/command/motor_speed", Actuators, queue_size=1)

        self.receivedImuQuat = Quaternion()

        self.thrustConstant = 8.54858e-06
        self.momentConstant = 1.6e-2
        g = 9.81  # [m/s^2]
        m = 0.716  # [kg]
        Ixx = 0.007  # [kg*m^2]
        Iyy = 0.007  # [kg*m^2]
        Izz = 0.012  # [kg*m^2]
        gamma = self.thrustConstant / self.momentConstant
        dt = 0.01  # [sec]
        L = 0.17  # [m]
        # state update matrix
        A = np.array([[1, 0, 0, dt, 0, 0, 0, 0, 0, 0, 0, 0],
                      [0, 1, 0, 0, dt, 0, 0, 0, 0, 0, 0, 0],
                      [0, 0, 1, 0, 0, dt, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 1, 0, 0, 0, dt * g, 0, 0, 0, 0],
                      [0, 0, 0, 0, 1, 0, -dt * g, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 0, 1, 0, 0, dt, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, dt, 0],
                      [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, dt],
                      [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
                      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]])
        # input matrix
        B = np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
                      [0, 0, 0, 0], [dt / m, 0, 0, 0], [0, 0, 0, 0],
                      [0, 0, 0, 0], [0, 0, 0, 0], [0, dt / Ixx, 0, 0],
                      [0, 0, dt / Iyy, 0], [0, 0, 0, dt / Izz]])

        self.equilibriumInput = np.zeros((4, 1))
        self.equilibriumInput[0] = m * g
        self.PI = 3.14159
        self.speedAllocationMatrix = np.array([[
            self.thrustConstant, self.thrustConstant, self.thrustConstant,
            self.thrustConstant
        ], [0, L * self.thrustConstant, 0, (-1) * L * self.thrustConstant],
                                               [(-1) * L * self.thrustConstant,
                                                0, L * self.thrustConstant, 0],
                                               [
                                                   self.momentConstant,
                                                   (-1) * self.momentConstant,
                                                   self.momentConstant,
                                                   (-1) * self.momentConstant
                                               ]])

        QMult = 1
        Q = QMult * np.eye(12)
        Q[2][2] = 500 / QMult
        Q[8][8] = 10000 / QMult
        R = 1000 * np.array([[1, 0, 0, 0], [0, 5, 0, 0], [0, 0, 5, 0],
                             [0, 0, 0, 0.00001]])
        # R = 1000*np.array([[1, 0, 0, 0],
        #                   [0, 5, 0, 0],
        #                   [0, 0, 5, 0],
        #                   [0, 0, 0, 0.001]])
        Uinf = linalg.solve_discrete_are(A, B, Q, R, None, None)
        self.dlqrGain = np.dot(np.linalg.inv(R + np.dot(B.T, np.dot(Uinf, B))),
                               np.dot(B.T, np.dot(Uinf, A)))

        # time now subtracted by start time
        self.startTime = rospy.get_time()
        # generate the waypoints
        WaypointGeneration = WaypointGen()
        self.waypoints, self.desVel, self.desAcc, self.timeVec = WaypointGeneration.waypoint_calculation(
        )
        self.desiredPos = WaypointGeneration.desiredPos
        self.desiredTimes = WaypointGeneration.desiredTimes

        self.attitudeControlOnly = 0
        # deadbands [x-pos, y-pos, z-pos, yaw]
        self.waypointDeadband = np.array(([0.3, 0.3, 0.5, 1 * self.PI / 180]))
    def __init__(self):
        self.dlqrPublisher = rospy.Publisher(
            "/hummingbird/command/motor_speed", Actuators, queue_size=1)

        self.receivedImuQuat = Quaternion()

        self.thrustConstant = 8.54858e-06
        self.momentConstant = 1.6e-2
        g = 9.81  # [m/s^2]
        m = 0.716  # [kg]
        Ixx = 0.007  # [kg*m^2]
        Iyy = 0.007  # [kg*m^2]
        Izz = 0.012  # [kg*m^2]
        gamma = self.thrustConstant / self.momentConstant
        dt = 0.01  # [sec]
        L = 0.17  # [m]
        # state update matrix
        A = np.array([[1, 0, 0, dt, 0, 0, 0, 0, 0, 0, 0, 0],
                      [0, 1, 0, 0, dt, 0, 0, 0, 0, 0, 0, 0],
                      [0, 0, 1, 0, 0, dt, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 1, 0, 0, 0, dt * g, 0, 0, 0, 0],
                      [0, 0, 0, 0, 1, 0, -dt * g, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 0, 1, 0, 0, dt, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, dt, 0],
                      [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, dt],
                      [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
                      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
                      [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]])
        # input matrix
        B = np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
                      [0, 0, 0, 0], [dt / m, 0, 0, 0], [0, 0, 0, 0],
                      [0, 0, 0, 0], [0, 0, 0, 0], [0, dt / Ixx, 0, 0],
                      [0, 0, dt / Iyy, 0], [0, 0, 0, dt / Izz]])
        # output matrix
        C = np.array(([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
                       0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]))
        # enlarged state matrix with the error accumulation as a state
        Ag = np.vstack((np.hstack((A, np.zeros(
            (12, 2)))), np.hstack((C, np.eye(2)))))
        # enlarged input matrix with the error accumulation as a state
        Bg = np.vstack((B, np.zeros((2, 4))))

        self.equilibriumInput = np.zeros((4, 1))
        self.equilibriumInput[0] = m * g
        self.PI = 3.14159
        self.speedAllocationMatrix = np.array([[
            self.thrustConstant, self.thrustConstant, self.thrustConstant,
            self.thrustConstant
        ], [0, L * self.thrustConstant, 0, (-1) * L * self.thrustConstant],
                                               [(-1) * L * self.thrustConstant,
                                                0, L * self.thrustConstant, 0],
                                               [
                                                   self.momentConstant,
                                                   (-1) * self.momentConstant,
                                                   self.momentConstant,
                                                   (-1) * self.momentConstant
                                               ]])

        QMult = 1
        Q = QMult * np.eye(12)
        Q[2][2] = 500 / QMult
        Q[8][8] = 10000 / QMult
        # state cost with enlarged state vector
        Qint = np.eye(2)
        Qint[1][1] = 1
        Qg = block_diag(Q, Qint)
        R = 1000 * np.array([[1, 0, 0, 0], [0, 5, 0, 0], [0, 0, 5, 0],
                             [0, 0, 0, 0.000001]])
        # R = np.array([[1, 0, 0, 0],
        #               [0, 1, 0, 0],
        #               [0, 0, 1, 0],
        #               [0, 0, 0, 0.1]])
        UinfInt = linalg.solve_discrete_are(Ag, Bg, Qg, R, None, None)
        # gain matrix containing both the lqr gain and the integral gain
        self.combinedGainMatrix = np.dot(
            np.linalg.inv(R + np.dot(Bg.T, np.dot(UinfInt, Bg))),
            np.dot(Bg.T, np.dot(UinfInt, Ag)))
        self.dlqrGainInt = self.combinedGainMatrix[:, 0:12]
        print('LQR Gain With Integrator: ')
        print(self.dlqrGainInt)
        print('\n')
        self.integralGain = self.combinedGainMatrix[:, 12:20]
        print('Integral Gain: ')
        print(self.integralGain)
        print('\n')
        self.previousError = np.zeros((2, 1))

        Uinf = linalg.solve_discrete_are(A, B, Q, R, None, None)
        self.dlqrGain = np.dot(np.linalg.inv(R + np.dot(B.T, np.dot(Uinf, B))),
                               np.dot(B.T, np.dot(Uinf, A)))
        print('LQR Gain: ')
        print(self.dlqrGain)
        print('\n')

        # time now subtracted by start time
        self.startTime = rospy.get_time()
        # generate the waypoints
        WaypointGeneration = WaypointGen()
        self.waypoints, self.desVel, self.desAcc, self.timeVec = WaypointGeneration.waypoint_calculation(
        )
        self.desiredPos = WaypointGeneration.desiredPos
        self.desiredTimes = WaypointGeneration.desiredTimes

        # deadbands [x-pos, y-pos, z-pos, yaw]
        self.waypointDeadband = np.array(([0.5, 0.5, 0.5, 5 * self.PI / 180]))
        self.waypointEndAchieved = 0
        # error accumulation limits
        self.errorAccumLimit = np.array(([0.5, 1 * self.PI / 180]))
#!/usr/bin/env python3
from __future__ import print_function
from __future__ import division
import rospy
import rosbag
import numpy as np
import matplotlib.pyplot as plt
from waypoint_generation_library import WaypointGen
from scipy import linalg
from nav_msgs.msg import Odometry
from geometry_msgs.msg import Quaternion
from sensor_msgs.msg import Imu
from tf.transformations import euler_from_quaternion, quaternion_from_euler
from mpl_toolkits import mplot3d

WaypointGeneration = WaypointGen()
waypoints, desVel, desAcc, timeVec = WaypointGeneration.waypoint_calculation()
desiredPos = WaypointGeneration.desiredPos

# plot the waypoints    
figPos = plt.figure()
axPos = plt.axes(projection = '3d')
axPos.plot3D(desiredPos[:,0], desiredPos[:,1], desiredPos[:,2], 'ro')

pnt3d = axPos.scatter(waypoints[:,0], waypoints[:,1], waypoints[:,2], c = timeVec)
cbar = plt.colorbar(pnt3d)
cbar.set_label("Time [sec]")
# label the axes and give title
axPos.set_xlabel('X-Axis [m]')
axPos.set_ylabel('Y-Axis [m]')
axPos.set_zlabel('Z-Axis [m]')