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()
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()
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()
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)
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!")