def run(self):

        # continuous loop that monitors the information coming from the quadcopter
        while 1:

            # stores message from the quadcopter
            msg = self.master.recv_match(blocking=False)
            if msg:
                # stores the message type
                msg_type = msg.get_type()
                #print msg_type # debugging to check which data streams are operational

                # checks if the message contains information
                if msg.get_type() == "BAD_DATA":
                    if mavutil.all_printable(msg.data):
                        sys.stdout.write(msg.data)
                        sys.stdout.flush()
                else:
                    # add in new messages to monitor below
                    if msg_type == "ATTITUDE":

                        # publishes information to the rostopic
                        self.pub_attitude.publish(msg.roll * 180 / 3.1415, msg.pitch * 180 / 3.1415,
                                                  msg.yaw * 180 / 3.1415, msg.rollspeed, msg.pitchspeed, msg.yawspeed)

                        #upadtes imu values
                        self.imu_yaw = msg.yaw * 180 / 3.14159
                        self.imu_roll = msg.roll * 180 / 3.14159
                        self.imu_pitch = msg.pitch * 180 / 3.14159

                    # updates the channel data
                    elif msg_type == "RC_CHANNELS_RAW":
                        self.ch1 = msg.chan1_raw
                        self.ch2 = msg.chan2_raw
                        self.ch3 = msg.chan3_raw
                        self.ch4 = msg.chan4_raw
                        self.ch5 = msg.chan5_raw
                        self.ch6 = msg.chan6_raw
                        self.ch7 = msg.chan7_raw
                        self.ch8 = msg.chan8_raw


            #checks if channel 5 is below the threshold and gives back control to the transmitter
            if self.ch5 < 1400:
                if not self.transmitter_control:
                    if self.have_control:

                        # informs via terminal
                        print "You no longer have control, Transmitter has taken over control"
                        self.transmitter_control = True
                        self.have_control = False

                        # changes the control message on the ui
                        ui.control_toggle_button.setText("Take Over Control")
                        self.disconnect_pwm_channels()
            else:
                # turns off transmitter control so that the program is able to take over when requested
                self.transmitter_control = False
            time.sleep(0.01)
예제 #2
0
def mainloop():
    rospy.init_node('roscopter')
    while not rospy.is_shutdown():
        rospy.sleep(0.001)
        msg = master.recv_match(blocking=False)
        if not msg:
            continue
        #print msg.get_type()
        if msg.get_type() == "BAD_DATA":
            if mavutil.all_printable(msg.data):
                sys.stdout.write(msg.data)
                sys.stdout.flush()
        else:
            msg_type = msg.get_type()
            if msg_type == "RC_CHANNELS_RAW":
                pub_rc.publish([
                    msg.chan1_raw, msg.chan2_raw, msg.chan3_raw, msg.chan4_raw,
                    msg.chan5_raw, msg.chan6_raw, msg.chan7_raw, msg.chan8_raw
                ])
            if msg_type == "HEARTBEAT":
                pub_state.publish(
                    msg.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED,
                    msg.base_mode
                    & mavutil.mavlink.MAV_MODE_FLAG_GUIDED_ENABLED,
                    mavutil.mode_string_v10(msg))
            if msg_type == "VFR_HUD":
                pub_vfr_hud.publish(msg.airspeed, msg.groundspeed, msg.heading,
                                    msg.throttle, msg.alt, msg.climb)

            if msg_type == "GPS_RAW_INT":
                fix = NavSatStatus.STATUS_NO_FIX
                if msg.fix_type >= 3:
                    fix = NavSatStatus.STATUS_FIX
                pub_gps.publish(
                    NavSatFix(
                        latitude=msg.lat / 1e07,
                        longitude=msg.lon / 1e07,
                        altitude=msg.alt / 1e03,
                        status=NavSatStatus(status=fix,
                                            service=NavSatStatus.SERVICE_GPS)))
            #pub.publish(String("MSG: %s"%msg))
            if msg_type == "ATTITUDE":
                pub_attitude.publish(msg.roll, msg.pitch, msg.yaw,
                                     msg.rollspeed, msg.pitchspeed,
                                     msg.yawspeed)

            if msg_type == "LOCAL_POSITION_NED":
                print "Local Pos: (%f %f %f) , (%f %f %f)" % (
                    msg.x, msg.y, msg.z, msg.vx, msg.vy, msg.vz)

            if msg_type == "RAW_IMU":
                pub_raw_imu.publish(Header(), msg.time_usec, msg.xacc,
                                    msg.yacc, msg.zacc, msg.xgyro, msg.ygyro,
                                    msg.zgyro, msg.xmag, msg.ymag, msg.zmag)
