Beispiel #1
0
    def publish_thrust(self, thrust):

        # create single message
        thrust_msg = RateThrust()
        thrust_msg.thrust.z = thrust
        self.input_publisher.publish(thrust_msg)
        rospy.loginfo(thrust_msg)
        rospy.loginfo("Published body vertical thrust: {}".format(thrust))
Beispiel #2
0
 def step(self, action):
     [thrustd, dphi, dtheta, dpsi] = action
     new_ctrl = RateThrust()
     new_ctrl.angular_rates.x = dphi
     new_ctrl.angular_rates.y = dtheta
     new_ctrl.angular_rates.z = dpsi
     new_ctrl.thrust.z = thrustd
     self.ctrl_pub.publish(new_ctrl)
Beispiel #3
0
    def callback(self, msg):
        rt_msg = RateThrust()
        t = np.array([msg.ua.x, msg.ua.y, msg.ua.z + 9.81])
        norm = np.linalg.norm(t)
        rt_msg.thrust.z = norm

        rt_msg.angular_rates.x = msg.twist.angular.x
        rt_msg.angular_rates.y = msg.twist.angular.y
        rt_msg.angular_rates.z = msg.twist.angular.z
        self.thrust_publisher.publish(rt_msg)
Beispiel #4
0
def handle_output_path(req):
    print("returning path instructions")
    msg = RateThrust()
    msg.header.frame_id = "uav/imu"
    msg.header.stamp = Time.now()
    msg.thrust.z = self.idleThrust + 1
    msg.angular_rates.x = 0.05
    msg.angular_rates.y = 0.05
    msg.angular_rates.z = 0.05
    return OutputPathsResponse(msg)
Beispiel #5
0
 def controlCommandCallback(self, msg):
     print(msg.expected_execution_time.to_sec() - rospy.Time.now().to_sec())
     rateThrustCommand = RateThrust()
     rateThrustCommand.header.stamp = rospy.Time.now()
     rateThrustCommand.angular_rates.x = msg.bodyrates.x
     rateThrustCommand.angular_rates.y = msg.bodyrates.y
     rateThrustCommand.angular_rates.z = msg.bodyrates.z
     rateThrustCommand.thrust.x = 0
     rateThrustCommand.thrust.y = 0
     rateThrustCommand.thrust.z = msg.collective_thrust
     self.bodyRatesCommandPub.publish(rateThrustCommand)
 def publish_thrust(self, thrust):
     """
     @description publish thrust values to 'wake up' flightgoggles 
     simulator. It assumes flightgoggles simulator is running
     """
     # create single message
     thrust_msg = RateThrust()
     thrust_msg.thrust.z = thrust
     self.fg_publisher.publish(thrust_msg)
     rospy.loginfo(thrust_msg)
     rospy.loginfo("Published body vertical thrust: {}".format(thrust))
Beispiel #7
0
 def command(self, c, omega):
     omega_x = float(omega[0]) / self.max_omega
     omega_y = float(omega[1]) / self.max_omega
     omega_z = float(omega[2]) / self.max_omega
     msg = RateThrust()
     msg.thrust.x = 0
     msg.thrust.y = 0
     msg.thrust.z = c
     msg.angular_rates.x = omega_x
     msg.angular_rates.y = omega_y
     msg.angular_rates.z = omega_z
     self.rate_thrust_publisher.publish(msg)
def Publish_rateThrust(Thrust,roll_rate,pitch_rate,yaw_rate):
    rate_data=RateThrust()
      
    rate_data.header.stamp = rospy.Time.now()
    rate_data.header.frame_id = "uav/imu"
    rate_data.angular_rates.x=np.float64(roll_rate)
    rate_data.angular_rates.y=np.float64(pitch_rate)
    rate_data.angular_rates.z=np.float64(yaw_rate)
    rate_data.thrust.x=np.float64(0.0)
    rate_data.thrust.x=np.float64(0.0)
    rate_data.thrust.z=np.float64(Thrust)
    
    pub.publish(rate_data)
    def callback(self, range, rate_thrust, pid_z, pid_roll, pid_pitch,
                 pid_yaw):
        print(range.range)
        if range.range >= -1.0:
            msg = RateThrust()
            msg.header.frame_id = "uav/imu"
            msg.header.stamp = Time.now()
            msg.thrust.z = self.idle_thrust + 1
            msg.angular_rates.x = 0
            msg.angular_rates.y = 0
            msg.angular_rates.z = 0

            self.pub_vel.publish(msg)
        else:
            print("Its here")
            msg = RateThrust()
            msg.header.frame_id = "uav/imu"
            msg.header.stamp = Time.now()
            msg.thrust.z = rate_thrust.thrust.z - pid_z.data
            msg.angular_rates.x = rate_thrust.angular_rates.x - pid_roll.data
            msg.angular_rates.y = rate_thrust.angular_rates.y - pid_pitch.data
            msg.angular_rates.z = rate_thrust.angular_rates.z - pid_yaw.data

            self.pub_vel.publish(msg)
    def __init__(self):
        self.beginning_time = rospy.get_time()
        self.idle_thrust = float(9.81)

        self.path_sub = message_filters.Subscriber(
            '/pathplanning/input/rateThrust', RateThrust)
        self.ratethrust_z_sub = message_filters.Subscriber(
            "/rateThrustZ/control_effort", Float64)
        self.ratethrust_roll_sub = message_filters.Subscriber(
            "/rateThrustPitch/control_effort", Float64)
        self.ratethrust_pitch_sub = message_filters.Subscriber(
            "/rateThrustRoll/control_effort", Float64)
        self.ratethrust_yaw_sub = message_filters.Subscriber(
            "/rateThrustYaw/control_effort", Float64)
        self.ratethrust_height_sub = message_filters.Subscriber(
            "/rateThrustYaw/control_effort", Float64)

        self.pub_vel = rospy.Publisher('output/rateThrust',
                                       RateThrust,
                                       queue_size=2)

        ts = message_filters.ApproximateTimeSynchronizer([
            self.ratethrust_height_sub, self.path_sub, self.ratethrust_z_sub,
            self.ratethrust_roll_sub, self.ratethrust_pitch_sub,
            self.ratethrust_yaw_sub
        ],
                                                         10,
                                                         0.1,
                                                         allow_headerless=True)
        ts.registerCallback(self.callback)

        time_to_start = 0.5
        d = rospy.Duration(time_to_start, 0)
        now = rospy.get_rostime()
        end_time = d + now

        msg = RateThrust()
        msg.header.frame_id = "uav/imu"
        msg.header.stamp = Time.now()
        msg.thrust.z = self.idle_thrust + 0.1
        msg.angular_rates.x = 0
        msg.angular_rates.y = 0
        msg.angular_rates.z = 0

        while rospy.get_rostime() < end_time:
            print("ITS STARTING")
            self.pub_vel.publish(msg)
    def __init__(self):
        rospy.init_node('robot_controller', anonymous=True)
        self.local_deg_pub = rospy.Publisher('/uav/input/rateThrust',
                                             RateThrust,
                                             queue_size=10)
        self.reset_pub = rospy.Publisher('/uav/collision', Empty, queue_size=1)
        self.tf_pos_sub = rospy.Subscriber('/tf', TFMessage, self.tf_callback)
        self.joy_sub = rospy.Subscriber('/control_nodes/joy', Joy,
                                        self.joy_callback)

        self.rate = rospy.Rate(30)

        self.pose = TFMessage()
        self.deg = RateThrust()
        self.joy = Joy()
        self.reset = Empty()
        self.mode = 2  #default is mode 2
    def callback(self,data):

        rt_msg = RateThrust()
        rt_msg.header.stamp = rospy.Time.now()
        rt_msg.header.frame_id = 'uav/imu'

        rt_msg.angular_rates.x = 0.0
        rt_msg.angular_rates.y = 0.0
        rt_msg.angular_rates.z = 0.0

        rt_msg.thrust.x = 0.0
        rt_msg.thrust.y = 0.0
        rt_msg.thrust.z = 9.9
        self.rt_publisher.publish(rt_msg)

        #rospy.loginfo("Published rateThrust message :) !")
        rospy.loginfo(rt_msg)
 def crash_vehicle(self):
     self.crashFlag = False
     while 1:
         if self.loc_flag:
             print self.get_dist_to_gate()
         target_rate_thrust = RateThrust()
         target_rate_thrust.header.frame_id = "home"
         target_rate_thrust.header.stamp = rospy.Time.now()
         target_rate_thrust.angular_rates.x = 1
         target_rate_thrust.angular_rates.y = 0
         target_rate_thrust.angular_rates.z = 0
         target_rate_thrust.thrust.z = 10.5
         self.rate_thrust_pub.publish(target_rate_thrust)
         if self.crashFlag:
             break
         self.rate.sleep()
     self.crashFlag = False
     print 'crashed'
