Exemple #1
0
class ARDrone(Drone):
    def __init__(self):
        super().__init__()

        self.bebop = Bebop()

        print("connecting to bebop drone")
        self.connection.emit("progress")
        self.success = self.bebop.connect(5)
        if self.success:
            self.connection.emit("on")
            self.bebop.set_max_altitude(20)
            self.bebop.set_max_distance(20)
            self.bebop.set_max_rotation_speed(180)
            self.bebop.set_max_vertical_speed(2)
            self.bebop.enable_geofence(1)
            self.bebop.set_hull_protection(1)

            # todo: battery signal to emit (look in sensors)
            #TODO test this piece of code
            self.bebop.set_user_sensor_callback(print,
                                                self.bebop.sensors.battery)
        else:
            print("refresh....")
            self.connection.emit("off")

    def take_off(self):
        self.bebop.safe_takeoff(5)

    def land(self):
        self.bebop.safe_land(5)

    def stop(self):
        self.bebop.disconnect()

    def fly_direct(self, roll, pitch, yaw, vertical_movement):
        my_roll = self.bebop._ensure_fly_command_in_range(roll)
        my_pitch = self.bebop_ensure_fly_command_in_range(pitch)
        my_yaw = self.bebop_ensure_fly_command_in_range(yaw)
        my_vertical = self.bebop_ensure_fly_command_in_range(vertical_movement)
        command_tuple = self.bebop.command_parser.get_command_tuple(
            "ardrone3", "Piloting", "PCMD")
        self.bebop.drone_connection.send_single_pcmd_command(
            command_tuple, my_roll, my_pitch, my_yaw, my_vertical)

    def process_motion(self, _up, _rotate, _front, _right):
        velocity_up = _up * self.max_vert_speed
        velocity_yaw = _rotate * self.max_rotation_speed
        velocity_pitch = _front * self.max_horiz_speed
        velocity_roll = _right * self.max_horiz_speed
        #print("PRE", velocity_roll, velocity_pitch, velocity_up, velocity_yaw)
        self.fly_direct(velocity_roll, velocity_pitch, velocity_yaw,
                        velocity_up)
    # cc = ba[4:8]  # number of extra header fields
    print(pt.uint)  # for testing purposes
    # return ba[(12 + cc) * 8:]  # bit contents


# create drone and start video
drone = Bebop()
drone.connect(10)
drone.set_video_resolutions("rec1080_stream480")
drone.set_video_framerate("24_FPS")
drone.start_video_stream()

# create socket of required type, and bind to port
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # opens with ipv4 address and reads UDP packet
sock.bind(('192.168.42.63', 55004))  # binds machine to port

# receive packet and get payload
for _ in range(10):
    msg = sock.recv(4096)
    strip_packet(msg)
    # payload = stripPacket(msg)

'''The received contents are H.264 encoded video. While we can put packets together, there doesn't seem to be 
documentation on manual conversion to video or images, as all methods result in using opencv or other libraries/apps. 
Hence we adopt the opencv approach. This code can stay because it required far too much research to throw away. '''

# test message
sock.close()
drone.disconnect()
print("done")
        elif ch == "f":
            print("flip")
            bebop.flip(direction="front")
            c.send(("controller received " + ch).encode('utf-8'))

        elif ch == "l":
            print("land")
            bebop.safe_land(10)
            c.send(("controller received " + ch).encode('utf-8'))

        elif ch == "q" or len(ch) == 0:  # ソケットがSIGPIPEになったときも着地
            print("end")
            bebop.safe_land(10)
            c.send(("controller received " + ch).encode('utf-8'))
            c.close()
            break

    print("DONE - disconnecting")
    bebop.smart_sleep(5)
    print(bebop.sensors.battery)
    bebop.disconnect()

except:
    print("error!")
    bebop.safe_land(10)
    c.close()
    print("DONE - disconnecting")
    bebop.smart_sleep(5)
    print(bebop.sensors.battery)
    bebop.disconnect()