예제 #3
0
def mainloop():
    rospy.init_node('roscopter')
    while not rospy.is_shutdown():
        rospy.sleep(0.001)
        msg = master.recv_match(blocking=False)
        if not msg:
            continue
        #print msg.get_type()
        if msg.get_type() == "BAD_DATA":
            if mavutil.all_printable(msg.data):
                sys.stdout.write(msg.data)
                sys.stdout.flush()
        else: 
            msg_type = msg.get_type()
            if msg_type == "RC_CHANNELS_RAW" :
                pub_rc.publish([msg.chan1_raw, msg.chan2_raw, msg.chan3_raw, msg.chan4_raw, msg.chan5_raw, msg.chan6_raw, msg.chan7_raw, msg.chan8_raw]) 
            if msg_type == "HEARTBEAT":
                pub_state.publish(msg.base_mode & mavutil.mavlink.MAV_MODE_FLAG_SAFETY_ARMED, 
                                  msg.base_mode & mavutil.mavlink.MAV_MODE_FLAG_GUIDED_ENABLED, 
                                  mavutil.mode_string_v10(msg))
            if msg_type == "VFR_HUD":
                pub_vfr_hud.publish(msg.airspeed, msg.groundspeed, msg.heading, msg.throttle, msg.alt, msg.climb)

            if msg_type == "GPS_RAW_INT":
                fix = NavSatStatus.STATUS_NO_FIX
                if msg.fix_type >=3:
                    fix=NavSatStatus.STATUS_FIX
                pub_gps.publish(NavSatFix(latitude = msg.lat/1e07,
                                          longitude = msg.lon/1e07,
                                          altitude = msg.alt/1e03,
                                          status = NavSatStatus(status=fix, service = NavSatStatus.SERVICE_GPS) 
                                          ))
            #pub.publish(String("MSG: %s"%msg))
            if msg_type == "ATTITUDE" :
                pub_attitude.publish(msg.roll, msg.pitch, msg.yaw, msg.rollspeed, msg.pitchspeed, msg.yawspeed)
                px4_time[0] = msg.time_boot_ms  # get the time from px4
                local_time[0] = time.time()     # get the local start time

            if msg_type == "LOCAL_POSITION_NED" :
                print "Local Pos: (%f %f %f) , (%f %f %f)" %(msg.x, msg.y, msg.z, msg.vx, msg.vy, msg.vz)

            if msg_type == "RAW_IMU" :
                pub_raw_imu.publish (Header(), msg.time_usec, 
                                     msg.xacc, msg.yacc, msg.zacc, 
                                     msg.xgyro, msg.ygyro, msg.zgyro,
                                     msg.xmag, msg.ymag, msg.zmag)