Beispiel #14
0
    def ControlLoop(self):
        # Set the rate
        rate = rospy.Rate(50)

        # Keep track how many loops have happend
        loop_counter = 0

        # While running
        while not rospy.is_shutdown():

            # Create the message we are going to send
            msg = RateThrust()
            msg.header.stamp = rospy.get_rostime()

            # If the drone has not been armed
            if self.armed == False:

                # Arm the drone
                msg.thrust = Vector3(0, 0, 10)
                msg.angular_rates = Vector3(0, 0, 0)
                self.armed = True

            # Behave normally
            else:
                # Use a PID to calculate the rates you want to publish to maintain an angle
                roll_output = self.rollPID.get_output(self.roll_setpoint,
                                                      self.roll_reading)
                pitch_output = self.pitchPID.get_output(
                    self.pitch_setpoint, self.pitch_reading)
                if self.no_yaw:
                    yaw_output = self.yaw_output
                    #rospy.loginfo("my output: " + str(yaw_output) + " old yaw:" + str(self.yawPID.get_output(self.yaw_setpoint, self.yaw_reading)))

                else:
                    yaw_output = self.yawPID.get_output(
                        self.yaw_setpoint, self.yaw_reading)

                # Create the message
                msg.thrust = Vector3(0, 0, self.thrust_setpoint)
                msg.angular_rates = Vector3(roll_output, pitch_output,
                                            yaw_output)

            # Publish the message
            self.rate_pub.publish(msg)

            # Sleep any excess time
            rate.sleep()
 def gate_cb(self, state):
     markers = state.markers
     for marker in markers:
         if marker.landmarkID.data == "Gate10":
             if marker.markerID.data == "1":
                 marker1 = [marker.x, marker.y]
             if marker.markerID.data == "2":
                 marker2 = [marker.x, marker.y]
             if marker.markerID.data == "3":
                 marker3 = [marker.x, marker.y]
             if marker.markerID.data == "4":
                 marker4 = [marker.x, marker.y]
     # try:
     marker1, marker2, marker3, marker4
     markersArr = np.array([marker1, marker2, marker3, marker4])
     if self.imu_cb_flag:
         imu_state = [
             self.ang_x, self.ang_y, self.ang_z, self.lin_x, self.lin_y,
             self.lin_z
         ]
         nn_input = np.concatenate(
             (markersArr.flatten(), np.array(imu_state)))
         print nn_input
         outputs = self.model.predict(nn_input.reshape(-1, 14))
         roll = outputs[0][0]
         pitch = outputs[0][1]
         yaw = 0
         thrust = outputs[0][2]
         print outputs
         ang_scale = 1
         thrust_scale = 1
         target_attitude_thrust = RateThrust()
         target_attitude_thrust.header.frame_id = "home"
         target_attitude_thrust.header.stamp = rospy.Time.now()
         target_attitude_thrust.angular_rates.x = roll
         target_attitude_thrust.angular_rates.y = pitch
         target_attitude_thrust.angular_rates.z = yaw
         target_attitude_thrust.thrust.z = thrust
         self.attitude_thrust_pub.publish(target_attitude_thrust)
    def __init__(self):
        # Rate init
        # DECIDE ON PUBLISHING RATE
        self.rate = rospy.Rate(120.0)  # MUST be more then 2Hz
        self.joy_cb_flag = False
        self.imu_cb_flag = False
        self.attitude_thrust_pub = rospy.Publisher("/uav/input/rateThrust",
                                                   RateThrust,
                                                   queue_size=10)
        self.model = load_model('working_model_roll_pitch_thrust.h5')
        self.model._make_predict_function()
        self.counter = 1
        attitude_target_sub = rospy.Subscriber("/joy", Joy, self.joy_cb)
        attitude_target_sub = rospy.Subscriber("/uav/sensors/imu", Imu,
                                               self.imu_cb)
        attitude_target_sub = rospy.Subscriber("/uav/camera/left/ir_beacons",
                                               IRMarkerArray, self.gate_cb)
        self.attitude_thrust_pub = rospy.Publisher("/uav/input/rateThrust",
                                                   RateThrust,
                                                   queue_size=10)

        thrust_scale = 2
        ang_scale = 1
        counter = 0
        while not rospy.is_shutdown():
            # if(self.joy_cb_flag == True):
            target_attitude_thrust = RateThrust()
            target_attitude_thrust.header.frame_id = "home"
            target_attitude_thrust.header.stamp = rospy.Time.now()
            target_attitude_thrust.angular_rates.x = 0
            target_attitude_thrust.angular_rates.y = 0
            target_attitude_thrust.angular_rates.z = 0
            target_attitude_thrust.thrust.z = 10.5
            self.attitude_thrust_pub.publish(target_attitude_thrust)
            self.rate.sleep()
            counter += 1
            if counter > 20:
                break
 def act(self, state, counter):
     # if np.random.rand() <= self.epsilon:
     #     return random.randrange(self.action_size)
     print state
     outputs = self.model.predict(state.reshape(-1, 14))
     roll = outputs[0][0]
     pitch = outputs[0][1]
     yaw = 0
     thrust = outputs[0][2]
     print outputs
     ang_scale = 1
     thrust_scale = 1
     target_rate_thrust = RateThrust()
     target_rate_thrust.header.frame_id = "home"
     target_rate_thrust.header.stamp = rospy.Time.now()
     target_rate_thrust.angular_rates.x = roll
     target_rate_thrust.angular_rates.y = pitch
     target_rate_thrust.angular_rates.z = yaw
     if counter < 5:
         target_rate_thrust.thrust.z = thrust + 1
     else:
         target_rate_thrust.thrust.z = thrust
     self.rate_thrust_pub.publish(target_rate_thrust)
     return outputs  # returns action
Beispiel #18
0
def pubRateThrust():
    # pub = rospy.Publisher('output/rateThrust', RateThrust, queue_size=10)
    rospy.init_node('talker', anonymous=True)
    rate = rospy.Rate(10)  # 10hz
    while not rospy.is_shutdown():
        thr_msg = RateThrust()
        thr_msg.header.frame_id = "uav/imu"
        thr_msg.header.stamp = rospy.Time.now()

        marker = IRMarker()

        pitch = 0.0
        roll = -0.1
        yaw = 0.5
        vertical = 11

        thr_msg.angular_rates.x = roll
        thr_msg.angular_rates.y = pitch
        thr_msg.angular_rates.z = yaw
        thr_msg.thrust.z = vertical

        # rospy.loginfo(thr_msg)
        # pub.publish(thr_msg)
        rate.sleep()
    def ControlLoop(self):
        # Set the rate
        rate = rospy.Rate(50)

        # Keep track how many loops have happend
        loop_counter = 0

        # While running
        while not rospy.is_shutdown():

            # Create the message we are going to send
            msg = RateThrust()
            msg.header.stamp = rospy.get_rostime()

            # If the drone has not been armed
            if self.armed == False:
                # Arm the drone
                msg.thrust = Vector3(0, 0, 10)
                msg.angular_rates = Vector3(0, 0, 0)

            # Behave normally (Drone is armed)
            else:
                # Use a PID to calculate the rates you want to publish to maintain an angle
                output = [
                    pids.get_output(setp, read) for pids, setp, read in zip(
                        self.rpy_PIDS, self.rpy_setpoints, self.rpy_readings)
                ]

                # Create the message
                msg.thrust = Vector3(0, 0, self.thrust_setpoint)
                msg.angular_rates = Vector3(output[0], output[1], output[2])

            # Publish the message
            self.rate_pub.publish(msg)

            # Sleep any excess time
            rate.sleep()