Exemple #4
0
class myoBebop(object):

	def __init__(self , indoorFly = True):
		'''类初始化函数'''
		self.bebop = None 
		self.indoorFlyFlag = indoorFly
		self.actionType = "rest"   #当前的动作类型
		self.startSuccessFlag = False #初始化是否成功标志位
		self.takeOfFlag = False		#是否起飞标志位
		self.landFlag = True	#是否降落标志位
		self.startFlag = False	#程序开始标志位
		self.executeCommondFlag = True		#命令执行成功标志位
		#动作映射字典
		self.actionMapDict = {	"front"	: 	"fist"  , 	"back" 	:	 "open_hand" , 
								"left"	: 	"one" , 	"right" : 	 "two" ,
								"up"	:	"good",		"down"	:	 "low" ,
								"rotateLeft" : "three" ,  "rotateRight" : "four" , 
								"takeOf": 	"ok"  , 	"land" 	: 	 "love"}
		self.tempCount = 0   #计数
		self.excuteFlag1 = True   #读取动作类别标志位
		self.excuteFlag2 = True	  #读取按键值的标志位
		self.flyType = 0  #飞机飞行类别(0:正常飞行 , 1:特技飞行)
		self.moveStepTime = 1  #飞行器水平运行步长时间
		self.rotateStepTime = 1 #飞行器旋转运行步长时间

	def start(self):
		'''开始函数'''
		#初始化飞机对象
		self.bebop = Bebop()
		#连接飞机  
		print("connecting")
		self.success = self.bebop.connect(10)  #与飞机进行连接(最大尝试次数为10次)
		if self.success == True: 
			print("sleeping")  
			self.bebop.smart_sleep(5)
			self.bebop.ask_for_state_update()   #获取飞机的状态
			if self.indoorFlyFlag == True:
				self.setIndoorFly()
				print("set indoor fly sucess!!!")
			print("The aircraft was successfully initialized!")
			self.startSuccessFlag = True   #开始成功

		else:
			print("The connection failed. Please check again!")
			self.startSuccessFlag = False   #开始失败
		self.removeExitFile()


	def bebopFly(self , actionType):
		'''根据动作类别进行相应的动作'''
		if actionType == self.actionMapDict["front"]:   #向前飞
			self.executeCommondFlag = False   
			
			print("flying state is %s" % self.bebop.sensors.flying_state)
			if self.flyType == 0:
				self.bebop.fly_direct(roll=0, pitch=50, yaw=0, vertical_movement=0, duration=self.moveStepTime)
				print("fly front")
			elif self.flyType == 1:
				self.success = self.bebop.flip(direction="front")
				print("flip front")
				print("mambo flip result %s" % self.success)
				self.bebop.smart_sleep(5)
			self.executeCommondFlag = True

		elif actionType == self.actionMapDict["back"]:   #向后飞
			self.executeCommondFlag = False
			
			print("flying state is %s" % self.bebop.sensors.flying_state)
			if self.flyType == 0:
				self.bebop.fly_direct(roll=0, pitch=-50, yaw=0, vertical_movement=0, duration=self.moveStepTime)
				print("fly back")
			elif self.flyType == 1:
				self.success = self.bebop.flip(direction="back")
				print("flip back")
				print("mambo flip result %s" % self.success)
				self.bebop.smart_sleep(5)
			self.executeCommondFlag = True

		elif actionType == self.actionMapDict["left"]:   #左飞
			self.executeCommondFlag = False
			
			print("flying state is %s" % self.bebop.sensors.flying_state)
			if self.flyType == 0:
				self.bebop.fly_direct(roll=50, pitch=0, yaw=0, vertical_movement=0, duration=self.moveStepTime)
				print("fly left")
			elif self.flyType == 1:
				self.success = self.bebop.flip(direction="left")
				print("flip left")
				print("mambo flip result %s" % self.success)
				self.bebop.smart_sleep(5)
			self.executeCommondFlag = True

		elif actionType == self.actionMapDict["right"]:   #右飞
			self.executeCommondFlag = False
			
			print("flying state is %s" % self.bebop.sensors.flying_state)
			if self.flyType == 0:
				self.bebop.fly_direct(roll=-50, pitch=0, yaw=0, vertical_movement=0, duration=self.moveStepTime)
				print("fly right")
			elif self.flyType == 1:
				self.success = self.bebop.flip(direction="right")
				print("flip right")
				print("mambo flip result %s" % self.success)
				self.bebop.smart_sleep(5)
			self.executeCommondFlag = True

		elif actionType == self.actionMapDict["up"]:   #上飞
			self.executeCommondFlag = False
			print("flying state is %s" % self.bebop.sensors.flying_state)
			if self.flyType == 0:
				self.bebop.fly_direct(roll = 0, pitch = 0, yaw = 0, vertical_movement=50, duration = self.moveStepTime)
				print("fly up")
			elif self.flyType == 1:
				pass
			self.executeCommondFlag = True

		elif actionType == self.actionMapDict["down"]:   #下飞
			self.executeCommondFlag = False
			print("flying state is %s" % self.bebop.sensors.flying_state)
			if self.flyType == 0:
				self.bebop.fly_direct(roll = 0, pitch = 0, yaw = 0, vertical_movement= - 50, duration = self.moveStepTime)
				print("fly down")
			elif self.flyType == 1:
				pass
			self.executeCommondFlag = True

		elif actionType == self.actionMapDict["rotateLeft"]:   #向左旋转
			self.executeCommondFlag = False
			print("flying state is %s" % self.bebop.sensors.flying_state)
			if self.flyType == 0:
				self.bebop.fly_direct(roll=0, pitch=0, yaw=50, vertical_movement=0, duration=self.moveStepTime)
				print("fly rotateLeft")
			elif self.flyType == 1:
				pass
			self.executeCommondFlag = True

		elif actionType == self.actionMapDict["rotateRight"]:   #向右旋转
			self.executeCommondFlag = False
			print("flying state is %s" % self.bebop.sensors.flying_state)
			if self.flyType == 0:
				self.bebop.fly_direct(roll=0, pitch=0, yaw = -50, vertical_movement=0, duration=self.moveStepTime)
				print("fly rotateRight")
			elif self.flyType == 1:
				pass
			self.executeCommondFlag = True

		elif actionType == self.actionMapDict["takeOf"]: #起飞
			self.startFlag = True
			if self.landFlag == True:
				self.landFlag = False
				self.executeCommondFlag = False
				print("take of ")
				self.bebop.safe_takeoff(10)
				self.bebop.smart_sleep(5)
				self.executeCommondFlag = True
				self.takeOfFlag = True

		elif actionType == self.actionMapDict["land"]: #降落
			if self.takeOfFlag == True:
				self.takeOfFlag = False
				self.executeCommondFlag = False
				print("land ")
				self.bebop.safe_land(10)
				self.bebop.smart_sleep(5)
				self.landFlag = True
				self.executeCommondFlag = True
	#myo失去连接后,飞机自动着落		
	def safeAction(self):
		if self.startFlag == True:
			if self.flyType == 0:
				if self.tempCount > 100:
					self.bebop.safe_land(10)
					self.bebop.smart_sleep(5)
					print("DONE - disconnecting")
					self.bebop.disconnect()
					self.mThread.forcedStopThread()
			elif self.flyType == 1:
				if self.tempCount > 300:
					self.bebop.safe_land(10)
					self.bebop.smart_sleep(5)
					print("DONE - disconnecting")
					self.bebop.disconnect()
					self.mThread.forcedStopThread()

	def setTheActionMain(self):
		'''设置动作类别线程函数'''
		if self.excuteFlag1 == True:
			self.excuteFlag1 = False
			os.system("python2 myoMain.py")
			time.sleep(0.01)

	def removeExitFile(self , fileName = "actionTempData.dat" ):
		'''删除已经存在的文件'''
		if os.path.exists(fileName) == True:
			os.remove(fileName)

	def setIndoorFly(self):
		'''设置室内飞行的参数'''
		self.bebop.set_max_tilt(5)
		self.bebop.set_max_vertical_speed(1)

	def getKeyValueMain(self):
		'''获取按键值的线程函数'''
		if self.excuteFlag2 == True:
			self.excuteFlag2 = False
			os.system("python2 quit.py" ) 
			time.sleep(0.01)
	#按键退出函数
	def quitMain(self):
		print("quit")
		self.bebop.safe_land(10)
		self.bebop.smart_sleep(5)
		self.bebop.disconnect()
		self.mThread.forcedStopThread()

	def getTheActionMain(self):
		'''得到动作类别线程函数'''
		global quitFlag
		while True:
			self.actionType = getTheCurrentAction()
			getTheKeyValue()
			if quitFlag == True:
				self.quitMain()
			else:
				if self.actionType == None:
					self.tempCount += 1
				else:
					self.tempCount = 0
				self.safeAction()
				if self.executeCommondFlag == True:
					self.bebopFly(self.actionType)
				time.sleep(0.01)

	def run(self):
		'''运行主程序'''
		try:
			self.mThread = myThread()
			self.mThread.addThread('setTheActionMain' , self.setTheActionMain , 0)
			self.mThread.addThread('getTheActionMain' , self.getTheActionMain , 0)
			self.mThread.addThread('getKeyValueMain' , self.getKeyValueMain , 0)
			self.mThread.runThread()
		except KeyboardInterrupt:
			print("DONE")
			self.bebop.disconnect()
			self.mThread.forcedStopThread()
