예제 #1
0
    def landDrones(self, ignoreInterrupt=False):
        if not (self.appController.trajectoryEnabled or self.appController.positioningEnabled):
            return

        Logger.log("Landing drones...")
        swarmController = self.appController.swarmController
        commander = swarmController.broadcaster.high_level_commander
        light_controller = swarmController.broadcaster.light_controller

        light_controller.set_color(32, 32, 32, 4.0, True)
        commander.land(SequenceController.LANDING_HEIGHT, 4.0)

        for drone in swarmController.connectedDrones:
            if (drone.state == DroneState.IN_FLIGHT):
                drone.state = DroneState.LANDING

        self.appController.sequenceUpdated.emit()
        threadUtil.interruptibleSleep(4.5, ignoreInterrupt)

        light_controller.set_color(0, 0, 0, 0.25, True)
        commander.stop()

        for drone in swarmController.connectedDrones:
            if (drone.state == DroneState.LANDING):
                drone.state = DroneState.CONNECTED

        self.appController.sequenceUpdated.emit()
        exceptionUtil.checkInterrupt(ignoreInterrupt)
예제 #2
0
    def resetEstimator(self):
        self.crazyflie.cf.param.set_value('kalman.resetEstimation', '1')
        time.sleep(0.25)

        exceptionUtil.checkInterrupt()
        self.crazyflie.cf.param.set_value('kalman.resetEstimation', '0')
        self.startPosition = (0, 0, 0)
        self.waitForEstimator()
예제 #3
0
def interruptibleSleep(duration, ignore=False, interval=0.25):
    start = time.time()
    elapsed = time.time() - start

    while elapsed < duration:
        sleepTime = max(min(interval, duration - elapsed), 0)
        time.sleep(sleepTime)
        exceptionUtil.checkInterrupt(ignore)
        elapsed = time.time() - start
예제 #4
0
    def writeLedTimings(self, color_data):
        mems = self.crazyflie.cf.mem.get_mems(
            MemoryElement.TYPE_DRIVER_LEDTIMING)
        if self.crazyflie is None or len(color_data) == 0:
            Logger.error("Could not upload LED data", self.swarmIndex)
            raise ValueError("Cannot write led timing data")

        self.write(lambda: mems[0].write_raw(color_data, self.writeComplete))
        exceptionUtil.checkInterrupt()
예제 #5
0
    def waitForEstimator(self):
        startTime = time.time()
        log_config = LogConfig(name='Kalman Variance', period_in_ms=500)
        log_config.add_variable('kalman.varPX', 'float')
        log_config.add_variable('kalman.varPY', 'float')
        log_config.add_variable('kalman.varPZ', 'float')
        log_config.add_variable('kalman.stateX', 'float')
        log_config.add_variable('kalman.stateY', 'float')
        log_config.add_variable('kalman.stateZ', 'float')

        var_y_history = [1000] * 10
        var_x_history = [1000] * 10
        var_z_history = [1000] * 10
        threshold = 0.001

        with SyncLogger(self.crazyflie, log_config) as logger:
            for log_entry in logger:

                exceptionUtil.checkInterrupt()
                data = log_entry[1]

                var_x_history.append(data['kalman.varPX'])
                var_x_history.pop(0)
                var_y_history.append(data['kalman.varPY'])
                var_y_history.pop(0)
                var_z_history.append(data['kalman.varPZ'])
                var_z_history.pop(0)

                min_x = min(var_x_history)
                max_x = max(var_x_history)
                min_y = min(var_y_history)
                max_y = max(var_y_history)
                min_z = min(var_z_history)
                max_z = max(var_z_history)

                x = data['kalman.stateX']
                y = data['kalman.stateY']
                z = data['kalman.stateZ']

                has_converged = (max_x - min_x) < threshold and (
                    max_y - min_y) < threshold and (max_z - min_z) < threshold
                timed_out = (time.time() -
                             startTime) > Drone.ESTIMATOR_TIMEOUT_SEC

                if has_converged:
                    print("Initial position for drone", self.swarmIndex,
                          "has converged, to position: ",
                          ("({:.2f}, {:.2f}, {:.2f})".format(x, y, z)))
                    self.startPosition = (float(x), float(y), float(z))
                    break
                elif timed_out:
                    Logger.error("Drone position sensor failed to update!",
                                 self.swarmIndex)
                    self.setError()
                    raise DroneException(
                        "Drone did not achieve the target position")