Beispiel #20
0
    def pid_controller(self, state_msg, traj_msg):
        # In general    u = -K*x + (N_u + K*N_x)*r
        # r = reference state
        # x = state
        # K = LQR gains
        # N_u, N_x = refrence input and reference state matrices

        # extract reference values
        x_r, y_r, z_r = [
            traj_msg.pose.position.x, traj_msg.pose.position.y,
            traj_msg.pose.position.z
        ]
        vx_r, vy_r, vz_r = [
            traj_msg.twist.linear.x, traj_msg.twist.linear.y,
            traj_msg.twist.linear.z
        ]
        ori_quat_r = [
            traj_msg.pose.orientation.x, traj_msg.pose.orientation.y,
            traj_msg.pose.orientation.z, traj_msg.pose.orientation.w
        ]
        psi_r, theta_r, phi_r = tf.transformations.euler_from_quaternion(
            ori_quat_r, axes='rzyx')
        p_r, q_r, r_r = [
            traj_msg.twist.angular.x, traj_msg.twist.angular.y,
            traj_msg.twist.angular.z
        ]
        #print("Traj rot: \n{}".format(traj_msg.rot))
        Rbw_ref = np.array(
            [[traj_msg.rot[0], traj_msg.rot[1], traj_msg.rot[2]],
             [traj_msg.rot[3], traj_msg.rot[4], traj_msg.rot[5]],
             [traj_msg.rot[6], traj_msg.rot[7], traj_msg.rot[8]]])
        #print("Rbw ref: \n{}".format(Rbw_ref))

        # extract drone real state values
        x, y, z = [
            state_msg.pose.position.x, state_msg.pose.position.y,
            state_msg.pose.position.z
        ]
        vx, vy, vz = [
            state_msg.twist.linear.x, state_msg.twist.linear.y,
            state_msg.twist.linear.z
        ]
        ori_quat = [
            state_msg.pose.orientation.x, state_msg.pose.orientation.y,
            state_msg.pose.orientation.z, state_msg.pose.orientation.w
        ]
        psi, theta, phi = tf.transformations.euler_from_quaternion(ori_quat,
                                                                   axes='rzyx')
        Rwb = tf.transformations.quaternion_matrix(ori_quat)
        Rbw = Rwb[0:3, 0:3].T  # get body to world frame rotation
        p, q, r = [
            state_msg.twist.angular.x, state_msg.twist.angular.y,
            state_msg.twist.angular.z
        ]

        # ******************************************#
        #            POSITION CONTROL LOOP
        # ******************************************#
        if (self.loops == 0):

            # compute desired input ua = ua_ref + ua_e
            # ue_ref : from dif flatness
            # ua_e = -Kp*(p - p_ref) - Kd * (v - v_ref)    using PID controller
            pos = np.array([[x], [y], [z]])
            pos_ref = np.array([[x_r], [y_r], [z_r]])
            v = np.array([[vx], [vy], [vz]])
            v_ref = np.array([[vx_r], [vy_r], [vz_r]])

            Kp = np.diag([lqrg.Kpx2, lqrg.Kpy2, lqrg.Kpz2])
            Kd = np.diag([lqrg.Kdx2, lqrg.Kdy2, lqrg.Kdz2])
            Ki = np.diag([lqrg.Kix2, lqrg.Kiy2, lqrg.Kiz2])

            self.pos_err = self.pos_err + (pos - pos_ref)
            ua_e = -1.0 * np.dot(Kp, pos - pos_ref) - 1.0 * np.dot(
                Kd, v - v_ref) - 1.0 * np.dot(Ki,
                                              self.pos_err)  # PID control law
            #print("pos error mag: {}".format(np.linalg.norm(pos - pos_ref)))
            #print("vel error mag: {}".format(np.linalg.norm(v-v_ref)))
            ua_ref = np.array([[traj_msg.ua.x], [traj_msg.ua.y],
                               [traj_msg.ua.z]])

            ua = ua_e + ua_ref  # desired acceleration
            #print("ua mag {}".format(np.linalg.norm(ua)))
            ua = self.clip_vector(ua, self.max_thrust)  # saturate input

            # compute Thrust -T- as
            #   T = m*wzb.T*(ua + g*zw)
            #
            e3 = np.array([[0.0], [0.0],
                           [1.0]])  #  z axis of body expressed in body frame
            zw = np.array(
                [[0.0], [0.0],
                 [1.0]])  #  z axis of world frame expressed in world frame
            #Rwb = tf.transformations.euler_matrix(psi, theta, phi, axes='rzyx') # world to body frame rotation
            #print("Rbw real: \n{}".format(Rbw))

            wzb = np.dot(Rbw, e3)  # zb expressed in world frame
            self.T = self.m * np.dot(wzb.T, (ua + g * zw))[0][0]
            #print("T : {}".format(self.T))

            # Following Fassler, Fontana, Theory and Math Behing RPG Quadrotor Control
            #  Rbw_des = [xb_des yb_des zb_des]  with zb_des = ua + g*zw / ||ua + g*zw||
            #  represents the desired orientation (and not the one coming from dif flatness)
            zb_des = (ua + g * zw) / np.linalg.norm(ua + g * zw)
            #T = self.m*np.dot(zb_des.T,(-ua + g*zw))[0][0]

            #print("PSI value: {}".format(psi_r))
            yc_des = np.array(df_flat.get_yc(
                psi_r))  #transform to np.array 'cause comes as np.matrix
            xb_des = np.cross(yc_des, zb_des, axis=0)
            xb_des = xb_des / np.linalg.norm(xb_des)
            yb_des = np.cross(zb_des, xb_des, axis=0)

            self.Rbw_des = np.concatenate((xb_des, yb_des, zb_des), axis=1)

            # Orientation error matrix is
            # Rbw.T*Rbw_des  because iff Rbw = Rbw_des, then Rbw.T*Rbw_des = I_3

            # Define angular velocity error
            w_b = np.array([[p], [q], [r]])
            w_b_r = np.array([[p_r], [q_r], [r_r]])
            #print("w_b ref: \n{}".format(w_b_r))
            self.w_b_des = np.dot(Rbw.T, np.dot(Rbw_ref, w_b_r))
            #print("w_b des: \n{}".format(w_b_des))
            w_b_e = w_b - np.dot(Rbw.T, np.dot(self.Rbw_des, self.w_b_des))
            # compute input with PID control law

            Kp = np.diag([lqrg.Kp1, lqrg.Kp1, lqrg.Kp1])
            Kd = np.diag([lqrg.Kd1, lqrg.Kd1, lqrg.Kd1])
            #w_b_in = -np.dot(Kp,or_e) - np.dot(Kd,w_b_e)

            self.loops = self.loops + 1

        else:
            self.loops = self.loops + 1
            if (self.loops == self.pos_loop_freq):
                self.loops = 0
                #print("**Loops: {}".format(self.loops))

        #print("Position Error: {}".format(np.linalg.norm(self.pos_err)))
        #print("T computed: {}".format(self.T))

        # ******************************************#
        #        ORIENTATION CONTROL LOOP
        # ******************************************#

        # ********************************** #
        #        USING EULER ANGLES          #
        # ********************************** #

        or_des = np.array(
            df_flat.RotToRPY_ZYX(self.Rbw_des)
        )  # ... need to convert to np.array to use this function..
        #print("Orientation des: {}".format(or_des))
        phi_des = or_des[0][0]
        theta_des = or_des[1][0]
        psi_des = or_des[2][0]

        # phi (x axis) angular position dynamics control law
        uc_e_x = -1.0 * self.Kr * phi + (self.N_ur +
                                         np.dot(self.Kr, self.N_xr)) * phi_des
        # theta (y axis) angular position dynamics control law
        uc_e_y = -1.0 * self.Kr * theta + (
            self.N_ur + np.dot(self.Kr, self.N_xr)) * theta_des
        # psi (z axis) angular position dynamics control law
        uc_e_z = -1.0 * self.Kr * psi + (self.N_ur +
                                         np.dot(self.Kr, self.N_xr)) * psi_des

        #compose angular position dynamics input vector
        #uc_e = np.array([[uc_e_x[0]],[uc_e_y[0]],[uc_e_z[0]]])

        # the final input to the drone is u = u_e + u_r
        # input =  error_input + reference_input
        ucx, ucy, ucz = [
            traj_msg.uc.x + uc_e_x.item(0), traj_msg.uc.y + uc_e_y.item(0),
            traj_msg.uc.z + uc_e_z.item(0)
        ]
        uc = np.array([[ucx], [ucy], [ucz]])
        #print(ua,uc)

        # compute w_b angular velocity commands as
        #  w_b = K.inv * uc
        #  where  (euler angle derivate) = K*w_b
        K = np.array(
            [[1.0,
              np.sin(phi) * np.tan(theta),
              np.cos(phi) * np.tan(theta)],
             [0.0, np.cos(phi), -1.0 * np.sin(phi)],
             [0.0,
              np.sin(phi) / np.cos(theta),
              np.cos(phi) / np.cos(theta)]])

        Kinv = np.linalg.inv(K)

        w_b_in = np.dot(Kinv, uc)

        # create and fill message
        rt_msg = RateThrust()

        rt_msg.header.stamp = rospy.Time.now()
        rt_msg.header.frame_id = 'uav/imu'

        rt_msg.angular_rates.x = 1.0 * self.w_b_des[0][0] + 1.0 * w_b_in[0][
            0]  #- p_r #traj_msg.twist.angular.x
        rt_msg.angular_rates.y = 1.0 * self.w_b_des[1][0] + 1.0 * w_b_in[1][
            0]  #- q_r  #traj_msg.twist.angular.y
        rt_msg.angular_rates.z = 1.0 * self.w_b_des[2][0] + 1.0 * w_b_in[2][
            0]  #- r_r #traj_msg.twist.angular.z

        rt_msg.thrust.x = 0.0
        rt_msg.thrust.y = 0.0
        rt_msg.thrust.z = self.T  # self.m*np.linalg.norm(t)

        # publish
        self.input_publisher.publish(rt_msg)
        rospy.loginfo(rt_msg)
 def gate_cb(self, state):
     self.counter += 1
     print self.counter
     markers = state.markers
     for marker in markers:
         if marker.landmarkID.data == "Gate10":
             if marker.markerID.data == "1":
                 marker1 = [marker.x, marker.y]
             if marker.markerID.data == "2":
                 marker2 = [marker.x, marker.y]
             if marker.markerID.data == "3":
                 marker3 = [marker.x, marker.y]
             if marker.markerID.data == "4":
                 marker4 = [marker.x, marker.y]
         if marker.landmarkID.data == "Gate21":
             if marker.markerID.data == "2":
                 marker221 = [marker.x, marker.y]
             if marker.markerID.data == "3":
                 marker321 = [marker.x, marker.y]
             if marker.markerID.data == "4":
                 marker421 = [marker.x, marker.y]
     try:
         marker1, marker2, marker3, marker4
         markersArr = np.array([marker1, marker2, marker3, marker4])
     except:
         print 'gate 10 not in view'
     if self.counter > 250:
         try:
             marker221, marker321, marker421
             y_diff = marker321[1] - marker221[1]
             marker121 = [marker421[0], marker421[0] - y_diff]
             # print 'markers'
             # print marker121,marker221,marker321,marker421
             markersArr = np.array(
                 [marker221, marker121, marker321, marker421])
         except:
             print 'gate 21 not in view'
     if self.imu_cb_flag:
         imu_state = [
             self.ang_x, self.ang_y, self.ang_z, self.lin_x, self.lin_y,
             self.lin_z
         ]
         nn_input = np.concatenate(
             (markersArr.flatten(), np.array(imu_state)))
         # print nn_input
         outputs = self.model.predict(nn_input.reshape(-1, 14))
         roll = outputs[0][0]
         pitch = outputs[0][1]
         yaw = 0
         thrust = outputs[0][2]
         # print outputs
         if abs(roll) == 0.25:
             roll = 0
         if self.counter > 320:
             thrust = 12.4
             roll = 0
         ang_scale = 1
         thrust_scale = 1
         target_attitude_thrust = RateThrust()
         target_attitude_thrust.header.frame_id = "home"
         target_attitude_thrust.header.stamp = rospy.Time.now()
         target_attitude_thrust.angular_rates.x = roll
         target_attitude_thrust.angular_rates.y = pitch
         target_attitude_thrust.angular_rates.z = yaw
         target_attitude_thrust.thrust.z = thrust
         self.attitude_thrust_pub.publish(target_attitude_thrust)