Exemple #5
0
class Drone:
    def __init__(self):
        self.drone = Bebop()

    def take_off(self):
        ### Connect to Bebop drone and take off ###
        success = self.drone.connect1(10)
        print(success)
        self.drone.safe_takeoff(2)

    def step(self, roll, pitch, yaw, vertical_movement, duration):
        ### Moves the Bebop drone given input parameters ###
        self.drone.fly_direct(self, roll, pitch, yaw, vertical_movement,
                              duration)

    def square(self):
        ### Move the drone in a square pattern###
        #move left and wait 1 second
        self.drone.fly_direct(self,
                              roll=-15,
                              pitch=0,
                              yaw=0,
                              vertical_movement=0,
                              duration=1)
        self.drone.smart_sleep(1)
        #move forward and wait 1 second
        self.drone.fly_direct(self,
                              roll=0,
                              pitch=15,
                              yaw=0,
                              vertical_movement=0,
                              duration=1)
        self.drone.smart_sleep(1)
        #move right and wait 1 second
        self.drone.fly_direct(self,
                              roll=15,
                              pitch=0,
                              yaw=0,
                              vertical_movement=0,
                              duration=1)
        self.drone.smart_sleep(1)
        #move back and wait 1 second
        self.drone.fly_direct(self,
                              roll=0,
                              pitch=-15,
                              yaw=0,
                              vertical_movement=0,
                              duration=1)
        self.drone.smart_sleep(1)

    def zigzag(self):
        ### Move the drone in a 3D zigzag pattern###
        #move left-forward-up and wait 1 second
        self.drone.fly_direct(self,
                              roll=-15,
                              pitch=15,
                              yaw=0,
                              vertical_movement=15,
                              duration=1)
        self.drone.smart_sleep(1)
        #move right-forward-down and wait 1 second
        self.drone.fly_direct(self,
                              roll=15,
                              pitch=15,
                              yaw=0,
                              vertical_movement=-15,
                              duration=1)
        self.drone.smart_sleep(1)
        #move left and wait 1 second
        self.drone.fly_direct(self,
                              roll=-15,
                              pitch=0,
                              yaw=0,
                              vertical_movement=0,
                              duration=1)
        self.drone.smart_sleep(1)
        #move right-back-up and wait 1 second
        self.drone.fly_direct(self,
                              roll=15,
                              pitch=-15,
                              yaw=0,
                              vertical_movement=15,
                              duration=1)
        self.drone.smart_sleep(1)
        #move left-back-down and wait 1 second
        self.drone.fly_direct(self,
                              roll=-15,
                              pitch=-15,
                              yaw=0,
                              vertical_movement=-15,
                              duration=1)
        self.drone.smart_sleep(1)

    def disconnect(self):
        ### Disconect Bebop drone ###
        self.drone.disconnect()

    def land(self):
        ### Disconnect Bebop drone and land ###
        success = self.drone.connect1(10)
        print(success)
        self.drone.ask_for_state_update()
        self.drone.safe_land(5)
        self.drone.disconnect()