예제 #4
0
파일: position.py 프로젝트: dut09/roscopter
def mainloop():
    print("Waiting")
    global hz_counter
    hz_counter=1;
    trate = 1.0/rate
    first_time_imu=True
    first_time_pos=True
    earliercmdtime = 0
    ## Set home values from Vicon/Kinect data ##
    rospy.sleep(.1)
    set_home()
    
    ## Integration and differentiation error initialized ##
    I_ex=0.0; I_ey=0.0; I_ez=0.0
    D_ex=0.0; D_ey=0.0; D_ez=0.0
    new_err_x=0.0; new_err_y=0.0; new_err_z=0.0;

    ## IMU values initialized ##
    imu_roll=0.0; imu_pitch=0.0; first_yaw=0.0;
    imu_yaw=0.0; first_roll=0.0; first_pitch=0.0

    ## Position values initialised ##
    pos_x=0.0; pos_y=0.0; pos_z=0.0
  
    
    while not rospy.is_shutdown(): # start loop
       
        #continue
        if float(time.time())-trate >= earliercmdtime:
                earliercmdtime = time.time()
               
                hz_counter =1;
		if connect_APM:      # enable these lines if you want to obtain the data from the arducopter on-the-fly
	#            msg = master.recv_match(blocking=False)
	#            if not msg:
	#                continue
		    if 0:#msg:
			    if msg.get_type() == "BAD_DATA":
				if mavutil.all_printable(msg.data):
				    sys.stdout.write(msg.data)
				    sys.stdout.flush()
			    else: 
				msg_type = msg.get_type()
				if msg_type == "ATTITUDE" :
				    pub_attitude.publish(msg.roll*180/3.1415, msg.pitch*180/3.1415, msg.yaw*180/3.1415, msg.rollspeed, msg.pitchspeed, msg.yawspeed)
		    	            if first_time_imu:
					first_time_imu=False
					first_yaw = msg.yaw
					first_roll = msg.roll
					first_pitch = msg.pitch
					imu_yaw = msg.yaw
					imu_roll = msg.roll
					imu_pitch = msg.pitch
				    else:
					imu_yaw = msg.yaw
					imu_roll = msg.roll
					imu_pitch = msg.pitch	   

		
                ## Update position values ##
		(old_pos_x,old_pos_y,old_pos_z,pos_x,pos_y,pos_z) = update_pos_values(pos_x,pos_y,pos_z,vicon_x,vicon_y,vicon_z,first_time_pos)	
		(err_x,err_y,err_z) = calc_pos_error(home_x,home_y,home_z,pos_x,pos_y,pos_z)   # home - pos
		(d_x, d_y, d_z) = calc_pos_error(old_pos_x,old_pos_y,old_pos_z,pos_x,pos_y,pos_z) 

		## Toggle for first time through loop ##
		if first_time_pos:
		    first_time_pos=False

		## PID controller  (roll+pitch and thrust, yaw later) ##
		I_ex = I_ex + err_x*trate
		I_ey = I_ey + err_y*trate
		I_ez = I_ez + err_z*trate

		V_x = d_x*trate	# units of m/s
		V_y = d_y*trate	# units of m/s
		V_z = d_z*trate	# units of m/s

		## Cap the integration error as well after certain value ##
		if (I_ex) > I_ex_MAX:
		    I_ex = I_ex_MAX #* I_ex / abs(I_ex)

		if (I_ex) < -I_ex_MAX:
		    I_ex = -I_ex_MAX #* I_ex / abs(I_ex)

		if (I_ey) > I_ey_MAX:
		    I_ey = I_ey_MAX #* I_ey / abs(I_ey)

		if (I_ey) < -I_ey_MAX:
		    I_ey = -I_ey_MAX #* I_ey / abs(I_ey)

		if (I_ez) > I_ez_MAX:
		    I_ez = I_ez_MAX #* I_ez / abs(I_ez)

		if (I_ez) < I_ez_MAX:
		    I_ez = -I_ez_MAX #* I_ez / abs(I_ez)
	     
		p_pitch = pitch_P * err_x
		i_pitch = pitch_I * I_ex
		d_pitch = pitch_D * V_x

		p_roll =  roll_P * err_y
		i_roll =  roll_I * I_ey
		d_roll =  roll_D * V_y

		p_th = thrust_P * err_z
		i_th = thrust_I * (I_ez)
		d_th = thrust_D * V_z

		##  Calculate PID values to send
		sendroll =  (p_roll + i_roll + d_roll) #

		
		sendpitch = (p_pitch + i_pitch + d_pitch) 
		###### neg pitch     === hexacopter will move forward
		###### pos pitch     === hexacopter will move backward
		###### neg roll     === hexacopter will move left
		###### pos roll     === hexacopter will move right

	        sendthrust = p_th + i_th + d_th
                sendyaw = yaw_P*(vicon_yaw  - home_yaw) #0 #-imu_yaw 

		## Cap the roll/pitch/yaw/thrust values ##
		if (sendroll) > roll_MAX:
		    sendroll = roll_MAX #* sendroll / abs(sendroll)

		if (sendroll) < -roll_MAX:
		    sendroll = -roll_MAX #* sendroll / abs(sendroll)
	 

		if (sendpitch) > pitch_MAX:
		    sendpitch = pitch_MAX #* sendpitch / abs(sendpitch)
		   
		if (sendpitch) < -pitch_MAX:
		    sendpitch = -pitch_MAX #* sendpitch / abs(sendpitch)



	  	if sendthrust > thrust_MAX:
		    sendthrust = thrust_MAX
		if sendthrust < 0:
		    sendthrust = 0

               
		## Send values to APM ##
		if connect_APM:
		    master.mav.set_roll_pitch_yaw_thrust_send(master.target_system, master.target_component, 
		                			      sendroll, sendpitch, sendyaw, sendthrust)

                send_odometry.transform.translation.x = sendroll * 180/3.14159
                send_odometry.transform.translation.y = sendpitch * 180/3.14159
                send_odometry.transform.translation.z = sendyaw * 180/3.14159
		## Print some output to display for debugging ##