Beispiel #22
0
#! /usr/bin/python
import rospy
import math
from mav_msgs.msg import RateThrust
from std_msgs.msg import Bool

if __name__ == '__main__':
    rospy.init_node('msp_fc_test_node')
    pub = rospy.Publisher('/uav/control/rate_thrust', RateThrust, queue_size=1)
    pub_arm = rospy.Publisher('/uav/control/arm', Bool, queue_size=1)
    rate = rospy.Rate(10)
    i = 0
    while not rospy.is_shutdown():
        msg = RateThrust()
        msg.angular_rates.x = 0
        msg.angular_rates.y = 0
        msg.angular_rates.z = 0
        msg.thrust.z = 0  # math.sin(i) / 2 + 0.5

        pub.publish(msg)

        arm_msg = Bool()
        arm_msg.data = True
        pub_arm.publish(arm_msg)
        i += 0.1
        rate.sleep()
Beispiel #23
0
def main():
    # init rosnodes
    rospy.init_node('lqr_controller')
    tf_listener = tf.TransformListener()
    imu_sub = rospy.Subscriber('/uav/sensors/imu', Imu, callback=imu_cb, queue_size=1)
    start_sim_pub = rospy.Publisher('/uav/input/arm', Empty, queue_size=1)
    end_sim_pub = rospy.Publisher('/uav/input/reset', Empty, queue_size=1)
    ctrl_pub = rospy.Publisher('/uav/input/rateThrust', RateThrust, queue_size=10)
    path_pub = rospy.Publisher('ref_traj', Path, queue_size=1)
    tf_br = tf.TransformBroadcaster()

    # Global Constants
    Ixx = rospy.get_param("/uav/flightgoggles_uav_dynamics/vehicle_inertia_xx")
    Iyy = rospy.get_param("/uav/flightgoggles_uav_dynamics/vehicle_inertia_yy")
    Izz = rospy.get_param("/uav/flightgoggles_uav_dynamics/vehicle_inertia_zz")
    m = rospy.get_param("/uav/flightgoggles_uav_dynamics/vehicle_mass")
    g = 9.81
    # aggr = rospy.get_param("/splinegen/aggr")

    aggr = 10**4
    T = 40.0 # T=None to use aggr instead.

    # Flat Dynamics
    FLAT_STATES = 7
    FLAT_CTRLS = 4
    A = np.zeros((FLAT_STATES, FLAT_STATES))
    A[0:3, 3:6] = np.eye(3)
    B = np.zeros((FLAT_STATES, FLAT_CTRLS))
    B[3:, :] = np.eye(4)
    Gff = np.array([[0, 0, g, 0]]).T  # gravity compensation
    Q = np.diag([10, 10, 20, 0.01, 0.01, 0.01, 10])
    R = np.eye(FLAT_CTRLS) * 1

    # Trajectory generation
    # get gate poses
    num_gates = 14
    gate_ids = list(range(0, num_gates))
    gate_transforms = get_gate_positions(gate_ids)

    # inital drone pose and generated spline of waypoints
    print("Solving for optimal trajectory...")
    dt = 0.05
    rate = rospy.Rate(int(1./dt))
    x0 = np.array([[0., 0., 1., 0., 0., 0., 0.]]).T
    drone_traj = DroneTrajectory()
    drone_traj.set_start(position=x0[:3], velocity=x0[3:6])
    drone_traj.set_end(position=x0[:3], velocity=x0[3:6])
    for (trans, rot) in gate_transforms.values():
        drone_traj.add_gate(trans, rot)
    drone_traj.solve(aggr, T=T)

    # PID Controller for setting angular rates
    pid_phi = PID(Kp=7, Ki=0, Kd=1, setpoint=0)
    pid_theta = PID(Kp=7, Ki=0, Kd=1, setpoint=0)

    # Optimal control law for flat system
    print("Solving linear feedback system...")
    K, S, E = control.lqr(A, B, Q, R)

    # Generate trajectory (starttime-sensitive)
    print("Generating optimal trajectory...")
    start_time = rospy.get_time()
    xref_traj = drone_traj.as_path(dt=dt, frame='world', start_time=rospy.Time.now())
    max_time = xref_traj.poses[-1].header.stamp.to_sec() - start_time

    # plotting
    N = len(xref_traj.poses) + int(3.0 / dt)
    time_axis = []
    xref_traj_series = np.zeros((FLAT_STATES, N))
    x_traj_series = np.zeros((FLAT_STATES, N))

    # run simulation
    print("Running simulation and executing controls...")
    iter = 0
    x = x0
    prev_pose = None

    phid_traj = []
    thetad_traj = []
    psid_traj = []

    phi_traj = []
    theta_traj = []
    psi_traj = []
    # for pose in xref_traj.poses:
    while not rospy.is_shutdown() and iter < N:
        # publish arm command and ref traj
        start_sim_pub.publish(Empty())
        path_pub.publish(xref_traj)

        # get next target waypoint
        t = (rospy.get_time() - start_time) # % max_time
        pos_g, vel_g, ori_g = drone_traj.full_pose(t)

        # TODO: Use these desired roll/pitch or the ones generated from fdbk law?
        [psid, _, _] = Rotation.from_quat(ori_g).as_euler('ZYX')
        psid = 0
        
        xref = np.array([[
            pos_g[0], pos_g[1], pos_g[2],
            vel_g[0], vel_g[1], vel_g[2],
            psid]]).T
        xref_traj_series[:, iter] = np.ndarray.flatten(xref)
        tf_br.sendTransform((xref[0][0], xref[1][0], xref[2][0]),
            ori_g,
            rospy.Time.now(),
            "xref_pose",
            "world")

        # feedforward acceleration
        ff = np.array([[
            drone_traj.val(t=t, order=2, dim=0),
            drone_traj.val(t=t, order=2, dim=1),
            drone_traj.val(t=t, order=2, dim=2),
            0]]).T

        try:
            (trans, rot) = tf_listener.lookupTransform('world', 'uav/imu', rospy.Time(0))
        except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
            continue

        # calculate linear velocities, define new state
        lin_vel = (np.array(trans) - x[:3,0]) / dt
        x[:3,0] = trans  # new position
        x[3:6,0] = lin_vel  # new linear velocity
        [psi, theta, phi] = Rotation.from_quat(rot).as_euler("ZYX")
        x[6] = psi
        phi_traj.append(phi)
        theta_traj.append(theta)
        psi_traj.append(psi)
        x_traj_series[:, iter] = np.ndarray.flatten(x)

        u = -K*(x-xref) + Gff + ff
        # print("%.3f, %.3f, %.3f" % (ff[0][0], ff[1][0], ff[2][0]))
        up = np.array(
            np.ndarray.flatten(u).tolist()[0])
        [thrustd, phid, thetad, psid] = inverse_dyn(rot, xref, up, m)
        # [psid, thetad, phid] = Rotation.from_quat(ori_g).as_euler('ZYX')
        phid_traj.append(phid)
        thetad_traj.append(thetad)
        psid_traj.append(psid)

        # generate desired roll, pitch rates, minimize error btwn desired and current
        dphi = pid_phi(phi - phid)
        dtheta = pid_theta(theta - thetad)
        dpsi = u[3]

        # convert rotation quaternion to euler angles and rotation matrix
        
        # rpy rates around around body axis
        # print(thrustd)
        new_ctrl = RateThrust()
        new_ctrl.angular_rates.x = dphi
        new_ctrl.angular_rates.y = dtheta
        new_ctrl.angular_rates.z = dpsi
        new_ctrl.thrust.z = thrustd
        ctrl_pub.publish(new_ctrl)

        # Plot results
        time_axis.append(t)
        iter += 1
        rate.sleep()

    end_sim_pub.publish(Empty())
    np.savez(file="lqr_and_xref", lqr_xtraj=x_traj_series, xref_traj_series=xref_traj_series)


    # fig, axs = plt.subplots(1, 3)
    # fig.suptitle('Target(red) v.s actual(green) roll and pitch')
    # axs[0].set_title('phi')
    # axs[1].set_title('theta')
    # axs[2].set_title('psi')
    # axs[0].scatter(time_axis, phid_traj, c = 'r')
    # axs[0].scatter(time_axis, phi_traj, c = 'g')
    # axs[1].scatter(time_axis, thetad_traj, c = 'r')
    # axs[1].scatter(time_axis, theta_traj, c = 'g')
    # axs[2].scatter(time_axis, psid_traj, c = 'r')
    # axs[2].scatter(time_axis, psi_traj, c = 'g')
    # plt.show()

    # plot x, y, z, vx, vy, vz
    fig, axs = plt.subplots(2, 3)
    axs[0, 0].set_title('X')
    axs[0, 1].set_title('Y')
    axs[0, 2].set_title('Z')
    axs[1, 0].set_title('VX')
    axs[1, 1].set_title('VY')
    axs[1, 2].set_title('VZ')
    for ax in axs.flat:
        ax.set(xlabel='Time(s)')
    fig.suptitle('Absolute State error v.s time (LQR)')
    x_error = abs(xref_traj_series - x_traj_series)
    for i in range(3):
        # position
        axs[0, i].scatter(time_axis, x_error[i,:iter], c = 'r')

        # velocity
        axs[1, i].scatter(time_axis, x_error[i+3,:iter], c = 'r')
        axs[1, i].scatter(time_axis, x_error[i+3,:iter], c = 'g')

    plt.show()