Exemple #6
0
class PyParrot(gui.MyFrame1):
    def __init__(self, parent):
        gui.MyFrame1.__init__(self, parent)
        self.statusBar.SetStatusWidths([100, -1])
        self.statusBar.SetStatusText('Not Connected')
        self.lc_commands.InsertColumn(0, 'command', width=300)
        self.bebop = Bebop()

        # load saved commands from file
        self._loadJsonFile()
    
    def OnClose( self, event ):
        if wx.MessageBox("Commands are not yet saved. Do you want to save now?", "Save Changes", wx.ICON_QUESTION | wx.YES_NO) == wx.YES:
            # Retrive commands from lc_commands
            cmdList = []
            for i in range(self.lc_commands.GetItemCount()):
                cmdList.append(self.lc_commands.GetItemText(i))
            self._saveJsonFile(cmdList)

        self.OnDisconnect(None)
        event.Skip() # calls the parent close method

    def OnConnect( self, event ):
        isConnected = self.bebop.connect(10)
        statusText = 'Connected'
        if not isConnected:
            statusText = 'Not ' + statusText
        self.statusBar.SetStatusText(statusText)

    def OnDisconnect( self, event ):
        self.bebop.disconnect()
        self.statusBar.SetStatusText('Disconnected')
        self.statusBar.SetStatusText(f'Battery: {self.bebop.sensors.battery}%', 1)

    def OnTakeOff( self, event ):
        self.bebop.safe_takeoff(10)

        # By default, setting the status text only sets the first
        # one. So we must specify the second status text (index 1
        # , instead of index 0)
        self.statusBar.SetStatusText('Taking off', 1)

    def OnLand( self, event ):
        self.bebop.safe_land(10)
        self.statusBar.SetStatusText('Landing', 1)

    def OnAddTakeOff( self, event ):
        self._addCommand(f'{CmdType.TakeOff.value},10')

    def OnAddLand( self, event ):
        self._addCommand(f'{CmdType.Land.value},10')

    def OnAddRelative( self, event ):
        x = int(self.fld_x.GetValue())
        y = int(self.fld_y.GetValue())
        z = int(self.fld_z.GetValue())
        rads = int(self.fld_radians.GetValue())
        self._addCommand(f'{CmdType.Relative.value},{x},{y},{z},{rads}')

    def OnAddDirect( self, event ):
        roll = int(self.fld_roll.GetValue())
        pitch = int(self.fld_pitch.GetValue())
        yaw = int(self.fld_yaw.GetValue())
        vertical = int(self.fld_vertical.GetValue())
        duration = int(self.fld_duration.GetValue())
        self._addCommand(f'{CmdType.Direct.value},{roll},{pitch},{yaw},{vertical},{duration}')

    def OnAddSleep( self, event ):
        sleep = int(self.fld_sleep.GetValue())
        self._addCommand(f'{CmdType.Sleep.value},{sleep}')

    def OnAddFlip( self, event ):
        dir = str(self.fld_direction.GetValue())
        self._addCommand(f'{CmdType.Flip.value},{dir}')

    def OnAddFlyGrid(self, event):
        print("Make sure you take off first!")
        heightGain = int(self.fld_gridHeight.GetValue())
        lengthForward = int(self.fld_gridLength.GetValue())
        width = int(self.fld_gridWidth.GetValue())
        biLines = int(self.fld_gridLines.GetValue())
        widthSection = width/(biLines+1)

        # Rise
        self._addCommand(f'{CmdType.Relative.value},0,0,{heightGain},0')
        # Fly forward and turn right
        self._addCommand(f'{CmdType.Relative.value},{lengthForward},0,0,90')
        # Flip
        self._addCommand(f'{"flip"},{"up"}')
        # Fly right and turn right
        self._addCommand(f'{CmdType.Relative.value},{widthSection},0,0,90')
        # Flip
        self._addCommand(f'{"flip"},{"up"}')
        # Fly back and turn left
        self._addCommand(f'{CmdType.Relative.value},{lengthForward},0,0,-90')
        # Flip
        self._addCommand(f'{"flip"},{"up"}')
        while (biLines >= 2):
            biLines -= 2
            # Fly right and turn left
            self._addCommand(f'{CmdType.Relative.value},{widthSection},0,0,-90')
            # Flip
            self._addCommand(f'{"flip"},{"up"}')
            # Fly forward and turn right
            self._addCommand(f'{CmdType.Relative.value},{lengthForward},0,0,90')
            # Flip
            self._addCommand(f'{"flip"},{"up"}')
            # Fly right and turn right
            self._addCommand(f'{CmdType.Relative.value},{widthSection},0,0,90')
            # Flip
            self._addCommand(f'{"flip"},{"up"}')
            # Fly back and turn left
            self._addCommand(f'{CmdType.Relative.value},{lengthForward},0,0,-90')
            # Flip
            self._addCommand(f'{"flip"},{"up"}')
        if (biLines == 1):
            biLines -= 1
            # Fly right and turn left
            self._addCommand(f'{CmdType.Relative.value},{widthSection},0,0,-90')
            # Flip
            self._addCommand(f'{"flip"},{"up"}')
            # Fly forward
            self._addCommand(f'{CmdType.Relative.value},{lengthForward},0,0,0')
            # Flip
            self._addCommand(f'{"flip"},{"up"}')
            # Fly back left to home
            self._addCommand(f'{CmdType.Relative.value},{-lengthForward},{-width},0,0')
            # Flip
            self._addCommand(f'{"flip"},{"up"}')
            # Descend
            self._addCommand(f'{CmdType.Relative.value},0,0,{-heightGain},0')
        else:
            # Fly left and turn left
            self._addCommand(f'{CmdType.Relative.value},{-width},0,0,-90')
            # Flip
            self._addCommand(f'{"flip"},{"up"}')
            # Descend
            self._addCommand(f'{CmdType.Relative.value},0,0,{-heightGain},0')
        print("Make sure you land!")

    def OnRemove( self, event ):
        self.lc_commands.DeleteItem(self.lc_commands.GetFocusedItem())

    def OnUp( self, event ):
        """Swap the selected item with the one above it"""
        index = self.lc_commands.GetFocusedItem()
        if index >= 1:
            selItemStr = self.lc_commands.GetItemText(index)
            aboveItemStr = self.lc_commands.GetItemText(index-1)
            self.lc_commands.SetItemText(index, aboveItemStr)
            self.lc_commands.SetItemText(index-1, selItemStr)
            self.lc_commands.Focus(index-1)

    def OnDown( self, event ):
        """Swap the selected item with the one below it"""
        index = self.lc_commands.GetFocusedItem()
        if index < self.lc_commands.GetItemCount() - 1:
            selItemStr = self.lc_commands.GetItemText(index)
            belowItemStr = self.lc_commands.GetItemText(index+1)
            self.lc_commands.SetItemText(index, belowItemStr)
            self.lc_commands.SetItemText(index+1, selItemStr)
            self.lc_commands.Focus(index+1)

    def OnClear( self, event ):
        self.lc_commands.DeleteAllItems()

    def OnRunFromSelection( self, event ):
        index = self.lc_commands.GetFocusedItem()
        while index > 0:
            self.lc_commands.DeleteItem(index - 1)
            index = self.lc_commands.GetFocusedItem()
            
        self.OnRunCommands(event)

    def OnRunCommands( self, event ):
        """Go through each item in lc_commands and convert the string to 
        a list. Then use the first item in the list to determine the 
        command type, and the rest of the items are the params"""

        # Retrive commands from lc_commands
        cmdList = []
        for i in range(self.lc_commands.GetItemCount()):
            cmdList.append(self.lc_commands.GetItemText(i))

        self._saveJsonFile(cmdList)
        
        # Abort running attempt if not connected
        if not self.bebop.drone_connection.is_connected:
            print("No Connection. Aborting process.")
            return

        # === Run Commands ===
        for i in range(self.lc_commands.GetItemCount()):
            args = self.lc_commands.GetItemText(i).split(',')
            self.statusBar.SetStatusText(f'Executing command: {args}', 1)
            try:
                if (args[0] == CmdType.Sleep.value):
                    self.bebop.smart_sleep(int(args[1]))

                elif args[0] == CmdType.TakeOff.value:
                    self.bebop.safe_takeoff(int(args[1]))

                elif args[0] == CmdType.Land.value:
                    self.bebop.safe_land(int(args[1]))

                elif args[0] == CmdType.Direct.value:
                    self.bebop.fly_direct(int(args[1]), int(args[2]), int(args[3]), int(args[4]), int(args[5]))

                elif args[0] == CmdType.Relative.value:
                    self.bebop.move_relative(int(args[1]), int(args[2]), int(args[3]), math.radians(int(args[4])))

                elif args[0] == CmdType.Flip.value:
                    self.bebop.flip(str(args[1]))
            except Exception as e:
                print("Error occurred: ")
                print(e)
                continue
            
    
    def _loadJsonFile(self):
        # Open up JSON file with last run commands
        filePath = os.getcwd() + os.sep + "cmd_data.json"
        if os.path.isfile(filePath):
            f = open(filePath,"r")
            s = f.read()
            commands = json.loads(s)
            # Input commands into GUI interface
            for c in commands:
                self._addCommand(c)

    def _saveJsonFile(self, cmdList):
        # Place all commands into JSON file and write them to the disk
        jsonStr = json.dumps(cmdList)
        filePath = os.getcwd() + os.sep + "cmd_data.json"
        with open(filePath,"w") as f:
            f.write(jsonStr)

    def _addCommand(self, cmd: str):
        self.lc_commands.InsertItem(self.lc_commands.GetItemCount(), cmd)
        self.statusBar.SetStatusText(f'Added command: {cmd}', 1)
