class Drone: def __init__(self, config, ovbuffer): self.config = config self.every = config["time"]["updateEverySec"] self.runTime = time.time() self.state_takeoff = False self.state_land = False self.ovbuffer = ovbuffer self.simulate = config["simulate"] if not self.simulate: self.tello = Tello() self.tello.connect() self.height = 0 self.cntrlChannel = config["cntrlChannel"] self.power2height = config["power2height"] self.minStep = config["minimalStepCM"] self.speed = config["speed"] # 20 mkV^2 = 30 cm above the ground. # 80 mkV^2 = 200 cm above the ground. self.timer = RepeatedTimer(self.every, self.scene) def time(self): return time.time() - self.runTime def start(self): config = self.config if self.time() > config["time"]["takeOff"] and not self.state_takeoff: self.logPos("takeoff") self.state_takeoff = True self.height = config["defaultHeightCM"] try: if not self.simulate: self.tello.takeoff() except Exception as e: print(e) def finish(self, force=False): if self.state_takeoff or force: self.logPos("land") try: if not self.simulate: self.tello.land() except Exception as e: print(e) self.state_land = True try: if not self.simulate: self.tello.end() except Exception as e: print(e) def scene(self): config = self.config self.logPos("scene") if not self.state_takeoff: self.start() if self.time() > config["time"]["maxLand"] and not self.state_land: self.finish() if self.time() > config["time"][ "rythmAnalyzeStart"] and not self.state_land and self.state_takeoff: self.onRythm() def onRythm(self): channelPower = self.ovbuffer.lastSeries[-1] eegPower = 0 if self.cntrlChannel in channelPower: eegPower = channelPower[self.cntrlChannel] minEegP, maxEegP = self.power2height[0] minH, maxH = self.power2height[1] self.logPos("eegPower={}, minEegP={}, maxEegP={}".format( eegPower, minEegP, maxEegP)) if eegPower >= minEegP and eegPower <= maxEegP: h = (eegPower - minEegP) / (maxEegP - minEegP) * (maxH - minH) realH = minH + h changeH = int(realH - self.height) if abs(changeH) > self.minStep: self.height = realH self.logPos("eegPower={}, go to XYZ, change={}".format( eegPower, changeH)) if not self.simulate: self.tello.go_xyz_speed(0, 0, changeH, self.speed) else: self.logPos("eegPower={}, change to small, change={}".format( eegPower, changeH)) def logPos(self, title=""): print("time={}: height={} {}".format(self.time(), self.height, title))
# sets drone starting position for first move prevPos = findHouse() # takeoff drone.connect() time.sleep(5) drone.takeoff() time.sleep(5) drone.move_up(40) time.sleep(5) # scroll through list and find unwatered lawn for r in plot: for c in r: if c == 1: x = (plot.index(r) - prevPos[0]) * 40 y = (r.index(c) - prevPos[1]) * 40 drone.go_xyz_speed(x, y, 0, 20) # move to unwatered lawn space time.sleep(5) prevPos = [plot.index(r), r.index(c) ] # set starting pos for next move to current location r[r.index( c)] = 0 # mark current space as empty to tell drone to move on time.sleep(3) x = (findHouse()[0] - prevPos[0]) * 40 y = (findHouse()[1] - prevPos[1]) * 40 drone.go_xyz_speed(x, y, 0, 20) # moves back to initial position (house) time.sleep(3) drone.land()
############################## ####### control functions : ############################## # drone.move_x(int dist) # x : up, down, left, right, forawrd, back # dist : 20-500 # drone.rotate_clockwise(int deg) # drone.rotate_counter_clockwise(int deg) # deg : 1-3600 # drone.flip_x() # x : left, right, forward, back drone.go_xyz_speed(x, y, z, speed) # x,y,z : 20-500 # speed : 10-100 # fly to xyz relative to current position drone.curve_xyz_speed(x1, y1, z1, x2, y2, z2, speed) # goto x2y2z2 via x1y1z1 # radius b/w 0.5 - 10 meters # x,y,z : -500-500 # speed : 10-60 drone.set_speed(x) # x : 10-100 drone.send_rc_control(lr, fb, ud, yv) # velocity : -100 - 100