Beispiel #24
0
def main():
    # rosparams
    aggr = 10**4
    T = 40.0  # T=None to use aggr instead.

    # init rosnodes
    rospy.init_node('lqr_controller')
    tf_listener = tf.TransformListener()
    imu_sub = rospy.Subscriber('/uav/sensors/imu',
                               Imu,
                               callback=imu_data,
                               queue_size=1)
    start_sim_pub = rospy.Publisher('/uav/input/arm', Empty, queue_size=1)
    end_sim_pub = rospy.Publisher('/uav/input/reset', Empty, queue_size=1)
    ctrl_pub = rospy.Publisher('/uav/input/rateThrust',
                               RateThrust,
                               queue_size=10)
    path_pub = rospy.Publisher('ref_traj', Path, queue_size=1)
    prediction_pub = rospy.Publisher('mpc_pred', Path, queue_size=10)
    reference_pub = rospy.Publisher('mpc_ref', Path, queue_size=10)
    tf_br = tf.TransformBroadcaster()

    # Global Constants
    Ixx = rospy.get_param("/uav/flightgoggles_uav_dynamics/vehicle_inertia_xx")
    Iyy = rospy.get_param("/uav/flightgoggles_uav_dynamics/vehicle_inertia_yy")
    Izz = rospy.get_param("/uav/flightgoggles_uav_dynamics/vehicle_inertia_zz")
    m = rospy.get_param("/uav/flightgoggles_uav_dynamics/vehicle_mass")
    g = 9.81

    # Flat Dynamics
    FLAT_STATES = 7
    FLAT_CTRLS = 4
    A = np.zeros((FLAT_STATES, FLAT_STATES))
    A[0:3, 3:6] = np.eye(3)
    B = np.zeros((FLAT_STATES, FLAT_CTRLS))
    B[3:, :] = np.eye(4)
    Gff = np.array([[0, 0, g, 0]]).T  # gravity compensation
    Q = np.diag([20, 20, 20, 0.1, 0.1, 0.1, 1])
    R = np.diag([.1, .1, .1, 10])
    S = Q * 10

    # Trajectory generation
    # get gate poses
    num_gates = 14
    gate_ids = list(range(0, num_gates))
    gate_transforms = get_gate_positions(gate_ids)

    # inital drone pose and generated spline of waypoints
    print("Solving for optimal trajectory...")
    dt = 0.06
    rate = rospy.Rate(int(1. / dt))
    x0 = np.array([[0., 0., 1., 0., 0., 0., 0.]]).T
    drone_traj = DroneTrajectory()
    drone_traj.set_start(position=x0[:3], velocity=x0[3:6])
    drone_traj.set_end(position=x0[:3], velocity=x0[3:6])
    for (trans, rot) in gate_transforms.values():
        drone_traj.add_gate(trans, rot)
    drone_traj.solve(aggr, T=T)

    # PID Controller for setting angular rates
    pid_phi = PID(Kp=7, Ki=0, Kd=1, setpoint=0)
    pid_theta = PID(Kp=7, Ki=0, Kd=1, setpoint=0)

    # Optimal control law for flat system
    print("Solving linear feedback system...")
    # K, S, E = control.lqr(A, B, Q, R)
    horizon = 10
    mpc = DroneMPC(A, B, Q, R, S, N=horizon, dt=dt)

    # Generate trajectory (starttime-sensitive)
    print("Generating trajectory for visualizing...")
    start_time = rospy.get_time()
    xref_traj = drone_traj.as_path(dt=dt,
                                   frame='world',
                                   start_time=rospy.Time.now())

    # plotting
    N = len(xref_traj.poses) + int(3.0 / dt)
    time_axis = []
    xref_traj_series = np.zeros((FLAT_STATES, N))
    x_traj_series = np.zeros((FLAT_STATES, N))

    # run simulation
    print("Running simulation and executing controls...")
    iter = 0
    x = x0
    prev_pose = None

    phid_traj = []
    thetad_traj = []
    psid_traj = []

    phi_traj = []
    theta_traj = []
    psi_traj = []
    # for pose in xref_traj.poses:
    while not rospy.is_shutdown() and iter < N:
        # publish arm command and ref traj
        start_sim_pub.publish(Empty())
        path_pub.publish(xref_traj)

        try:
            (trans, rot) = tf_listener.lookupTransform('world', 'uav/imu',
                                                       rospy.Time(0))
        except (tf.LookupException, tf.ConnectivityException,
                tf.ExtrapolationException):
            continue

        # calculate linear velocities, define new state
        lin_vel = (np.array(trans) - x[:3, 0]) / dt
        x[:3, 0] = trans  # new position
        x[3:6, 0] = lin_vel  # new linear velocity
        [psi, theta, phi] = Rotation.from_quat(rot).as_euler("ZYX")
        x[6] = psi
        phi_traj.append(phi)
        theta_traj.append(theta)
        psi_traj.append(psi)
        x_traj_series[:, iter] = np.ndarray.flatten(x)

        # get next target waypoint
        t = rospy.get_time() - start_time
        poses = [
            drone_traj.val(t + offset, dim=None, order=0)
            for offset in np.arange(0, (horizon + 1) * dt, dt)
        ]
        vels = [
            drone_traj.val(t + offset, dim=None, order=1)
            for offset in np.arange(0, (horizon + 1) * dt, dt)
        ]
        psis = [atan2(v[1], v[0]) for v in vels]

        if psis[0] - psi < -np.pi:
            psis[0] += 2 * np.pi
        if psis[0] - psi > np.pi:
            psis[0] -= 2 * np.pi

        for i in range(len(psis[0:-2])):
            if psis[i + 1] - psis[i] < -np.pi:
                psis[i + 1] += 2 * np.pi
            if psis[i + 1] - psis[i] > np.pi:
                psis[i + 1] -= 2 * np.pi

        ref_traj = [[p[0], p[1], p[2], v[0], v[1], v[2], psi]
                    for p, v, psi in zip(poses, vels, psis)]
        pos_g, vel_g, ori_g = drone_traj.full_pose(t)

        xref = np.array([[
            pos_g[0], pos_g[1], pos_g[2], vel_g[0], vel_g[1], vel_g[2], psis[0]
        ]]).T
        xref_traj_series[:, iter] = np.ndarray.flatten(xref)
        tf_br.sendTransform((xref[0][0], xref[1][0], xref[2][0]), ori_g,
                            rospy.Time.now(), "xref_pose", "world")

        # feedforward acceleration
        # ff = np.array([[
        #     drone_traj.val(t=t, order=2, dim=0),
        #     drone_traj.val(t=t, order=2, dim=1),
        #     drone_traj.val(t=t, order=2, dim=2),
        #     0]]).T

        u_mpc, x_mpc = mpc.solve(x, np.array(ref_traj).transpose())
        u = u_mpc[:, 0].flatten() + Gff.flatten()

        reference_pub.publish(
            mpc.to_path(np.array(ref_traj).transpose(),
                        start_time=rospy.Time.now(),
                        frame='world'))
        prediction_pub.publish(
            mpc.to_path(x_mpc, start_time=rospy.Time.now(), frame='world'))

        # print(xref)
        # print("fb: {}, ff: {}".format(-K * (x - xref), ff))
        # print("%.3f, %.3f, %.3f" % (ff[0][0], ff[1][0], ff[2][0]))
        [thrustd, phid, thetad, psid] = inverse_dyn(rot, x.flatten(), u, m)
        # [psid, thetad, phid] = Rotation.from_quat(ori_g).as_euler('ZYX')
        phid_traj.append(phid)
        thetad_traj.append(thetad)
        psid_traj.append(psid)

        # generate desired roll, pitch rates, minimize error btwn desired and current
        dphi = pid_phi(phi - phid)
        dtheta = pid_theta(theta - thetad)
        dpsi = u[3]

        # convert rotation quaternion to euler angles and rotation matrix

        # rpy rates around around body axis
        # print(thrustd)
        new_ctrl = RateThrust()
        new_ctrl.angular_rates.x = dphi
        new_ctrl.angular_rates.y = dtheta
        new_ctrl.angular_rates.z = dpsi
        new_ctrl.thrust.z = thrustd
        ctrl_pub.publish(new_ctrl)

        # Plot results
        time_axis.append(t)
        iter += 1
        rate.sleep()

    end_sim_pub.publish(Empty())

    # fig, axs = plt.subplots(1, 3)
    # fig.suptitle('Target(red) v.s actual(green) roll and pitch')
    # axs[0].set_title('phi')
    # axs[1].set_title('theta')
    # axs[2].set_title('psi')
    # axs[0].scatter(time_axis, phid_traj, c='r')
    # axs[0].scatter(time_axis, phi_traj, c='g')
    # axs[1].scatter(time_axis, thetad_traj, c='r')
    # axs[1].scatter(time_axis, theta_traj, c='g')
    # axs[2].scatter(time_axis, psid_traj, c='r')
    # axs[2].scatter(time_axis, psi_traj, c='g')
    # plt.show()

    # plot x, y, z, vx, vy, vz
    fig, axs = plt.subplots(2, 3)
    axs[0, 0].set_title('X')
    axs[0, 1].set_title('Y')
    axs[0, 2].set_title('Z')
    axs[1, 0].set_title('VX')
    axs[1, 1].set_title('VY')
    axs[1, 2].set_title('VZ')
    for ax in axs.flat:
        ax.set(xlabel='Time(s)')
    fig.suptitle('Absolute State error v.s time (MPC)')
    x_error = abs(xref_traj_series - x_traj_series)
    for i in range(3):
        # position
        axs[0, i].scatter(time_axis, x_error[i, :iter], c='r')
        # axs[0, i].scatter(time_axis, x_traj_series[i,:iter], c = 'g')

        # velocity
        # axs[1, i].scatter(time_axis, xref_traj_series[i+3,:iter], c = 'r')
        axs[1, i].scatter(time_axis, x_error[i + 3, :iter], c='g')

    plt.show()