Exemple #7
0
class drone:
    def __init__(self, home):
        self.rango_largo = properties.RANGO_LARGO
        self.rango_ancho = properties.RANGO_ANCHO
        self.mapa_largo = properties.MAPA_LARGO / self.rango_largo
        self.mapa_ancho = properties.MAPA_ANCHO / self.rango_ancho
        self.ip = None
        self.port = None
        self.search_map = [[0 for j in range(int(self.mapa_largo))]for i in range(int(self.mapa_ancho))]
        self.current_position = home
        self.current_rotation = math.pi / 2
        self.mutex_search_map = threading.Lock()
        self.poi_position = None
        self.home = home
        self.bebop = Bebop()
        self.init_time = None
        self.obstaculos = properties.OBSTACLES
        self.max_altitude = properties.MAX_ALTITUDE
        self.pathToFollow = None
        self.destinationZone = None
        self.countIter = 0
        self.logMapTimestamp = None
        self.logMap = None

    def initialize(self, ip, port):
        self.initSearchMapWithObstacles()
        init_time = time.time()
        self.init_time = init_time
        if properties.ALGORITHM == SH_ORIGINAL:
            self.search_map[self.home[0]][self.home[1]] = 1
        elif properties.ALGORITHM == SH_TIMESTAMP or ALGORITHM == SH_NO_GREEDY_TIMESTAMP or ALGORITHM == RANDOM:
            self.search_map = [[init_time for j in range(int(self.mapa_largo))]for i in range(int(self.mapa_ancho))]
        # elif properties.ALGORITHM == RANDOM:
        #     self.search_map[self.home[0]][self.home[1]] = 1
        self.ip = ip
        self.port = port
        # success = self.bebop.connect(10)
        # print(success)
        self.bebop.set_max_altitude(self.max_altitude)
        self.bebop.ask_for_state_update()
        if properties.STREAMING_MODE_ON:
            self.initializeStreaming()
        self.logMap = [[0 for j in range(int(self.mapa_largo))]for i in range(int(self.mapa_ancho))]
        self.logMapTimestamp = [[init_time for j in range(int(self.mapa_largo))]for i in range(int(self.mapa_ancho))]

    def initSearchMapWithObstacles(self):
        for obstacle in self.obstaculos:
            self.search_map[obstacle[0]][obstacle[1]] = -1

    def take_off(self):
        self.bebop.safe_takeoff(10)

    def land(self):
        self.bebop.safe_land(10)

    def move(self, new_position):
        verticalMove = self.getDronVerticalAlignment()
        if properties.ROTATE:
            rotation_diff = utils.angleDifference(self.current_position, new_position, self.current_rotation)
            distance_diff = utils.cartesianDistance(self.current_position, new_position)
            self.bebop.move_relative(0, 0, 0, rotation_diff)
            time.sleep(2)
            self.bebop.move_relative(distance_diff, 0, verticalMove, 0)
            self.current_rotation -= rotation_diff
            time.sleep(2)
        else:
            dx, dy = new_position[0] - self.current_position[0], new_position[1] - self.current_position[1]
            real_dx, real_dy = dx * self.rango_ancho, dy * self.rango_largo
            self.bebop.move_relative(real_dx, real_dy, verticalMove, 0)
        time.sleep(2)
        self.current_position = new_position
        self.mutex_search_map.acquire()
        utils.printMatrix(self.search_map)
        self.mutex_search_map.release()

    def setPoiPosition(self, poiPosition):
        self.poi_position = poiPosition

    def explore(self, forcePosition):
        if properties.ALGORITHM == SH_ORIGINAL:
            return self.explore_sh_original(forcePosition)
        elif properties.ALGORITHM == SH_TIMESTAMP:
            return self.explore_sh_timestamp(forcePosition)
        elif properties.ALGORITHM == RANDOM:
            return self.explore_random(forcePosition)
        elif properties.ALGORITHM == SH_NO_GREEDY or properties.ALGORITHM == SH_NO_GREEDY_TIMESTAMP:
            return self.explore_sh_no_greedy2(forcePosition)

    def explore_sh_original(self, forcePosition):
        firstTime = True
        x = self.current_position[0]
        y = self.current_position[1]
        best_values = []
        for y2 in range(-1, 2):
            for x2 in range(-1, 2):
                x3 = x + x2
                y3 = y + y2
                if self.validatePosition(x3, y3, forcePosition):
                    if firstTime:
                        self.mutex_search_map.acquire()
                        val = self.search_map[x3][y3]
                        self.mutex_search_map.release()
                        firstTime = False
                    # print("x3: " + str(x3) + " y3: " + str(y3) + " self.mapa_ancho: " + str(self.mapa_ancho) + " self.mapa_largo: " + str(self.mapa_largo))
                    self.mutex_search_map.acquire()
                    if (self.search_map[x3][y3] == val):
                        best_values.append((x3, y3))
                        val = self.search_map[x3][y3]
                    elif self.search_map[x3][y3] < val:
                        best_values = [(x3, y3)]
                        val = self.search_map[x3][y3]
                    self.mutex_search_map.release()
        selected = self.selectBestValue(best_values)
        return selected

    def explore_sh_timestamp(self, forcePosition):
        firstTime = True
        x = self.current_position[0]
        y = self.current_position[1]
        best_values = []
        for y2 in range(-1, 2):
            for x2 in range(-1, 2):
                x3 = x + x2
                y3 = y + y2
                if self.validatePosition(x3, y3, forcePosition):
                    if firstTime:
                        self.mutex_search_map.acquire()
                        val = self.search_map[x3][y3]
                        self.mutex_search_map.release()
                        firstTime = False
                    self.mutex_search_map.acquire()
                    if (self.search_map[x3][y3] == val):
                        best_values.append((x3, y3))
                        val = self.search_map[x3][y3]
                    elif self.search_map[x3][y3] < val:
                        best_values = [(x3, y3)]
                        val = self.search_map[x3][y3]
                    self.mutex_search_map.release()
        selected = self.selectBestValue(best_values)
        return selected

    def explore_random(self, forcePosition):
        x = self.current_position[0]
        y = self.current_position[1]
        best_values = []
        for y2 in range(-1, 2):
            for x2 in range(-1, 2):
                x3 = x + x2
                y3 = y + y2
                if self.validatePosition(x3, y3, forcePosition):
                    best_values.append((x3, y3))
        selected = self.selectBestValue(best_values)
        return selected