#		stdscr.addstr(0, 0, "Position controller is running...")
#		if connect_APM:
#		    stdscr.addstr(1, 0, "Connection to APM established...")
#		else:
#		    stdscr.addstr(1, 0, "******Warning: No connection to APM!*************")

#		stdscr.addstr(3, 0, "The gains are:")
#		stdscr.addstr(4, 0, "              P       I       D")
#		stdscr.addstr(5, 0, "Roll          %.3f   %.3f   %.3f" % (roll_P, roll_I, roll_D))
#		stdscr.addstr(6, 0, "Pitch         %.3f   %.3f   %.3f" % (pitch_P, pitch_I, pitch_D))
#		stdscr.addstr(7, 0, "Yaw           %.3f   %.3f   %.3f" % (yaw_P, yaw_I, yaw_D))
#		stdscr.addstr(8, 0, "Thrust        %.3f   %.3f   %.3f" % (thrust_P, thrust_I, thrust_D))
#		stdscr.addstr(10, 0, "Home position is:    (%+.3f,%+.3f,%+.3f) m" % (home_x, home_y, home_z))
#		stdscr.addstr(11, 0, "Current position is: (%+.3f,%+.3f,%+.3f) m" % (pos_x, pos_y, pos_z))
#		stdscr.addstr(12, 0, "Position error is:   (%+.3f,%+.3f,%+.3f) m" % (err_x, err_y, err_z))
	#	if connect_APM:
	#	    stdscr.addstr(14, 0, "The IMU values are  (%+.3f,%+.3f,%+.3f) deg     " % (imu_roll/deg2pi, imu_pitch/deg2pi, imu_yaw/deg2pi))
	#	else:
	#	    stdscr.addstr(14, 0, "The IMU values are not available!")
#		stdscr.addstr(15, 0, "The Vicon values are  (%+.3f,%+.3f,%+.3f) deg      " % (vicon_roll/deg2pi,vicon_pitch/deg2pi,vicon_yaw/deg2pi))
#		stdscr.addstr(17, 0, "Sending control commands to APM:")
#		stdscr.addstr(18, 0, "Roll (deg)    Pitch (deg)    Yaw (deg)    Thrust (PWM)")
#		stdscr.addstr(19, 0, "%+.3f         %+.3f         %+.3f         %+.3f" % (sendroll/deg2pi, sendpitch/deg2pi, sendyaw/deg2pi, sendthrust))
#		stdscr.addstr(20, 0, "      \n")
#		stdscr.refresh()
 #       else:
 #               hz_counter =0; #stdscr.addstr(22, 0, " The rate of command is not correct")
                pub_odom .publish(send_odometry)