Beispiel #25
0
    def callback(self, image, ir_marker):
        if self.current_state == 'rotating_to_gate':
            self.target_quaternion = reorient_to_centroid(
                self.init_vector, self.current_coords,
                self.current_orientation, self.gate_list[self.target_gate + 1])
            next_gate_rotmat = q2q_to_rot(self.current_orientation,
                                          self.target_quaternion)
            roll_pitch_yaw = rotationMatrixToEulerAngles(next_gate_rotmat)
            print(roll_pitch_yaw)
            #Controls time to rotate
            time_to_rotate = 2
            d = rospy.Duration(time_to_rotate, 0)
            now = rospy.get_rostime()
            end_time = d + now

            msg = RateThrust()
            msg.header.frame_id = "uav/imu"
            msg.header.stamp = Time.now()
            msg.thrust.z = self.idle_thrust
            msg.angular_rates.x = roll_pitch_yaw[0] / time_to_rotate
            msg.angular_rates.y = roll_pitch_yaw[1] / time_to_rotate
            msg.angular_rates.z = roll_pitch_yaw[2] / time_to_rotate

            while rospy.get_rostime() < end_time:
                print("ITS AT STATE 1")
                self.pub_vel.publish(msg)
            self.current_state = states[1]

        elif self.current_state == 'rotating_to_IR_centroid':
            # minimum_distance = 99999
            # closest_gate=''
            #
            # for key in range(len(gate_dictionary)):
            #     x,y = IR_marker_centroid_calculator(key)
            #     dist = abs(math.hypot(x - image_center_x, y - image_center_y))
            #     if dist < minimum_distance:
            #         dist = minimum_distance
            #         closest_gate = key
            gate_dictionary = IR_marker_cluster_seperator(ir_marker)
            target_gate_list = gate_dictionary[gates[self.target_gate]]
            #print(gate_dictionary, "REEEEEEEEEEEEEEEEE", target_gate_list)
            x, y = IR_marker_centroid_calculator(target_gate_list)
            delta_x = (-1) * (image_center_x - x)
            delta_y = (-1) * (image_center_y - y)

            msg = RateThrust()
            msg.header.frame_id = "uav/imu"
            msg.header.stamp = Time.now()
            msg.thrust.z = self.idle_thrust + 1
            msg.angular_rates.x = 0
            msg.angular_rates.y = delta_y / 15
            msg.angular_rates.z = delta_x / 15
            print("ITS AT STATE 2")
            self.pub_vel.publish(msg)

            if ((abs(delta_x) < 100) and (abs(delta_y)) < 100):
                self.current_state = states[2]

        elif self.current_state == 'flying':
            gate_dictionary = IR_marker_cluster_seperator(ir_marker)
            target_gate_list = gate_dictionary[gates[self.target_gate]]
            if len(target_gate_list) is 0:
                successful_gate_callback(self)

                msg = RateThrust()
                msg.header.frame_id = "uav/imu"
                msg.header.stamp = Time.now()
                msg.thrust.z = self.idle_thrust
                msg.angular_rates.x = 0
                msg.angular_rates.y = 0
                msg.angular_rates.z = 0
                #print("ITS AT STATE 3")
                self.pub_vel.publish(msg)
            else:
                x, y = IR_marker_centroid_calculator(target_gate_list)
                delta_x = (-1) * (image_center_x - x)
                delta_y = (-1) * (image_center_y - y)

                msg = RateThrust()
                msg.header.frame_id = "uav/imu"
                msg.header.stamp = Time.now()
                msg.thrust.z = self.idle_thrust + 0.1
                msg.angular_rates.x = 100
                msg.angular_rates.y = delta_x / 30
                msg.angular_rates.z = delta_y / 30
                self.pub_vel.publish(msg)
                #print("ITS AT STATE 3")
        elif self.current_state == 'hover':
            msg = RateThrust()
            msg.header.frame_id = "uav/imu"
            msg.header.stamp = Time.now()
            msg.thrust.z = self.idle_thrust + 1
            msg.angular_rates.x = 0
            msg.angular_rates.y = 0
            msg.angular_rates.z = 0
def clean(control):
    cleaned=RateThrust()
    cleaned.head=control.head
    cleaned.angular_rates=control.bodyrates
    cleaned.thrust=control.collective_thrust
    return cleaned
Beispiel #27
0
    def callback(self, state_msg, traj_msg):

        # In general    u = -K*x + (N_u + K*N_x)*r
        # r = reference state
        # x = state
        # K = LQR gains
        # N_u, N_x = refrence input and reference state matrices

        # extract reference values
        x_r, y_r, z_r = [
            traj_msg.pose.position.x, traj_msg.pose.position.y,
            traj_msg.pose.position.z
        ]
        vx_r, vy_r, vz_r = [
            traj_msg.twist.linear.x, traj_msg.twist.linear.y,
            traj_msg.twist.linear.z
        ]
        ori_quat_r = [
            traj_msg.pose.orientation.x, traj_msg.pose.orientation.y,
            traj_msg.pose.orientation.z, traj_msg.pose.orientation.w
        ]
        psi_r, theta_r, phi_r = tf.transformations.euler_from_quaternion(
            ori_quat_r, axes='rzyx')
        p_r, q_r, r_r = [
            traj_msg.twist.angular.x, traj_msg.twist.angular.y,
            traj_msg.twist.angular.z
        ]

        # extract drone real state values
        x, y, z = [
            state_msg.pose.position.x, state_msg.pose.position.y,
            state_msg.pose.position.z
        ]
        vx, vy, vz = [
            state_msg.twist.linear.x, state_msg.twist.linear.y,
            state_msg.twist.linear.z
        ]
        ori_quat = [
            state_msg.pose.orientation.x, state_msg.pose.orientation.y,
            state_msg.pose.orientation.z, state_msg.pose.orientation.w
        ]
        psi, theta, phi = tf.transformations.euler_from_quaternion(ori_quat,
                                                                   axes='rzyx')
        p, q, r = [
            state_msg.twist.angular.x, state_msg.twist.angular.y,
            state_msg.twist.angular.z
        ]

        #compute state error:  error = reference - real
        x_e, y_e, z_e = [x - x_r, y - y_r, z - z_r]
        vx_e, vy_e, vz_e = [vx - vx_r, vy - vy_r, vz - vz_r]
        phi_e, theta_e, psi_e = [phi - phi_r, theta - theta_r, psi - psi_r]
        p_e, q_e, r_e = [p - p_r, q - q_r, r - r_r]

        # compute input error u = -Kx
        # first, for translation dynamics
        ua_e_x = -1.0 * np.dot(self.Kt, np.array([[x_e], [vx_e]]))
        ua_e_y = -1.0 * np.dot(self.Kt, np.array([[y_e], [vy_e]]))
        ua_e_z = -1.0 * np.dot(self.Kt, np.array([[z_e], [vz_e]]))

        # second, for orientation dynamics
        uc_e_x = -1.0 * np.dot(self.Kr, np.array([phi_e]))
        uc_e_y = -1.0 * np.dot(self.Kr, np.array([theta_e]))
        uc_e_z = -1.0 * np.dot(self.Kr, np.array([psi_e]))
        #print("uc_e_x: {} type: {}".format(uc_e_x,type(uc_e_x)) )
        #print("ua_e_x: {} type: {}".format(ua_e_x,type(ua_e_x)) )

        # the final input to the drone is u = u_e + u_r
        # input =  error_input + reference_input
        #print("traj_msg.ua.x: {} type: {}".format(traj_msg.ua.x,type(traj_msg.ua.x)) )
        uax, uay, uaz = [
            traj_msg.ua.x + ua_e_x.item(0), traj_msg.ua.y + ua_e_y.item(0),
            traj_msg.ua.z + ua_e_z.item(0)
        ]
        ucx, ucy, ucz = [
            traj_msg.uc.x + uc_e_x.item(0), traj_msg.uc.y + uc_e_y.item(0),
            traj_msg.uc.z + uc_e_z.item(0)
        ]
        #print("uax: {} type: {}".format(uax,type(uax)) )

        ua = np.array([[uax], [uay], [uaz]])
        uc = np.array([[ucx], [ucy], [ucz]])
        #print(ua,uc)

        # compute Thrust -T- as
        #   T = m*wzb.T*(ua + g*zw)
        #
        zb = np.array([[0.0], [0.0],
                       [1.0]])  #  z axis of body expressed in body frame
        zw = np.array([[0.0], [0.0], [1.0]
                       ])  #  z axis of world frame expressed in world frame
        Rwb = tf.transformations.euler_matrix(
            psi_r, theta_r, phi_r, axes='rzyx')  # world to body frame rotation
        Rbw = Rwb[0:3, 0:3].T  # body to world frame rotation only

        wzb = np.dot(Rbw, zb)  # zb expressed in world frame
        T = self.m * np.dot(wzb.T, (ua + g * zw))[0]
        #print(wzb.T,type(wzb))

        # compute w_b angular velocity commands as
        #  w_b = K.inv * uc
        #  where  (euler angle derivate) = K*w_b
        K = np.array([[
            1.0,
            np.sin(phi_r) * np.tan(theta_r),
            np.cos(phi_r) * np.tan(theta_r)
        ], [0.0, np.cos(phi_r), -1.0 * np.sin(phi_r)],
                      [
                          0.0,
                          np.sin(phi_r) / np.cos(theta_r),
                          np.cos(phi_r) / np.cos(theta_r)
                      ]])

        Kinv = np.linalg.inv(K)

        w_b = np.dot(Kinv, uc).flatten()

        # create and fill message
        rt_msg = RateThrust()

        rt_msg.header.stamp = rospy.Time.now()
        rt_msg.header.frame_id = 'uav/imu'

        rt_msg.angular_rates.x = w_b[0]  #traj_msg.twist.angular.x
        rt_msg.angular_rates.y = w_b[1]  #traj_msg.twist.angular.y
        rt_msg.angular_rates.z = w_b[2]  #traj_msg.twist.angular.z

        rt_msg.thrust.x = 0.0
        rt_msg.thrust.y = 0.0
        rt_msg.thrust.z = T[0]  # self.m*np.linalg.norm(t)

        # publish
        self.input_publisher.publish(rt_msg)
        rospy.loginfo(rt_msg)