# primer intento de algoritmo no greedy, si se lo trabaja un poco puede funcionar
    def explore_sh_no_greedy(self, forcePosition):
        firstTime = True
        x = self.current_position[0]
        y = self.current_position[1]
        best_values = []
        for y2 in range(-1, 2):
            for x2 in range(-1, 2):
                x3 = x + x2
                y3 = y + y2
                if self.validatePosition(x3, y3, forcePosition):
                    if firstTime:
                        self.mutex_search_map.acquire()
                        val = self.search_map[x3][y3]
                        self.mutex_search_map.release()
                        firstTime = False
                    self.mutex_search_map.acquire()
                    currentRegion = self.getCurrentRegion()
                    bestRegion = self.selectUnexploredRegion()
                    if self.isClosestToBestRegion(currentRegion, bestRegion, x2, y2):
                        if (self.search_map[x3][y3] == val):
                            best_values.append((x3, y3))
                            val = self.search_map[x3][y3]
                        elif self.search_map[x3][y3] < val:
                            best_values = [(x3, y3)]
                            val = self.search_map[x3][y3]
                    self.mutex_search_map.release()
        selected = self.selectBestValue(best_values)
        return selected

    def explore_sh_no_greedy2(self, forcePosition):
        if self.pathToFollow is not None and len(self.pathToFollow) > 0:
            return self.getNewPositionFromPath()
        else:
            newZone = self.isChangeZone()
            if newZone is not None:
                self.destinationZone = newZone
                self.getZonePath(newZone)
                # self.selectNewZone(newZone)
                return self.getNewPositionFromPath()
            else:
                if ALGORITHM == SH_NO_GREEDY:
                    return self.explore_sh_original(forcePosition)
                else:
                    return self.explore_sh_timestamp(forcePosition)

    def explore_sh_no_greedy_timestamp(self, forcePosition):
        if self.pathToFollow is not None and len(self.pathToFollow) > 0:
            return self.getNewPositionFromPath()
        else:
            newZone = self.isChangeZone()
            if newZone is not None:
                self.destinationZone = newZone
                self.getZonePath(newZone)
                # self.selectNewZone(newZone)
                return self.getNewPositionFromPath()
            else:
                return self.explore_sh_timestamp(forcePosition)

    def getNewPositionFromPath(self):
        new_position = self.pathToFollow[0]
        del self.pathToFollow[0]
        if self.getPositionZone(new_position) == self.destinationZone and self.isUnexploredPosition(new_position):
            self.pathToFollow = None
            self.destinationZone = None
        return new_position

    def isUnexploredPosition(self, new_position):
        if ALGORITHM == SH_NO_GREEDY_TIMESTAMP or ALGORITHM == SH_TIMESTAMP:
            timeBetweenLastVisit = time.time() - self.search_map[new_position[0]][new_position[1]]
            firstTime = self.search_map[new_position[0]][new_position[1]] == self.init_time
            return timeBetweenLastVisit > TIME_COVERAGE_REFRESH or firstTime
        else:
            return self.search_map[new_position[0]][new_position[1]] == self.countIter

    def isChangeZone(self):
        currentZone = self.getCurrentRegion()
        zonesCoverage = self.getZonesCoverage()
        currentZoneCoverage = zonesCoverage[currentZone - 1]
        minZoneCoverage = min(zonesCoverage)
        if minZoneCoverage >= MIN_ACCEPTABLE_COVERAGE:
            self.countIter += 1
            # self.updateCoverageCondition()
            zonesCoverage = self.getZonesCoverage()
            currentZoneCoverage = zonesCoverage[currentZone - 1]
            minZoneCoverage = min(zonesCoverage)
        if currentZoneCoverage >= MIN_ACCEPTABLE_COVERAGE or currentZoneCoverage - minZoneCoverage > COVERAGE_THRESHOLD:
            newZone = self.selectUnexploredRegion()
            return newZone
        return None

    def updateCoverageCondition(self):
        if self.init_time is not None:
            self.init_time = time.time()
        else:
            self.countIter += 1

    def getZonePath(self, newZone):
        zonePosition = self.selectPositionInZone(newZone)
        pathfinder = Pathfinder(self.current_position, zonePosition)
        pathToFollow = pathfinder.findPath()
        self.pathToFollow = pathfinder.parsePathToCoordinates(pathToFollow)

    def selectPositionInZone(self, zone):
        if zone == 1:
            position = (0, 0)
        elif zone == 2:
            position = (0, int(self.mapa_largo - 1))
        elif zone == 3:
            position = (int(self.mapa_ancho - 1), 0)
        else:
            position = (int(self.mapa_ancho - 1), int(self.mapa_largo - 1))
        # if zone == 1 or zone == 2:
        #     while position[0] < self.mapa_ancho and self.search_map[position[0], position[1]] == -1:
        #         position = (position[0] + 1, 0)
        # elif zone == 3 or zone == 4:
        #     while position[0] < self.mapa_largo and self.search_map[position[0], position[1]] == -1:
        #         position = (0, position[1] + 1)
        # asumo que encuentro posicion valida
        return position

    def selectNewZone(self, currentZone):
        newZone = random.randint(0, 3)
        while newZone == currentZone:
            newZone = random.randint(0, 3)
        return newZone

    def isClosestToBestRegion(currentRegion, bestRegion, x, y):
        if currentRegion == bestRegion:
            return True
        bestCoordinates = getBestCoordinates(currentRegion, bestRegion)
        if x in bestCoordinates[0] and y in bestCoordinates[1]:
            return True
        return False

    def getBestCoordinates(currentRegion, bestRegion):
        if currentRegion == 1:
            if bestRegion == 2:
                return [(-1, 1), (0, 1), (1, 1)]
            elif bestRegion == 3:
                return [(1, -1), (1, 0), (1, 1)]
            else:
                return [(0, 1), (1, 1), (1, 0)]
        elif currentRegion == 2:
            if bestRegion == 1:
                return [(-1, -1), (0, -1), (1, 1)]
            elif bestRegion == 3:
                return [(1, -1), (0, -1), (1, 0)]
            else:
                return [(1, -1), (1, 0), (1, 1)]
        elif currentRegion == 3:
            if bestRegion == 1:
                return [(-1, -1), (-1, 0), (-1, 1)]
            elif bestRegion == 2:
                return [(-1, 0), (-1, 1), (0, 1)]
            else:
                return [(-1, 1), (0, 1), (1, 1)]
        else:
            if bestRegion == 1:
                return [(-1, -1), (-1, 0), (0, -1)]
            elif bestRegion == 2:
                return [(-1, -1), (-1, 0), (-1, 1)]
            else:
                return [(-1, -1), (0, -1), (1, -1)]

    def getCurrentRegion(self):
        return self.getPositionZone(self.current_position)

    def getPositionZone(self, position):
        if self.mapa_largo / 2 > position[1] and self .mapa_ancho / 2 > position[0]:
            return 1
        elif self.mapa_largo / 2 <= position[1] and self .mapa_ancho / 2 > position[0]:
            return 2
        elif self.mapa_largo / 2 > position[1] and self .mapa_ancho / 2 <= position[0]:
            return 3
        elif self.mapa_largo / 2 <= position[1] and self .mapa_ancho / 2 <= position[0]:
            return 4

    def selectUnexploredRegion(self):
        regionCoverage = []
        regionCoverage.append(getMapCoverage(self, 0, self.mapa_ancho / 2, 0, self.mapa_largo / 2))
        regionCoverage.append(getMapCoverage(self, self.mapa_ancho / 2, self.mapa_ancho, 0, self.mapa_largo / 2))
        regionCoverage.append(getMapCoverage(self, 0, self.mapa_ancho / 2, self.mapa_largo / 2, self.mapa_largo))
        regionCoverage.append(getMapCoverage(self, self.mapa_ancho / 2, self.mapa_ancho, self.mapa_largo / 2, self.mapa_largo))
        selectedZone = regionCoverage.index(min(regionCoverage)) + 1
        if selectedZone == self.getCurrentRegion():
            return None
        return selectedZone

    def getZonesCoverage(self):
        regionCoverage = []
        regionCoverage.append(getMapCoverage(self, 0, self.mapa_ancho / 2, 0, self.mapa_largo / 2))
        regionCoverage.append(getMapCoverage(self, self.mapa_ancho / 2, self.mapa_ancho, 0, self.mapa_largo / 2))
        regionCoverage.append(getMapCoverage(self, 0, self.mapa_ancho / 2, self.mapa_largo / 2, self.mapa_largo))
        regionCoverage.append(getMapCoverage(self, self.mapa_ancho / 2, self.mapa_ancho, self.mapa_largo / 2, self.mapa_largo))
        return regionCoverage

    def selectBestValue(self, best_values):
        lenght = len(best_values)
        # print("selectBestValue: " + str(lenght))
        if(lenght == 1):
            return best_values[0]
        else:
            selected = random.randint(0, lenght - 1)
            return best_values[selected]

    def validatePosition(self, x3, y3, forcePosition):
        condition = x3 >= 0 and y3 >= 0 and x3 < self.mapa_ancho and y3 < self.mapa_largo
        tupla = (x3, y3)
        if self.pointIsObstacule(x3, y3):
            return False
        elif (forcePosition is not None):
            return (condition and self.minDistanceToTarget(self.home, self.current_position, tupla))
        elif self.poi_position is not None:
            return (condition and self.minDistanceToTarget(self.poi_position, self.current_position, tupla))
        elif self.checkBatteryStatus() == NORMAL:
            return condition
        else:
            return (condition and self.minDistanceToTarget(self.home, self.current_position, tupla))

    def minDistanceToTarget(self, target, positionA, positionB):
        # print("minDistanceToTarget")
        distance2 = self.calculateDistance(target, positionA)
        distance1 = self.calculateDistance(target, positionB)
        # print("distance1: " + str(distance1) + " distance2: " + str(distance2))
        return (distance1 <= distance2)

    def pointIsObstacule(self, x1, x2):
        isObstacule = False
        for obs in self.obstaculos:
            if obs[0] == x1 and obs[1] == x2:
                isObstacule = True
        return isObstacule

    def calculateDistance(self, tuple1, tuple2):
        return math.sqrt((tuple2[1] - tuple1[1])**2 + (tuple2[0] - tuple1[0])**2)

    def updateSearchMap(self, tupla):
        self.mutex_search_map.acquire()
        if properties.ALGORITHM == SH_ORIGINAL or properties.ALGORITHM == SH_NO_GREEDY:
            self.search_map[tupla[0]][tupla[1]] += 1
        elif properties.ALGORITHM == SH_TIMESTAMP or ALGORITHM == SH_NO_GREEDY_TIMESTAMP or ALGORITHM == RANDOM:
            self.search_map[tupla[0]][tupla[1]] = time.time()
        self.logMap[tupla[0]][tupla[1]] += 1
        self.logMapTimestamp[tupla[0]][tupla[1]] = time.time()
        self.mutex_search_map.release()

    def getSearchMap(self):
        # self.mutex_search_map.acquire()
        return [[self.search_map[i][j] for j in range(int(self.mapa_largo))]for i in range(int(self.mapa_ancho))]
        # self.mutex_search_map.release()

    def getDroneAltitude(self):
        return self.bebop.sensors.sensors_dict["AltitudeChanged_altitude"]

    def checkDroneAltitudeStatus(self):
        altitude = self.getDroneAltitude()
        if (altitude < properties.MIN_ALTITUDE):
            return TOO_LOW
        elif (altitude > properties.MAX_ALTITUDE):
            return TOO_HIGH
        else:
            return ALTITUDE_OK

    def getDronVerticalAlignment(self):
        droneAltitudeStatus = self.checkDroneAltitudeStatus()
        verticalAlignment = 0
        if (droneAltitudeStatus == TOO_LOW or droneAltitudeStatus == TOO_HIGH):
            # negative goes up, positive goes down
            verticalAlignment = self.getDroneAltitude() - properties.OPTIMAL_ALTITUDE
        else:
            verticalAlignment = 0
        return verticalAlignment

    def getBatteryPercentage(self):
        return self.bebop.sensors.battery

    def checkBatteryStatus(self):
        batteryPercentage = self.getBatteryPercentage()
        if batteryPercentage < 5:
            return CRITICAL
        elif batteryPercentage < 10:
            return LOW
        else:
            return NORMAL

    def goHome(self):
        if self.current_position != self.home:
            pathfinder = Pathfinder(self.current_position, self.home)
            pathToFollow = pathfinder.findPath()
            pathfinder.printFinalMap()
            for nextPosition in pathfinder.parsePathToCoordinates(pathToFollow):
                self.move(nextPosition)

    def getClosestCoordinateToTarget(self, target, pos):
        res = self.current_position[pos]
        if res < target[pos]:
            res = res + 1
        elif res > target[pos]:
            res = res - 1
        return res

    def moveToPoiCritico(self, path):
        for nextPosition in path:
            self.move(nextPosition)

    def moveNextPositionPOICritico(self, new_position):
        dx, dy = new_position[0] - self.current_position[0], new_position[1] - self.current_position[1]
        real_dx, real_dy = dx * self.rango_ancho, dy * self.rango_largo
        verticalMove = self.getDronVerticalAlignment()
        self.bebop.move_relative(real_dx, real_dy, verticalMove, 0)
        time.sleep(2)
        self.current_position = new_position

    def disconnect(self):
        if properties.STREAMING_MODE_ON:
            self.closeStreaming()
        self.bebop.disconnect()

    def initializeStreaming(self):
        print("-- Starting Streaming... --")
        self.bebop.set_video_resolutions('rec720_stream720')
        self.bebop.start_video_stream()
        print("-- Streaming Started! --")

    def closeStreaming(self):
        print("-- Stopping Streaming... --")
        self.bebop.stop_video_stream()
        print("-- Streaming stopped!")