예제 #6
0
 def writeBaseStationData(self, geometryOne, geometryTwo):
     geo_dict = {0: geometryOne, 1: geometryTwo}
     helper = LighthouseMemHelper(self.crazyflie.cf)
     writer = LighthouseConfigWriter(self.crazyflie.cf,
                                     nr_of_base_stations=2)
     self.write(lambda: helper.write_geos(geo_dict, self.writeComplete))
     self.write(lambda: writer.write_and_store_config(self.writeComplete,
                                                      geos=geo_dict,
                                                      calibs=calibration.
                                                      CALIBRATION_DATA))
     exceptionUtil.checkInterrupt()
예제 #7
0
    def writeTrajectory(self, data):
        if self.crazyflie is None or len(data) == 0:
            Logger.error("Could not upload trajectory data!", self.swarmIndex)
            raise ValueError("Cannot write trajectory data")

        trajectoryMemory = self.crazyflie.cf.mem.get_mems(
            MemoryElement.TYPE_TRAJ)[0]
        self.write(lambda: trajectoryMemory.write_raw(data, self.writeComplete,
                                                      self.writeFailed))

        exceptionUtil.checkInterrupt()
        self.crazyflie.cf.high_level_commander.define_trajectory_compressed(
            Drone.TRAJECTORY_ID, 0)
예제 #8
0
    def updateSensors(self, uploadGeometry, geometryOne, geometryTwo):
        Logger.log("Updating sensor & positioning data", self.swarmIndex)
        self.crazyflie.cf.param.set_value('lighthouse.method', '0')
        self.crazyflie.cf.param.set_value('lighthouse.systemType', '1')

        # PID controller
        self.crazyflie.cf.param.set_value('stabilizer.controller', '0')
        self.crazyflie.cf.param.set_value('commander.enHighLevel', '1')
        exceptionUtil.checkInterrupt()

        if uploadGeometry:
            self.writeBaseStationData(geometryOne, geometryTwo)
            self.resetEstimator()

        self.state = DroneState.CONNECTED
        self.light_controller.set_color(0, 255, 0, 0.0, True)
        exceptionUtil.checkInterrupt()
예제 #9
0
    def waitForTargetPosition(self,
                              targetX,
                              targetY,
                              targetZ,
                              timeoutSeconds=None):
        startTime = time.time()
        log_config = LogConfig(name='Kalman Position', period_in_ms=50)
        log_config.add_variable('kalman.stateX', 'float')
        log_config.add_variable('kalman.stateY', 'float')
        log_config.add_variable('kalman.stateZ', 'float')
        threshold = 0.05

        with SyncLogger(self.crazyflie, log_config) as logger:
            for log_entry in logger:

                exceptionUtil.checkInterrupt()
                data = log_entry[1]

                x = float(data['kalman.stateX'])
                y = float(data['kalman.stateY'])
                z = float(data['kalman.stateZ'])

                has_converged = abs(targetX - x) < threshold and abs(
                    targetY - y) and abs(targetZ - z)
                timed_out = (time.time() - startTime
                             ) > timeoutSeconds if timeoutSeconds else False

                if has_converged:
                    print("Target position for drone", self.swarmIndex,
                          "has converged. Target was:",
                          ("({:.2f}, {:.2f}, {:.2f})".format(
                              targetX, targetY, targetZ)),
                          ", converged to position: ",
                          ("({:.2f}, {:.2f}, {:.2f})".format(x, y, z)))
                    break
                elif timed_out:
                    Logger.error("Drone failed to reach target position!",
                                 self.swarmIndex)
                    self.setError()
                    raise ConnectionAbortedError(
                        "Drone position was not able to converge!")