Beispiel #28
0
    def linear_velocity_control(self, state_msg, traj_msg):
        # In general    u = -K*x + (N_u + K*N_x)*r
        # r = reference state
        # x = state
        # K = LQR gains
        # N_u, N_x = refrence input and reference state matrices

        # extract reference values
        x_r, y_r, z_r = [
            traj_msg.pose.position.x, traj_msg.pose.position.y,
            traj_msg.pose.position.z
        ]
        vx_r, vy_r, vz_r = [
            traj_msg.twist.linear.x, traj_msg.twist.linear.y,
            traj_msg.twist.linear.z
        ]
        ori_quat_r = [
            traj_msg.pose.orientation.x, traj_msg.pose.orientation.y,
            traj_msg.pose.orientation.z, traj_msg.pose.orientation.w
        ]
        psi_r, theta_r, phi_r = tf.transformations.euler_from_quaternion(
            ori_quat_r, axes='rzyx')
        p_r, q_r, r_r = [
            traj_msg.twist.angular.x, traj_msg.twist.angular.y,
            traj_msg.twist.angular.z
        ]

        # extract drone real state values
        x, y, z = [
            state_msg.pose.position.x, state_msg.pose.position.y,
            state_msg.pose.position.z
        ]
        vx, vy, vz = [
            state_msg.twist.linear.x, state_msg.twist.linear.y,
            state_msg.twist.linear.z
        ]
        ori_quat = [
            state_msg.pose.orientation.x, state_msg.pose.orientation.y,
            state_msg.pose.orientation.z, state_msg.pose.orientation.w
        ]
        psi, theta, phi = tf.transformations.euler_from_quaternion(ori_quat,
                                                                   axes='rzyx')
        p, q, r = [
            state_msg.twist.angular.x, state_msg.twist.angular.y,
            state_msg.twist.angular.z
        ]

        # vx dynamics control law
        ua_e_x = -1.0 * self.Kr * vx + (self.N_ur +
                                        np.dot(self.Kr, self.N_xr)) * vx_r
        # vy dynamics control law
        ua_e_y = -1.0 * self.Kr * vy + (self.N_ur +
                                        np.dot(self.Kr, self.N_xr)) * vy_r
        # vz dynamics control law
        ua_e_z = -1.0 * self.Kr * vz + (self.N_ur +
                                        np.dot(self.Kr, self.N_xr)) * vz_r

        # compose position dynamics input vector
        #ua_e = np.array([[ua_e_x[0]],[ua_e_y[0]],[ua_e_z[0]]])

        # phi (x axis) angular position dynamics control law
        uc_e_x = -1.0 * self.Kr * phi + (self.N_ur +
                                         np.dot(self.Kr, self.N_xr)) * phi_r
        # theta (y axis) angular position dynamics control law
        uc_e_y = -1.0 * self.Kr * theta + (
            self.N_ur + np.dot(self.Kr, self.N_xr)) * theta_r
        # psi (z axis) angular position dynamics control law
        uc_e_z = -1.0 * self.Kr * psi + (self.N_ur +
                                         np.dot(self.Kr, self.N_xr)) * psi_r

        #compose angular position dynamics input vector
        #uc_e = np.array([[uc_e_x[0]],[uc_e_y[0]],[uc_e_z[0]]])

        # the final input to the drone is u = u_e + u_r
        # input =  error_input + reference_input
        uax, uay, uaz = [
            traj_msg.ua.x + ua_e_x.item(0), traj_msg.ua.y + ua_e_y.item(0),
            traj_msg.ua.z + ua_e_z.item(0)
        ]
        ucx, ucy, ucz = [
            traj_msg.uc.x + uc_e_x.item(0), traj_msg.uc.y + uc_e_y.item(0),
            traj_msg.uc.z + uc_e_z.item(0)
        ]

        ua = np.array([[uax], [uay], [uaz]])
        uc = np.array([[ucx], [ucy], [ucz]])
        #print(ua,uc)

        # compute Thrust -T- as
        #   T = m*wzb.T*(ua + g*zw)
        #
        zb = np.array([[0.0], [0.0],
                       [1.0]])  #  z axis of body expressed in body frame
        zw = np.array([[0.0], [0.0], [1.0]
                       ])  #  z axis of world frame expressed in world frame
        Rwb = tf.transformations.euler_matrix(
            psi, theta, phi, axes='rzyx')  # world to body frame rotation
        Rbw = Rwb[0:3, 0:3].T  # body to world frame rotation only

        wzb = np.dot(Rbw, zb)  # zb expressed in world frame
        T = self.m * np.dot(wzb.T, (ua + g * zw))[0]
        #print(wzb.T,type(wzb))

        # compute w_b angular velocity commands as
        #  w_b = K.inv * uc
        #  where  (euler angle derivate) = K*w_b
        K = np.array(
            [[1.0,
              np.sin(phi) * np.tan(theta),
              np.cos(phi) * np.tan(theta)],
             [0.0, np.cos(phi), -1.0 * np.sin(phi)],
             [0.0,
              np.sin(phi) / np.cos(theta),
              np.cos(phi) / np.cos(theta)]])

        Kinv = np.linalg.inv(K)

        w_b = np.dot(Kinv, uc).flatten()

        # create and fill message
        rt_msg = RateThrust()

        rt_msg.header.stamp = rospy.Time.now()
        rt_msg.header.frame_id = 'uav/imu'

        rt_msg.angular_rates.x = w_b[0]  #traj_msg.twist.angular.x
        rt_msg.angular_rates.y = w_b[1]  #traj_msg.twist.angular.y
        rt_msg.angular_rates.z = w_b[2]  #traj_msg.twist.angular.z

        rt_msg.thrust.x = 0.0
        rt_msg.thrust.y = 0.0
        rt_msg.thrust.z = T[0]  # self.m*np.linalg.norm(t)

        # publish
        self.input_publisher.publish(rt_msg)
        rospy.loginfo(rt_msg)
Beispiel #29
0
    #     target_i = 1 - target_i
    #     thetad = theta_targets[target_i]
    # xref_i = 1 - xref_i
    # xref = targets[xref_i]
    # print("New target: (%d,%d,%d)" % (xref[0], xref[1], xref[2]))

    # generate desired roll, pitch rates, minimize error btwn desired and current
    dphi = pid_phi(phi - phid)
    dtheta = pid_theta(theta - thetad)
    # print(dtheta)
    dpsi = u[3]

    # convert rotation quaternion to euler angles and rotation matrix

    # rpy rates around around body axis
    new_ctrl = RateThrust()
    new_ctrl.angular_rates.x = dphi
    new_ctrl.angular_rates.y = dtheta
    new_ctrl.angular_rates.z = dpsi
    new_ctrl.thrust.z = thrustd
    ctrl_pub.publish(new_ctrl)

    # oscillate btwn two points to get step responses of angles
    error = np.linalg.norm((x - xref)[:3])

    # Plot results
    time_axis.append(iter)
    roll_data.append(phi)
    rolld_data.append(phid)
    pitch_data.append(theta)
    pitchd_data.append(thetad)
Beispiel #30
0
    def geometric_controller(self, state_msg, traj_msg):

        # In general    u = -K*x + (N_u + K*N_x)*r
        # r = reference state
        # x = state
        # K = LQR gains
        # N_u, N_x = refrence input and reference state matrices

        # extract reference values
        x_r, y_r, z_r = [
            traj_msg.pose.position.x, traj_msg.pose.position.y,
            traj_msg.pose.position.z
        ]
        vx_r, vy_r, vz_r = [
            traj_msg.twist.linear.x, traj_msg.twist.linear.y,
            traj_msg.twist.linear.z
        ]
        ori_quat_r = [
            traj_msg.pose.orientation.x, traj_msg.pose.orientation.y,
            traj_msg.pose.orientation.z, traj_msg.pose.orientation.w
        ]
        psi_r, theta_r, phi_r = tf.transformations.euler_from_quaternion(
            ori_quat_r, axes='rzyx')
        p_r, q_r, r_r = [
            traj_msg.twist.angular.x, traj_msg.twist.angular.y,
            traj_msg.twist.angular.z
        ]
        w_b_r = np.array([[p_r], [q_r], [r_r]])
        Rbw_ref = np.array(
            [[traj_msg.rot[0], traj_msg.rot[1], traj_msg.rot[2]],
             [traj_msg.rot[3], traj_msg.rot[4], traj_msg.rot[5]],
             [traj_msg.rot[6], traj_msg.rot[7], traj_msg.rot[8]]])
        #print("Rbw ref: \n{}".format(Rbw_ref))

        # extract drone real state values
        x, y, z = [
            state_msg.pose.position.x, state_msg.pose.position.y,
            state_msg.pose.position.z
        ]
        vx, vy, vz = [
            state_msg.twist.linear.x, state_msg.twist.linear.y,
            state_msg.twist.linear.z
        ]
        ori_quat = [
            state_msg.pose.orientation.x, state_msg.pose.orientation.y,
            state_msg.pose.orientation.z, state_msg.pose.orientation.w
        ]
        psi, theta, phi = tf.transformations.euler_from_quaternion(ori_quat,
                                                                   axes='rzyx')
        Rwb = tf.transformations.quaternion_matrix(ori_quat)
        Rbw = Rwb[0:3, 0:3].T  # get body to world frame rotation
        p, q, r = [
            state_msg.twist.angular.x, state_msg.twist.angular.y,
            state_msg.twist.angular.z
        ]
        w_b = np.array([[p], [q], [r]])

        # ******************************************#
        #            POSITION CONTROL LOOP
        # ******************************************#
        if (self.loops == 0):

            # compute desired input ua = ua_ref + ua_e
            # ue_ref : from dif flatness
            # ua_e = -Kp*(p - p_ref) - Kd * (v - v_ref)    using PID controller
            pos = np.array([[x], [y], [z]])
            pos_ref = np.array([[x_r], [y_r], [z_r]])
            v = np.array([[vx], [vy], [vz]])
            v_ref = np.array([[vx_r], [vy_r], [vz_r]])

            Kp = np.diag([lqrg.Kpx2, lqrg.Kpy2, lqrg.Kpz2])
            Kd = np.diag([lqrg.Kdx2, lqrg.Kdy2, lqrg.Kdz2])
            Ki = np.diag([lqrg.Kix2, lqrg.Kiy2, lqrg.Kiz2])

            self.pos_err = self.pos_err + (pos - pos_ref)
            ua_e = -1.0 * np.dot(Kp, pos - pos_ref) - 1.0 * np.dot(
                Kd, v - v_ref) - 1.0 * np.dot(Ki,
                                              self.pos_err)  # PID control law
            #print("pos error mag: {}".format(np.linalg.norm(pos - pos_ref)))
            #print("vel error mag: {}".format(np.linalg.norm(v-v_ref)))
            ua_ref = np.array([[traj_msg.ua.x], [traj_msg.ua.y],
                               [traj_msg.ua.z]])

            ua = ua_e + ua_ref  # desired acceleration
            #print("ua mag {}".format(np.linalg.norm(ua)))
            ua = self.clip_vector(ua, self.max_thrust)  # saturate input

            # compute Thrust -T- as
            #   T = m*wzb.T*(ua + g*zw)
            #
            e3 = np.array([[0.0], [0.0],
                           [1.0]])  #  z axis of body expressed in body frame
            zw = np.array(
                [[0.0], [0.0],
                 [1.0]])  #  z axis of world frame expressed in world frame
            #Rwb = tf.transformations.euler_matrix(psi, theta, phi, axes='rzyx') # world to body frame rotation
            #print("Rbw real: \n{}".format(Rbw))

            wzb = np.dot(Rbw, e3)  # zb expressed in world frame
            self.T = self.m * np.dot(wzb.T, (ua + g * zw))[0][0]
            #print("T : {}".format(self.T))

            # Following Fassler, Fontana, Theory and Math Behing RPG Quadrotor Control
            #  Rbw_des = [xb_des yb_des zb_des]  with zb_des = ua + g*zw / ||ua + g*zw||
            #  represents the desired orientation (and not the one coming from dif flatness)
            zb_des = (ua + g * zw) / np.linalg.norm(ua + g * zw)
            #T = self.m*np.dot(zb_des.T,(-ua + g*zw))[0][0]

            #print("PSI value: {}".format(psi_r))
            yc_des = np.array(df_flat.get_yc(
                psi_r))  #transform to np.array 'cause comes as np.matrix
            xb_des = np.cross(yc_des, zb_des, axis=0)
            xb_des = xb_des / np.linalg.norm(xb_des)
            yb_des = np.cross(zb_des, xb_des, axis=0)

            self.Rbw_des = np.concatenate((xb_des, yb_des, zb_des), axis=1)

            # Orientation error matrix is
            # Rbw.T*Rbw_des  because iff Rbw = Rbw_des, then Rbw.T*Rbw_des = I_3

            Kp = np.diag([lqrg.Kp1, lqrg.Kp1, lqrg.Kp1])
            Kd = np.diag([lqrg.Kd1, lqrg.Kd1, lqrg.Kd1])
            #w_b_in = -np.dot(Kp,or_e) - np.dot(Kd,w_b_e)

            self.loops = self.loops + 1

        else:
            self.loops = self.loops + 1
            if (self.loops == self.pos_loop_freq):
                self.loops = 0

        #print("Position Error: {}".format(np.linalg.norm(self.pos_err)))
        #print("T computed: {}".format(self.T))

        # ******************************************#
        #        ORIENTATION CONTROL LOOP
        # ******************************************#

        # ********************************** #
        #      USING ROTATION MATRIX         #
        # ********************************** #

        # Calculate input using Propietary method
        #self.w_b_in = self.get_wdes_1(Rbw, self.Rbw_des, self.w_b_des, self.Kw)
        #self.w_b_in = self.get_wdes_2(Rbw, self.Rbw_des, self.Katt)

        #w_b_e = w_b - np.dot(self.Rbw_des.T, np.dot(Rbw_ref, w_b_r))

        #self.w_b_des = -1.0*np.dot(self.Kw, np.dot(Rbw.T, np.dot(Rbw_ref,w_b_r)))

        #or_e = 0.5*self.vex( (np.dot(self.Rbw_des.T,Rbw) - np.dot(Rbw.T,self.Rbw_des)) )
        #or_e = -1.0*np.dot(self.Ko, or_e)

        # compute feedback angular velocity
        self.Rbw_ref_dot = np.dot(Rbw_ref, self.hat(w_b_r))
        w_fb = self.get_wdes_4(Rbw, self.Rbw_des, self.Rbw_ref_dot, w_b_r)

        delta_t = rospy.Time.now() - self.t1
        delta_t = delta_t.to_sec()
        print("Delta t: {}".format(delta_t))
        #w_fb = w_fb / 1.0

        self.t1 = rospy.Time.now()

        # create and fill message
        rt_msg = RateThrust()

        rt_msg.header.stamp = rospy.Time.now()
        rt_msg.header.frame_id = 'uav/imu'

        rt_msg.angular_rates.x = w_fb[0][
            0]  #+ or_e[0][0]  #self.w_b_in[0][0]  + w_b_r[0][0]
        rt_msg.angular_rates.y = w_fb[1][
            0]  #+ or_e[1][0] #self.w_b_in[1][0]  + w_b_r[1][0]
        rt_msg.angular_rates.z = w_fb[2][
            0]  #+ or_e[2][0] #self.w_b_in[2][0]  + w_b_r[2][0]

        rt_msg.thrust.x = 0.0
        rt_msg.thrust.y = 0.0
        rt_msg.thrust.z = self.T  # self.m*np.linalg.norm(t)

        # publish
        self.input_publisher.publish(rt_msg)
        rospy.loginfo(rt_msg)