예제 #10
0
    def setInitialPosition(self, drone):
        exceptionUtil.checkInterrupt()

        sequence = SequenceController.CURRENT
        track = sequence.getTrack(drone.swarmIndex)
        commander = drone.commander
        self.appController.updateSequence()
        exceptionUtil.checkInterrupt()

        if track is not None:

            r, g, b = sequence.getStartingColor(drone.swarmIndex)
            x, y, z = sequence.getStartingPosition(drone.swarmIndex)
            drone.light_controller.set_color(r, g, b, 0.25, True)

            if self.appController.trajectoryEnabled or self.appController.positioningEnabled:
                Logger.log("Getting into position", drone.swarmIndex)

                # Step 0 - Make sure the drone has reached its takeoff position
                initialX, initialY, initialZ = drone.startPosition

                print("Waiting for drone", drone.swarmIndex, "to converge to position", ("({:.2f}, {:.2f}, {:.2f})".format(initialX, initialY, SequenceController.MIN_HEIGHT)))
                drone.waitForTargetPosition(initialX, initialY, SequenceController.MIN_HEIGHT)

                # Step 1 - Move to some height determined by index
                targetHeight = min(SequenceController.MIN_HEIGHT + (drone.swarmIndex * 0.1), SequenceController.MAX_HEIGHT)
                numDrones = len(self.appController.swarmController.connectedDrones)
                moveTime = 5.0 + (numDrones * 0.3)

                print("Moving drone", drone.swarmIndex, "to position", ("({:.2f}, {:.2f}, {:.2f})".format(initialX, initialY, targetHeight)), "over time:", moveTime)
                commander.go_to(initialX, initialY, targetHeight, 0, moveTime)
                threadUtil.interruptibleSleep(moveTime + 0.25)
                print("Waiting for drone", drone.swarmIndex, "to converge to position", ("({:.2f}, {:.2f}, {:.2f})".format(initialX, initialY, targetHeight)))
                drone.waitForTargetPosition(initialX, initialY, targetHeight)

                # Step 2 - Move to position, maintaining target height
                print("Moving drone", drone.swarmIndex, "to position", ("({:.2f}, {:.2f}, {:.2f})".format(x, y, targetHeight)), "over time:", 8.0)
                commander.go_to(x, y, targetHeight, 0, 8.0)
                threadUtil.interruptibleSleep(8.25)
                print("Waiting for drone", drone.swarmIndex, "to converge to position", ("({:.2f}, {:.2f}, {:.2f})".format(x, y, targetHeight)))
                drone.waitForTargetPosition(x, y, targetHeight)

                # Step 3 - Move to actual starting position
                print("Moving drone", drone.swarmIndex, "to position", ("({:.2f}, {:.2f}, {:.2f})".format(x, y, z)), "over time:", 8.0)
                commander.go_to(x, y, z, 0.0, 8.0)
                threadUtil.interruptibleSleep(8.25)
                print("Waiting for drone", drone.swarmIndex, "to converge to position", ("({:.2f}, {:.2f}, {:.2f})".format(x, y, z)))
                drone.waitForTargetPosition(x, y, z)

            Logger.log("Ready!", drone.swarmIndex)
            self.appController.updateSequence()
            exceptionUtil.checkInterrupt()
예제 #11
0
    def uploadFlightData(self, drone):
        sequence = SequenceController.CURRENT
        track = sequence.getTrack(drone.swarmIndex)
        exceptionUtil.checkInterrupt()

        if track is not None:
            Logger.log("Uploading trajectory & LED data", drone.swarmIndex)

            if self.appController.trajectoryEnabled:
                trajectoryData = bytearray(track['CompressedTrajectory'])
                drone.writeTrajectory(trajectoryData)
                exceptionUtil.checkInterrupt()

            if self.appController.colorSequenceEnabled:
                lightData = bytearray(track['LedTimings'])
                drone.writeLedTimings(lightData)
                exceptionUtil.checkInterrupt()