Example #1
0
    def start(self, cf):
        self._lc_stab = LogConfig(name="Log-Stab", period_in_ms=50)
        self._lc_stab.add_variable("stabilizer.roll", "float")
        self._lc_stab.add_variable("stabilizer.pitch", "float")
        self._lc_stab.add_variable("stabilizer.yaw", "float")
        self._lc_stab.add_variable("stabilizer.thrust", "float")

        self._lc_motor = LogConfig(name="Log-Motor", period_in_ms=50)
        self._lc_motor.add_variable("pm.vbat", "float")
        self._lc_motor.add_variable("motor.m1", "float")  # Front (green)
        self._lc_motor.add_variable("motor.m2", "float")  # Right
        self._lc_motor.add_variable("motor.m3", "float")  # Back (red)
        self._lc_motor.add_variable("motor.m4", "float")  # Left

        cf.log.add_config(self._lc_stab)
        cf.log.add_config(self._lc_motor)
        if self._lc_stab.valid and self._lc_motor.valid:
            self._lc_stab.data_received_cb.add_callback(self._log_data)
            self._lc_stab.error_cb.add_callback(self._log_error)
            self._lc_stab.start()
            self._lc_motor.data_received_cb.add_callback(self._log_data)
            self._lc_motor.error_cb.add_callback(self._log_error)
            self._lc_motor.start()
            logger.info("Starting CFLog")
        else:
            logger.error("Could not add logconfig since some variables are not in TOC")
    def _read_config_files(self):
        """Read and parse log configurations"""
        configsfound = [os.path.basename(f) for f in
                        glob.glob(sys.path[1] + "/log/[A-Za-z_-]*.json")]
        new_dsList = []
        for conf in configsfound:
            try:
                logger.info("Parsing [%s]", conf)
                json_data = open(sys.path[1] + "/log/%s" % conf)
                self.data = json.load(json_data)
                infoNode = self.data["logconfig"]["logblock"]

                logConf = LogConfig(infoNode["name"],
                                    int(infoNode["period"]))
                for v in self.data["logconfig"]["logblock"]["variables"]:
                    if v["type"] == "TOC":
                        logConf.add_variable(str(v["name"]), v["fetch_as"])
                    else:
                        logConf.add_variable("Mem", v["fetch_as"],
                                             v["stored_as"],
                                             int(v["address"], 16))
                new_dsList.append(logConf)
                json_data.close()
            except Exception as e:
                logger.warning("Exception while parsing logconfig file: %s", e)
        self.dsList = new_dsList
    def _handle_logging(self, data):
        resp = {"version": 1}
        if data["action"] == "create":
            lg = LogConfig(data["name"], data["period"])
            for v in data["variables"]:
                lg.add_variable(v)
            lg.started_cb.add_callback(self._logging_started)
            lg.added_cb.add_callback(self._logging_added)
            try:
                lg.data_received_cb.add_callback(self._logdata_callback)
                self._logging_configs[data["name"]] = lg
                self._cf.log.add_config(lg)
                lg.create()
                self._log_added_queue.get(block=True, timeout=LOG_TIMEOUT)
                resp["status"] = 0
            except KeyError as e:
                resp["status"] = 1
                resp["msg"] = str(e)
            except AttributeError as e:
                resp["status"] = 2
                resp["msg"] = str(e)
            except queue.Empty:
                resp["status"] = 3
                resp["msg"] = "Log configuration did not start"
        if data["action"] == "start":
            try:
                self._logging_configs[data["name"]].start()
                self._log_started_queue.get(block=True, timeout=LOG_TIMEOUT)
                resp["status"] = 0
            except KeyError as e:
                resp["status"] = 1
                resp["msg"] = "{} config not found".format(str(e))
            except queue.Empty:
                resp["status"] = 2
                resp["msg"] = "Log configuration did not stop"
        if data["action"] == "stop":
            try:
                self._logging_configs[data["name"]].stop()
                self._log_started_queue.get(block=True, timeout=LOG_TIMEOUT)
                resp["status"] = 0
            except KeyError as e:
                resp["status"] = 1
                resp["msg"] = "{} config not found".format(str(e))
            except queue.Empty:
                resp["status"] = 2
                resp["msg"] = "Log configuration did not stop"
        if data["action"] == "delete":
            try:
                self._logging_configs[data["name"]].delete()
                self._log_added_queue.get(block=True, timeout=LOG_TIMEOUT)
                resp["status"] = 0
            except KeyError as e:
                resp["status"] = 1
                resp["msg"] = "{} config not found".format(str(e))
            except queue.Empty:
                resp["status"] = 2
                resp["msg"] = "Log configuration did not stop"

        return resp
 def createConfigFromSelection(self):
     logconfig = LogConfig(str(self.configNameCombo.currentText()),
                           self.period)
     for node in self.getNodeChildren(self.varTree.invisibleRootItem()):
         parentName = node.text(NAME_FIELD)
         for leaf in self.getNodeChildren(node):
             varName = leaf.text(NAME_FIELD)
             varType = str(leaf.text(CTYPE_FIELD))
             completeName = "%s.%s" % (parentName, varName)
             logconfig.add_variable(completeName, varType)
     return logconfig
Example #5
0
    def _connected(self, linkURI):
        self._update_ui_state(UIState.CONNECTED, linkURI)

        Config().set("link_uri", str(linkURI))

        lg = LogConfig("Battery", 1000)
        lg.add_variable("pm.vbat", "float")
        try:
            self.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self.batteryUpdatedSignal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
    def connectionDone(self, linkURI):
        self.setUIState(UIState.CONNECTED, linkURI)

        GuiConfig().set("link_uri", linkURI)

        lg = LogConfig("Battery", 1000)
        lg.add_variable("pm.vbat", "float")
        self.cf.log.add_config(lg)
        if lg.valid:
            lg.data_received_cb.add_callback(self.batteryUpdatedSignal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup loggingblock!")
    def _register_logblock(self, logblock_name, variables, data_cb, error_cb,
                           update_period=UPDATE_PERIOD_LOG):
        """Register log data to listen for. One logblock can contain a limited
        number of parameters (6 for floats)."""
        lg = LogConfig(logblock_name, update_period)
        for variable in variables:
            if self._is_in_log_toc(variable):
                lg.add_variable('{}.{}'.format(variable[0], variable[1]),
                                variable[2])

        self._helper.cf.log.add_config(lg)
        lg.data_received_cb.add_callback(data_cb)
        lg.error_cb.add_callback(error_cb)
        lg.start()
        return lg
 def _connected(self, link_uri):
     lg = LogConfig("GPS", 1000)
     lg.add_variable("gps.lat", "float")
     lg.add_variable("gps.long", "float")
     lg.add_variable("gps.alt", "float")
     self._cf.log.add_config(lg)
     if lg.valid:
         lg.data_received_cb.add_callback(self._log_data_signal.emit)
         lg.error_cb.add_callback(self._log_error_signal.emit)
         lg.start()
     else:
         logger.warning("Could not setup logging block for GPS!")
Example #9
0
    def makeLog(self):
        """ Makes a log. All ative children are added """

        #print " -> Making new Log with %d ms interval"
        if self.lg:
            print " ---> Previous Log detected, removing first"
            self.lg.delete()


        self.fm = FreqMonitor(window=max(10, int(1.2*float(self.text(2)))))
        self.lg = LogConfig(self.name, 1000/int(float(self.text(2))))
        #print " ---> Adding children to new log"
        for x in range(self.childCount()):
            c = self.child(x)
            if c.isChecked():
                name = c.log.group+"."+c.log.name
                self.lg.add_variable(name, c.log.ctype)
                #print " --- --> Adding child[%d]: [%s] to new log"%(x, name)

        #print " ---> Checking log with TOC"
        self.treeWidget().cf.log.add_config(self.lg)
        if self.lg.valid:
            #print " --- --> PASS"
            self.lg.data_received_cb.add_callback(self.logDataCB)
            self.lg.started_cb.add_callback(self.logStartedCB)
            self.lg.error_cb.add_callback(self.treeWidget().sig_logError.emit)
            self.lg.error_cb.add_callback(self.errorLog)
            #print " --- --> callbacks added, starting new log NOW"
            self.lg.start()
        else:
            #print " --- --> FAIL"
            self.errorLog(None, "Invalid Config")
            self.lg = None
Example #10
0
    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""

        print "Connected to %s" % link_uri
        self._cf.commander.send_setpoint(0, 0, 0, 20000)

        # The definition of the logconfig can be made before connecting
        self._lg_stab = LogConfig(name="Logger", period_in_ms=10)
        self._lg_stab.add_variable("stabilizer.roll", "float")
        self._lg_stab.add_variable("stabilizer.pitch", "float")
        self._lg_stab.add_variable("stabilizer.yaw", "float")
        self._lg_stab.add_variable("stabilizer.thrust", "uint16_t")
        self._lg_stab.add_variable("gyro.x", "float")
        self._lg_stab.add_variable("gyro.y", "float")
        self._lg_stab.add_variable("gyro.z", "float")

        # Adding the configuration cannot be done until a Crazyflie is
        # connected, since we need to check that the variables we
        # would like to log are in the TOC.
        self._cf.log.add_config(self._lg_stab)
        if self._lg_stab.valid:
            # This callback will receive the data
            self._lg_stab.data_received_cb.add_callback(self._stab_log_data)
            # This callback will be called on errors
            self._lg_stab.error_cb.add_callback(self._stab_log_error)
            # Start the logging
            self._lg_stab.start()
        else:
            print("Could not add logconfig since some variables are not in TOC")
Example #11
0
    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""
        print('Connected to %s' % link_uri)

        # The definition of the logconfig can be made before connecting
        self._lg_stab = LogConfig(name='Stabilizer', period_in_ms=10)
        self._lg_stab.add_variable('stabilizer.roll', 'float')
        self._lg_stab.add_variable('stabilizer.pitch', 'float')
        self._lg_stab.add_variable('stabilizer.yaw', 'float')

        # Adding the configuration cannot be done until a Crazyflie is
        # connected, since we need to check that the variables we
        # would like to log are in the TOC.
        try:
            self._cf.log.add_config(self._lg_stab)
            # This callback will receive the data
            self._lg_stab.data_received_cb.add_callback(self._stab_log_data)
            # This callback will be called on errors
            self._lg_stab.error_cb.add_callback(self._stab_log_error)
            # Start the logging
            self._lg_stab.start()
        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))
        except AttributeError:
            print('Could not add Stabilizer log config, bad configuration.')

        # Start a timer to disconnect in 10s
        t = Timer(5, self._cf.close_link)
        t.start()
	def _connected(self, link_uri):

		#initial time to be shown in the screen
		self.init_time = time.time()

		#Threat 1 that will control the quadridrone
		Thread(target=self._ramp_motors).start() 
		
		#Thread 2 that will show results in the screen
		Thread(target=self._show_values).start() 


		self._lg_stab = LogConfig(name='Stabilizer', period_in_ms=30)
		#self._lg_stab.addVariable(LogVariable("stabilizer.thrust", "uint16_t"))
		self._lg_stab.add_variable('stabilizer.roll', 'float')
		self._lg_stab.add_variable('stabilizer.pitch', 'float')
		self._lg_stab.add_variable('stabilizer.yaw', 'float')
		self._lg_stab.add_variable('stabilizer.thrust', "uint16_t")

		# Adding the configuration cannot be done until a Crazyflie is
		# connected, since we need to check that the variables we
		# would like to log are in the TOC.
		try:
			self._cf.log.add_config(self._lg_stab)
			# This callback will receive the data
			self._lg_stab.data_received_cb.add_callback(self._stab_log_data)
			# This callback will be called on errors
			self._lg_stab.error_cb.add_callback(self._stab_log_error)
			#Thread 3 that will read from the TOC table, and start the logging
			self._lg_stab.start()
		except KeyError as e:
			print('Could not start log configuration, {} not found in TOC'.format(str(e)))
		except AttributeError:
			print('Could not add Stabilizer log config, bad configuration.')
Example #13
0
    def _connected(self, linkURI):
        self._update_ui_state(UIState.CONNECTED, linkURI)

        Config().set("link_uri", str(linkURI))

        lg = LogConfig("Battery", 1000)
        lg.add_variable("pm.vbat", "float")
        try:
            self.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self.batteryUpdatedSignal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))

        mem = self.cf.mem.get_mems(MemoryElement.TYPE_DRIVER_LED)[0]
        mem.write_data(self._led_write_done)
Example #14
0
    def __init__(self, link_uri):
        """ Initialize and run the example with the specified link_uri """

        self._cf = Crazyflie()

        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        self._lg_stab = LogConfig(name="Logger", period_in_ms=10)
        self._lg_stab.add_variable('acc.x', "float")
        self._lg_stab.add_variable('acc.y', "float")
        self._lg_stab.add_variable('acc.zw', "float")
        self._lg_stab.add_variable('gyro.x', "float")
        self._lg_stab.add_variable('gyro.y', "float")
        self._lg_stab.add_variable('gyro.z', "float")

        # PID for Z velocity??
        # self._lg_stab.add_variable('acc.z', "float")
        # self._lg_stab.add_variable("", "float")

        self._cf.open_link(link_uri)

        print("Connecting to %s" % link_uri)

        self._acc_x = 0.0
        self._acc_y = 0.0
        self._acc_zw = 0.0
        self._gyro_x = 0.0
        self._gyro_y = 0.0
        self._gyro_z = 0.0
        # self._acc_z = 0.0
        # self._vel_z = 0.0

        # ROLL/PITCH
        maxangle = 0.25

        kpangle = 2.0
        kiangle = 0.0
        kdangle = 0.1

        self._acc_pid_x = pid.PID(
            0, 0, kpangle, kiangle, kdangle, -maxangle, maxangle)
        self._acc_pid_y = pid.PID(
            0, 0, kpangle, kiangle, kdangle, -maxangle, maxangle)
        self._acc_pid_z = pid.PID(0, 0, 10, 0.0005, 0.1, 1/6, 2)

        self._gyro_x_pid = pid.PID(
            0, 0, kpangle, kiangle, kdangle, -maxangle, maxangle)
        self._gyro_y_pid = pid.PID(
            0, 0, kpangle, kiangle, kdangle, -maxangle, maxangle)
        # self._gyro_z_pid = pid.PID(
        #     0, 0, kpangle, kiangle, kdangle, -maxangle, maxangle)

        self._is_connected = True
        # self._acc_log = []
        self.exit = False
def start_position_printing(scf):
    log_conf = LogConfig(name='Position', period_in_ms=500)
    log_conf.add_variable('kalman.stateX', 'float')
    log_conf.add_variable('kalman.stateY', 'float')
    log_conf.add_variable('kalman.stateZ', 'float')

    scf.cf.log.add_config(log_conf)
    log_conf.data_received_cb.add_callback(position_callback)
    log_conf.start()
Example #16
0
    def _set_available_sensors(self, name, available):
        logger.info("[%s]: %s", name, available)
        available = eval(available)
        if ("HMC5883L" in name):
            if (not available):
                self.actualASL.setText("N/A")
                self.actualASL.setEnabled(False)
            else:
                self.actualASL.setEnabled(True)
                self.helper.inputDeviceReader.set_alt_hold_available(available)
                if (not self.logBaro and not self.logAltHold):
                    # The sensor is available, set up the logging
                    self.logBaro = LogConfig("Baro", 200)
                    self.logBaro.add_variable(PARAM_NAME_ESTIMATED_Z, "float")

                    try:
                        self.helper.cf.log.add_config(self.logBaro)
                        self.logBaro.data_received_cb.add_callback(
                            self._baro_data_signal.emit)
                        self.logBaro.error_cb.add_callback(
                            self._log_error_signal.emit)
                        self.logBaro.start()
                    except KeyError as e:
                        logger.warning(str(e))
                    except AttributeError as e:
                        logger.warning(str(e))
                    self.logAltHold = LogConfig("AltHold", 200)
                    self.logAltHold.add_variable(PARAM_NAME_ALT_HOLD_TARGET,
                                                 "float")

                    try:
                        self.helper.cf.log.add_config(self.logAltHold)
                        self.logAltHold.data_received_cb.add_callback(
                            self._althold_data_signal.emit)
                        self.logAltHold.error_cb.add_callback(
                            self._log_error_signal.emit)
                        self.logAltHold.start()
                    except KeyError as e:
                        logger.warning(str(e))
                    except AttributeError:
                        logger.warning(str(e))
    def _set_available_sensors(self, name, available):
        logger.info("[%s]: %s", name, available)
        available = eval(available)
        if ("HMC5883L" in name):
            if (not available):
                self.maxAltitudeLabel.setEnabled(False)
                self.maxAltitude.setEnabled(False)
                self.actualASL.setText("N/A")
                self.actualASL.setEnabled(False)
                self.checkBox_ffbaro.setEnabled(False)       
                self.checkBox_ffbaro.setChecked(False) 
            else:
                self.actualASL.setEnabled(True)
                self.checkBox_ffbaro.setEnabled(True)
                self.helper.inputDeviceReader.setAltHoldAvailable(available)
                if (not self.logBaro and not self.logAltHold):
                    # The sensor is available, set up the logging
                    self.logBaro = LogConfig("Baro", 200)
                    self.logBaro.add_variable("baro.aslLong", "float")

                    self.helper.cf.log.add_config(self.logBaro)
                    if self.logBaro.valid:
                        self.logBaro.data_received_cb.add_callback(self._baro_data_signal.emit)
                        self.logBaro.error_cb.add_callback(self._log_error_signal.emit)
                        self.logBaro.start()
                    else:
                        logger.warning("Could not setup logconfiguration after "
                                       "connection!")            
                    self.logAltHold = LogConfig("AltHold", 200)
                    self.logAltHold.add_variable("altHold.target", "float")

                    self.helper.cf.log.add_config(self.logAltHold)
                    if self.logAltHold.valid:
                        self.logAltHold.data_received_cb.add_callback(self._althold_data_signal.emit)
                        self.logAltHold.error_cb.add_callback(self._log_error_signal.emit)
                        self.logAltHold.start()
                    else:
                        logger.warning("Could not setup logconfiguration after "
                                       "connection!")                        
def wait_for_position_estimator(scf):
    print('Waiting for estimator to find position...')

    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')

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

    threshold = 0.001

    with SyncLogger(scf, log_config) as logger:
        for log_entry in logger:
            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)

            # print("{} {} {}".
            #       format(max_x - min_x, max_y - min_y, max_z - min_z))

            if (max_x - min_x) < threshold and (
                    max_y - min_y) < threshold and (
                    max_z - min_z) < threshold:
                break
	def setup_cf(self):
		"""
		Sets up the CrazyFlie before running the experiment. This includes configuring some params to default values
		and requesting the CrazyFlie to log certain variables back at constant intervals.
		Doesn't return anything, but raises exceptions if anything goes wrong.
		"""
		try:  # Send some default values for CF params
			self.crazyflie.param.set_value('controller.tiltComp', '{:d}'.format(True))
			self.crazyflie.param.set_value('flightmode.poshold', '{:d}'.format(False))  # Disable poshold and althold by default
			self.crazyflie.param.set_value('flightmode.althold', '{:d}'.format(False))
			self.crazyflie.param.set_value('flightmode.posSet', '{:d}'.format(False))
			self.crazyflie.param.set_value('flightmode.yawMode', '0')
			self.crazyflie.param.set_value('flightmode.timeoutStab', '{:d}'.format(1000*60*10))  # Stabilize (rpy=0) CF if doesn't receive a radio command in 10min
			self.crazyflie.param.set_value('flightmode.timeoutShut', '{:d}'.format(1000*60*20))  # Shutdown CF if doesn't receive a radio command in 20min
			self.crazyflie.param.set_value('posCtlPid.thrustBase', '{}'.format(self.TAKEOFF_THRUST))
			self.crazyflie.param.set_value("ring.effect", "1")  # Turn off LED ring
			self.crazyflie.param.set_value("ring.headlightEnable", "0")  # Turn off LED headlight
		except Exception as e:
			raise Exception("Couldn't initialize CrazyFlie params to their desired values. Details: {}".format(e.message))

		# Create a log configuration and include all variables that want to be logged
		self.cf_log = LogConfig(name="cf_log", period_in_ms=10)
		self.cf_log.add_variable("stabilizer.roll", "float")
		self.cf_log.add_variable("stabilizer.pitch", "float")
		self.cf_log.add_variable("stabilizer.yaw", "float")
		self.cf_log.add_variable("posEstimatorAlt.estimatedZ", "float")
		self.cf_log.add_variable("posEstimatorAlt.velocityZ", "float")
		try:
			self.crazyflie.log.add_config(self.cf_log)  # Validate the log configuration and attach it to our CF
		except Exception as e:
			raise Exception("Couldn't attach the log config to the CrazyFlie, bad configuration. Details: {}".format(e.message))
		self.cf_log.data_received_cb.add_callback(self.on_cf_log_new_data)  # Register appropriate callbacks
		self.cf_log.error_cb.add_callback(self.on_cf_log_error)
		self.cf_log.start()  # Start logging!

		# Get the CF's initial yaw (should be facing the camera) so we can have PID_yaw maintain that orientation
		if self.ASK_FOR_TARGET_YAW:  # Either ask the user to press Enter to indicate the CF's orientation is ready
			raw_input("\nRotate the drone so it faces the camera, press Enter when you're ready...\n")
		else:  # Or automatically detect the first yaw log packet and set the current orientation as the desired yaw
			while abs(self.cf_yaw) < 0.01:  # Wait until first cf_yaw value is received (cf_yaw=0 by default)
				time.sleep(0.1)
		self.cf_PID_yaw.SetPoint = self.cf_yaw
		print "Target yaw set at {:.2f}.".format(self.cf_yaw)

		self.crazyflie.add_port_callback(CRTPPort.CONSOLE, self.print_cf_console)
		self.crazyflie.commander.send_setpoint(0, 0, 0, 0)  # New firmware version requires to send thrust=0 at least once to "unlock thrust"
Example #20
0
    def __init__(self, link_uri):
        """ Initialize and run the example with the specified link_uri """

        self._cf = Crazyflie()

        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        self._asl = 0
        self._thrust = 0
        self.exit = False
        
        self._logger = LogConfig(name='Logger', period_in_ms=10)
        self._logger.add_variable("baro.asl", "float")
        self._logger.add_variable("stabilizer.thrust", "float")
         
        self._cf.open_link(link_uri)

        print("Connecting to %s" % link_uri)
Example #21
0
    def _connected(self):
        self.uiState = UIState.CONNECTED
        self._update_ui_state()

        Config().set("link_uri", str(self._selected_interface))

        lg = LogConfig("Battery", 1000)
        lg.add_variable("pm.vbat", "float")
        lg.add_variable("pm.state", "int8_t")
        try:
            self.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self.batteryUpdatedSignal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))

        mems = self.cf.mem.get_mems(MemoryElement.TYPE_DRIVER_LED)
        if len(mems) > 0:
            mems[0].write_data(self._led_write_done)
    def _set_available_sensors(self, name, available):
        logger.info("[%s]: %s", name, available)
        available = eval(available)

        self.actualHeight.setEnabled(True)
        self.helper.inputDeviceReader.set_alt_hold_available(available)
        if not self.logBaro:
            # The sensor is available, set up the logging
            self.logBaro = LogConfig("Baro", 200)
            self.logBaro.add_variable(LOG_NAME_ESTIMATED_Z, "float")

            try:
                self.helper.cf.log.add_config(self.logBaro)
                self.logBaro.data_received_cb.add_callback(
                    self._baro_data_signal.emit)
                self.logBaro.error_cb.add_callback(
                    self._log_error_signal.emit)
                self.logBaro.start()
            except KeyError as e:
                logger.warning(str(e))
            except AttributeError as e:
                logger.warning(str(e))
Example #23
0
    def __init__(self, link_uri):

        self._cf = Crazyflie()

        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        self._logger = LogConfig(name='Logger', period_in_ms=10)
        self._logger.add_variable('acc.x', 'float')
        self._logger.add_variable('acc.y', 'float')
        self._logger.add_variable('acc.z', 'float')
        self._logger.add_variable('acc.zw', 'float')

        self._acc_x = 0
        self._acc_y = 0
        self._acc_z = 0
        self._acc_zw = 0.0001

        self.log = []
        self.pidLog = []
        self.acc_pid_x = None
        self.acc_pid_y = None
        self.acc_pid_z = None

        self.vel_pid_x = None
        self.vel_pid_y = None
        self.vel_pid_z = None

        print("Connecting to %s" % link_uri)
        self._cf.open_link(link_uri)
        self.is_connected = True
        self.exit = False
        self.init = False

        Thread(target=self._exit_task).start()
        Thread(target=self._run_task).start()
Example #24
0
def wait_for_position_estimator(scf):
    print('Waiting for estimator to find position...')

    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')

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

    threshold = 0.0008  #0.001

    with SyncLogger(scf, log_config) as logger:
        for log_entry in logger:
            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)

            # print("{} {} {}".
            #       format(max_x - min_x, max_y - min_y, max_z - min_z))

            if (max_x - min_x) < threshold and (
                    max_y - min_y) < threshold and (max_z - min_z) < threshold:
                break
Example #25
0
    def _wait_for_position_estimator(self):
        """Waits until the position estimator reports a consistent location after resetting."""
        print('Waiting for estimator to find position...')

        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')

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

        threshold = 0.001

        with SyncLogger(self.scf, log_config) as logger:
            for log_entry in logger:
                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)

                if (max_x - min_x) < threshold and (
                        max_y - min_y) < threshold and (max_z -
                                                        min_z) < threshold:
                    break
Example #26
0
    def _connected(self, link_uri):
        """Callback when the Crazyflie has been connected"""

        logger.debug("Crazyflie connected to {}".format(link_uri))

        # self.pub = rospy.Publisher('chatter', String, queue_size=10)
        # rospy.init_node('talker', anonymous=True, disable_signals=False)
        # # rate = rospy.Rate(10)

        lg = LogConfig("Stabilizer", Config().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        # lg.add_variable("stabilizer.pitch", "float")
        # lg.add_variable("stabilizer.yaw", "float")
        # lg.add_variable("stabilizer.thrust", "uint16_t")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._log_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))
Example #27
0
    def crazyFlieloop(self):
        #wall_follower = WallFollowerController()
        #wall_follower.init(0.5)
        twist = Twist()

        #log_config.data_received_cb.add_callback(self.data_received)

        cflib.crtp.init_drivers(enable_debug_driver=False)
        cf = Crazyflie(rw_cache='./cache')

        lg_states = LogConfig(name='kalman_states', period_in_ms=100)
        lg_states.add_variable('stabilizer.yaw')
        lg_states.add_variable('kalman_states.ox')
        lg_states.add_variable('kalman_states.oy')
        lg_states.add_variable('updown_laser.back_range')
        lg_states.add_variable('updown_laser.front_range')
        lg_states.add_variable('updown_laser.left_range')
        lg_states.add_variable('updown_laser.right_range')
        lg_states.data_received_cb.add_callback(self.data_received)

        ''' lg_states.add_variable('rssiCR.rssi')
        lg_states.add_variable('rssiCR.distance')

        lg_states.add_variable('rssiCR.pos_x')
        lg_states.add_variable('rssiCR.pos_y')'''

        fh = open("log_test.txt", "w")
    

        with SyncCrazyflie(self.URI, cf=cf) as scf:
            with MotionCommander(scf,0.3) as motion_commander:
                with MultiRanger(scf) as multi_ranger:
                    with Stabilization(scf) as stabilization:
                        with SyncLogger(scf, lg_states) as logger_states:
                            bug_controller = WallFollowerController()
                            bug_controller.init(0.7,0.5)


                            keep_flying = True
                            time.sleep(1)

                           # param_name = "rssiCR.start"
                           # param_value = "1"
                           # cf.param.set_value(param_name, param_value)

                            twist.linear.x = 0.2
                            twist.linear.y = 0.0
                            twist.angular.z = 0
                            heading_prev = 0.0
                            heading = 0.0
                            angle_to_goal = 0.0;
                            kalman_x = 0.0
                            kalman_y = 0.0
                            already_reached_far_enough = False
                            state = "TURN_TO_GOAL"
                            prev_heading = stabilization.heading
                            angle_outbound = stabilization.heading;
                            state_start_time =0
                            rssi = 0
                            distance = 0
                            first_run = True
                            x_0 = 0
                            y_0 = 0
                            state_WF="FORWARD"
                            while keep_flying:

                                # crazyflie related stuff
                                for log_entry_1 in logger_states:
                                    data = log_entry_1[1]

                                    heading = math.radians(float(data["stabilizer.yaw"]));
                                    pos_x =float(data["kalman_states.ox"])-0.5
                                    pos_y =float(data["kalman_states.oy"])-1.5
                                    kalman_x = float(data["kalman_states.ox"])
                                    kalman_y = float(data["kalman_states.oy"])
                                    #rssi = float(data["rssiCR.rssi"])
                                    #distance = float(data["rssiCR.distance"])



                                    if first_run is True:
                                        x_0 = kalman_x
                                        y_0 = kalman_y
                                        first_run = False
                                        
                                    if pos_x == 0:
                                        pos_x = 0.02
                                    if pos_y == 0:
                                        pos_y = 0.02
                                        
                                        
                                    rel_coord_x = self.goal_coord_x[self.coord_index]-(kalman_x-x_0);
                                    rel_coord_y = self.goal_coord_y[self.coord_index]-(kalman_y-y_0);
                            
                                    self.distance_to_goal = math.sqrt(math.pow(rel_coord_x,2)+math.pow(rel_coord_y,2))
                                    self.angle_to_goal = wraptopi(np.arctan2(rel_coord_y,rel_coord_x))

                                    break


                                time.sleep(0.1)
                                
                                #Handle state transitions
                                if state =="STATE_MACHINE":
                                    if self.distance_to_goal<1.0   and self.coord_index is not len(self.goal_coord_x)-1:
                                        state = self.transition("TURN_TO_GOAL")
                                        self.coord_index = self.coord_index + 1
                                        self.distance_to_goal = 10
                                        self.angle_to_goal = 10
                                    if self.distance_to_goal<1.0  and self.coord_index is len(self.goal_coord_x)-1:
                                        state = self.transition("STOP")
                                if state =="TURN_TO_GOAL":
                                    if time.time()-self.state_start_time > 1 and logicIsCloseTo(stabilization.heading,wraptopi(self.angle_to_goal),0.1):
                                        state = self.transition("STATE_MACHINE")

                                #Handle state actions
                                if state=="STATE_MACHINE":
                                    #twist = bug_controller.stateMachine(multi_ranger.front,multi_ranger.right,multi_ranger.left,stabilization.heading,wraptopi(self.angle_to_goal),self.distance_to_goal)
                                    print("front_range",self.front_range)
                                    twist,state_WF = bug_controller.stateMachine(self.front_range,self.left_range,self.right_range,stabilization.heading,wraptopi(self.angle_to_goal),self.distance_to_goal)
                                    twist.linear.x = 0.5;
                                    twist.linear.y = 0.0;
                                    
                                    circumference = 2 * 0.5 * math.pi
                                    rate = 2*math.pi * 0.5 / circumference
                                    twist.angular.z = rate;
                                if state =="TURN_TO_GOAL":
                                    twist.linear.x = 0.0;
                                    twist.linear.y = 0.0;
                                    twist.angular.z = 0.6;
                                if state =="STOP":
                                    twist.linear.x = 0.0;
                                    twist.linear.y = 0.0;
                                    twist.angular.z = 0.0;
                                    keep_flying = False

                                if self.front_range == None:
                                    self.front_range = 8
                                if self.back_range == None:
                                    self.back_range = 8
                                if self.left_range == None:
                                    self.left_range = 8
                                if self.right_range == None:
                                    self.right_range = 8					
                                fh.write("%f, %f,  %f, %f, %s\n"% (self.front_range,self.back_range,self.left_range,self.right_range,state_WF))
                                ''' if len(pos)>0:
                                    fh.write("%f, %f,  %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n"% (twist.linear.x, -1*math.degrees(twist.angular.z), self.distance_to_goal,self.angle_to_goal, stabilization.heading, kalman_x, kalman_y, pos_x, pos_y,pos[0],pos[2],rssi,distance))
                                else:
                                    fh.write("%f, %f,  %f, %f, %f, %f, %f, %f, %f, 0, 0, %f, %f\n"% (twist.linear.x, -1*math.degrees(twist.angular.z), self.distance_to_goal,self.angle_to_goal, stabilization.heading, kalman_x, kalman_y, pos_x, pos_y,rssi,distance))'''

                                print(state)
                                motion_commander._set_vel_setpoint(twist.linear.x,twist.linear.y,0,-1*math.degrees(twist.angular.z))
                                '''
                                if self.back_range is not None :
                                    if self.back_range < 0.2:
                                        print("up range is activated")
                                        keep_flying = False'''

                            motion_commander.stop()

                            print("demo terminated")
                            fh.close()
class SwarmTab(Tab, example_tab_class):
    uiSetupReadySignal = pyqtSignal()

    _motor_data_signal = pyqtSignal(int, object, object)
    _imu_data_signal = pyqtSignal(int, object, object)
    _baro_data_signal = pyqtSignal(int, object, object)

    _input_updated_signal = pyqtSignal(float, float, float, float)
    _rp_trim_updated_signal = pyqtSignal(float, float)
    _emergency_stop_updated_signal = pyqtSignal(bool)
    _assisted_control_updated_signal = pyqtSignal(bool)
    _heighthold_input_updated_signal = pyqtSignal(float, float, float, float)
    _hover_input_updated_signal = pyqtSignal(float, float, float, float)

    _log_error_signal = pyqtSignal(object, str)

    _plotter_log_error_signal = pyqtSignal(object, str)
    _log_data_signal = pyqtSignal(int, object, object)
    _disconnected_signal = pyqtSignal(str)
    _connected_signal = pyqtSignal(str)

    colors = [
        (60, 200, 60),    # green
        (40, 100, 255),   # blue
        (255, 130, 240),  # magenta
        (255, 26, 28),    # red
        (255, 170, 0),    # orange
        (40, 180, 240),   # cyan
        (153, 153, 153),  # grey
        (176, 96, 50),    # brown
        (180, 60, 240),   # purple
    ]

    # UI_DATA_UPDATE_FPS = 10

    connectionFinishedSignal = pyqtSignal(str)
    disconnectedSignal = pyqtSignal(str)

    _limiting_updated = pyqtSignal(bool, bool, bool)

    def __init__(self, tabWidget, helper, *args):
        super(SwarmTab, self).__init__(*args)
        self.setupUi(self)

        self.tabName = "Swarm"
        self.menuName = "Swarm"

        self.tabWidget = tabWidget
        self.helper = helper

        self.disconnectedSignal.connect(self.disconnected)
        self.connectionFinishedSignal.connect(self.connected)
        # Incoming signals
        self.helper.cf.connected.add_callback(
            self.connectionFinishedSignal.emit)
        self.helper.cf.disconnected.add_callback(self.disconnectedSignal.emit)

        self._input_updated_signal.connect(self.updateInputControl)
        self.helper.inputDeviceReader.input_updated.add_callback(
            self._input_updated_signal.emit)
        self._rp_trim_updated_signal.connect(self.calUpdateFromInput)
        self.helper.inputDeviceReader.rp_trim_updated.add_callback(
            self._rp_trim_updated_signal.emit)
        self._emergency_stop_updated_signal.connect(self.updateEmergencyStop)
        self.helper.inputDeviceReader.emergency_stop_updated.add_callback(
            self._emergency_stop_updated_signal.emit)

        self.helper.inputDeviceReader.heighthold_input_updated.add_callback(
            self._heighthold_input_updated_signal.emit)
        self._heighthold_input_updated_signal.connect(
            self._heighthold_input_updated)
        self.helper.inputDeviceReader.hover_input_updated.add_callback(
            self._hover_input_updated_signal.emit)
        self._hover_input_updated_signal.connect(
            self._hover_input_updated)

        self.helper.inputDeviceReader.assisted_control_updated.add_callback(
            self._assisted_control_updated_signal.emit)

        self._assisted_control_updated_signal.connect(
            self._assisted_control_updated)

        self._imu_data_signal.connect(self._imu_data_received)
        self._baro_data_signal.connect(self._baro_data_received)
        self._motor_data_signal.connect(self._motor_data_received)

        self._log_error_signal.connect(self._logging_error)

        # PlotWidget Stuff
        self._plot = PlotWidget(fps=30)
        # Check if we could find the PyQtImport. If not, then
        # set this tab as disabled
        self.enabled = self._plot.can_enable
        self._model = LogConfigModel()
        self.dataSelector.setModel(self._model)
        self.plotLayout.addWidget(self._plot)
        self._log_data_signal.connect(self._log_data_received)
        self._plotter_log_error_signal.connect(self._plotter_logging_error)

        if self.enabled:
            self._disconnected_signal.connect(self._disconnected)
            self.helper.cf.disconnected.add_callback(
                self._disconnected_signal.emit)

            self._connected_signal.connect(self._connected)
            self.helper.cf.connected.add_callback(
                self._connected_signal.emit)

            self.helper.cf.log.block_added_cb.add_callback(self._config_added)
            self.dataSelector.currentIndexChanged.connect(
                self._selection_changed)

        self._previous_config = None
        self._started_previous = False

        # Connect UI signals that are in this tab
        #self.flightModeCombo.currentIndexChanged.connect(self.flightmodeChange)
        # self.minThrust.valueChanged.connect(self.minMaxThrustChanged)
        # self.maxThrust.valueChanged.connect(self.minMaxThrustChanged)
        # self.thrustLoweringSlewRateLimit.valueChanged.connect(
        #     self.thrustLoweringSlewRateLimitChanged)
        # self.slewEnableLimit.valueChanged.connect(
        #     self.thrustLoweringSlewRateLimitChanged)
        self.targetCalRoll.valueChanged.connect(self._trim_roll_changed)
        self.inputTypeComboBox.currentIndexChanged.connect(self.inputtypeChange)
        self.stepHeightCombo.valueChanged.connect(self._step_height_changed)
        self.frequencyCombo.valueChanged.connect(self._sine_frequency_changed)
        self.referenceHeightCheckbox.toggled.connect(lambda: self._use_ref_input(self.referenceHeightCheckbox.isChecked()))
        self.targetCalPitch.valueChanged.connect(self._trim_pitch_changed)
        self.updateGainsBtn.clicked.connect(self._controller_gain_changed)
        self.k1Combo.valueChanged.connect(self._k123_gain_changed)
        self.k2Combo.valueChanged.connect(self._k123_gain_changed)
        self.k3Combo.valueChanged.connect(self._k123_gain_changed)
        # self.maxAngle.valueChanged.connect(self.maxAngleChanged)
        # self.maxYawRate.valueChanged.connect(self.maxYawRateChanged)
        self.uiSetupReadySignal.connect(self.uiSetupReady)
        self.clientXModeCheckbox.toggled.connect(self.changeXmode)
        self.isInCrazyFlightmode = False
        self.uiSetupReady()

        # self.clientXModeCheckbox.setChecked(Config().get("client_side_xmode"))
        #
        # self.crazyflieXModeCheckbox.clicked.connect(
        #     lambda enabled:
        #     self.helper.cf.param.set_value("flightmode.x",
        #                                    str(enabled)))
        # self.helper.cf.param.add_update_callback(
        #     group="flightmode", name="xmode",
        #     cb=(lambda name, checked:
        #         self.crazyflieXModeCheckbox.setChecked(eval(checked))))
        #
        # self.ratePidRadioButton.clicked.connect(
        #     lambda enabled:
        #     self.helper.cf.param.set_value("flightmode.ratepid",
        #                                    str(enabled)))
        #
        # self.angularPidRadioButton.clicked.connect(
        #     lambda enabled:
        #     self.helper.cf.param.set_value("flightmode.ratepid",
        #                                    str(not enabled)))
        #
        # self._led_ring_headlight.clicked.connect(
        #     lambda enabled:
        #     self.helper.cf.param.set_value("ring.headlightEnable",
        #                                    str(enabled)))

        # self.helper.cf.param.add_update_callback(
        #     group="flightmode", name="ratepid",
        #     cb=(lambda name, checked:
        #         self.ratePidRadioButton.setChecked(eval(checked))))

        # self.helper.cf.param.add_update_callback(
        #     group="cpu", name="flash",
        #     cb=self._set_enable_client_xmode)

        # self.helper.cf.param.add_update_callback(
        #     group="ring", name="headlightEnable",
        #     cb=(lambda name, checked:
        #         self._led_ring_headlight.setChecked(eval(checked))))

        self._ledring_nbr_effects = 0

        # self.helper.cf.param.add_update_callback(
        #     group="ring",
        #     name="effect",
        #     cb=self._ring_effect_updated)

        self.helper.cf.param.add_update_callback(
            group="imu_sensors",
            cb=self._set_available_sensors)

        # self.helper.cf.param.all_updated.add_callback(
        #     self._ring_populate_dropdown)

        self.logBaro = None
        self.logAltHold = None

        self.ai = AttitudeIndicator()
        self.verticalLayout_2.addWidget(self.ai)
        # self.logo = QLabel(self)
        # pixmap = QPixmap('C:\dev\crazyflie-clients-python\src\cfclient/SUTDLogo.png')
        # self.logo.setPixmap(pixmap.scaled(150, 150, Qt.KeepAspectRatio))
        # self.verticalLayout.addWidget(self.logo)
        self.splitter.setSizes([1000, 1])

        self.targetCalPitch.setValue(Config().get("trim_pitch"))
        self.targetCalRoll.setValue(Config().get("trim_roll"))

        self.helper.inputDeviceReader.alt1_updated.add_callback(
            self.alt1_updated)
        self.helper.inputDeviceReader.alt2_updated.add_callback(
            self.alt2_updated)
        self._tf_state = 0
        self._ring_effect = 0

        # # Connect callbacks for input device limiting of rpƶƶ/pitch/yaw/thust
        # self.helper.inputDeviceReader.limiting_updated.add_callback(
        #     self._limiting_updated.emit)
        # self._limiting_updated.connect(self._set_limiting_enabled)

    def _set_enable_client_xmode(self, name, value):
        if eval(value) <= 128:
            self.clientXModeCheckbox.setEnabled(True)
        else:
            self.clientXModeCheckbox.setEnabled(False)
            self.clientXModeCheckbox.setChecked(False)

    def _set_limiting_enabled(self, rp_limiting_enabled,
                              yaw_limiting_enabled,
                              thrust_limiting_enabled):
        self.maxAngle.setEnabled(rp_limiting_enabled)
        self.targetCalRoll.setEnabled(rp_limiting_enabled)
        self.targetCalPitch.setEnabled(rp_limiting_enabled)
        self.maxYawRate.setEnabled(yaw_limiting_enabled)
        self.maxThrust.setEnabled(thrust_limiting_enabled)
        self.minThrust.setEnabled(thrust_limiting_enabled)
        self.slewEnableLimit.setEnabled(thrust_limiting_enabled)
        self.thrustLoweringSlewRateLimit.setEnabled(thrust_limiting_enabled)

    def thrustToPercentage(self, thrust):
        return ((thrust / MAX_THRUST) * 100.0)

    def uiSetupReady(self):
        flightComboIndex = self.flightModeCombo.findText(
            Config().get("flightmode"), Qt.MatchFixedString)
        if (flightComboIndex < 0):
            self.flightModeCombo.setCurrentIndex(0)
            self.flightModeCombo.currentIndexChanged.emit(0)
        else:
            self.flightModeCombo.setCurrentIndex(flightComboIndex)
            self.flightModeCombo.currentIndexChanged.emit(flightComboIndex)

    def _logging_error(self, log_conf, msg):
        QMessageBox.about(self, "Log error",
                          "Error when starting log config [%s]: %s" % (
                              log_conf.name, msg))

    def _motor_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualM1.setValue(data["motor.m1"])
            self.actualM2.setValue(data["motor.m2"])
            self.actualM3.setValue(data["motor.m3"])
            self.actualM4.setValue(data["motor.m4"])

    def _baro_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            estimated_z = data[LOG_NAME_ESTIMATED_Z]
            self.actualHeight.setText(("%.2f" % estimated_z))
            self.ai.setBaro(estimated_z, self.is_visible())

    def _heighthold_input_updated(self, roll, pitch, yaw, height):
        if (self.isVisible() and
                (self.helper.inputDeviceReader.get_assisted_control() ==
                 self.helper.inputDeviceReader.ASSISTED_CONTROL_HEIGHTHOLD)):
            self.targetRoll.setText(("%0.2f deg" % roll))
            self.targetPitch.setText(("%0.2f deg" % pitch))
            self.targetYaw.setText(("%0.2f deg/s" % yaw))
            self.targetHeight.setText(("%.2f m" % height))
            self.ai.setHover(height, self.is_visible())

    def _hover_input_updated(self, vx, vy, yaw, height):
        if (self.isVisible() and
                (self.helper.inputDeviceReader.get_assisted_control() ==
                 self.helper.inputDeviceReader.ASSISTED_CONTROL_HOVER)):
            self.targetRoll.setText(("%0.2f m/s" % vy))
            self.targetPitch.setText(("%0.2f m/s" % vx))
            self.targetYaw.setText(("%0.2f deg/s" % yaw))
            self.targetHeight.setText(("%.2f m" % height))
            self.ai.setHover(height, self.is_visible())

    def _imu_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualRoll.setText(("%.2f" % data["stabilizer.roll"]))
            self.actualPitch.setText(("%.2f" % data["stabilizer.pitch"]))
            self.actualYaw.setText(("%.2f" % data["stabilizer.yaw"]))
            self.actualThrust.setText("%.2f%%" %
                                      self.thrustToPercentage(
                                          data["stabilizer.thrust"]))

            self.ai.setRollPitch(-data["stabilizer.roll"],
                                 data["stabilizer.pitch"], self.is_visible())

    def connected(self, linkURI):
        # Reset Gains
        self.helper.cf.param.set_value("posCtlPid.zKd", str(0.0))
        self.helper.cf.param.set_value("posCtlPid.zKi", str(0.5))
        self.helper.cf.param.set_value("posCtlPid.zKp", str(40.0))
        self.k1Combo.setValue(40.0)
        self.helper.cf.param.set_value("posCtlPid.zVelMax", str(15.0))
        self.helper.cf.param.set_value("velCtlPid.vzKd", str(0.0))
        self.helper.cf.param.set_value("velCtlPid.vzKi", str(0.0))
        self.helper.cf.param.set_value("velCtlPid.vzKp", str(15.0))
        self.k2Combo.setValue(15.0)
        self.k3Combo.setValue(0.0)

        # IMU & THRUST
        lg = LogConfig("Stabilizer", Config().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        # MOTOR
        lg = LogConfig("Motors", Config().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        self._populate_assisted_mode_dropdown()

    def _set_available_sensors(self, name, available):
        logger.info("[%s]: %s", name, available)
        available = eval(available)

        self.actualHeight.setEnabled(True)
        self.helper.inputDeviceReader.set_alt_hold_available(available)
        if not self.logBaro:
            # The sensor is available, set up the logging
            self.logBaro = LogConfig("Baro", 200)
            self.logBaro.add_variable(LOG_NAME_ESTIMATED_Z, "float")

            try:
                self.helper.cf.log.add_config(self.logBaro)
                self.logBaro.data_received_cb.add_callback(
                    self._baro_data_signal.emit)
                self.logBaro.error_cb.add_callback(
                    self._log_error_signal.emit)
                self.logBaro.start()
            except KeyError as e:
                logger.warning(str(e))
            except AttributeError as e:
                logger.warning(str(e))

    def disconnected(self, linkURI):
        self.ai.setRollPitch(0, 0)
        self.actualM1.setValue(0)
        self.actualM2.setValue(0)
        self.actualM3.setValue(0)
        self.actualM4.setValue(0)
        self.actualRoll.setText("")
        self.actualPitch.setText("")
        self.actualYaw.setText("")
        self.actualThrust.setText("")
        self.actualHeight.setText("")
        self.targetHeight.setText("Not Set")
        self.ai.setHover(0, self.is_visible())
        self.targetHeight.setEnabled(False)
        self.actualHeight.setEnabled(False)
        self.clientXModeCheckbox.setEnabled(False)
        self.logBaro = None
        self.logAltHold = None
        # self._led_ring_effect.setEnabled(False)
        # self._led_ring_effect.clear()
        # try:
        #     self._led_ring_effect.currentIndexChanged.disconnect(
        #         self._ring_effect_changed)
        # except TypeError:
        #     # Signal was not connected
        #     pass
        # self._led_ring_effect.setCurrentIndex(-1)
        # self._led_ring_headlight.setEnabled(False)

        try:
            self._assist_mode_combo.currentIndexChanged.disconnect(
                self._assist_mode_changed)
        except TypeError:
            # Signal was not connected
            pass
        self._assist_mode_combo.setEnabled(False)
        self._assist_mode_combo.clear()

    def minMaxThrustChanged(self):
        self.helper.inputDeviceReader.min_thrust = self.minThrust.value()
        self.helper.inputDeviceReader.max_thrust = self.maxThrust.value()
        if (self.isInCrazyFlightmode is True):
            Config().set("min_thrust", self.minThrust.value())
            Config().set("max_thrust", self.maxThrust.value())

    def thrustLoweringSlewRateLimitChanged(self):
        self.helper.inputDeviceReader.thrust_slew_rate = (
            self.thrustLoweringSlewRateLimit.value())
        self.helper.inputDeviceReader.thrust_slew_limit = (
            self.slewEnableLimit.value())
        if (self.isInCrazyFlightmode is True):
            Config().set("slew_limit", self.slewEnableLimit.value())
            Config().set("slew_rate", self.thrustLoweringSlewRateLimit.value())

    def maxYawRateChanged(self):
        logger.debug("MaxYawrate changed to %d", self.maxYawRate.value())
        self.helper.inputDeviceReader.max_yaw_rate = self.maxYawRate.value()
        if (self.isInCrazyFlightmode is True):
            Config().set("max_yaw", self.maxYawRate.value())

    def maxAngleChanged(self):
        logger.debug("MaxAngle changed to %d", self.maxAngle.value())
        self.helper.inputDeviceReader.max_rp_angle = self.maxAngle.value()
        if (self.isInCrazyFlightmode is True):
            Config().set("max_rp", self.maxAngle.value())

    def _trim_pitch_changed(self, value):
        logger.debug("Pitch trim updated to [%f]" % value)
        self.helper.inputDeviceReader.trim_pitch = value
        Config().set("trim_pitch", value)

    def _trim_roll_changed(self, value):
        logger.debug("Roll trim updated to [%f]" % value)
        self.helper.inputDeviceReader.trim_roll = value
        Config().set("trim_roll", value)

    def _k123_gain_changed(self):
        logger.debug("controller gains updated")
        self.updateGainsBtn.setStyleSheet("background-color:#0078d7; color:#ffffff;")
        self.resetGainsBtn.setStyleSheet("background-color:#0078d7; color:#ffffff;")

    def _controller_gain_changed(self):
        self.updateGainsBtn.setStyleSheet("background-color:#f0f0f0; color:#000000;")
        self.helper.cf.param.set_value("posCtlPid.zKi", str(self.k3Combo.value()))
        self.helper.cf.param.set_value("posCtlPid.zKp", str(self.k1Combo.value()))
        self.helper.cf.param.set_value("velCtlPid.vzKp", str(self.k2Combo.value()))

    def _reset_gain_changed(self):
        # Reset Gains
        self.k1Combo.value(40.0)
        self.k2Combo.setValue(15.0)
        self.k3Combo.setValue(0.0)
        self.helper.cf.param.set_value("posCtlPid.zKi", str(self.k3Combo.value()))
        self.helper.cf.param.set_value("posCtlPid.zKp", str(self.k1Combo.value()))
        self.helper.cf.param.set_value("velCtlPid.vzKp", str(self.k2Combo.value()))
        self.resetGainsBtn.setStyleSheet("background-color:#f0f0f0; color:#000000;")

    def _step_height_changed(self, reference):
        logger.debug("Reference height updated to [%f]" % reference)
        self.targetHeight.setText(("%.2f m" % reference))
        self.ai.setHover(reference, self.is_visible())
        self.helper.referenceHeight = reference
        self.helper.inputTime = 0.0

    def _sine_frequency_changed(self, freq):
        logger.debug("Sine-wave frequency updated to [%f]" % freq)
        self.helper.sinewaveFrequency = freq
        self.helper.inputTime = 0.0

    def _use_ref_input(self, enabled):
        logger.debug("Using reference input")
        self.helper.useReferenceHeight = enabled
        self.helper.inputTime = 0.0

    def inputtypeChange(self, item):
        logger.debug("Changed input type to %s",
                     self.inputTypeComboBox.itemText(item))
        self.helper.inputType = item
        self.helper.inputTime = 0.0
        # item is a number, #0 = 'Step Input', #1 = 'Sine Wave', #2 = 'Ramp'

    def calUpdateFromInput(self, rollCal, pitchCal):
        logger.debug("Trim changed on joystick: roll=%.2f, pitch=%.2f",
                     rollCal, pitchCal)
        self.targetCalRoll.setValue(rollCal)
        self.targetCalPitch.setValue(pitchCal)

    def updateInputControl(self, roll, pitch, yaw, thrust):
        self.targetRoll.setText(("%0.2f deg" % roll))
        self.targetPitch.setText(("%0.2f deg" % pitch))
        self.targetYaw.setText(("%0.2f deg/s" % yaw))
        self.targetThrust.setText(("%0.2f %%" %
                                   self.thrustToPercentage(thrust)))
        self.thrustProgress.setValue(thrust)

    def setMotorLabelsEnabled(self, enabled):
        self.M1label.setEnabled(enabled)
        self.M2label.setEnabled(enabled)
        self.M3label.setEnabled(enabled)
        self.M4label.setEnabled(enabled)

    def emergencyStopStringWithText(self, text):
        return ("<html><head/><body><p>"
                "<span style='font-weight:600; color:#7b0005;'>{}</span>"
                "</p></body></html>".format(text))

    def updateEmergencyStop(self, emergencyStop):
        if emergencyStop:
            self.setMotorLabelsEnabled(False)
            self.emergency_stop_label.setText(
                self.emergencyStopStringWithText("Kill switch active"))
        else:
            self.setMotorLabelsEnabled(True)
            self.emergency_stop_label.setText("")

    def flightmodeChange(self, item):
        Config().set("flightmode", str(self.flightModeCombo.itemText(item)))
        logger.debug("Changed flightmode to %s",
                     self.flightModeCombo.itemText(item))
        self.isInCrazyFlightmode = False
        if (item == 0):  # Normal
            self.maxAngle.setValue(Config().get("normal_max_rp"))
            self.maxThrust.setValue(Config().get("normal_max_thrust"))
            self.minThrust.setValue(Config().get("normal_min_thrust"))
            self.slewEnableLimit.setValue(Config().get("normal_slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                Config().get("normal_slew_rate"))
            self.maxYawRate.setValue(Config().get("normal_max_yaw"))
        if (item == 1):  # Advanced
            self.maxAngle.setValue(Config().get("max_rp"))
            self.maxThrust.setValue(Config().get("max_thrust"))
            self.minThrust.setValue(Config().get("min_thrust"))
            self.slewEnableLimit.setValue(Config().get("slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                Config().get("slew_rate"))
            self.maxYawRate.setValue(Config().get("max_yaw"))
            self.isInCrazyFlightmode = True

        if (item == 0):
            newState = False
        else:
            newState = True
        self.maxThrust.setEnabled(newState)
        self.maxAngle.setEnabled(newState)
        self.minThrust.setEnabled(newState)
        self.thrustLoweringSlewRateLimit.setEnabled(newState)
        self.slewEnableLimit.setEnabled(newState)
        self.maxYawRate.setEnabled(newState)

    def _assist_mode_changed(self, item):
        mode = None

        if (item == 0):  # Altitude hold
            mode = JoystickReader.ASSISTED_CONTROL_ALTHOLD
        if (item == 1):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_POSHOLD
        if (item == 2):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_HEIGHTHOLD
        if (item == 3):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_HOVER

        self.helper.inputDeviceReader.set_assisted_control(mode)
        Config().set("assistedControl", mode)

    def _assisted_control_updated(self, enabled):
        if self.helper.inputDeviceReader.get_assisted_control() == \
                JoystickReader.ASSISTED_CONTROL_POSHOLD:
            self.targetThrust.setEnabled(not enabled)
            self.targetRoll.setEnabled(not enabled)
            self.targetPitch.setEnabled(not enabled)
        elif ((self.helper.inputDeviceReader.get_assisted_control() ==
                JoystickReader.ASSISTED_CONTROL_HEIGHTHOLD) or
                (self.helper.inputDeviceReader.get_assisted_control() ==
                 JoystickReader.ASSISTED_CONTROL_HOVER)):
            self.targetThrust.setEnabled(not enabled)
            self.targetHeight.setEnabled(enabled)
        else:
            self.helper.cf.param.set_value("flightmode.althold", str(enabled))

    @pyqtSlot(bool)
    def changeXmode(self, checked):
        self.helper.cf.commander.set_client_xmode(checked)
        Config().set("client_side_xmode", checked)
        logger.info("Clientside X-mode enabled: %s", checked)

    def alt1_updated(self, state):
        if state:
            new_index = (self._ring_effect+1) % (self._ledring_nbr_effects+1)
            self.helper.cf.param.set_value("ring.effect",
                                           str(new_index))

    def alt2_updated(self, state):
        self.helper.cf.param.set_value("ring.headlightEnable", str(state))

    def _ring_populate_dropdown(self):
        try:
            nbr = int(self.helper.cf.param.values["ring"]["neffect"])
            current = int(self.helper.cf.param.values["ring"]["effect"])
        except KeyError:
            return

        # Used only in alt1_updated function
        self._ring_effect = current
        self._ledring_nbr_effects = nbr

        hardcoded_names = {0: "Off",
                           1: "White spinner",
                           2: "Color spinner",
                           3: "Tilt effect",
                           4: "Brightness effect",
                           5: "Color spinner 2",
                           6: "Double spinner",
                           7: "Solid color effect",
                           8: "Factory test",
                           9: "Battery status",
                           10: "Boat lights",
                           11: "Alert",
                           12: "Gravity",
                           13: "LED tab"}

        for i in range(nbr + 1):
            name = "{}: ".format(i)
            if i in hardcoded_names:
                name += hardcoded_names[i]
            else:
                name += "N/A"
            self._led_ring_effect.addItem(name, i)

        self._led_ring_effect.currentIndexChanged.connect(
            self._ring_effect_changed)

        self._led_ring_effect.setCurrentIndex(current)
        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x01):
            self._led_ring_effect.setEnabled(True)
            self._led_ring_headlight.setEnabled(True)

    def _ring_effect_changed(self, index):
        self._ring_effect = index
        if index > -1:
            i = self._led_ring_effect.itemData(index)
            logger.info("Changed effect to {}".format(i))
            if i != int(self.helper.cf.param.values["ring"]["effect"]):
                self.helper.cf.param.set_value("ring.effect", str(i))

    def _ring_effect_updated(self, name, value):
        if self.helper.cf.param.is_updated:
            self._led_ring_effect.setCurrentIndex(int(value))

    def _populate_assisted_mode_dropdown(self):
        self._assist_mode_combo.addItem("Altitude hold", 0)
        self._assist_mode_combo.addItem("Position hold", 1)
        self._assist_mode_combo.addItem("Height hold", 2)
        self._assist_mode_combo.addItem("Hover", 3)
        heightHoldPossible = False
        hoverPossible = False

        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x09):
            heightHoldPossible = True

        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x0A):
            heightHoldPossible = True
            hoverPossible = True

        if not heightHoldPossible:
            self._assist_mode_combo.model().item(2).setEnabled(False)
        else:
            self._assist_mode_combo.model().item(0).setEnabled(False)

        if not hoverPossible:
            self._assist_mode_combo.model().item(3).setEnabled(False)
        else:
            self._assist_mode_combo.model().item(0).setEnabled(False)

        self._assist_mode_combo.currentIndexChanged.connect(
            self._assist_mode_changed)
        self._assist_mode_combo.setEnabled(True)

        try:
            assistmodeComboIndex = Config().get("assistedControl")
            if assistmodeComboIndex == 3 and not hoverPossible:
                self._assist_mode_combo.setCurrentIndex(0)
                self._assist_mode_combo.currentIndexChanged.emit(0)
            elif assistmodeComboIndex == 0 and hoverPossible:
                self._assist_mode_combo.setCurrentIndex(3)
                self._assist_mode_combo.currentIndexChanged.emit(3)
            elif assistmodeComboIndex == 2 and not heightHoldPossible:
                self._assist_mode_combo.setCurrentIndex(0)
                self._assist_mode_combo.currentIndexChanged.emit(0)
            elif assistmodeComboIndex == 0 and heightHoldPossible:
                self._assist_mode_combo.setCurrentIndex(2)
                self._assist_mode_combo.currentIndexChanged.emit(2)
            else:
                self._assist_mode_combo.setCurrentIndex(assistmodeComboIndex)
                self._assist_mode_combo.currentIndexChanged.emit(
                                                    assistmodeComboIndex)
        except KeyError:
            defaultOption = 0
            if hoverPossible:
                defaultOption = 3
            elif heightHoldPossible:
                defaultOption = 2
            self._assist_mode_combo.setCurrentIndex(defaultOption)
            self._assist_mode_combo.currentIndexChanged.emit(defaultOption)

    def _connected(self, link_uri):
        """Callback when the Crazyflie has been connected"""
        self._plot.removeAllDatasets()
        self._plot.set_title("")

    def _disconnected(self, link_uri):
        """Callback for when the Crazyflie has been disconnected"""
        self._model.beginResetModel()
        self._model.reset()
        self._model.endResetModel()
        self.dataSelector.setCurrentIndex(-1)
        self._previous_config = None
        self._started_previous = False

    def _log_data_signal_wrapper(self, ts, data, logconf):
        """Wrapper for signal"""

        # For some reason the *.emit functions are not
        # the same over time (?!) so they cannot be registered and then
        # removed as callbacks.
        self._log_data_signal.emit(ts, data, logconf)

    def _log_error_signal_wrapper(self, config, msg):
        """Wrapper for signal"""

        # For some reason the *.emit functions are not
        # the same over time (?!) so they cannot be registered and then
        # removed as callbacks.
        self._plotter_log_error_signal.emit(config, msg)

    def _selection_changed(self, i):
        """Callback from ComboBox when a new item has been selected"""

        # Check if we have disconnected
        if i < 0:
            return
        # First check if we need to stop the old block
        if self._started_previous and self._previous_config:
            logger.debug("Should stop config [%s], stopping!",
                         self._previous_config.name)
            self._previous_config.delete()

        # Remove our callback for the previous config
        if self._previous_config:
            self._previous_config.data_received_cb.remove_callback(
                self._log_data_signal_wrapper)
            self._previous_config.error_cb.remove_callback(
                self._log_error_signal_wrapper)

        lg = self._model.get_config(i)
        if not lg.started:
            logger.debug("Config [%s] not started, starting!", lg.name)
            self._started_previous = True
            lg.start()
        else:
            self._started_previous = False
        self._plot.removeAllDatasets()
        color_selector = 0

        self._plot.set_title(lg.name)

        for d in lg.variables:
            self._plot.add_curve(d.name, self.colors[
                color_selector % len(self.colors)])
            color_selector += 1
        lg.data_received_cb.add_callback(self._log_data_signal_wrapper)
        lg.error_cb.add_callback(self._log_error_signal_wrapper)

        self._previous_config = lg

    def _config_added(self, logconfig):
        """Callback from the log layer when a new config has been added"""
        logger.debug("Callback for new config [%s]", logconfig.name)
        self._model.add_block(logconfig)

    def _plotter_logging_error(self, log_conf, msg):
        """Callback from the log layer when an error occurs"""
        QMessageBox.about(
            self, "Plot error", "Error when starting log config [%s]: %s" % (
                log_conf.name, msg))

    def _log_data_received(self, timestamp, data, logconf):
        """Callback when the log layer receives new data"""

        # Check so that the incoming data belongs to what we are currently
        # logging
        if self._previous_config:
            if self._previous_config.name == logconf.name:
                self._plot.add_data(data, timestamp)
    def connected(self, linkURI):
        # Reset Gains
        self.helper.cf.param.set_value("posCtlPid.zKd", str(0.0))
        self.helper.cf.param.set_value("posCtlPid.zKi", str(0.5))
        self.helper.cf.param.set_value("posCtlPid.zKp", str(40.0))
        self.k1Combo.setValue(40.0)
        self.helper.cf.param.set_value("posCtlPid.zVelMax", str(15.0))
        self.helper.cf.param.set_value("velCtlPid.vzKd", str(0.0))
        self.helper.cf.param.set_value("velCtlPid.vzKi", str(0.0))
        self.helper.cf.param.set_value("velCtlPid.vzKp", str(15.0))
        self.k2Combo.setValue(15.0)
        self.k3Combo.setValue(0.0)

        # IMU & THRUST
        lg = LogConfig("Stabilizer", Config().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        # MOTOR
        lg = LogConfig("Motors", Config().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        self._populate_assisted_mode_dropdown()
Example #30
0
from cflib.crazyflie import Crazyflie
from cflib.crazyflie.log import LogConfig
from cflib.crazyflie.syncCrazyflie import SyncCrazyflie
from cflib.crazyflie.syncLogger import SyncLogger

URI = 'radio://0/40/2M/E7E7E7E7E7'


def position_callback(timestamp, data, logconf):
    print(data)


if __name__ == '__main__':
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    log_conf = LogConfig(name='Position', period_in_ms=500)
    log_conf.add_variable('ranging.distance2', 'float')
    #log_conf.add_variable('kalman.stateX', 'float')
    #log_conf.add_variable('kalman.stateZ', 'float')
    #log_conf.add_variable('stabilizer.roll', 'float')
    #log_conf.add_variable('stabilizer.pitch', 'float')
    #log_conf.add_variable('stabilizer.yaw', 'float')

    with SyncCrazyflie(URI, cf=Crazyflie(rw_cache='./cache')) as scf:
        scf.cf.log.add_config(log_conf)
        log_conf.data_received_cb.add_callback(position_callback)
        log_conf.start()
        for i in range(60):
            time.sleep(1)
Example #31
0
def main():
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    # Scan for Crazyflies and use the first one found
    print('Scanning interfaces for Crazyflies...')
    available = cflib.crtp.scan_interfaces()
    print('Crazyflies found:')
    for i in available:
        print(i[0])

    if len(available) == 0:
        print('No Crazyflies found, cannot run example')
    else:

        if (small_log):
            logConfig_stab = LogConfig(name='AttitudeBeforePosCtrl',
                                       period_in_ms=log_intervall)
            logConfig_stab.add_variable('bposatt.roll', 'float')
            logConfig_stab.add_variable('bposatt.pitch', 'float')
            logConfig_stab.add_variable('bposatt.yaw', 'float')
            logConfig_stab.add_variable('bposatt.actuatorThrust', 'float')

            logConfig_state = LogConfig(name='AttitudeAfterPosCtrl',
                                        period_in_ms=log_intervall)
            logConfig_state.add_variable('aposatt.roll', 'float')
            logConfig_state.add_variable('aposatt.pitch', 'float')
            logConfig_state.add_variable('aposatt.yaw', 'float')
            logConfig_state.add_variable('aposatt.actuatorThrust', 'float')

        logConfig_all = LogConfig(name='PositionLog',
                                  period_in_ms=log_intervall)
        logConfig_all.add_variable('stateEstimate.x', 'float')
        logConfig_all.add_variable('stateEstimate.y', 'float')
        logConfig_all.add_variable('stateEstimate.z', 'float')

        with SyncCrazyflie(URI) as scf:
            cf = scf.cf

            if (small_log):
                logger_stab = SyncLogger(scf, logConfig_stab)
                logger_state = SyncLogger(scf, logConfig_state)
                logger_stab.connect()
                logger_state.connect()

            logger_all = SyncLogger(scf, logConfig_all)
            logger_all.connect()

            cf.param.set_value('kalman.resetEstimation', '1')
            time.sleep(0.1)
            cf.param.set_value('kalman.resetEstimation', '0')
            time.sleep(2)

            for y in range(maneuver_iterations):
                cf.commander.send_hover_setpoint(0, 0, 0, y * maneuver_step)
                time.sleep(time_step)

            for i in range(balance_iterations):
                print_message("Balancing out " + str(i))
                cf.commander.send_hover_setpoint(0, 0, 0, height)
                time.sleep(time_step)

            log_start = logger_all._queue.qsize()

            for i in range(log_iterations):
                print_message("Logging " + str(i))
                cf.commander.send_hover_setpoint(0, 0, 0, height)
                time.sleep(time_step)

            log_end = logger_all._queue.qsize()
            log_count = log_end - log_start

            print_message("Start:{}, end:{}".format(log_start, log_end))
            print_message("To log {} lines.".format(log_end - log_start + 1))

            for y in range(maneuver_iterations - 1):
                cf.commander.send_hover_setpoint(0, 0, 0,
                                                 height - (y * maneuver_step))
                time.sleep(time_step)

            cf.commander.send_hover_setpoint(0, 0, 0, 0.1)
            time.sleep(time_step)
            time.sleep(time_step)
            cf.commander.send_stop_setpoint()  #land
            time.sleep(1.5)

            print_message("Landed, writing out log...")

            if (small_log):
                with open(log_file_name(logConfig_stab), "w") as f:
                    log_count = write_out_log(logger_stab, f, log_start,
                                              log_end)
                    print_message("logged stabilizer")

                with open(log_file_name(logConfig_state), "w") as f:
                    log_count = write_out_log(logger_state, f, log_start,
                                              log_end)
                    print_message("logged state")

                logger_stab.disconnect()
                logger_state.disconnect()

            with open(log_file_name(logConfig_all), "w") as f:
                log_count = write_out_log(logger_all, f, log_start, log_end)
            logger_all.disconnect()
            print_message("Done logging.")
Example #32
0
class FlightTab(Tab, flight_tab_class):
    uiSetupReadySignal = pyqtSignal()
    _accel_data_signal = pyqtSignal(int, object, object)
    _gyro_data_signal = pyqtSignal(int, object, object)
    _motor_data_signal = pyqtSignal(int, object, object)
    _imu_data_signal = pyqtSignal(int, object, object)
    _althold_data_signal = pyqtSignal(int, object, object)
    _baro_data_signal = pyqtSignal(int, object, object)

    _input_updated_signal = pyqtSignal(float, float, float, float)
    _rp_trim_updated_signal = pyqtSignal(float, float)
    _emergency_stop_updated_signal = pyqtSignal(bool)

    _log_error_signal = pyqtSignal(object, str)

    #UI_DATA_UPDATE_FPS = 10

    connectionFinishedSignal = pyqtSignal(str)
    disconnectedSignal = pyqtSignal(str)

    def __init__(self, tabWidget, helper, *args):
        global D
        D.thrust = 0
        D.pitch = 0
        D.yawrate = 0
        D.roll = 0
        rospy.init_node("cf_flightTab")
        self.motor_pub = rospy.Publisher("cf_motorData", MotorData)
        self.stab_pub = rospy.Publisher("cf_stabData", StabData)
        self.acc_pub = rospy.Publisher("cf_accData", AccelData)
        self.gyro_pub = rospy.Publisher("cf_gyroData", GyroData)
        rospy.Subscriber("cf_textcmd", String, self._cmdCB)
        
        
        super(FlightTab, self).__init__(*args)
        self.setupUi(self)

        self.tabName = "Flight Control"
        self.menuName = "Flight Control"

        self.tabWidget = tabWidget
        self.helper = helper

        self.disconnectedSignal.connect(self.disconnected)
        self.connectionFinishedSignal.connect(self.connected)
        # Incomming signals
        self.helper.cf.connected.add_callback(
            self.connectionFinishedSignal.emit)
        self.helper.cf.disconnected.add_callback(self.disconnectedSignal.emit)

        self._input_updated_signal.connect(self.updateInputControl)
        self.helper.inputDeviceReader.input_updated.add_callback(
                                     self._input_updated_signal.emit)
        self._rp_trim_updated_signal.connect(self.calUpdateFromInput)
        self.helper.inputDeviceReader.rp_trim_updated.add_callback(
                                     self._rp_trim_updated_signal.emit)
        self._emergency_stop_updated_signal.connect(self.updateEmergencyStop)
        self.helper.inputDeviceReader.emergency_stop_updated.add_callback(
                                     self._emergency_stop_updated_signal.emit)
        
        self.helper.inputDeviceReader.althold_updated.add_callback(
                    lambda enabled: self.helper.cf.param.set_value("flightmode.althold", enabled))
        self._gyro_data_signal.connect(self._gyro_data_received)
        self._accel_data_signal.connect(self._accel_data_received)
        self._imu_data_signal.connect(self._imu_data_received)
        self._baro_data_signal.connect(self._baro_data_received)
        self._althold_data_signal.connect(self._althold_data_received)
        self._motor_data_signal.connect(self._motor_data_received)

        self._log_error_signal.connect(self._logging_error)

        # Connect UI signals that are in this tab
        self.flightModeCombo.currentIndexChanged.connect(self.flightmodeChange)
        self.minThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.maxThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.thrustLoweringSlewRateLimit.valueChanged.connect(
                                      self.thrustLoweringSlewRateLimitChanged)
        self.slewEnableLimit.valueChanged.connect(
                                      self.thrustLoweringSlewRateLimitChanged)
        self.targetCalRoll.valueChanged.connect(self._trim_roll_changed)
        self.targetCalPitch.valueChanged.connect(self._trim_pitch_changed)
        self.maxAngle.valueChanged.connect(self.maxAngleChanged)
        self.maxYawRate.valueChanged.connect(self.maxYawRateChanged)
        self.uiSetupReadySignal.connect(self.uiSetupReady)
        self.clientXModeCheckbox.toggled.connect(self.changeXmode)
        self.isInCrazyFlightmode = False
        self.uiSetupReady()

        self.clientXModeCheckbox.setChecked(GuiConfig().get("client_side_xmode"))

        self.crazyflieXModeCheckbox.clicked.connect(
                             lambda enabled:
                             self.helper.cf.param.set_value("flightmode.x",
                                                            str(enabled)))
        self.helper.cf.param.add_update_callback(
                        group="flightmode", name="xmode",
                        cb=( lambda name, checked:
                        self.crazyflieXModeCheckbox.setChecked(eval(checked))))
        self.ratePidRadioButton.clicked.connect(
                    lambda enabled:
                    self.helper.cf.param.set_value("flightmode.ratepid",
                                                   str(enabled)))
        self.angularPidRadioButton.clicked.connect(
                    lambda enabled:
                    self.helper.cf.param.set_value("flightmode.ratepid",
                                                   str(not enabled)))
        self.helper.cf.param.add_update_callback(
                    group="flightmode", name="ratepid",
                    cb=(lambda name, checked:
                    self.ratePidRadioButton.setChecked(eval(checked))))
        
        self.helper.cf.param.add_update_callback(
                    group="flightmode", name="althold",
                    cb=(lambda name, enabled:
                    self.helper.inputDeviceReader.setAltHold(eval(enabled))))

        self.helper.cf.param.add_update_callback(
                        group="imu_sensors",
                        cb=self._set_available_sensors)
                
        self.logBaro = None
        self.logAltHold = None

        self.ai = AttitudeIndicator()
        self.verticalLayout_4.addWidget(self.ai)
        self.splitter.setSizes([1000,1])

        self.targetCalPitch.setValue(GuiConfig().get("trim_pitch"))
        self.targetCalRoll.setValue(GuiConfig().get("trim_roll"))

    def thrustToPercentage(self, thrust):
        return ((thrust / MAX_THRUST) * 100.0)

    def uiSetupReady(self):
        flightComboIndex = self.flightModeCombo.findText(
                             GuiConfig().get("flightmode"), Qt.MatchFixedString)
        if (flightComboIndex < 0):
            self.flightModeCombo.setCurrentIndex(0)
            self.flightModeCombo.currentIndexChanged.emit(0)
        else:
            self.flightModeCombo.setCurrentIndex(flightComboIndex)
            self.flightModeCombo.currentIndexChanged.emit(flightComboIndex)

    def _logging_error(self, log_conf, msg):
        QMessageBox.about(self, "Log error", "Error when starting log config"
                " [%s]: %s" % (log_conf.name, msg))
    
    def _cmdCB(self, data):
        m = data.data
        print ("Recieved command: " + m)
        if m is 'q':
            self.helper.cf.commander.send_setpoint(0, 0, 0, 0)
        elif m.count(" ")>0:
            hpr,value=m.split(" ")
            if(hpr is "pitch" or hpr is "p"):
                D.pitch= float(value)
            if(hpr=="yawrate" or hpr is "y"):
                D.yawrate= float(value)
            if(hpr=="roll" or hpr is "r"):
                D.roll=float(value)
            if(hpr=="thrust" or hpr is "t"):
                D.thrust= int(value)
            print (D.thrust)
            if D.thrust <= 10000:
                D.thrust = 10001
            elif D.thrust > 60000:
                D.thrust = 60000
            self.helper.cf.commander.send_setpoint(D.roll, D.pitch, D.yawrate, D.thrust)

    def _motor_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualM1.setValue(data["motor.m1"])
            self.actualM2.setValue(data["motor.m2"])
            self.actualM3.setValue(data["motor.m3"])
            self.actualM4.setValue(data["motor.m4"])
            d = MotorData()
            d.m1 = data["motor.m1"]
            d.m2 = data["motor.m2"]
            d.m3 = data["motor.m3"]
            d.m4 = data["motor.m4"]
            self.motor_pub.publish(d)

    def _gyro_data_received(self, timestamp, data, logconf):
        if self.isVisible():
             d = GyroData()
             d.x = data["gyro.x"]
             d.y = data["gyro.y"]
             d.z = data["gyro.z"]
             self.gyro_pub.publish(d)
   
    def _accel_data_received(self, timestamp, data, logconf):
         if self.isVisible():
             d = AccelData() 
             d.x = data["acc.x"]
             d.y = data["acc.y"]
             d.z = data["acc.z"]
             self.acc_pub.publish(d)

    def _baro_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualASL.setText(("%.2f" % data["baro.aslLong"]))
            self.ai.setBaro(data["baro.aslLong"])
        
    def _althold_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            target = data["altHold.target"]
            if target>0:
                if not self.targetASL.isEnabled():
                    self.targetASL.setEnabled(True) 
                self.targetASL.setText(("%.2f" % target))
                self.ai.setHover(target)    
            elif self.targetASL.isEnabled():
                self.targetASL.setEnabled(False)
                self.targetASL.setText("Not set")   
                self.ai.setHover(0)    
        
    def _imu_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualRoll.setText(("%.2f" % data["stabilizer.roll"]))
            self.actualPitch.setText(("%.2f" % data["stabilizer.pitch"]))
            self.actualYaw.setText(("%.2f" % data["stabilizer.yaw"]))
            self.actualThrust.setText("%.2f%%" %
                                      self.thrustToPercentage(
                                                      data["stabilizer.thrust"]))
    
            self.ai.setRollPitch(-data["stabilizer.roll"],
                                 data["stabilizer.pitch"])
            d = StabData()
            d.pitch = data["stabilizer.pitch"]
            d.roll = data["stabilizer.roll"]
            d.yaw = data["stabilizer.yaw"]
            self.stab_pub.publish(d)

    def connected(self, linkURI):
        # IMU & THRUST
        lg = LogConfig("Stabalizer", GuiConfig().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")

        self.helper.cf.log.add_config(lg)
        if (lg.valid):
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup logconfiguration after "
                           "connection!")

        # MOTOR
        lg = LogConfig("Motors", GuiConfig().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        self.helper.cf.log.add_config(lg)
        if lg.valid:
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup logconfiguration after "
                           "connection!")
        
        #Accel
        lg = LogConfig("Accelerometer", GuiConfig().get("ui_update_period"))
        lg.add_variable("acc.x")
        lg.add_variable("acc.y")
        lg.add_variable("acc.z")
        
        self.helper.cf.log.add_config(lg)
        if lg.valid:
            lg.data_received_cb.add_callback(self._accel_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup logconfiguration after "
                           "connection!")

        #Gyroscope
        lg = LogConfig("Gyroscope", GuiConfig().get("ui_update_period"))
        lg.add_variable("gyro.x")
        lg.add_variable("gyro.y")
        lg.add_variable("gyro.z")
        
        self.helper.cf.log.add_config(lg)
        if lg.valid:
            print ("Gyro logging started correctly")
            lg.data_received_cb.add_callback(self._gyro_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        else:
            logger.warning("Could not setup logconfiguration after "
                           "connection!")
            
    def _set_available_sensors(self, name, available):
        logger.info("[%s]: %s", name, available)
        available = eval(available)
        if ("HMC5883L" in name):
            if (not available):
                self.actualASL.setText("N/A")
                self.actualASL.setEnabled(False)
            else:
                self.actualASL.setEnabled(True)
                self.helper.inputDeviceReader.setAltHoldAvailable(available)
                if (not self.logBaro and not self.logAltHold):
                    # The sensor is available, set up the logging
                    self.logBaro = LogConfig("Baro", 200)
                    self.logBaro.add_variable("baro.aslLong", "float")

                    self.helper.cf.log.add_config(self.logBaro)
                    if self.logBaro.valid:
                        self.logBaro.data_received_cb.add_callback(
                            self._baro_data_signal.emit)
                        self.logBaro.error_cb.add_callback(
                            self._log_error_signal.emit)
                        self.logBaro.start()
                    else:
                        logger.warning("Could not setup logconfiguration after "
                                       "connection!")            
                    self.logAltHold = LogConfig("AltHold", 200)
                    self.logAltHold.add_variable("altHold.target", "float")

                    self.helper.cf.log.add_config(self.logAltHold)
                    if self.logAltHold.valid:
                        self.logAltHold.data_received_cb.add_callback(
                            self._althold_data_signal.emit)
                        self.logAltHold.error_cb.add_callback(
                            self._log_error_signal.emit)
                        self.logAltHold.start()
                    else:
                        logger.warning("Could not setup logconfiguration after "
                                       "connection!")                        

    def disconnected(self, linkURI):
        self.ai.setRollPitch(0, 0)
        self.actualM1.setValue(0)
        self.actualM2.setValue(0)
        self.actualM3.setValue(0)
        self.actualM4.setValue(0)
        self.actualRoll.setText("")
        self.actualPitch.setText("")
        self.actualYaw.setText("")
        self.actualThrust.setText("")
        self.actualASL.setText("")
        self.targetASL.setText("Not Set")
        self.targetASL.setEnabled(False)
        self.actualASL.setEnabled(False)
        self.logBaro = None
        self.logAltHold = None

    def minMaxThrustChanged(self):
        self.helper.inputDeviceReader.set_thrust_limits(
                            self.minThrust.value(), self.maxThrust.value())
        if (self.isInCrazyFlightmode == True):
            GuiConfig().set("min_thrust", self.minThrust.value())
            GuiConfig().set("max_thrust", self.maxThrust.value())

    def thrustLoweringSlewRateLimitChanged(self):
        self.helper.inputDeviceReader.set_thrust_slew_limiting(
                            self.thrustLoweringSlewRateLimit.value(),
                            self.slewEnableLimit.value())
        if (self.isInCrazyFlightmode == True):
            GuiConfig().set("slew_limit", self.slewEnableLimit.value())
            GuiConfig().set("slew_rate", self.thrustLoweringSlewRateLimit.value())

    def maxYawRateChanged(self):
        logger.debug("MaxYawrate changed to %d", self.maxYawRate.value())
        self.helper.inputDeviceReader.set_yaw_limit(self.maxYawRate.value())
        if (self.isInCrazyFlightmode == True):
            GuiConfig().set("max_yaw", self.maxYawRate.value())

    def maxAngleChanged(self):
        logger.debug("MaxAngle changed to %d", self.maxAngle.value())
        self.helper.inputDeviceReader.set_rp_limit(self.maxAngle.value())
        if (self.isInCrazyFlightmode == True):
            GuiConfig().set("max_rp", self.maxAngle.value())

    def _trim_pitch_changed(self, value):
        logger.debug("Pitch trim updated to [%f]" % value)
        self.helper.inputDeviceReader.set_trim_pitch(value)
        GuiConfig().set("trim_pitch", value)

    def _trim_roll_changed(self, value):
        logger.debug("Roll trim updated to [%f]" % value)
        self.helper.inputDeviceReader.set_trim_roll(value)
        GuiConfig().set("trim_roll", value)

    def calUpdateFromInput(self, rollCal, pitchCal):
        logger.debug("Trim changed on joystick: roll=%.2f, pitch=%.2f",
                     rollCal, pitchCal)
        self.targetCalRoll.setValue(rollCal)
        self.targetCalPitch.setValue(pitchCal)

    def updateInputControl(self, roll, pitch, yaw, thrust):
        self.targetRoll.setText(("%0.2f" % roll))
        self.targetPitch.setText(("%0.2f" % pitch))
        self.targetYaw.setText(("%0.2f" % yaw))
        self.targetThrust.setText(("%0.2f %%" %
                                   self.thrustToPercentage(thrust)))
        self.thrustProgress.setValue(thrust)

    def setMotorLabelsEnabled(self, enabled):
        self.M1label.setEnabled(enabled)
        self.M2label.setEnabled(enabled)
        self.M3label.setEnabled(enabled)
        self.M4label.setEnabled(enabled)

    def emergencyStopStringWithText(self, text):
        return ("<html><head/><body><p>"
                "<span style='font-weight:600; color:#7b0005;'>{}</span>"
                "</p></body></html>".format(text))

    def updateEmergencyStop(self, emergencyStop):
        if emergencyStop:
            self.setMotorLabelsEnabled(False)
            self.emergency_stop_label.setText(
                      self.emergencyStopStringWithText("Kill switch active"))
        else:
            self.setMotorLabelsEnabled(True)
            self.emergency_stop_label.setText("")

    def flightmodeChange(self, item):
        GuiConfig().set("flightmode", self.flightModeCombo.itemText(item))
        logger.info("Changed flightmode to %s",
                    self.flightModeCombo.itemText(item))
        self.isInCrazyFlightmode = False
        if (item == 0):  # Normal
            self.maxAngle.setValue(GuiConfig().get("normal_max_rp"))
            self.maxThrust.setValue(GuiConfig().get("normal_max_thrust"))
            self.minThrust.setValue(GuiConfig().get("normal_min_thrust"))
            self.slewEnableLimit.setValue(GuiConfig().get("normal_slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                                              GuiConfig().get("normal_slew_rate"))
            self.maxYawRate.setValue(GuiConfig().get("normal_max_yaw"))
        if (item == 1):  # Advanced
            self.maxAngle.setValue(GuiConfig().get("max_rp"))
            self.maxThrust.setValue(GuiConfig().get("max_thrust"))
            self.minThrust.setValue(GuiConfig().get("min_thrust"))
            self.slewEnableLimit.setValue(GuiConfig().get("slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                                                  GuiConfig().get("slew_rate"))
            self.maxYawRate.setValue(GuiConfig().get("max_yaw"))
            self.isInCrazyFlightmode = True

        if (item == 0):
            newState = False
        else:
            newState = True
        self.maxThrust.setEnabled(newState)
        self.maxAngle.setEnabled(newState)
        self.minThrust.setEnabled(newState)
        self.thrustLoweringSlewRateLimit.setEnabled(newState)
        self.slewEnableLimit.setEnabled(newState)
        self.maxYawRate.setEnabled(newState)

    @pyqtSlot(bool)
    def changeXmode(self, checked):
        self.helper.cf.commander.set_client_xmode(checked)
        GuiConfig().set("client_side_xmode", checked)
        logger.info("Clientside X-mode enabled: %s", checked)
class FlightTab(Tab, flight_tab_class):
    uiSetupReadySignal = pyqtSignal()

    _motor_data_signal = pyqtSignal(int, object, object)
    _imu_data_signal = pyqtSignal(int, object, object)
    _baro_data_signal = pyqtSignal(int, object, object)

    _input_updated_signal = pyqtSignal(float, float, float, float)
    _rp_trim_updated_signal = pyqtSignal(float, float)
    _emergency_stop_updated_signal = pyqtSignal(bool)
    _assisted_control_updated_signal = pyqtSignal(bool)
    _heighthold_input_updated_signal = pyqtSignal(float, float, float, float)
    _hover_input_updated_signal = pyqtSignal(float, float, float, float)

    _log_error_signal = pyqtSignal(object, str)

    # UI_DATA_UPDATE_FPS = 10

    connectionFinishedSignal = pyqtSignal(str)
    disconnectedSignal = pyqtSignal(str)

    _limiting_updated = pyqtSignal(bool, bool, bool)

    def __init__(self, tabWidget, helper, *args):
        super(FlightTab, self).__init__(*args)
        self.setupUi(self)

        self.tabName = "Flight Control"
        self.menuName = "Flight Control"

        self.tabWidget = tabWidget
        self.helper = helper

        self.disconnectedSignal.connect(self.disconnected)
        self.connectionFinishedSignal.connect(self.connected)
        # Incomming signals
        self.helper.cf.connected.add_callback(
            self.connectionFinishedSignal.emit)
        self.helper.cf.disconnected.add_callback(self.disconnectedSignal.emit)

        self._input_updated_signal.connect(self.updateInputControl)
        self.helper.inputDeviceReader.input_updated.add_callback(
            self._input_updated_signal.emit)
        self._rp_trim_updated_signal.connect(self.calUpdateFromInput)
        self.helper.inputDeviceReader.rp_trim_updated.add_callback(
            self._rp_trim_updated_signal.emit)
        self._emergency_stop_updated_signal.connect(self.updateEmergencyStop)
        self.helper.inputDeviceReader.emergency_stop_updated.add_callback(
            self._emergency_stop_updated_signal.emit)

        self.helper.inputDeviceReader.heighthold_input_updated.add_callback(
            self._heighthold_input_updated_signal.emit)
        self._heighthold_input_updated_signal.connect(
            self._heighthold_input_updated)
        self.helper.inputDeviceReader.hover_input_updated.add_callback(
            self._hover_input_updated_signal.emit)
        self._hover_input_updated_signal.connect(self._hover_input_updated)

        self.helper.inputDeviceReader.assisted_control_updated.add_callback(
            self._assisted_control_updated_signal.emit)

        self._assisted_control_updated_signal.connect(
            self._assisted_control_updated)

        self._imu_data_signal.connect(self._imu_data_received)
        self._baro_data_signal.connect(self._baro_data_received)
        self._motor_data_signal.connect(self._motor_data_received)

        self._log_error_signal.connect(self._logging_error)

        # Connect UI signals that are in this tab
        self.flightModeCombo.currentIndexChanged.connect(self.flightmodeChange)
        self.minThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.maxThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.thrustLoweringSlewRateLimit.valueChanged.connect(
            self.thrustLoweringSlewRateLimitChanged)
        self.slewEnableLimit.valueChanged.connect(
            self.thrustLoweringSlewRateLimitChanged)
        self.targetCalRoll.valueChanged.connect(self._trim_roll_changed)
        self.targetCalPitch.valueChanged.connect(self._trim_pitch_changed)
        self.maxAngle.valueChanged.connect(self.maxAngleChanged)
        self.maxYawRate.valueChanged.connect(self.maxYawRateChanged)
        self.uiSetupReadySignal.connect(self.uiSetupReady)
        self.clientXModeCheckbox.toggled.connect(self.changeXmode)
        self.isInCrazyFlightmode = False
        self.uiSetupReady()

        self.clientXModeCheckbox.setChecked(Config().get("client_side_xmode"))

        self.crazyflieXModeCheckbox.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "flightmode.x", str(enabled)))
        self.helper.cf.param.add_update_callback(
            group="flightmode",
            name="xmode",
            cb=(lambda name, checked: self.crazyflieXModeCheckbox.setChecked(
                eval(checked))))

        self.ratePidRadioButton.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "flightmode.ratepid", str(enabled)))

        self.angularPidRadioButton.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "flightmode.ratepid", str(not enabled)))

        self._led_ring_headlight.clicked.connect(
            lambda enabled: self.helper.cf.param.set_value(
                "ring.headlightEnable", str(enabled)))

        self.helper.cf.param.add_update_callback(
            group="flightmode",
            name="ratepid",
            cb=(lambda name, checked: self.ratePidRadioButton.setChecked(
                eval(checked))))

        self.helper.cf.param.add_update_callback(
            group="cpu", name="flash", cb=self._set_enable_client_xmode)

        self.helper.cf.param.add_update_callback(
            group="ring",
            name="headlightEnable",
            cb=(lambda name, checked: self._led_ring_headlight.setChecked(
                eval(checked))))

        self._ledring_nbr_effects = 0

        self.helper.cf.param.add_update_callback(group="ring",
                                                 name="effect",
                                                 cb=self._ring_effect_updated)

        self.helper.cf.param.add_update_callback(
            group="imu_sensors", cb=self._set_available_sensors)

        self.helper.cf.param.all_updated.add_callback(
            self._ring_populate_dropdown)

        self.logBaro = None
        self.logAltHold = None

        self.ai = AttitudeIndicator()
        self.verticalLayout_4.addWidget(self.ai)
        self.splitter.setSizes([1000, 1])

        self.targetCalPitch.setValue(Config().get("trim_pitch"))
        self.targetCalRoll.setValue(Config().get("trim_roll"))

        self.helper.inputDeviceReader.alt1_updated.add_callback(
            self.alt1_updated)
        self.helper.inputDeviceReader.alt2_updated.add_callback(
            self.alt2_updated)
        self._tf_state = 0
        self._ring_effect = 0

        # Connect callbacks for input device limiting of rpƶƶ/pitch/yaw/thust
        self.helper.inputDeviceReader.limiting_updated.add_callback(
            self._limiting_updated.emit)
        self._limiting_updated.connect(self._set_limiting_enabled)

    def _set_enable_client_xmode(self, name, value):
        if eval(value) <= 128:
            self.clientXModeCheckbox.setEnabled(True)
        else:
            self.clientXModeCheckbox.setEnabled(False)
            self.clientXModeCheckbox.setChecked(False)

    def _set_limiting_enabled(self, rp_limiting_enabled, yaw_limiting_enabled,
                              thrust_limiting_enabled):
        self.maxAngle.setEnabled(rp_limiting_enabled)
        self.targetCalRoll.setEnabled(rp_limiting_enabled)
        self.targetCalPitch.setEnabled(rp_limiting_enabled)
        self.maxYawRate.setEnabled(yaw_limiting_enabled)
        self.maxThrust.setEnabled(thrust_limiting_enabled)
        self.minThrust.setEnabled(thrust_limiting_enabled)
        self.slewEnableLimit.setEnabled(thrust_limiting_enabled)
        self.thrustLoweringSlewRateLimit.setEnabled(thrust_limiting_enabled)

    def thrustToPercentage(self, thrust):
        return ((thrust / MAX_THRUST) * 100.0)

    def uiSetupReady(self):
        flightComboIndex = self.flightModeCombo.findText(
            Config().get("flightmode"), Qt.MatchFixedString)
        if (flightComboIndex < 0):
            self.flightModeCombo.setCurrentIndex(0)
            self.flightModeCombo.currentIndexChanged.emit(0)
        else:
            self.flightModeCombo.setCurrentIndex(flightComboIndex)
            self.flightModeCombo.currentIndexChanged.emit(flightComboIndex)

    def _logging_error(self, log_conf, msg):
        QMessageBox.about(
            self, "Log error",
            "Error when starting log config [%s]: %s" % (log_conf.name, msg))

    def _motor_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualM1.setValue(data["motor.m1"])
            self.actualM2.setValue(data["motor.m2"])
            self.actualM3.setValue(data["motor.m3"])
            self.actualM4.setValue(data["motor.m4"])

    def _baro_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            estimated_z = data[LOG_NAME_ESTIMATED_Z]
            self.actualHeight.setText(("%.2f" % estimated_z))
            self.ai.setBaro(estimated_z, self.is_visible())

    def _heighthold_input_updated(self, roll, pitch, yaw, height):
        if (self.isVisible() and
            (self.helper.inputDeviceReader.get_assisted_control()
             == self.helper.inputDeviceReader.ASSISTED_CONTROL_HEIGHTHOLD)):
            self.targetRoll.setText(("%0.2f deg" % roll))
            self.targetPitch.setText(("%0.2f deg" % pitch))
            self.targetYaw.setText(("%0.2f deg/s" % yaw))
            self.targetHeight.setText(("%.2f m" % height))
            self.ai.setHover(height, self.is_visible())

    def _hover_input_updated(self, vx, vy, yaw, height):
        if (self.isVisible()
                and (self.helper.inputDeviceReader.get_assisted_control()
                     == self.helper.inputDeviceReader.ASSISTED_CONTROL_HOVER)):
            self.targetRoll.setText(("%0.2f m/s" % vy))
            self.targetPitch.setText(("%0.2f m/s" % vx))
            self.targetYaw.setText(("%0.2f deg/s" % yaw))
            self.targetHeight.setText(("%.2f m" % height))
            self.ai.setHover(height, self.is_visible())

    def _imu_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualRoll.setText(("%.2f" % data["stabilizer.roll"]))
            self.actualPitch.setText(("%.2f" % data["stabilizer.pitch"]))
            self.actualYaw.setText(("%.2f" % data["stabilizer.yaw"]))
            self.actualThrust.setText(
                "%.2f%%" % self.thrustToPercentage(data["stabilizer.thrust"]))

            self.ai.setRollPitch(-data["stabilizer.roll"],
                                 data["stabilizer.pitch"], self.is_visible())

    def connected(self, linkURI):
        # IMU & THRUST
        lg = LogConfig("Stabilizer", Config().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        # MOTOR
        lg = LogConfig("Motors", Config().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        self._populate_assisted_mode_dropdown()

    def _set_available_sensors(self, name, available):
        logger.info("[%s]: %s", name, available)
        available = eval(available)

        self.actualHeight.setEnabled(True)
        self.helper.inputDeviceReader.set_alt_hold_available(available)
        if not self.logBaro:
            # The sensor is available, set up the logging
            self.logBaro = LogConfig("Baro", 200)
            self.logBaro.add_variable(LOG_NAME_ESTIMATED_Z, "float")

            try:
                self.helper.cf.log.add_config(self.logBaro)
                self.logBaro.data_received_cb.add_callback(
                    self._baro_data_signal.emit)
                self.logBaro.error_cb.add_callback(self._log_error_signal.emit)
                self.logBaro.start()
            except KeyError as e:
                logger.warning(str(e))
            except AttributeError as e:
                logger.warning(str(e))

    def disconnected(self, linkURI):
        self.ai.setRollPitch(0, 0)
        self.actualM1.setValue(0)
        self.actualM2.setValue(0)
        self.actualM3.setValue(0)
        self.actualM4.setValue(0)
        self.actualRoll.setText("")
        self.actualPitch.setText("")
        self.actualYaw.setText("")
        self.actualThrust.setText("")
        self.actualHeight.setText("")
        self.targetHeight.setText("Not Set")
        self.ai.setHover(0, self.is_visible())
        self.targetHeight.setEnabled(False)
        self.actualHeight.setEnabled(False)
        self.clientXModeCheckbox.setEnabled(False)
        self.logBaro = None
        self.logAltHold = None
        self._led_ring_effect.setEnabled(False)
        self._led_ring_effect.clear()
        try:
            self._led_ring_effect.currentIndexChanged.disconnect(
                self._ring_effect_changed)
        except TypeError:
            # Signal was not connected
            pass
        self._led_ring_effect.setCurrentIndex(-1)
        self._led_ring_headlight.setEnabled(False)

        try:
            self._assist_mode_combo.currentIndexChanged.disconnect(
                self._assist_mode_changed)
        except TypeError:
            # Signal was not connected
            pass
        self._assist_mode_combo.setEnabled(False)
        self._assist_mode_combo.clear()

    def minMaxThrustChanged(self):
        self.helper.inputDeviceReader.min_thrust = self.minThrust.value()
        self.helper.inputDeviceReader.max_thrust = self.maxThrust.value()
        if (self.isInCrazyFlightmode is True):
            Config().set("min_thrust", self.minThrust.value())
            Config().set("max_thrust", self.maxThrust.value())

    def thrustLoweringSlewRateLimitChanged(self):
        self.helper.inputDeviceReader.thrust_slew_rate = (
            self.thrustLoweringSlewRateLimit.value())
        self.helper.inputDeviceReader.thrust_slew_limit = (
            self.slewEnableLimit.value())
        if (self.isInCrazyFlightmode is True):
            Config().set("slew_limit", self.slewEnableLimit.value())
            Config().set("slew_rate", self.thrustLoweringSlewRateLimit.value())

    def maxYawRateChanged(self):
        logger.debug("MaxYawrate changed to %d", self.maxYawRate.value())
        self.helper.inputDeviceReader.max_yaw_rate = self.maxYawRate.value()
        if (self.isInCrazyFlightmode is True):
            Config().set("max_yaw", self.maxYawRate.value())

    def maxAngleChanged(self):
        logger.debug("MaxAngle changed to %d", self.maxAngle.value())
        self.helper.inputDeviceReader.max_rp_angle = self.maxAngle.value()
        if (self.isInCrazyFlightmode is True):
            Config().set("max_rp", self.maxAngle.value())

    def _trim_pitch_changed(self, value):
        logger.debug("Pitch trim updated to [%f]" % value)
        self.helper.inputDeviceReader.trim_pitch = value
        Config().set("trim_pitch", value)

    def _trim_roll_changed(self, value):
        logger.debug("Roll trim updated to [%f]" % value)
        self.helper.inputDeviceReader.trim_roll = value
        Config().set("trim_roll", value)

    def calUpdateFromInput(self, rollCal, pitchCal):
        logger.debug("Trim changed on joystick: roll=%.2f, pitch=%.2f",
                     rollCal, pitchCal)
        self.targetCalRoll.setValue(rollCal)
        self.targetCalPitch.setValue(pitchCal)

    def updateInputControl(self, roll, pitch, yaw, thrust):
        self.targetRoll.setText(("%0.2f deg" % roll))
        self.targetPitch.setText(("%0.2f deg" % pitch))
        self.targetYaw.setText(("%0.2f deg/s" % yaw))
        self.targetThrust.setText(
            ("%0.2f %%" % self.thrustToPercentage(thrust)))
        self.thrustProgress.setValue(thrust)

    def setMotorLabelsEnabled(self, enabled):
        self.M1label.setEnabled(enabled)
        self.M2label.setEnabled(enabled)
        self.M3label.setEnabled(enabled)
        self.M4label.setEnabled(enabled)

    def emergencyStopStringWithText(self, text):
        return ("<html><head/><body><p>"
                "<span style='font-weight:600; color:#7b0005;'>{}</span>"
                "</p></body></html>".format(text))

    def updateEmergencyStop(self, emergencyStop):
        if emergencyStop:
            self.setMotorLabelsEnabled(False)
            self.emergency_stop_label.setText(
                self.emergencyStopStringWithText("Kill switch active"))
        else:
            self.setMotorLabelsEnabled(True)
            self.emergency_stop_label.setText("")

    def flightmodeChange(self, item):
        Config().set("flightmode", str(self.flightModeCombo.itemText(item)))
        logger.debug("Changed flightmode to %s",
                     self.flightModeCombo.itemText(item))
        self.isInCrazyFlightmode = False
        if (item == 0):  # Normal
            self.maxAngle.setValue(Config().get("normal_max_rp"))
            self.maxThrust.setValue(Config().get("normal_max_thrust"))
            self.minThrust.setValue(Config().get("normal_min_thrust"))
            self.slewEnableLimit.setValue(Config().get("normal_slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                Config().get("normal_slew_rate"))
            self.maxYawRate.setValue(Config().get("normal_max_yaw"))
        if (item == 1):  # Advanced
            self.maxAngle.setValue(Config().get("max_rp"))
            self.maxThrust.setValue(Config().get("max_thrust"))
            self.minThrust.setValue(Config().get("min_thrust"))
            self.slewEnableLimit.setValue(Config().get("slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                Config().get("slew_rate"))
            self.maxYawRate.setValue(Config().get("max_yaw"))
            self.isInCrazyFlightmode = True

        if (item == 0):
            newState = False
        else:
            newState = True
        self.maxThrust.setEnabled(newState)
        self.maxAngle.setEnabled(newState)
        self.minThrust.setEnabled(newState)
        self.thrustLoweringSlewRateLimit.setEnabled(newState)
        self.slewEnableLimit.setEnabled(newState)
        self.maxYawRate.setEnabled(newState)

    def _assist_mode_changed(self, item):
        mode = None

        if (item == 0):  # Altitude hold
            mode = JoystickReader.ASSISTED_CONTROL_ALTHOLD
        if (item == 1):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_POSHOLD
        if (item == 2):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_HEIGHTHOLD
        if (item == 3):  # Position hold
            mode = JoystickReader.ASSISTED_CONTROL_HOVER

        self.helper.inputDeviceReader.set_assisted_control(mode)
        Config().set("assistedControl", mode)

    def _assisted_control_updated(self, enabled):
        if self.helper.inputDeviceReader.get_assisted_control() == \
                JoystickReader.ASSISTED_CONTROL_POSHOLD:
            self.targetThrust.setEnabled(not enabled)
            self.targetRoll.setEnabled(not enabled)
            self.targetPitch.setEnabled(not enabled)
        elif ((self.helper.inputDeviceReader.get_assisted_control()
               == JoystickReader.ASSISTED_CONTROL_HEIGHTHOLD)
              or (self.helper.inputDeviceReader.get_assisted_control()
                  == JoystickReader.ASSISTED_CONTROL_HOVER)):
            self.targetThrust.setEnabled(not enabled)
            self.targetHeight.setEnabled(enabled)
        else:
            self.helper.cf.param.set_value("flightmode.althold", str(enabled))

    @pyqtSlot(bool)
    def changeXmode(self, checked):
        self.helper.cf.commander.set_client_xmode(checked)
        Config().set("client_side_xmode", checked)
        logger.info("Clientside X-mode enabled: %s", checked)

    def alt1_updated(self, state):
        if state:
            new_index = (self._ring_effect + 1) % (self._ledring_nbr_effects +
                                                   1)
            self.helper.cf.param.set_value("ring.effect", str(new_index))

    def alt2_updated(self, state):
        self.helper.cf.param.set_value("ring.headlightEnable", str(state))

    def _ring_populate_dropdown(self):
        try:
            nbr = int(self.helper.cf.param.values["ring"]["neffect"])
            current = int(self.helper.cf.param.values["ring"]["effect"])
        except KeyError:
            return

        # Used only in alt1_updated function
        self._ring_effect = current
        self._ledring_nbr_effects = nbr

        hardcoded_names = {
            0: "Off",
            1: "White spinner",
            2: "Color spinner",
            3: "Tilt effect",
            4: "Brightness effect",
            5: "Color spinner 2",
            6: "Double spinner",
            7: "Solid color effect",
            8: "Factory test",
            9: "Battery status",
            10: "Boat lights",
            11: "Alert",
            12: "Gravity",
            13: "LED tab",
            14: "Color fader",
            15: "Link quality"
        }

        for i in range(nbr + 1):
            name = "{}: ".format(i)
            if i in hardcoded_names:
                name += hardcoded_names[i]
            else:
                name += "N/A"
            self._led_ring_effect.addItem(name, i)

        self._led_ring_effect.currentIndexChanged.connect(
            self._ring_effect_changed)

        self._led_ring_effect.setCurrentIndex(current)
        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x01):
            self._led_ring_effect.setEnabled(True)
            self._led_ring_headlight.setEnabled(True)

    def _ring_effect_changed(self, index):
        self._ring_effect = index
        if index > -1:
            i = self._led_ring_effect.itemData(index)
            logger.info("Changed effect to {}".format(i))
            if i != int(self.helper.cf.param.values["ring"]["effect"]):
                self.helper.cf.param.set_value("ring.effect", str(i))

    def _ring_effect_updated(self, name, value):
        if self.helper.cf.param.is_updated:
            self._led_ring_effect.setCurrentIndex(int(value))

    def _populate_assisted_mode_dropdown(self):
        self._assist_mode_combo.addItem("Altitude hold", 0)
        self._assist_mode_combo.addItem("Position hold", 1)
        self._assist_mode_combo.addItem("Height hold", 2)
        self._assist_mode_combo.addItem("Hover", 3)
        heightHoldPossible = False
        hoverPossible = False

        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x09):
            heightHoldPossible = True
            self.helper.inputDeviceReader.set_hover_max_height(1.0)

        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x0E):
            heightHoldPossible = True
            self.helper.inputDeviceReader.set_hover_max_height(2.0)

        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x0A):
            heightHoldPossible = True
            hoverPossible = True
            self.helper.inputDeviceReader.set_hover_max_height(1.0)

        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x0F):
            heightHoldPossible = True
            hoverPossible = True
            self.helper.inputDeviceReader.set_hover_max_height(2.0)

        if not heightHoldPossible:
            self._assist_mode_combo.model().item(2).setEnabled(False)
        else:
            self._assist_mode_combo.model().item(0).setEnabled(False)

        if not hoverPossible:
            self._assist_mode_combo.model().item(3).setEnabled(False)
        else:
            self._assist_mode_combo.model().item(0).setEnabled(False)

        self._assist_mode_combo.currentIndexChanged.connect(
            self._assist_mode_changed)
        self._assist_mode_combo.setEnabled(True)

        try:
            assistmodeComboIndex = Config().get("assistedControl")
            if assistmodeComboIndex == 3 and not hoverPossible:
                self._assist_mode_combo.setCurrentIndex(0)
                self._assist_mode_combo.currentIndexChanged.emit(0)
            elif assistmodeComboIndex == 0 and hoverPossible:
                self._assist_mode_combo.setCurrentIndex(3)
                self._assist_mode_combo.currentIndexChanged.emit(3)
            elif assistmodeComboIndex == 2 and not heightHoldPossible:
                self._assist_mode_combo.setCurrentIndex(0)
                self._assist_mode_combo.currentIndexChanged.emit(0)
            elif assistmodeComboIndex == 0 and heightHoldPossible:
                self._assist_mode_combo.setCurrentIndex(2)
                self._assist_mode_combo.currentIndexChanged.emit(2)
            else:
                self._assist_mode_combo.setCurrentIndex(assistmodeComboIndex)
                self._assist_mode_combo.currentIndexChanged.emit(
                    assistmodeComboIndex)
        except KeyError:
            defaultOption = 0
            if hoverPossible:
                defaultOption = 3
            elif heightHoldPossible:
                defaultOption = 2
            self._assist_mode_combo.setCurrentIndex(defaultOption)
            self._assist_mode_combo.currentIndexChanged.emit(defaultOption)
Example #34
0
        time.sleep(0.1)


if __name__ == '__main__':

    # # initializing the queue and event object
    q = queue.Queue(maxsize=0)
    e1 = threading.Event()
    e2 = threading.Event()

    # # initializing Crazyflie
    cflib.crtp.init_drivers(enable_debug_driver=False)

    with SyncCrazyflie(uri_3, cf=Crazyflie(rw_cache='./cache')) as scf_3:
        logconf_3 = LogConfig(name='Position', period_in_ms=500)
        logconf_3.add_variable('kalman.stateX', 'float')
        logconf_3.add_variable('kalman.stateY', 'float')
        logconf_3.add_variable('kalman.stateZ', 'float')
        scf_3.cf.log.add_config(logconf_3)
        logconf_3.data_received_cb.add_callback(
            lambda timestamp, data, logconf_3: log_pos_callback_2(
                uri_3, timestamp, data, logconf_3))

        with SyncCrazyflie(uri_2, cf=Crazyflie(rw_cache='./cache')) as scf_2:
            logconf_2 = LogConfig(name='Position', period_in_ms=500)
            logconf_2.add_variable('kalman.stateX', 'float')
            logconf_2.add_variable('kalman.stateY', 'float')
            logconf_2.add_variable('kalman.stateZ', 'float')
            scf_2.cf.log.add_config(logconf_2)
            logconf_2.data_received_cb.add_callback(
Example #35
0
def run_sequence(scf, params):
    cf = scf.cf
    base = params['base']
    z = params['h']

    #sets variables for liftoff, beginning, and end heights
    end = 0.3
    base = params['base']
    h = params['h']
    num = params['num']

    # lifts drones off and sends to beginning heights
    poshold(cf, 2, base)
    poshold(cf, 5, h)

    # The definition of the logconfig can be made before connecting
    log_config = LogConfig(name='Height', period_in_ms=50)
    log_config.add_variable('stateEstimate.z', 'float')
    with SyncLogger(scf, log_config) as logger:
        #sets the runtime
        endTime = time.time() + 45
        j = 0
        time_elapsed = float(0)

        for log_entry in logger:
            timestamp = log_entry[0]
            data = log_entry[1]
            currentPos[num] = data['stateEstimate.z']

            #first runthrough sets begin time of drone, and holds it in
            #current position for another second
            if j == 0:
                begin_T = timestamp
                j = 1
                poshold(cf, 1, h)
                print(0)

            #concurrent runthroughs run the consensus algorithm every
            #three seconds and sends the desired position every second
            else:
                time_elapsed = float((timestamp - begin_T)) / 1000

                #every three seconds runs consensus alg
                if time_elapsed.is_integer() and (int(time_elapsed) % 3) == 0:
                    #ensures all three drones have sent their positions before continuuing
                    while currentPos[0] == 0 or currentPos[
                            1] == 0 or currentPos[2] == 0 or currentPos[
                                3] == 0 or currentPos[4] == 0:
                        time.sleep(0.001)

                    #runs consensus algorithm only on one of the 3 parallel programs running
                    if num == 0:
                        print('running consensus')
                        consensus(currentPos)
                    #(nextPos)

                    #waits till the algorithm runs to continue
                    while (nextPos[0] == 0 or nextPos[1] == 0
                           or nextPos[2] == 0 or nextPos[3] == 0
                           or nextPos[4] == 0):
                        time.sleep(0.001)

                    #sends the update positions to the drones
                    poshold(cf, 1, nextPos[num])
                    #print(nextPos)

                #sends position for drones every second
                elif time_elapsed.is_integer():
                    if time_elapsed < 3:
                        poshold(cf, 1, h)
                    else:
                        poshold(cf, 1, nextPos[num])
            #if time_elapsed.is_integer():
            #print(time_elapsed)
            #print(currentPos)

            #appends the time and height data to a log
            savelog[num].append([time_elapsed, currentPos[num]])

            #ends program after endTime seconds
            if time.time() > endTime:
                break

    #poshold(cf,2, end)
    # # Base altitude in meters
    #print(currentPos)

    #sends drones to base height
    poshold(cf, 2, base)

    #saves the data for future use
    str1 = 'testing'
    str2 = '.csv'
    with open(str1 + str(num) + str2, 'w') as f:
        writer = csv.writer(f, delimiter=',')
        writer.writerows(savelog[num])
    cf.commander.send_stop_setpoint()
Example #36
0
class LogGroup(QTreeWidgetItem):
    """ Group
        If turned on and no children are active, activate all children
        if hz changed, create new log (and start if on)


        Everytime the children change, we stop, delete the old log and create a new one, optionally starting it
        Everytime the HZ changes, we stop, delete the old log and create a new one, optionally starting it

        Everytime we change, we start/stop the log
            We request a start, use partially checked
            Once started, use totally checked


    """



    def __init__(self, parent, name, children, hz=50):
        super(LogGroup, self).__init__(parent)
        self.name = name
        self.setFlags(self.flags() | Qt.ItemIsEditable | Qt.ItemIsUserCheckable)

        # Keep track of if all/none of the children are active
        self.cAll = True
        self.cNone = True
        self.validHZ = list(OrderedDict.fromkeys([round(100/floor(100/x),2) for x in range(1,100)]))
        self.hzTarget = hz

        # Monitor the incoming frequency
        self.fm = None
        self.fmOn = True

        # log config
        self.lg = None

        # Show text
        QtGui.QTreeWidgetItem.setData(self, 0, Qt.DisplayRole, QVariant(name))
        QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, Qt.Unchecked)
        QtGui.QTreeWidgetItem.setData(self, 1, Qt.DisplayRole, "Off")
        QtGui.QTreeWidgetItem.setData(self, 3, Qt.DisplayRole, QVariant(0))
        #QtGui.QTreeWidgetItem.setData(self, 4, Qt.CheckStateRole, Qt.Unchecked)
        self.readSettings()

        # Initialise Children
        for c in sorted(children.keys()):
            self.addChild(LogItem(self, children[c]))

        self.c = 0


        # Now everything is initialised except the logging
        # Start logging if active
        if self.checkState(0) == Qt.Checked:
            self.requestLog()


    def setEstimateHzOn(self, on):
        """ If on then we esstiamte the HZ """
        self.fmOn = on


    def getValidHZ(self, hz):
        # zip(list(OrderedDict.fromkeys([round(100/floor(100/x),2) for x in range(1,100)])),list(OrderedDict.fromkeys([1000/round(100/floor(100/x),2) for x in range(1,100)])))

        i = bisect.bisect_left(self.validHZ, hz)
        vHZ =  min(self.validHZ[max(0, i-1): i+2], key=lambda t: abs(hz - t))
        if hz!=vHZ:
            rospy.loginfo("Could not set HZ to specific value [%d], rounded to valid HZ [%.4f]", hz, vHZ)
        return vHZ


    def readSettings(self):
        """ Read the HZ and selected things to log from previous session """
        settings = QSettings("omwdunkley", "flieROS")

        # Read target HZ
        hzQv = settings.value("log_"+self.name+"_hz",QVariant(20))
        QtGui.QTreeWidgetItem.setData(self, 2, Qt.DisplayRole, hzQv)
        self.hzTarget = self.getValidHZ(hzQv.toFloat()[0])

        # Read if checked. If partially checked, uncheck
        onQv = settings.value("log_"+self.name+"_on", QVariant(Qt.Unchecked))
        QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, onQv if onQv.toInt()[0]!=Qt.PartiallyChecked else Qt.Unchecked)

        #onRos = settings.value("ros_"+self.name+"_on", QVariant(Qt.Unchecked))
        #QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, onRos)


    def writeSettings(self):
        """ Save the HZ and selected things to log between sessions"""
        settings = QSettings("omwdunkley", "flieROS")

        # Save target HZ
        settings.setValue("log_"+self.name+"_hz", self.data(2, Qt.DisplayRole))

        # Save checked state
        settings.setValue("log_"+self.name+"_on", self.data(0, Qt.CheckStateRole))
        #settings.setValue("ros_"+self.name+"_on", self.data(4, Qt.CheckStateRole))

        # Save children state too

        for x in range(self.childCount()):
            self.child(x).writeSettings()


    def updateFM(self):
        # if not self.isActive()
        if self.fm:
            hz = self.fm.get_hz()
            QtGui.QTreeWidgetItem.setData(self, 3, Qt.DisplayRole, round(hz,2))
            return self.name, hz#, -1.0 if self.lg is None else self.hzTarget
        else:
            return self.name, -1.0#, -1.0 if self.lg is None else self.hzTarget


    def logDataCB(self, ts, data, lg):
        """ Our data from the log """
        #print "LogCB data:", data.keys()
        # Update out HZ monitor
        if self.fmOn:
            self.fm.count()

        #TODO: add a checkbox in the row if we wanan send or not
        self.treeWidget().incomingData(data, ts)


    #TODO: there is bug here where the callbacks are called twice!! Holds for this + deleted CB
    def logStartedCB(self, on):
        """ Called when we actually start logging """
        self.c+=1
        #print "counter[%s]"%self.name, self.c
        #if self.c % 2 == 1:
         #   return


        if on:
            rospy.loginfo( "[%d: %s @ %.2fhz] LogCB STARTED" % (self.lg.id, self.name, self.hzTarget))
            QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, Qt.Checked)
            QtGui.QTreeWidgetItem.setData(self, 1, Qt.DisplayRole, "On")
            self.setAllState(Qt.Checked, activeOnly=True)
        else:
            rospy.loginfo( "[%s] LogCB STOPPED" % ( self.name))
            #print "[%s]LogCB ENDED(%d) " % (self.name, self.c)
            #if self.allSelected():
            #    self.setAllState(Qt.Unchecked)
            ##else:
            ##    self.setAllState(Qt.Checked, activeOnly=True)
            #QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, Qt.Unchecked)
            #QtGui.QTreeWidgetItem.setData(self, 1, Qt.DisplayRole, "Off")

    # def logAddedCB(self, l):
    #     """ Called when log added """
    #     print "LogCB added"
    #     QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, Qt.Checked)
    #     QtGui.QTreeWidgetItem.setData(self, 1, Qt.DisplayRole, "Added")


    def requestLog(self):
        """ user requested start """
        #print "Requested log start"

        #print "None selected:",self.noneSelected()
        self.setAllState(Qt.PartiallyChecked, activeOnly=not self.noneSelected())
        QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, Qt.PartiallyChecked)
        QtGui.QTreeWidgetItem.setData(self, 1, Qt.DisplayRole, "Requested")

        # Make and start log config
        self.makeLog()


    def stopLog(self):
        """ User request halt """
        #print "Requested log stop"
        if self.lg:
            self.lg.delete() #Invokes logStarted(False)
            self.lg = None
        if self.allSelected():
            self.setAllState(Qt.Unchecked)
        #else:
        #    self.setAllState(Qt.Checked, activeOnly=True)
        QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, Qt.Unchecked)
        QtGui.QTreeWidgetItem.setData(self, 1, Qt.DisplayRole, "Off")
        self.treeWidget().sig_logStatus.emit(self.name, -1)
        self.fm = None


    def errorLog(self, block, msg):
        """ When a log error occurs """
        #print "Log error: %s:", msg
        QtGui.QTreeWidgetItem.setData(self, 1, Qt.DisplayRole, "Err: %s"%msg)
        QtGui.QTreeWidgetItem.setData(self, 0, Qt.CheckStateRole, Qt.Unchecked)
        if self.allSelected():
            self.setAllState(Qt.Unchecked)
        else:
            self.setAllState(Qt.Checked, activeOnly=True)
        self.fm = None


    def setData(self, column, role, value):
        """ Only allow changing of the check state and the hz """

        # GROUP ON/OFF
        preValue = self.checkState(0)
        if role == Qt.CheckStateRole and column == 0 and preValue != value:
            # Check box changed, allow and trigger

            #print "\n\nCONFIG CHANGED\n"
            if preValue==Qt.PartiallyChecked:
                #print "User clicked: Waiting for log callback, cannot change config now"
                pass

            elif value==Qt.Checked:
                #print "User clicked: request logging"
                self.requestLog()

            elif value==Qt.Unchecked:
                #print "User clicked: request delete logging"
                self.stopLog()


        # HZ CHANGED
        if column == 2:
            #hz = min(max(value.toInt()[0],1),100)
            hz = self.getValidHZ(value.toFloat()[0])

            preHz = self.data(column, Qt.DisplayRole).toFloat()[0]
            #print "\n\nHZ CHANGED\n"
            if hz!=preHz:
                if preValue==Qt.PartiallyChecked:
                    pass
                    #print "Waiting for log callback, cannot change hz now"
                elif preValue==Qt.Checked:
                    #print "hz changed from %.2f to %.2f while logging, replace log" % (preHz, hz)
                    QtGui.QTreeWidgetItem.setData(self, column, role, hz)
                    self.hzTarget = hz
                    self.requestLog()
                elif preValue==Qt.Unchecked:
                    #print "hz changed from %.2f to %.2f, not logging yet" % (preHz, hz)
                    QtGui.QTreeWidgetItem.setData(self, column, role, hz)
                    self.hzTarget = hz

    def childStateChanged(self, child, newState):
        if self.checkState(0) == Qt.Unchecked:
            #print "Child Changed while not logging"
            QtGui.QTreeWidgetItem.setData(child, 0, Qt.CheckStateRole, newState)
        elif self.checkState(0) == Qt.PartiallyChecked:
            pass
            #print "Waiting for log callback"
        elif self.checkState(0) == Qt.Checked:
            QtGui.QTreeWidgetItem.setData(child, 0, Qt.CheckStateRole, newState)
            if self.noneSelected():
                #print "Last child unselected, remove logger"
                self.stopLog()
            elif self.allSelected():
                #print "All children selected while logging, update logger"
                self.requestLog()
            else:
                #print "Child Changed while logging, update logger"
                self.requestLog()


    def makeLog(self):
        """ Makes a log. All ative children are added """

        #print " -> Making new Log with %d ms interval"
        if self.lg:
            #print " ---> Previous Log detected, removing first"
            self.lg.delete()


        self.fm = FreqMonitor(window=max(10, int(1.2*self.hzTarget)))
        self.lg = LogConfig(self.name, int(round(1000./self.hzTarget)))
        #print " ---> Adding children to new log"
        for x in range(self.childCount()):
            c = self.child(x)
            if c.isChecked():
                name = c.log.group+"."+c.log.name
                self.lg.add_variable(name, c.log.ctype)
                #print " --- --> Adding child[%d]: [%s] to new log"%(x, name)

        #print " ---> Checking log with TOC"
        self.treeWidget().cf.log.add_config(self.lg)
        if self.lg.valid:
            #print " --- --> PASS"
            self.lg.data_received_cb.add_callback(self.logDataCB)
            self.lg.started_cb.add_callback(self.logStartedCB)
            self.lg.error_cb.add_callback(self.treeWidget().sig_logError.emit)
            self.lg.error_cb.add_callback(self.errorLog)

            self.treeWidget().sig_logStatus.emit(self.name, self.hzTarget)

            #print " --- --> callbacks added, starting new log NOW"
            self.lg.start()

        else:
            #print " --- --> FAIL"
            self.errorLog(None, "Invalid Config")
            self.lg = None
            self.fm = None


    def setAllState(self, chkState, activeOnly=False):
        """ Set all children on or off without their setData function. If activeOnly only set ones who are not off """
        if activeOnly:
            #print " -> Setting all ACTIVE children to checkstate [%d]", chkState
            for x in range(self.childCount()):
                if self.child(x).isChecked():
                    self.child(x).setState(chkState)
                    #print " --->", self.child(x).log.name
        else:
            #print " -> Setting all children to checkstate [%d]", chkState
            for x in range(self.childCount()):
                self.child(x).setState(chkState)
                #print " --->", self.child(x).log.name


    def allSelected(self):
        """ Returns true if all children are selected """
        for x in range(self.childCount()):
            if not self.child(x).isChecked():
                return False
        return True


    def noneSelected(self):
        """ Returns true if no children are selected """
        for x in range(self.childCount()):
            if self.child(x).isChecked():
                return False
        return True
Example #37
0
class TrafficController:
    CS_DISCONNECTED = 0
    CS_CONNECTING = 1
    CS_CONNECTED = 2

    STATE_UNKNOWN = -1
    STATE_IDLE = 0
    STATE_WAIT_FOR_POSITION_LOCK = 1
    STATE_WAIT_FOR_TAKE_OFF = 2  # Charging
    STATE_TAKING_OFF = 3
    STATE_HOVERING = 4
    STATE_WAITING_TO_GO_TO_INITIAL_POSITION = 5
    STATE_GOING_TO_INITIAL_POSITION = 6
    STATE_RUNNING_TRAJECTORY = 7
    STATE_GOING_TO_PAD = 8
    STATE_WAITING_AT_PAD = 9
    STATE_LANDING = 10
    STATE_CHECK_CHARGING = 11
    STATE_REPOSITION_ON_PAD = 12
    STATE_CRASHED = 13

    NO_PROGRESS = -1000.0

    PRE_STATE_TIMEOUT = 3

    def __init__(self, uri):
        self.uri = uri
        self.stay_alive = True
        self.reset_internal()
        self.connection_thread = threading.Thread(target=self.process)
        self.connection_thread.start()

    def reset_internal(self):
        self.connection_state = self.CS_DISCONNECTED
        self._cf = None
        self._log_conf = None
        self.copter_state = self.STATE_UNKNOWN
        self.vbat = -1.0
        self._time_for_next_connection_attempt = 0
        self.traj_cycles = None
        self.est_x = 0.0
        self.est_y = 0.0
        self.est_z = 0.0
        self.up_time_ms = 0
        self.flight_time_ms = 0

        # Pre states are used to prevent multiple calls to a copter
        # when waiting for the remote state to change
        self._pre_state_taking_off_end_time = 0
        self._pre_state_going_to_initial_position_end_time = 0

    def _pre_state_taking_off(self):
        return self._pre_state_taking_off_end_time > time.time()

    def _pre_state_going_to_initial_position(self):
        return self._pre_state_going_to_initial_position_end_time > time.time()

    def is_connected(self):
        return self.connection_state == self.CS_CONNECTED

    def has_found_position(self):
        return self.copter_state > self.STATE_WAIT_FOR_POSITION_LOCK

    def is_taking_off(self):
        return self.copter_state == self.STATE_TAKING_OFF or self._pre_state_taking_off()

    def is_ready_for_flight(self):
        return self.copter_state == self.STATE_HOVERING and not self._pre_state_going_to_initial_position()

    def is_flying(self):
        return self.copter_state == self.STATE_RUNNING_TRAJECTORY or \
               self.copter_state == self.STATE_WAITING_TO_GO_TO_INITIAL_POSITION or \
               self.copter_state == self.STATE_GOING_TO_INITIAL_POSITION or \
               self._pre_state_going_to_initial_position()

    def is_landing(self):
        return self.copter_state == self.STATE_GOING_TO_PAD or \
               self.copter_state == self.STATE_WAITING_AT_PAD or \
               self.copter_state == self.STATE_LANDING or \
               self.copter_state == self.STATE_CHECK_CHARGING or \
               self.copter_state == self.STATE_REPOSITION_ON_PAD

    def is_charging(self):
        return self.copter_state == self.STATE_WAIT_FOR_TAKE_OFF and not self._pre_state_taking_off()

    def is_crashed(self):
        return self.copter_state == self.STATE_CRASHED

    def take_off(self):
        if self.is_charging():
            if self._cf:
                self._pre_state_taking_off_end_time = time.time() + self.PRE_STATE_TIMEOUT
                self._cf.param.set_value('app.takeoff', 1)

    def start_trajectory(self, trajectory_delay, offset_x=0.0, offset_y=0.0, offset_z=0.0):
        if self.is_ready_for_flight():
            if self._cf:
                self._cf.param.set_value('app.offsx', offset_x)
                self._cf.param.set_value('app.offsy', offset_y)
                self._cf.param.set_value('app.offsz', offset_z)

                self._pre_state_going_to_initial_position_end_time = time.time() + self.PRE_STATE_TIMEOUT
                self._cf.param.set_value('app.start', trajectory_delay)

    def force_land(self):
        if self.connection_state == self.CS_CONNECTED:
            self._cf.param.set_value('app.stop', 1)

    def set_trajectory_count(self, count):
        if self.connection_state == self.CS_CONNECTED:
            self._cf.param.set_value('app.trajcount', count)

    def get_charge_level(self):
        return self.vbat

    def is_charged_for_flight(self):
        return self.vbat > 4.10

    def get_traj_cycles(self):
        return self.traj_cycles

    def process(self):
        while self.stay_alive:
            if self.connection_state == self.CS_DISCONNECTED:
                if time.time() > self._time_for_next_connection_attempt:
                    self._connect()

            time.sleep(1)
        self._cf.close_link()

    def _connected(self, link_uri):
        self.connection_state = self.CS_CONNECTED
        print('Connected to %s' % link_uri)

    def _all_updated(self):
        """Callback that is called when all parameters have been updated"""

        self.set_trajectory_count(2)
        self._setup_logging()

    def _connection_failed(self, link_uri, msg):
        print('Connection to %s failed: %s' % (link_uri, msg))
        self._set_disconnected(5)

    def _connection_lost(self, link_uri, msg):
        print('Connection to %s lost: %s' % (link_uri, msg))

    def _disconnected(self, link_uri):
        print('Disconnected from %s' % link_uri)
        self._set_disconnected()

    def _set_disconnected(self, hold_back_time=5):
        self.reset_internal()
        self._time_for_next_connection_attempt = time.time() + hold_back_time

    def _connect(self):
        if self.connection_state != self.CS_DISCONNECTED:
            print("Can only connect when disconnected")
            return

        self.connection_state = self.CS_CONNECTING

        self._cf = Crazyflie(rw_cache='./cache')

        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)
        self._cf.param.all_updated.add_callback(self._all_updated)
        # self._cf.console.receivedChar.add_callback(self._console_incoming) #print debug messages from Crazyflie

        print("Connecting to " + self.uri)
        self._cf.open_link(self.uri)

    def _console_incoming(self, console_text):
        print("CF {} DEBUG:".format( self.uri[-2:] ),console_text, end='')

    def _setup_logging(self):
        # print("Setting up logging")
        self._log_conf = LogConfig(name='Tower', period_in_ms=100)
        self._log_conf.add_variable('app.state', 'uint8_t')
        self._log_conf.add_variable('app.prgr', 'float')
        self._log_conf.add_variable('app.uptime', 'uint32_t')
        self._log_conf.add_variable('app.flighttime', 'uint32_t')
        self._log_conf.add_variable('pm.vbat', 'float')
        self._log_conf.add_variable('stateEstimate.x', 'float')
        self._log_conf.add_variable('stateEstimate.y', 'float')

        self._cf.log.add_config(self._log_conf)
        self._log_conf.data_received_cb.add_callback(self._log_data)
        self._log_conf.start()

    def _log_data(self, timestamp, data, logconf):
        self.copter_state = data['app.state']

        if self.copter_state != self.STATE_WAIT_FOR_TAKE_OFF:
            self._pre_state_taking_off_end_time = 0

        if self.copter_state != self.STATE_HOVERING:
            self._pre_state_going_to_initial_position_end_time = 0

        self.vbat = data['pm.vbat']

        self.up_time_ms = data['app.uptime']
        self.flight_time_ms = data['app.flighttime']

        self.traj_cycles = data['app.prgr']
        if self.traj_cycles <= self.NO_PROGRESS:
            self.traj_cycles = None

        self.est_x = data['stateEstimate.x']
        self.est_y = data['stateEstimate.y']

    def dump(self):
        print("***", self.uri)
        print("  Connection state:", self.connection_state)
        print("  Copter state:", self.copter_state)
        print("  Bat:", self.vbat)
        print("  Up time:", self.up_time_ms / 1000)
        print("  Flight time:", self.flight_time_ms / 1000)
        print("  _pre_state_taking_off:", self._pre_state_taking_off())
        print("  _pre_state_going_to_initial_position:", self._pre_state_going_to_initial_position())

    def terminate(self):
        self.stay_alive = False
if __name__ == '__main__':
    cflib.crtp.init_drivers(enable_debug_driver=False)

    # Set these to the position and yaw based on how your Crazyflie is placed
    # on the floor
    initial_x = 0.0
    initial_y = 0.0
    initial_z = 0.0
    initial_yaw = 0  # In degrees
    # 0: positive X direction
    # 90: positive Y direction
    # 180: negative X direction
    # 270: negative Y direction

    # define logging parameters
    lg_posEst = LogConfig(name='stateEstimate', period_in_ms=20)
    lg_posEst.add_variable('stateEstimate.x', 'float')
    lg_posEst.add_variable('stateEstimate.y', 'float')
    lg_posEst.add_variable('stateEstimate.z', 'float')
    lg_posEst.add_variable('stateEstimate.roll', 'float')
    lg_posEst.add_variable('stateEstimate.pitch', 'float')
    lg_posEst.add_variable('stateEstimate.yaw', 'float')

    # lg_posSet = LogConfig(name='posCtl', period_in_ms=20)
    # lg_posSet.add_variable('posCtl.targetX', 'float')
    # lg_posSet.add_variable('posCtl.targetY', 'float')
    # lg_posSet.add_variable('posCtl.targetZ', 'float')

    lg_pm = LogConfig(name='pm', period_in_ms=20)
    lg_pm.add_variable('pm.vbat', 'float')
    
    def _connected(self, link_uri):
        """ This callback is called from the Crazyflie API when a Crazyflie
        has been connected adn TOCs have been downloaded """
        print('connected to: %s' % link_uri)

        # Open text file for recording data
        self.datalog_Pos = open("log_data/Cf2log_Pos", "w")
        #self.datalog_Vel    = open("log_data/Cf2log_Vel","w")
        #self.datalog_Att    = open("log_data/Cf2log_Att","w")
        self.datalog_Att = open("log_data/Cf2log_Mtr", "w")

        # Reset Kalman filter
        self._cf.param.set_value('kalman.resetEstimation', '1')
        time.sleep(0.1)
        self._cf.param.set_value('kalman.resetEstimation', '0')
        time.sleep(2)
        print('Wait for Kalamn filter')

        # Feedback position estimated by KF
        logPos = LogConfig(name='Kalman Position',
                           period_in_ms=self.statefb_rate)
        logPos.add_variable('kalman.stateX', 'float')
        logPos.add_variable('kalman.stateY', 'float')
        logPos.add_variable('kalman.stateZ', 'float')

        # Feedback velocity estimated by KF
        logVel = LogConfig(name='Kalman Velocity',
                           period_in_ms=self.statefb_rate)
        logVel.add_variable('kalman.statePX', 'float')
        logVel.add_variable('kalman.statePY', 'float')
        logVel.add_variable('kalman.statePZ', 'float')

        # Feedback Quaternion attitude estimated by KF
        logAtt = LogConfig(name='Kalman Attitude',
                           period_in_ms=self.statefb_rate)
        logAtt.add_variable('kalman.q0', 'float')
        logAtt.add_variable('kalman.q1', 'float')
        logAtt.add_variable('kalman.q2', 'float')
        logAtt.add_variable('kalman.q3', 'float')

        # Feedback Multi ranger
        logMultiRa = LogConfig(name='Range', period_in_ms=self.statefb_rate)
        logMultiRa.add_variable('range.front', 'uint16_t')
        logMultiRa.add_variable('range.back', 'uint16_t')
        logMultiRa.add_variable('range.left', 'uint16_t')
        logMultiRa.add_variable('range.right', 'uint16_t')
        logMultiRa.add_variable('range.up', 'uint16_t')

        # Invoke logged states
        self._cf.log.add_config(logPos)
        self._cf.log.add_config(logVel)
        self._cf.log.add_config(logAtt)
        self._cf.log.add_config(logMultiRa)

        # Start invoking logged states
        if logPos.valid and logVel.valid:
            # Position
            logPos.data_received_cb.add_callback(self.log_pos_callback)
            logPos.error_cb.add_callback(logging_error)
            logPos.start()
            # Velocity
            logVel.data_received_cb.add_callback(self.log_vel_callback)
            logVel.error_cb.add_callback(logging_error)
            logVel.start()
            # Quadternion attitude
            logAtt.data_received_cb.add_callback(self.log_att_callback)
            logAtt.error_cb.add_callback(logging_error)
            logAtt.start()
            # Multi-Ranger
            logMultiRa.data_received_cb.add_callback(self.log_mtr_callback)
            logMultiRa.error_cb.add_callback(logging_error)
            logMultiRa.start()
        else:
            print(
                "One or more of the variables in the configuration was not found"
                + "in log TOC. No logging will be possible")

        # Start in a thread
        threading.Thread(target=self._run_controller).start()
class Odometry(threading.Thread):
    def __init__(self, cf):
        self.cf = cf
        super(Odometry, self).__init__()
        self.lg_pose = LogConfig(name='Stabilizer1', period_in_ms=100)
        self.lg_pose.add_variable('stateEstimate.x', 'float')
        self.lg_pose.add_variable('stateEstimate.y', 'float')
        self.lg_pose.add_variable('stateEstimate.z', 'float')
        self.lg_pose.add_variable('stateEstimate.roll', 'float')
        self.lg_pose.add_variable('stateEstimate.pitch', 'float')
        self.lg_pose.add_variable('stateEstimate.yaw', 'float')

        self.lg_velociy = LogConfig(name='Stabilizer2', period_in_ms=100)
        self.lg_velociy.add_variable('stateEstimate.vx', 'float')
        self.lg_velociy.add_variable('stateEstimate.vy', 'float')
        self.lg_velociy.add_variable('stateEstimate.vz', 'float')
        self.lg_velociy.add_variable('stateEstimateZ.ratePitch', 'float')
        self.lg_velociy.add_variable('stateEstimateZ.rateRoll', 'float')
        self.lg_velociy.add_variable('stateEstimateZ.rateYaw', 'float')

        self.x = 0
        self.y = 0
        self.z = 0
        self.roll = 0
        self.pitch = 0
        self.yaw = 0
        self.vz = 0
        self.vx = 0
        self.vy = 0
        self.ratePitch = 0
        self.rateRoll = 0
        self.rateYaw = 0

    def run(self):
        try:
            self.cf.log.add_config(self.lg_pose)
            self.cf.log.add_config(self.lg_velociy)
            self.is_connected = True
            self.lg_pose.data_received_cb.add_callback(self._pose_log_data)
            self.lg_velociy.data_received_cb.add_callback(
                self._velocity_log_data)

            self.lg_pose.start()
            self.lg_velociy.start()

        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))

    def _pose_log_data(self, timestamp, data, logconf):
        """Callback from a the log API when data arrives"""
        #print('[%d][%s]: %s' % (timestamp, logconf.name, data))
        self.x = data['stateEstimate.x']
        self.y = data['stateEstimate.y']
        self.z = data['stateEstimate.z']
        self.roll = data['stateEstimate.roll']
        self.pitch = data['stateEstimate.y']
        self.yaw = data['stateEstimate.y']
    # self.vx=data['stateEstimate.vx']
    # self.vy=data['stateEstimate.vy']
    #  self.vz=data['stateEstimate.vz']
    #  self.wx=data['stateEstimateZ.rateRoll']

    #   self.wy=data['stateEstimateZ.ratePitch']
    #   self.wz=data['stateEstimateZ.rateYaw']
    # print("odometry z=",self.z)

    def _velocity_log_data(self, timestamp, data, logconf):
        self.vx = data['stateEstimate.vx']
        self.vy = data['stateEstimate.vy']
        self.vz = data['stateEstimate.vz']
        self.wx = data['stateEstimateZ.rateRoll']
        self.wy = data['stateEstimateZ.ratePitch']
        self.wz = data['stateEstimateZ.rateYaw']
Example #41
0
class LoggingExample:
    """
    Simple logging example class that logs the Stabilizer from a supplied
    link uri and disconnects after 5s.
    
    """
    def __init__(self, link_uri):
        """ Initialize and run the example with the specified link_uri """

        # Create a Crazyflie object without specifying any cache dirs
        self._cf = Crazyflie()

        #functions used for motors
        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        # Connect some callbacks from the Crazyflie API
        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        print('Connecting to %s' % link_uri)

        # Try to connect to the Crazyflie
        self._cf.open_link(link_uri)

        # Variable used to keep main loop occupied until disconnect
        self.is_connected = True

    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""

        print('Connected to %s' % link_uri)

        # The definition of the logconfig can be made before connecting
        self._lg_acc = LogConfig(name='Accel', period_in_ms=10)
        #self._lg_acc.add_variable('mag.x', 'float')
        #self._lg_acc.add_variable('mag.y', 'float')
        self._lg_acc.add_variable('test.TESTVARIABLE', 'float')

        #self._lg_stab = LogConfig(name='Stabilizer', period_in_ms=10)
        #self._lg_stab.add_variable('stabilizer.roll', 'float')
        #self._lg_stab.add_variable('stabilizer.pitch', 'float')
        #self._lg_stab.add_variable('stabilizer.yaw', 'float')

        # Adding the configuration cannot be done until a Crazyflie is
        # connected, since we need to check that the variables we
        # would like to log are in the TOC.
        try:
            self._cf.log.add_config(self._lg_acc)
            # This callback will receive the data
            self._lg_acc.data_received_cb.add_callback(self._stab_log_data)

            # This callback will be called on errors
            self._lg_acc.error_cb.add_callback(self._stab_log_error)
            # Start the logging
            self._lg_acc.start()

        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))
        except AttributeError:
            print('Could not add Stabilizer log config, bad configuration.')

        # Start a timer to disconnect in 10s
        t = Timer(20, self._cf.close_link)
        t.start()

    def _stab_log_error(self, logconf, msg):
        ##        """Callback from the log API when an error occurs"""
        print('Error when logging %s: %s' % (logconf.name, msg))

    def _stab_log_data(self, timestamp, data, logconf):
        """Callback froma the log API when data arrives"""
        global maxi
        #print('[%s]: %s\n' % (logconf.name, data))
        #if data > maxi:
        maxi = data

        print('[%s]: %s\n' % (logconf.name, data))
        #Thread(target=self._ramp_motors).start()

    def _connection_failed(self, link_uri, msg):
        """Callback when connection initial connection fails (i.e no Crazyflie
        at the speficied address)"""
        print('Connection to %s failed: %s' % (link_uri, msg))
        self.is_connected = False

    def _connection_lost(self, link_uri, msg):
        """Callback when disconnected after a connection has been made (i.e
        Crazyflie moves out of range)"""
        print('Connection to %s lost: %s' % (link_uri, msg))

    def _disconnected(self, link_uri):
        """Callback when the Crazyflie is disconnected (called in all cases)"""
        print('Disconnected from %s' % link_uri)
        self.is_connected = False

    #def _connected(self, link_uri):

    def _ramp_motors(self):
        global maxi

        #j = int(maxi[0])*5000

        j = int(maxi['mag.z']) * 4000

        if j < 0:
            j = 0
        elif j > 60000:
            j = 60000

    #for item in maxi:
    #   j = int(item)

        thrust_mult = 1
        thrust_step = 500
        thrust = 20000
        pitch = 0
        roll = 0
        yawrate = 0

        # Unlock startup thrust protection
        self._cf.commander.send_setpoint(0, 0, 0, 0)
        print j
        #time.sleep(0.1)
        self._cf.commander.send_setpoint(roll, pitch, yawrate, j)
        time.sleep(0.1)
Example #42
0
 def default_log_config(sample_time_ms=10):
     config = LogConfig(name='Kalman Position and Velocity',
                        period_in_ms=sample_time_ms)
     config.add_variable(CFUtil.KEY_X, 'float')
     config.add_variable(CFUtil.KEY_Y, 'float')
     config.add_variable(CFUtil.KEY_Z, 'float')
     config.add_variable(CFUtil.KEY_DX, 'float')
     config.add_variable(CFUtil.KEY_DY, 'float')
     config.add_variable(CFUtil.KEY_DZ, 'float')
     config.add_variable(CFUtil.KEY_BAT, 'uint16_t')
     return config
Example #43
0
class UpDown:

    """docstring for UpDown"""

    def __init__(self, link_uri):

        self._cf = Crazyflie()

        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        self._logger = LogConfig(name='Logger', period_in_ms=10)
        self._logger.add_variable('acc.x', 'float')
        self._logger.add_variable('acc.y', 'float')
        self._logger.add_variable('acc.z', 'float')
        self._logger.add_variable('acc.zw', 'float')

        self._acc_x = 0
        self._acc_y = 0
        self._acc_z = 0
        self._acc_zw = 0.0001

        self.log = []
        self.pidLog = []
        self.acc_pid_x = None
        self.acc_pid_y = None
        self.acc_pid_z = None

        self.vel_pid_x = None
        self.vel_pid_y = None
        self.vel_pid_z = None

        print("Connecting to %s" % link_uri)
        self._cf.open_link(link_uri)
        self.is_connected = True
        self.exit = False
        self.init = False

        Thread(target=self._exit_task).start()
        Thread(target=self._run_task).start()

    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""
        self.initTime = time.clock()
        # self.log_file = open('log.txt', 'w')
        # self.pid_log = open('pid.txt', 'w')
        # self.log_file.write('[\n')
        # self.pid_log.write('[\n')
        try:
            self._cf.log.add_config(self._logger)
            # This callback will receive the data
            self._logger.data_received_cb.add_callback(self._acc_log_data)
            # This callback will be called on errors
            self._logger.error_cb.add_callback(self._acc_log_error)
            # Start the logging
            self._logger.start()
        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))
        except AttributeError:
            print('Could not add Logger log config, bad configuration.')

    def _acc_log_error(self, logconf, msg):
        """Callback from the log API when an error occurs"""
        print('Error when logging %s: %s' % (logconf.name, msg))

    def _acc_log_data(self, timestamp, data, logconf):
        """Callback from the log API when data arrives"""
        self._acc_x = float(data['acc.x'])
        self._acc_y = float(data['acc.y'])
        self._acc_z = float(data['acc.z'])
        self._acc_zw = data['acc.zw']

        # self.log_file.write(json.dumps(data, sort_keys=True) + ",\n")

        self.log.append(data)

        self.init = True

    def _connection_failed(self, link_uri, msg):
        """Callback when connection initial connection fails (i.e no Crazyflie
        at the specified address)"""
        print('Connection to %s failed: %s' % (link_uri, msg))
        self.is_connected = False
        # self.log_file.write(']')
        # self.pid_log.write(']')
        # self.log_file.close()
        # self.pid_log.close()

        with open('log.txt', 'w') as logFile:
            json.dump(self.log, logFile)
        with open('pid.txt', 'w') as pidFile:
            json.dump(self.pidLog, pidFile)

    def _connection_lost(self, link_uri, msg):
        """Callback when disconnected after a connection has been made (i.e
        Crazyflie moves out of range)"""
        print('Connection to %s lost: %s' % (link_uri, msg))
        # self.log_file.write(']')
        # self.pid_log.write(']')
        # self.log_file.close()
        # self.pid_log.close()
        with open('log.txt', 'w') as logFile:
            json.dump(self.log, logFile)
        with open('pid.txt', 'w') as pidFile:
            json.dump(self.pidLog, pidFile)

    def _disconnected(self, link_uri):
        """Callback when the Crazyflie is disconnected (called in all cases)"""
        print('Disconnected from %s' % link_uri)
        self.is_connected = False
        with open('log.txt', 'w') as logFile:
            json.dump(self.log, logFile)
        with open('pid.txt', 'w') as pidFile:
            json.dump(self.pidLog, pidFile)

    def _exit_task(self):
        while not self.exit:
            inp = int(input('Want to exit? [NO:0/YES:1]\n'))
            if inp == 1:
                self.exit = 1

    def _run_task(self):
        print("Running thread")
        self._cf.commander.send_setpoint(0, 0, 0, 0)

        while not self.exit:

            if not self.init:

                self.acc_pid_x = pid.PID(0, 0, 4.4, 0.05, 0.1, -1, 1)
                self.acc_pid_y = pid.PID(0, 0, 4.4, 0.05, 0.1, -1, 1)
                self.acc_pid_z = pid.PID(0, 0, 100, 0.0005, 0.1, 0.4, 2)
                # Thread(target=self._log_pid).start()
                continue

            inp_acc_x = self._acc_x
            self.out_acc_x, self.err_acc_x = self.acc_pid_x.compute(inp_acc_x)
            self.setPitch = -self.out_acc_x*10

            inp_acc_y = self._acc_y
            self.out_acc_y, self.err_acc_y = self.acc_pid_y.compute(inp_acc_y)
            self.setRoll = self.out_acc_y*10

            inp_acc_z = self._acc_zw
            self.out_acc_z, self.err_acc_z = self.acc_pid_z.compute(self._acc_zw)
            self.setThrust = int(60000*self.out_acc_z/2)
            self._thrust = self.setThrust

            # data = {"IN_X": inp_acc_x, "OUT_X": out_acc_x,
            #         "IN_Y": inp_acc_y, "OUT_Y": out_acc_y,
            #         "IN_Z": self._acc_zw, "OUT_Z": out_acc_z,
            #         "OUT_Roll": setRoll, "OUT_Pitch": setPitch,
            #         "OUT_Thrust": setThrust}

            # self.pidLog.append(data)

            # self.pid_log.write(json.dumps(data, sort_keys=True) + ",\n")

            self._cf.commander.send_setpoint(
                self.setRoll, self.setPitch, 0, self._thrust)
            time.sleep(0.01)

        # self.log_file.write(']')
        # self.pid_log.write(']')
        # self.log_file.close()
        # self.pid_log.close()

        self._cf.commander.send_setpoint(0, 0, 0, 0)
        time.sleep(1)
        self._cf.close_link()

    def _log_pid(self):
        data = {"IN_X": self._acc_x, "OUT_X": self.out_acc_x,
                "IN_Y": self._acc_y, "OUT_Y": self.out_acc_y,
                "IN_Z": self._acc_zw, "OUT_Z": self.out_acc_z,
                "OUT_Roll": self.setRoll, "OUT_Pitch": self.setPitch,
                "OUT_Thrust": self.setThrust}

        self.pidLog.append(data)
Example #44
0
class Comm:
    def __init__(self, link_uri):
        """ Initialize and run the test with the specified link_uri """

        self._cf = Crazyflie()

        self.mc = MotionCommander(self._cf, default_height=1.05)

        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        self._cf.open_link(link_uri)

        print('Connecting to %s' % link_uri)
        self.is_connected = True

    def _connected(self, link_uri):
        """ This callback is called from the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""

        print('Connected to %s' % link_uri)

        # The definition of the logconfig can be made before connecting
        self._lg_stab = LogConfig(name='Stabilizer', period_in_ms=10)
        self._lg_stab.add_variable('stabilizer.roll', 'float')
        self._lg_stab.add_variable('stabilizer.pitch', 'float')
        self._lg_stab.add_variable('stabilizer.yaw', 'float')

        self._log_conf = LogConfig(name="Accel", period_in_ms=10)
        self._log_conf.add_variable('acc.x', 'float')
        self._log_conf.add_variable('acc.y', 'float')
        self._log_conf.add_variable('acc.z', 'float')

        # Adding the configuration cannot be done until a Crazyflie is
        # connected, since we need to check that the variables we
        # would like to log are in the TOC.
        try:
            self._cf.log.add_config(self._lg_stab)

            # This callback will receive the data
            self._lg_stab.data_received_cb.add_callback(self._stab_log_data)

            # This callback will be called on errors
            self._lg_stab.error_cb.add_callback(self._stab_log_error)
            # Start the logging
            self._lg_stab.start()

            self._log = self._cf.log.add_config(self._log_conf)

            if self._log_conf is not None:
                self._log_conf.data_received_cb.add_callback(
                    self._log_accel_data)
                self._log_conf.start()
            else:
                print("acc.x/y/z not found in log TOC")

        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))
        except AttributeError:
            print('Could not add log config, bad configuration.')

        # Start a separate thread to do the motor test.
        # Do not hijack the calling thread!
        self.is_connected = True
        worker = Thread(target=self.flip_test)
        worker.start()

    def _log_accel_data(self, timestamp, data, logconf):
        #print('[%d] Accelerometer: x=%.2f, y=%.2f, z=%.2f' %
        #            (timestamp, data['acc.x'], data['acc.y'], data['acc.z']))
        """This is from the basiclog file"""

    def _stab_log_error(self, logconf, msg):
        """Callback from the log API when an error occurs"""
        #print('Error when logging %s: %s' % (logconf.name, msg))

    def _stab_log_data(self, timestamp, data, logconf):
        """Callback froma the log API when data arrives"""
        #print('[%d][%s]: %s' % (timestamp, logconf.name, data))

    def _connection_failed(self, link_uri, msg):
        """Callback when connection initial connection fails (i.e no Crazyflie
        at the specified address)"""
        print('Connection to %s failed: %s' % (link_uri, msg))

    def _connection_lost(self, link_uri, msg):
        """Callback when disconnected after a connection has been made (i.e
        Crazyflie moves out of range)"""
        print('Connection to %s lost: %s' % (link_uri, msg))

    def _disconnected(self, link_uri):
        """Callback when the Crazyflie is disconnected (called in all cases)"""
        print('Disconnected from %s' % link_uri)

    def flip_test(self):
        # Below is attempt to implememnt algorithm found in https://www.research-collection.ethz.ch/bitstream/handle/20.500.11850/151399/eth-165-01.pdf?sequence=1
        # Currently unknown how the provided initial values can make physical sense given the parameters of the Crazyflie (or any drone?)
        # U1 = 0.9 * beta_max
        # U2 = 0.5 * (beta_max + beta_min)
        # U3 = beta_min
        # U4 = U2
        # U5 = U1

        # theta_dd1 = -(beta_max - U1) / (alpha * L)
        # theta_dd2 = (beta_max - beta_min) / (2.0 * alpha * L)
        # theta_dd3 = 0.0
        # theta_dd4 = -theta_dd2
        # theta_dd5 = (beta_max - U5) / (alpha * L)

        # T3 = (2 * pi - (theta_d_max ** 2) / (2 * theta_dd2))

        # T2 = (theta_d_max - theta_dd1 * T1)

        print 'Enter to take off'

        c = raw_input()

        self.mc.take_off()

        print 'Enter to flip'

        c = raw_input()
        print 'Beginning test...'

        # Accelerate up
        tic = time.time()
        while time.time() - tic < 0.1:

            self.mc._cf.commander.send_setpoint(0, 0, 0, max_thrust)
            time.sleep(0.01)

        # Max differential thrust
        tic = time.time()
        while time.time() - tic < 0.14:
            self.mc._cf.commander.send_setpoint(360 * 8, 0, 0, max_thrust)
            time.sleep(0.01)

        # Coast
        time.sleep(0.01)

        # Stop rotate
        tic = time.time()
        while time.time() - tic < 0.15:
            self.mc._cf.commander.send_setpoint(-360 * 8, 0, 0, max_thrust)
            time.sleep(0.01)

        # Accelerate up
        tic = time.time()
        while time.time() - tic < 0.9:
            self.mc._cf.commander.send_setpoint(0, 0, 0, max_thrust)
            time.sleep(0.01)

        while True:
            self.mc.stop()
            time.sleep(0.01)
def main():
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    # Scan for Crazyflies and use the first one found
    print('Scanning interfaces for Crazyflies...')
    available = cflib.crtp.scan_interfaces()
    print('Crazyflies found:')
    for i in available:
        print(i[0])

    if len(available) == 0:
        print('No Crazyflies found, cannot run example')
    else:

        #create log config
        if (small_log):
            logConfig_stab = LogConfig(name='Stabilizer',
                                       period_in_ms=log_period)

            logConfig_stab.add_variable('stabilizer.roll', 'float')
            logConfig_stab.add_variable('stabilizer.pitch', 'float')
            logConfig_stab.add_variable('stabilizer.yaw', 'float')
            logConfig_stab.add_variable('stabilizer.thrust', 'float')

            logConfig_state = LogConfig(name='State', period_in_ms=log_period)
            logConfig_state.add_variable('stateEstimate.x', 'float')
            logConfig_state.add_variable('stateEstimate.y', 'float')
            logConfig_state.add_variable('stateEstimate.z', 'float')
            """
            logConfig_target = LogConfig(name='ControlTarget', period_in_ms=log_period)
            logConfig_target.add_variable('ctrltarget.roll', 'float')
            logConfig_target.add_variable('ctrltarget.pitch', 'float')
            logConfig_target.add_variable('ctrltarget.yaw', 'float')
            """

            logConfig_mpow = LogConfig(name='MotorPower',
                                       period_in_ms=log_period)
            logConfig_mpow.add_variable('motor.m1', 'int32_t')
            logConfig_mpow.add_variable('motor.m2', 'int32_t')
            logConfig_mpow.add_variable('motor.m3', 'int32_t')
            logConfig_mpow.add_variable('motor.m4', 'int32_t')

        if (big_log):
            logConfig_all = LogConfig(name='all', period_in_ms=log_period)

            logConfig_all.add_variable('stabilizer.thrust', 'float')

            logConfig_all.add_variable('motor.m1', 'int32_t')
            logConfig_all.add_variable('motor.m2', 'int32_t')
            logConfig_all.add_variable('motor.m3', 'int32_t')
            logConfig_all.add_variable('motor.m4', 'int32_t')

        with SyncCrazyflie(URI) as scf:
            cf = scf.cf

            #create logger
            if (small_log):
                logger_stab = SyncLogger(scf, logConfig_stab)
                logger_state = SyncLogger(scf, logConfig_state)
                logger_mpow = SyncLogger(scf, logConfig_mpow)

                logger_stab.connect()
                logger_state.connect()
                logger_mpow.connect()

                #logger_target = SyncLogger(scf, logConfig_target)
                #logger_target.connect()

            if (big_log):
                logger_all = SyncLogger(scf, logConfig_all)
                logger_all.connect()

            cf.param.set_value('kalman.resetEstimation', '1')
            time.sleep(0.1)
            cf.param.set_value('kalman.resetEstimation', '0')
            time.sleep(2)

            for y in range(10):
                cf.commander.send_hover_setpoint(0, 0, 0, y / 20)
                time.sleep(0.1)

            #start point logging
            if (small_log):
                log_start = logger_stab.qsize()
            else:
                log_start = logger_all.qsize()

            for i in range(50):
                print_message("Going " + str(i))
                cf.commander.send_hover_setpoint(0, 0, 0, 0.3)
                time.sleep(0.1)

            #end point logging
            if (small_log):
                log_end = logger_stab.qsize()
            else:
                log_end = logger_all.qsize()

            log_count = log_end - log_start

            print_message("Start:{}, end:{}".format(log_start, log_end))
            print_message("To log {} lines.".format(log_end - log_start + 1))

            for _ in range(10):
                cf.commander.send_hover_setpoint(0, 0, 0, 0.2)
                time.sleep(0.1)

            cf.commander.send_hover_setpoint(0, 0, 0, 0.1)
            time.sleep(0.2)
            cf.commander.send_stop_setpoint()  #land
            time.sleep(1.5)

            print_message("Landed, start logging...")

            #write log files
            if (small_log):
                with open(log_file_name(logConfig_stab), "w") as f:
                    log_count = write_out_log(logger_stab, f, log_start,
                                              log_end)
                    print_message("logged stabilizer")

                with open(log_file_name(logConfig_state), "w") as f:
                    log_count = write_out_log(logger_state, f, log_start,
                                              log_end)
                    print_message("logged state")
                """
                with open(log_file_name(logConfig_target), "w") as f:
                    log_count = write_out_log(logger_target, f, log_start, log_end)
                    print_message("logged control target")
                """

                with open(log_file_name(logConfig_mpow), "w") as f:
                    log_count = write_out_log(logger_mpow, f, log_start,
                                              log_end)
                    print_message("logged motor power")
                logger_stab.disconnect()
                logger_state.disconnect()
                logger_mpow.disconnect()

                #logger_target.disconnect()

            if (big_log):
                with open(log_file_name(logConfig_all), "w") as f:
                    log_count = write_out_log(logger_all, f, log_start,
                                              log_end)
                logger_all.disconnect()

            print_message("Done logging")
    def connected(self, linkURI):
        # IMU & THRUST
        lg = LogConfig("Stabilizer", Config().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        # MOTOR
        lg = LogConfig("Motors", Config().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x01):
            self._led_ring_effect.setEnabled(True)
            self._led_ring_headlight.setEnabled(True)
    def connected(self, linkURI):
        self.packetsSinceConnection = 0
        self.link_status = "Connected"
        print("Connected") #DEBUG
        
        """
        Configure the logger and start recording.

        The logging variables are added one after another to the logging
        configuration. Then the configuration is used to create a log packet
        which is cached on the Crazyflie. If the log packet is None, the
        program exits. Otherwise the logging packet receives a callback when
        it receives data, which prints the data from the logging packet's
        data dictionary as logging info.
        """
        lgM = LogConfig("logM", LOGVARS_MOTOR_INTERVALL)
        for f in LOGVARS_MOTOR:
            lgM.add_variable(f)
        self.crazyflie.log.add_config(lgM)
        
        lgSt = LogConfig("logSt", LOGVARS_STABILIZER_INTERVALL)
        for f in LOGVARS_STABILIZER:
            lgSt.add_variable(f)
        self.crazyflie.log.add_config(lgSt)
        
        lgAcc = LogConfig("logAcc", LOGVARS_ACC_INTERVALL)
        for f in LOGVARS_ACC:
            lgAcc.add_variable(f)
        self.crazyflie.log.add_config(lgAcc)
        
        lgBa = LogConfig("logBa", LOGVARS_BARO_INTERVALL)
        for f in LOGVARS_BARO:
            lgBa.add_variable(f)
        self.crazyflie.log.add_config(lgBa)
        
        lgSy = LogConfig("logSy", LOGVARS_SYSTEM_INTERVALL)
        for f in LOGVARS_SYSTEM:
            lgSy.add_variable(f)
        self.crazyflie.log.add_config(lgSy)
        
        if (lgM.valid and lgSt.valid and lgAcc.valid and lgBa.valid and lgSy.valid):
            lgM.data_received_cb.add_callback(self.on_log_data_motor)
            lgSt.data_received_cb.add_callback(self.on_log_data_stabilizer)
            lgAcc.data_received_cb.add_callback(self.on_log_data_acc)
            lgBa.data_received_cb.add_callback(self.on_log_data_baro)
            lgSy.data_received_cb.add_callback(self.on_log_data_system)

            lgM.error_cb.add_callback(self.onLogError)
            lgSt.error_cb.add_callback(self.onLogError)
            lgAcc.error_cb.add_callback(self.onLogError)
            lgBa.error_cb.add_callback(self.onLogError)
            lgSy.error_cb.add_callback(self.onLogError)

            lgM.start()
            lgSt.start()
            lgAcc.start()
            lgBa.start()
            lgSy.start()
            print("Crazyflie sensor log successfully started")
            rospy.loginfo("Crazyflie sensor log successfully started")
        else:
            rospy.logerror("Error while starting crazyflie sensr logs")
            logger.warning("Could not setup logconfiguration after connection!")
            print("Logging failed")
class FlightTab(Tab, flight_tab_class):

    uiSetupReadySignal = pyqtSignal()

    _motor_data_signal = pyqtSignal(int, object, object)
    _imu_data_signal = pyqtSignal(int, object, object)
    _althold_data_signal = pyqtSignal(int, object, object)
    _baro_data_signal = pyqtSignal(int, object, object)

    _input_updated_signal = pyqtSignal(float, float, float, float)
    _rp_trim_updated_signal = pyqtSignal(float, float)
    _emergency_stop_updated_signal = pyqtSignal(bool)

    _log_error_signal = pyqtSignal(object, str)

    #UI_DATA_UPDATE_FPS = 10

    connectionFinishedSignal = pyqtSignal(str)
    disconnectedSignal = pyqtSignal(str)

    _limiting_updated = pyqtSignal(bool, bool, bool)

    def __init__(self, tabWidget, helper, *args):
        super(FlightTab, self).__init__(*args)
        self.setupUi(self)

        self.tabName = "Flight Control"
        self.menuName = "Flight Control"

        self.tabWidget = tabWidget
        self.helper = helper

        self.disconnectedSignal.connect(self.disconnected)
        self.connectionFinishedSignal.connect(self.connected)
        # Incomming signals
        self.helper.cf.connected.add_callback(
            self.connectionFinishedSignal.emit)
        self.helper.cf.disconnected.add_callback(self.disconnectedSignal.emit)

        self._input_updated_signal.connect(self.updateInputControl)
        self.helper.inputDeviceReader.input_updated.add_callback(
                                     self._input_updated_signal.emit)
        self._rp_trim_updated_signal.connect(self.calUpdateFromInput)
        self.helper.inputDeviceReader.rp_trim_updated.add_callback(
                                     self._rp_trim_updated_signal.emit)
        self._emergency_stop_updated_signal.connect(self.updateEmergencyStop)
        self.helper.inputDeviceReader.emergency_stop_updated.add_callback(
                                     self._emergency_stop_updated_signal.emit)
        
        self.helper.inputDeviceReader.althold_updated.add_callback(
                    lambda enabled: self.helper.cf.param.set_value("flightmode.althold", enabled))

        self._imu_data_signal.connect(self._imu_data_received)
        self._baro_data_signal.connect(self._baro_data_received)
        self._althold_data_signal.connect(self._althold_data_received)
        self._motor_data_signal.connect(self._motor_data_received)

        self._log_error_signal.connect(self._logging_error)

        # Connect UI signals that are in this tab
        self.flightModeCombo.currentIndexChanged.connect(self.flightmodeChange)
        self.minThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.maxThrust.valueChanged.connect(self.minMaxThrustChanged)
        self.thrustLoweringSlewRateLimit.valueChanged.connect(
                                      self.thrustLoweringSlewRateLimitChanged)
        self.slewEnableLimit.valueChanged.connect(
                                      self.thrustLoweringSlewRateLimitChanged)
        self.targetCalRoll.valueChanged.connect(self._trim_roll_changed)
        self.targetCalPitch.valueChanged.connect(self._trim_pitch_changed)
        self.maxAngle.valueChanged.connect(self.maxAngleChanged)
        self.maxYawRate.valueChanged.connect(self.maxYawRateChanged)
        self.uiSetupReadySignal.connect(self.uiSetupReady)
        self.clientXModeCheckbox.toggled.connect(self.changeXmode)
        self.isInCrazyFlightmode = False
        self.uiSetupReady()

        self.clientXModeCheckbox.setChecked(Config().get("client_side_xmode"))

        self.crazyflieXModeCheckbox.clicked.connect(
                             lambda enabled:
                             self.helper.cf.param.set_value("flightmode.x",
                                                            str(enabled)))
        self.helper.cf.param.add_update_callback(
                        group="flightmode", name="xmode",
                        cb=( lambda name, checked:
                        self.crazyflieXModeCheckbox.setChecked(eval(checked))))

        self.ratePidRadioButton.clicked.connect(
                    lambda enabled:
                    self.helper.cf.param.set_value("flightmode.ratepid",
                                                   str(enabled)))

        self.angularPidRadioButton.clicked.connect(
                    lambda enabled:
                    self.helper.cf.param.set_value("flightmode.ratepid",
                                                   str(not enabled)))

        self._led_ring_headlight.clicked.connect(
                    lambda enabled:
                    self.helper.cf.param.set_value("ring.headlightEnable",
                                                   str(enabled)))

        self.helper.cf.param.add_update_callback(
                    group="flightmode", name="ratepid",
                    cb=(lambda name, checked:
                    self.ratePidRadioButton.setChecked(eval(checked))))

        self.helper.cf.param.add_update_callback(
                    group="cpu", name="flash",
                    cb=self._set_enable_client_xmode)

        self.helper.cf.param.add_update_callback(
                    group="ring", name="headlightEnable",
                    cb=(lambda name, checked:
                    self._led_ring_headlight.setChecked(eval(checked))))

        self.helper.cf.param.add_update_callback(
                    group="flightmode", name="althold",
                    cb=(lambda name, enabled:
                    self.helper.inputDeviceReader.enable_alt_hold(eval(enabled))))

        self._ledring_nbr_effects = 0

        self.helper.cf.param.add_update_callback(
                        group="ring",
                        name="neffect",
                        cb=(lambda name, value: self._set_neffect(eval(value))))

        self.helper.cf.param.add_update_callback(
                        group="imu_sensors",
                        cb=self._set_available_sensors)

        self.helper.cf.param.all_updated.add_callback(self._ring_populate_dropdown)

        self.logBaro = None
        self.logAltHold = None

        self.ai = AttitudeIndicator()
        self.verticalLayout_4.addWidget(self.ai)
        self.splitter.setSizes([1000,1])

        self.targetCalPitch.setValue(Config().get("trim_pitch"))
        self.targetCalRoll.setValue(Config().get("trim_roll"))

        self.helper.inputDeviceReader.alt1_updated.add_callback(self.alt1_updated)
        self.helper.inputDeviceReader.alt2_updated.add_callback(self.alt2_updated)
        self._tf_state = 0
        self._ring_effect = 0

        # Connect callbacks for input device limiting of rpƶƶ/pitch/yaw/thust
        self.helper.inputDeviceReader.limiting_updated.add_callback(
            self._limiting_updated.emit)
        self._limiting_updated.connect(self._set_limiting_enabled)

    def _set_enable_client_xmode(self, name, value):
        if eval(value) <= 128:
            self.clientXModeCheckbox.setEnabled(True)
        else:
            self.clientXModeCheckbox.setEnabled(False)
            self.clientXModeCheckbox.setChecked(False)

    def _set_limiting_enabled(self, rp_limiting_enabled,
                                    yaw_limiting_enabled,
                                    thrust_limiting_enabled):
        self.maxAngle.setEnabled(rp_limiting_enabled)
        self.targetCalRoll.setEnabled(rp_limiting_enabled)
        self.targetCalPitch.setEnabled(rp_limiting_enabled)
        self.maxYawRate.setEnabled(yaw_limiting_enabled)
        self.maxThrust.setEnabled(thrust_limiting_enabled)
        self.minThrust.setEnabled(thrust_limiting_enabled)
        self.slewEnableLimit.setEnabled(thrust_limiting_enabled)
        self.thrustLoweringSlewRateLimit.setEnabled(thrust_limiting_enabled)

    def _set_neffect(self, n):
        self._ledring_nbr_effects = n

    def thrustToPercentage(self, thrust):
        return ((thrust / MAX_THRUST) * 100.0)

    def uiSetupReady(self):
        flightComboIndex = self.flightModeCombo.findText(
                             Config().get("flightmode"), Qt.MatchFixedString)
        if (flightComboIndex < 0):
            self.flightModeCombo.setCurrentIndex(0)
            self.flightModeCombo.currentIndexChanged.emit(0)
        else:
            self.flightModeCombo.setCurrentIndex(flightComboIndex)
            self.flightModeCombo.currentIndexChanged.emit(flightComboIndex)

    def _logging_error(self, log_conf, msg):
        QMessageBox.about(self, "Log error", "Error when starting log config"
                " [%s]: %s" % (log_conf.name, msg))

    def _motor_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualM1.setValue(data["motor.m1"])
            self.actualM2.setValue(data["motor.m2"])
            self.actualM3.setValue(data["motor.m3"])
            self.actualM4.setValue(data["motor.m4"])
        
    def _baro_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualASL.setText(("%.2f" % data["baro.aslLong"]))
            self.ai.setBaro(data["baro.aslLong"])
        
    def _althold_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            target = data["altHold.target"]
            if target>0:
                if not self.targetASL.isEnabled():
                    self.targetASL.setEnabled(True) 
                self.targetASL.setText(("%.2f" % target))
                self.ai.setHover(target)    
            elif self.targetASL.isEnabled():
                self.targetASL.setEnabled(False)
                self.targetASL.setText("Not set")   
                self.ai.setHover(0)    
        
    def _imu_data_received(self, timestamp, data, logconf):
        if self.isVisible():
            self.actualRoll.setText(("%.2f" % data["stabilizer.roll"]))
            self.actualPitch.setText(("%.2f" % data["stabilizer.pitch"]))
            self.actualYaw.setText(("%.2f" % data["stabilizer.yaw"]))
            self.actualThrust.setText("%.2f%%" %
                                      self.thrustToPercentage(
                                                      data["stabilizer.thrust"]))
    
            self.ai.setRollPitch(-data["stabilizer.roll"],
                                 data["stabilizer.pitch"])

    def connected(self, linkURI):
        # IMU & THRUST
        lg = LogConfig("Stabilizer", Config().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        # MOTOR
        lg = LogConfig("Motors", Config().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        if self.helper.cf.mem.ow_search(vid=0xBC, pid=0x01):
            self._led_ring_effect.setEnabled(True)
            self._led_ring_headlight.setEnabled(True)

    def _set_available_sensors(self, name, available):
        logger.info("[%s]: %s", name, available)
        available = eval(available)
        if ("HMC5883L" in name):
            if (not available):
                self.actualASL.setText("N/A")
                self.actualASL.setEnabled(False)
            else:
                self.actualASL.setEnabled(True)
                self.helper.inputDeviceReader.set_alt_hold_available(available)
                if (not self.logBaro and not self.logAltHold):
                    # The sensor is available, set up the logging
                    self.logBaro = LogConfig("Baro", 200)
                    self.logBaro.add_variable("baro.aslLong", "float")

                    try:
                        self.helper.cf.log.add_config(self.logBaro)
                        self.logBaro.data_received_cb.add_callback(
                                self._baro_data_signal.emit)
                        self.logBaro.error_cb.add_callback(
                                self._log_error_signal.emit)
                        self.logBaro.start()
                    except KeyError as e:
                        logger.warning(str(e))
                    except AttributeError as e:
                        logger.warning(str(e))
                    self.logAltHold = LogConfig("AltHold", 200)
                    self.logAltHold.add_variable("altHold.target", "float")

                    try:
                        self.helper.cf.log.add_config(self.logAltHold)
                        self.logAltHold.data_received_cb.add_callback(
                            self._althold_data_signal.emit)
                        self.logAltHold.error_cb.add_callback(
                            self._log_error_signal.emit)
                        self.logAltHold.start()
                    except KeyError as e:
                        logger.warning(str(e))
                    except AttributeError:
                        logger.warning(str(e))

    def disconnected(self, linkURI):
        self.ai.setRollPitch(0, 0)
        self.actualM1.setValue(0)
        self.actualM2.setValue(0)
        self.actualM3.setValue(0)
        self.actualM4.setValue(0)
        self.actualRoll.setText("")
        self.actualPitch.setText("")
        self.actualYaw.setText("")
        self.actualThrust.setText("")
        self.actualASL.setText("")
        self.targetASL.setText("Not Set")
        self.targetASL.setEnabled(False)
        self.actualASL.setEnabled(False)
        self.clientXModeCheckbox.setEnabled(False)
        self.logBaro = None
        self.logAltHold = None
        self._led_ring_effect.setEnabled(False)
        self._led_ring_headlight.setEnabled(False)


    def minMaxThrustChanged(self):
        self.helper.inputDeviceReader.min_thrust = self.minThrust.value()
        self.helper.inputDeviceReader.max_thrust = self.maxThrust.value()
        if (self.isInCrazyFlightmode == True):
            Config().set("min_thrust", self.minThrust.value())
            Config().set("max_thrust", self.maxThrust.value())

    def thrustLoweringSlewRateLimitChanged(self):
        self.helper.inputDeviceReader.thrust_slew_rate = self.thrustLoweringSlewRateLimit.value()
        self.helper.inputDeviceReader.thrust_slew_limit = self.slewEnableLimit.value()
        if (self.isInCrazyFlightmode == True):
            Config().set("slew_limit", self.slewEnableLimit.value())
            Config().set("slew_rate", self.thrustLoweringSlewRateLimit.value())

    def maxYawRateChanged(self):
        logger.debug("MaxYawrate changed to %d", self.maxYawRate.value())
        self.helper.inputDeviceReader.max_yaw_rate = self.maxYawRate.value()
        if (self.isInCrazyFlightmode == True):
            Config().set("max_yaw", self.maxYawRate.value())

    def maxAngleChanged(self):
        logger.debug("MaxAngle changed to %d", self.maxAngle.value())
        self.helper.inputDeviceReader.max_rp_angle = self.maxAngle.value()
        if (self.isInCrazyFlightmode == True):
            Config().set("max_rp", self.maxAngle.value())

    def _trim_pitch_changed(self, value):
        logger.debug("Pitch trim updated to [%f]" % value)
        self.helper.inputDeviceReader.trim_pitch = value
        Config().set("trim_pitch", value)

    def _trim_roll_changed(self, value):
        logger.debug("Roll trim updated to [%f]" % value)
        self.helper.inputDeviceReader.trim_roll = value
        Config().set("trim_roll", value)

    def calUpdateFromInput(self, rollCal, pitchCal):
        logger.debug("Trim changed on joystick: roll=%.2f, pitch=%.2f",
                     rollCal, pitchCal)
        self.targetCalRoll.setValue(rollCal)
        self.targetCalPitch.setValue(pitchCal)

    def updateInputControl(self, roll, pitch, yaw, thrust):
        self.targetRoll.setText(("%0.2f" % roll))
        self.targetPitch.setText(("%0.2f" % pitch))
        self.targetYaw.setText(("%0.2f" % yaw))
        self.targetThrust.setText(("%0.2f %%" %
                                   self.thrustToPercentage(thrust)))
        self.thrustProgress.setValue(thrust)

    def setMotorLabelsEnabled(self, enabled):
        self.M1label.setEnabled(enabled)
        self.M2label.setEnabled(enabled)
        self.M3label.setEnabled(enabled)
        self.M4label.setEnabled(enabled)

    def emergencyStopStringWithText(self, text):
        return ("<html><head/><body><p>"
                "<span style='font-weight:600; color:#7b0005;'>{}</span>"
                "</p></body></html>".format(text))

    def updateEmergencyStop(self, emergencyStop):
        if emergencyStop:
            self.setMotorLabelsEnabled(False)
            self.emergency_stop_label.setText(
                      self.emergencyStopStringWithText("Kill switch active"))
        else:
            self.setMotorLabelsEnabled(True)
            self.emergency_stop_label.setText("")

    def flightmodeChange(self, item):
        Config().set("flightmode", str(self.flightModeCombo.itemText(item)))
        logger.debug("Changed flightmode to %s",
                    self.flightModeCombo.itemText(item))
        self.isInCrazyFlightmode = False
        if (item == 0):  # Normal
            self.maxAngle.setValue(Config().get("normal_max_rp"))
            self.maxThrust.setValue(Config().get("normal_max_thrust"))
            self.minThrust.setValue(Config().get("normal_min_thrust"))
            self.slewEnableLimit.setValue(Config().get("normal_slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                                              Config().get("normal_slew_rate"))
            self.maxYawRate.setValue(Config().get("normal_max_yaw"))
        if (item == 1):  # Advanced
            self.maxAngle.setValue(Config().get("max_rp"))
            self.maxThrust.setValue(Config().get("max_thrust"))
            self.minThrust.setValue(Config().get("min_thrust"))
            self.slewEnableLimit.setValue(Config().get("slew_limit"))
            self.thrustLoweringSlewRateLimit.setValue(
                                                  Config().get("slew_rate"))
            self.maxYawRate.setValue(Config().get("max_yaw"))
            self.isInCrazyFlightmode = True

        if (item == 0):
            newState = False
        else:
            newState = True
        self.maxThrust.setEnabled(newState)
        self.maxAngle.setEnabled(newState)
        self.minThrust.setEnabled(newState)
        self.thrustLoweringSlewRateLimit.setEnabled(newState)
        self.slewEnableLimit.setEnabled(newState)
        self.maxYawRate.setEnabled(newState)

    @pyqtSlot(bool)
    def changeXmode(self, checked):
        self.helper.cf.commander.set_client_xmode(checked)
        Config().set("client_side_xmode", checked)
        logger.info("Clientside X-mode enabled: %s", checked)

    def alt1_updated(self, state):
        if state:
            self._ring_effect += 1
            if self._ring_effect > self._ledring_nbr_effects:
                self._ring_effect = 0
            self.helper.cf.param.set_value("ring.effect", str(self._ring_effect))

    def alt2_updated(self, state):
        self.helper.cf.param.set_value("ring.headlightEnable", str(state))

    def _ring_populate_dropdown(self):
        try:
            nbr = int(self.helper.cf.param.values["ring"]["neffect"])
            current = int(self.helper.cf.param.values["ring"]["effect"])
        except KeyError:
            return

        hardcoded_names = {0: "Off",
                           1: "White spinner",
                           2: "Color spinner",
                           3: "Tilt effect",
                           4: "Brightness effect",
                           5: "Color spinner 2",
                           6: "Double spinner",
                           7: "Solid color effect",
                           8: "Factory test",
                           9: "Battery status",
                           10: "Boat lights",
                           11: "Alert",
                           12: "Gravity"}

        for i in range(nbr+1):
            name = "{}: ".format(i)
            if i in hardcoded_names:
                name += hardcoded_names[i]
            else:
                name += "N/A"
            self._led_ring_effect.addItem(name, QVariant(i))

        self._led_ring_effect.setCurrentIndex(current)
        self._led_ring_effect.currentIndexChanged.connect(self._ring_effect_changed)
        self.helper.cf.param.add_update_callback(group="ring",
                                         name="effect",
                                         cb=self._ring_effect_updated)

    def _ring_effect_changed(self, index):
        i = self._led_ring_effect.itemData(index).toInt()[0]
        logger.info("Changed effect to {}".format(i))
        if i != self.helper.cf.param.values["ring"]["effect"]:
            self.helper.cf.param.set_value("ring.effect", str(i))

    def _ring_effect_updated(self, name, value):
        self._led_ring_effect.setCurrentIndex(int(value))
    def _connected(self, link_uri):
        print('Connected to %s' % link_uri)

        lg_pose = LogConfig(name='test', period_in_ms=50)
        lg_pose.add_variable('stabilizer.roll', 'float')
        lg_pose.add_variable('stabilizer.pitch', 'float')
        lg_pose.add_variable('stabilizer.yaw', 'float')
        lg_pose.add_variable('stateEstimate.x', 'float')
        lg_pose.add_variable('stateEstimate.y', 'float')
        lg_pose.add_variable('stateEstimate.z', 'float')

        lg_lh_master = LogConfig(name='master', period_in_ms=50)
        lg_lh_master.add_variable('lighthouse.angle0x', 'float')
        lg_lh_master.add_variable('lighthouse.angle0y', 'float')
        lg_lh_master.add_variable('lighthouse.angle0x_3', 'float')
        lg_lh_master.add_variable('lighthouse.angle0y_3', 'float')
        lg_lh_master2 = LogConfig(name='master2', period_in_ms=50)
        lg_lh_master2.add_variable('lighthouse.angle0x_1', 'float')
        lg_lh_master2.add_variable('lighthouse.angle0y_1', 'float')
        lg_lh_master2.add_variable('lighthouse.angle0x_2', 'float')
        lg_lh_master2.add_variable('lighthouse.angle0y_2', 'float')

        lg_lh_slave = LogConfig(name='slave', period_in_ms=50)
        lg_lh_slave.add_variable('lighthouse.angle1x', 'float')
        lg_lh_slave.add_variable('lighthouse.angle1y', 'float')
        lg_lh_slave.add_variable('lighthouse.angle1x_3', 'float')
        lg_lh_slave.add_variable('lighthouse.angle1y_3', 'float')
        lg_lh_slave2 = LogConfig(name='slave2', period_in_ms=50)
        lg_lh_slave2.add_variable('lighthouse.angle1x_1', 'float')
        lg_lh_slave2.add_variable('lighthouse.angle1y_1', 'float')
        lg_lh_slave2.add_variable('lighthouse.angle1x_2', 'float')
        lg_lh_slave2.add_variable('lighthouse.angle1y_2', 'float')

        self._cf.log.add_config(lg_pose)
        lg_pose.data_received_cb.add_callback(self.data_receivedPose)
        lg_pose.start()

        self._cf.log.add_config(lg_lh_master)
        lg_lh_master.data_received_cb.add_callback(self.data_receivedSensor)
        lg_lh_master.start()

        self._cf.log.add_config(lg_lh_master2)
        lg_lh_master2.data_received_cb.add_callback(self.data_receivedSensor)
        lg_lh_master2.start()

        self._cf.log.add_config(lg_lh_slave)
        lg_lh_slave.data_received_cb.add_callback(self.data_receivedSensor)
        lg_lh_slave.start()

        self._cf.log.add_config(lg_lh_slave2)
        lg_lh_slave2.data_received_cb.add_callback(self.data_receivedSensor)
        lg_lh_slave2.start()

        self.read_geo_data()
Example #50
0

if __name__ == '__main__':
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    # Scan for Crazyflies and use the first one found
    print('Scanning interfaces for Crazyflies...')
    available = cflib.crtp.scan_interfaces()
    print('Crazyflies found:')
    for i in available:
        print(i[0])

    if len(available) == 0:
        print('No Crazyflies found, cannot run example')
    else:
        lg_stab = LogConfig(name='stateEstimator', period_in_ms=10)
        lg_stab.add_variable('stateEstimate.x', 'float')
        lg_stab.add_variable('stateEstimate.y', 'float')
        lg_stab.add_variable('stateEstimate.z', 'float')

        cf = Crazyflie(rw_cache='./cache')
        with SyncCrazyflie(available[0][0], cf=cf) as scf:
            with SyncLogger(scf, lg_stab) as logger:
                endTime = time.time() + 10

                for log_entry in logger:
                    timestamp = log_entry[0]
                    data = log_entry[1]
                    logconf_name = log_entry[2]

                    print('[%d][%s]: %s' % (timestamp, logconf_name, data))
Example #51
0
T = 5
pontos = [0, 20, -15, -20, 45, -37, 10]

# Only output errors from the logging framework
logging.basicConfig(level=logging.ERROR)

if __name__ == '__main__':
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    available = cflib.crtp.scan_interfaces()

    if len(available) == 0:
        print('No Crazyflies found, cannot run example')
    else:
        period_in_ms = 10
        lg_stab = LogConfig(name='Stabilizer', period_in_ms=10)
        lg_stab.add_variable('pm.batteryLevel', 'uint8_t')

        #RealimentaĆ§Ć£o PID rate
        lg_stab.add_variable('gyro.xRaw', 'float')
        lg_stab.add_variable('gyro.yRaw', 'float')
        #lg_stab.add_variable('gyro.zRaw', 'float')
        #lg_stab.add_variable('stateEstimateZ.rateRoll', 'int16_t')
        lg_stab.add_variable('stateEstimateZ.ratePitch', 'int16_t')
        #lg_stab.add_variable('stateEstimateZ.rateYaw', 'int16_t')
        lg_stab.add_variable('controller.cmd_roll', 'float')
        lg_stab.add_variable('controller.cmd_pitch', 'float')
        #lg_stab.add_variable('controller.cmd_yaw', 'float')
        i = 0

        #print("antes")
    def connected(self, linkURI):
        # IMU & THRUST
        lg = LogConfig("Stabilizer", Config().get("ui_update_period"))
        lg.add_variable("stabilizer.roll", "float")
        lg.add_variable("stabilizer.pitch", "float")
        lg.add_variable("stabilizer.yaw", "float")
        lg.add_variable("stabilizer.thrust", "uint16_t")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._imu_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        # MOTOR
        lg = LogConfig("Motors", Config().get("ui_update_period"))
        lg.add_variable("motor.m1")
        lg.add_variable("motor.m2")
        lg.add_variable("motor.m3")
        lg.add_variable("motor.m4")

        try:
            self.helper.cf.log.add_config(lg)
            lg.data_received_cb.add_callback(self._motor_data_signal.emit)
            lg.error_cb.add_callback(self._log_error_signal.emit)
            lg.start()
        except KeyError as e:
            logger.warning(str(e))
        except AttributeError as e:
            logger.warning(str(e))

        self._populate_assisted_mode_dropdown()
Example #53
0
class LoggingExample:
    """
    Simple logging example class that logs the Stabilizer from a supplied
    link uri and disconnects after 5s.
    """

    def __init__(self, link_uri):
        """ Initialize and run the example with the specified link_uri """

        # Create a Crazyflie object without specifying any cache dirs
        self._cf = Crazyflie()

        # Connect some callbacks from the Crazyflie API
        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        print('Connecting to %s' % link_uri)

        # Try to connect to the Crazyflie
        self._cf.open_link(link_uri)

        # Variable used to keep main loop occupied until disconnect
        self.is_connected = True

    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""
        print('Connected to %s' % link_uri)

        # The definition of the logconfig can be made before connecting
        self._lg_stab = LogConfig(name='Stabilizer', period_in_ms=10)
        self._lg_stab.add_variable('stabilizer.roll', 'float')
        self._lg_stab.add_variable('stabilizer.pitch', 'float')
        self._lg_stab.add_variable('stabilizer.yaw', 'float')

        # Adding the configuration cannot be done until a Crazyflie is
        # connected, since we need to check that the variables we
        # would like to log are in the TOC.
        try:
            self._cf.log.add_config(self._lg_stab)
            # This callback will receive the data
            self._lg_stab.data_received_cb.add_callback(self._stab_log_data)
            # This callback will be called on errors
            self._lg_stab.error_cb.add_callback(self._stab_log_error)
            # Start the logging
            self._lg_stab.start()
        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))
        except AttributeError:
            print('Could not add Stabilizer log config, bad configuration.')

        # Start a timer to disconnect in 10s
        t = Timer(5, self._cf.close_link)
        t.start()

    def _stab_log_error(self, logconf, msg):
        """Callback from the log API when an error occurs"""
        print('Error when logging %s: %s' % (logconf.name, msg))

    def _stab_log_data(self, timestamp, data, logconf):
        """Callback froma the log API when data arrives"""
        print('[%d][%s]: %s' % (timestamp, logconf.name, data))

    def _connection_failed(self, link_uri, msg):
        """Callback when connection initial connection fails (i.e no Crazyflie
        at the speficied address)"""
        print('Connection to %s failed: %s' % (link_uri, msg))
        self.is_connected = False

    def _connection_lost(self, link_uri, msg):
        """Callback when disconnected after a connection has been made (i.e
        Crazyflie moves out of range)"""
        print('Connection to %s lost: %s' % (link_uri, msg))

    def _disconnected(self, link_uri):
        """Callback when the Crazyflie is disconnected (called in all cases)"""
        print('Disconnected from %s' % link_uri)
        self.is_connected = False
Example #54
0
class LoggingExample:
    """
    Simple logging example class that logs the Stabilizer from a supplied
    link uri and disconnects after 5s.
    """
    def __init__(self, link_uri):
        """ Initialize and run the example with the specified link_uri """

        self._cf = Crazyflie(rw_cache='./cache')

        # Connect some callbacks from the Crazyflie API
        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        self.pubLS = rospy.Publisher('cf_tof_ranges', LaserScan, queue_size=10)
        self.pubRup = rospy.Publisher('cf_tof_up', Range, queue_size=10)

        rospy.init_node('talker', anonymous=True)
        self.pubLS_msg = LaserScan()
        self.pubLS_msg.angle_min = 0.0
        self.pubLS_msg.angle_max = 3.14159 / 2 * 3
        self.pubLS_msg.angle_increment = 3.14159 / 2
        self.pubLS_msg.range_min = 0.0
        self.pubLS_msg.range_max = 100.0
        self.pubLS_msg.header.frame_id = 'cf_base'

        self.range_msg_up = Range()
        self.range_msg_up.header.frame_id = 'cf_base'
        self.range_msg_up.min_range = 0.0
        self.range_msg_up.max_range = 100.0
        self.range_msg_up.field_of_view = 0.131  # 7.5 degrees

        print('Connecting to %s' % link_uri)

        # Try to connect to the Crazyflie
        self._cf.open_link(link_uri)

        # Variable used to keep main loop occupied until disconnect
        self.is_connected = True

        signal.signal(signal.SIGINT, self._signal_handler)

    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""
        print('Connected to %s' % link_uri)

        # The definition of the logconfig can be made before connecting
        self._lg_stab = LogConfig(name='RANGES', period_in_ms=10)
        self._lg_stab.add_variable('range.back', 'uint16_t')
        self._lg_stab.add_variable('range.left', 'uint16_t')
        self._lg_stab.add_variable('range.front', 'uint16_t')
        self._lg_stab.add_variable('range.right', 'uint16_t')
        self._lg_stab.add_variable('range.up', 'uint16_t')

        # Adding the configuration cannot be done until a Crazyflie is
        # connected, since we need to check that the variables we
        # would like to log are in the TOC.
        try:
            self._cf.log.add_config(self._lg_stab)
            # This callback will receive the data
            self._lg_stab.data_received_cb.add_callback(self._stab_log_data)
            # This callback will be called on errors
            self._lg_stab.error_cb.add_callback(self._stab_log_error)
            # Start the logging
            self._lg_stab.start()
        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))
        except AttributeError:
            print('Could not add Stabilizer log config, bad configuration.')
#	except KeyboardInterrupt:
#	    rethrow()
# Start a timer to disconnect in 10s
# t = Timer(5, self._cf.close_link)
# t.start()

    def _stab_log_error(self, logconf, msg):
        """Callback from the log API when an error occurs"""
        print('Error when logging %s: %s' % (logconf.name, msg))

    def _stab_log_data(self, timestamp, data, logconf):
        """Callback froma the log API when data arrives"""
        # print('[%d][%s]: %s' % (timestamp, logconf.name, data))
        #rangeStr = '[%d][%s]: %s' % (timestamp, logconf.name, data)
        #self.pub.publish(rangeStr)
        now = rospy.get_rostime()
        self.pubLS_msg.header.stamp.secs = now.secs
        self.pubLS_msg.header.stamp.nsecs = now.nsecs
        self.pubLS_msg.ranges = [
            data['range.front'] * 0.001, data['range.left'] * 0.001,
            data['range.back'] * 0.001, data['range.right'] * 0.001
        ]
        #self.pubLS.publish(self.pubLS_msg)

        self.range_msg_up.range = data['range.up'] * 0.001
        self.range_msg_up.header.stamp.secs = now.secs
        self.range_msg_up.header.stamp.nsecs = now.nsecs

#self.pubRup.publish(self.range_msg_up)

    def _connection_failed(self, link_uri, msg):
        """Callback when connection initial connection fails (i.e no Crazyflie
        at the speficied address)"""
        print('Connection to %s failed: %s' % (link_uri, msg))
        self.is_connected = False

    def _connection_lost(self, link_uri, msg):
        """Callback when disconnected after a connection has been made (i.e
        Crazyflie moves out of range)"""
        print('Connection to %s lost: %s' % (link_uri, msg))

    def _disconnected(self, link_uri):
        """Callback when the Crazyflie is disconnected (called in all cases)"""
        print('Disconnected from %s' % link_uri)
        self.is_connected = False

    def _signal_handler(self, sig, frame):
        print('You pressed Ctrl+C!')
        self.is_connected = False
        self._cf.close_link()
        sys.exit(0)
Example #55
0
class LoggingExample:
    """
    Simple logging example class that logs the Stabilizer from a supplied
    link uri and disconnects after 5s.
    """
    def __init__(self, link_uri):
        """ Initialize and run the example with the specified link_uri """

        self._cf = Crazyflie(rw_cache='./cache')

        # Connect some callbacks from the Crazyflie API
        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        print('Connecting to %s' % link_uri)

        # Try to connect to the Crazyflie
        self._cf.open_link(link_uri)

        # Variable used to keep main loop occupied until disconnect
        self.is_connected = True

    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""
        print('Connected to %s' % link_uri)

        # The definition of the logconfig can be made before connecting
        self._lg_stab = LogConfig(name='relative_pos', period_in_ms=200)
        self._lg_stab.add_variable('relative_pos.rlX0', 'float')
        self._lg_stab.add_variable('relative_pos.rlY0', 'float')
        self._lg_stab.add_variable('relative_pos.rlYaw0', 'float')

        # Adding the configuration cannot be done until a Crazyflie is
        # connected, since we need to check that the variables we
        # would like to log are in the TOC.
        try:
            self._cf.log.add_config(self._lg_stab)
            # This callback will receive the data
            self._lg_stab.data_received_cb.add_callback(self._stab_log_data)
            # This callback will be called on errors
            self._lg_stab.error_cb.add_callback(self._stab_log_error)
            # Start the logging
            self._lg_stab.start()
        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))
        except AttributeError:
            print('Could not add Stabilizer log config, bad configuration.')

        # Start a timer to disconnect in 10s
        t = Timer(1000, self._cf.close_link)
        t.start()

    def _stab_log_error(self, logconf, msg):
        """Callback from the log API when an error occurs"""
        print('Error when logging %s: %s' % (logconf.name, msg))

    def _stab_log_data(self, timestamp, data, logconf):
        """Callback froma the log API when data arrives"""
        global rlxCF, rlyCF, rlyawCF
        rlxCF = data['relative_pos.rlX0']
        rlyCF = data['relative_pos.rlY0']
        rlyawCF = data['relative_pos.rlYaw0']

    def _connection_failed(self, link_uri, msg):
        """Callback when connection initial connection fails (i.e no Crazyflie
        at the speficied address)"""
        print('Connection to %s failed: %s' % (link_uri, msg))
        self.is_connected = False

    def _connection_lost(self, link_uri, msg):
        """Callback when disconnected after a connection has been made (i.e
        Crazyflie moves out of range)"""
        print('Connection to %s lost: %s' % (link_uri, msg))

    def _disconnected(self, link_uri):
        """Callback when the Crazyflie is disconnected (called in all cases)"""
        print('Disconnected from %s' % link_uri)
        self.is_connected = False
Example #56
0
class cf_logging:
    def __init__(self, uri):
        self._cf = Crazyflie(rw_cache='./cache')

        # Define callback function variable
        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        print('Connecting to %s' % uri)
        self._cf.open_link(uri)

        self.is_connected = True

    def _connected(self, uri):
        print(f"Connected to {uri}")

        self._lg_stateEstimate = LogConfig(name="StateEstimation",
                                           period_in_ms=10)
        self._lg_stateEstimate.add_variable('stateEstimate.x', 'float')
        self._lg_stateEstimate.add_variable('stateEstimate.y', 'float')
        self._lg_stateEstimate.add_variable('stateEstimate.z', 'float')
        self._lg_stateEstimate.add_variable('stateEstimate.vx', 'float')
        self._lg_stateEstimate.add_variable('stateEstimate.vy', 'float')
        self._lg_stateEstimate.add_variable('stateEstimate.vz', 'float')

        try:
            self._cf.log.add_config(self._lg_stateEstimate)
            self._lg_stateEstimate.data_received_cb.add_callback(
                self.dataReceived_callback)
            self._lg_stateEstimate.error_cb.add_callback(self.error_callback)

            self._lg_stateEstimate.start()

        except KeyError as e:
            print(f"Could not start log config, {e} not found in TOC")

        except AttributeError:
            print('Could not add Stabilizer log config, bad configuration.')

        # Start a timer to disconnect in 5 seconds
        # Timer(5, self._cf.close_link).start()

    # Connection callback
    def _connection_failed(self, uri, msg):
        print(f"Connection to {uri} failed: {msg}.")

    def _connection_lost(self, uri, msg):
        print(f"Connection to {uri} lost: {msg}.")

    def _disconnected(self, uri):
        print(f"Disconnect from {uri}.")
        self.is_connected = False

    # Logging data connect
    def error_callback(self, logconf, msg):
        print(f"Error when logging {logconf.name}: {msg}")

    def dataReceived_callback(self, timestamp, data, logconf):
        x = data["stateEstimate.x"]
        y = data["stateEstimate.y"]
        z = data["stateEstimate.z"]
        print(f"\n\nX: {x}")
        print(f"\nY: {y}")
        print(f"\nZ: {z}")
streamingClient.rigidBodyListener = receiveRigidBodyFrame

streamingClient.run()

URI = 'radio://0/80/250K'

# Only output errors from the logging framework
logging.basicConfig(level=logging.ERROR)

if __name__ == '__main__':
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    cf = Crazyflie(rw_cache='./cache')

    lg_states = LogConfig(name='kalman_states', period_in_ms=10)
    lg_states.add_variable('kalman_states.ox')
    lg_states.add_variable('kalman_states.oy')

    with SyncCrazyflie(URI, cf=cf) as scf:
        with SyncLogger(scf, lg_states) as logger_states:
            with MotionCommander(scf) as motion_commander:
                keep_flying = True
                char = readchar.readchar()
                motion_commander.up(0.5)
                time.sleep(1)

                while (keep_flying):
                    if len(pos) > 0:
                        cf.extpos.send_extpos(pos[0], pos[1], pos[2])
                        #print("external",pos[1])
Example #58
0
    for i in available:
        print(i[0])

    if len(available) == 0:
        print('No Crazyflies found, cannot run example')
    else:
        #lg_stab = LogConfig(name='Stabilizer', period_in_ms=10)
        #lg_stab.add_variable('stabilizer.roll', 'float')
        #lg_stab.add_variable('stabilizer.pitch', 'float')
        #lg_stab.add_variable('stabilizer.yaw', 'float')

        #lg_motion = LogConfig(name='Motion', period_in_ms=1000)
        #lg_motion.add_variable('motion.deltaX', 'float')
        #lg_motion.add_variable('motion.deltaY', 'float')

        log_rssi = LogConfig(name='RSSI', period_in_ms=1000)
        log_rssi.add_variable('radio.rssi', 'float')

        cf = Crazyflie(rw_cache='./cache')
        with SyncCrazyflie(available[0][0], cf=cf) as scf:
            with SyncLogger(scf, log_rssi) as logger:
                endTime = time.time() + 10

                for log_entry in logger:
                    timestamp = log_entry[0]
                    data = log_entry[1]
                    logconf_name = log_entry[2]

                    #print('[%d][%s]: %s' % (timestamp, logconf_name, data))
                    print(data["radio.rssi"])
    logging.basicConfig(level=logging.ERROR)
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    # Scan for Crazyflies and use the first one found
    print('Scanning interfaces for Crazyflies...')
    available = cflib.crtp.scan_interfaces()
    print('Crazyflies found:')
    for i in available:
        print(i[0])

    if len(available) == 0:
        print(err_dict["2"])
    else:
        cf = Crazyflie(rw_cache='./cache')
        # Add logging config to logger
        lg_stab = LogConfig(name='Stabilizer', period_in_ms=12)
        lg_stab.add_variable('pm.vbat', 'float')
        lg_stab.add_variable('pm.batteryLevel', 'float')
        lg_stab.add_variable('pwm.m1_pwm', 'float')
        lg_stab.add_variable('baro.temp', 'float')
        with SyncCrazyflie(URI) as scf:
            # Define motion commander to crazyflie as mc:
            cf2 = CF(scf, available)
            cf2_psi = 0    # Get current yaw-angle of cf
            cf2_bat = cf2.vbat  # Get current battery level of cf
            cf2_blevel = cf2.blevel
            cf2_pwm = cf2.m1_pwm
            cf2_temp = cf2.temp
            cf2_phi = 0
            cf2_theta = 0
            marker_psi = 0  # Set marker angle to zero initially
class LoggingExample:
    """
    Simple logging example class that logs the Stabilizer from a supplied
    link uri and disconnects after 5s.
    """
    def __init__(self, link_uri):
        """ Initialize and run the example with the specified link_uri """

        self._cf = Crazyflie(rw_cache='./cache')

        # Connect some callbacks from the Crazyflie API
        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)

        print('Connecting to %s' % link_uri)

        # Try to connect to the Crazyflie
        # Lock the connection part to speed up
        lock = Lock()
        lock.acquire()
        self._cf.open_link(link_uri)
        lock.release()

        # Variable used to keep main loop occupied until disconnect
        self.my_connected = False

    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""
        print('Connected to %s' % link_uri)
        self.my_connected = True

        # The definition of the logconfig can be made before connecting
        # self._lg_stab = LogConfig(name='Stabilizer', period_in_ms=10)
        # set acceleration log config
        self._lg_acc = LogConfig(name="acc", period_in_ms=10)
        self._lg_acc.add_variable('acc.x', 'float')
        self._lg_acc.add_variable('acc.y', 'float')
        self._lg_acc.add_variable('acc.z', 'float')

        # vec, theta = euler2axangle(0, 1.5, 9, 'szyx')

        # open file in log directory
        # save_path = './log'
        curr_time = time.strftime("%Y%m%d-%H%M%S")
        # file_name = os.path.join(save_path, 'acc_'+curr_time+'.txt')
        file_name = 'acc_' + curr_time + '.txt'

        self.f = open(file_name, 'w')
        # Adding the configuration cannot be done until a Crazyflie is
        # connected, since we need to check that the variables we
        # would like to log are in the TOC.
        try:
            self._cf.log.add_config(self._lg_acc)
            # This callback will receive the data
            self._lg_acc.data_received_cb.add_callback(self._stab_log_data)
            # This callback will be called on errors
            self._lg_acc.error_cb.add_callback(self._stab_log_error)
            # Start the logging
            self._lg_acc.start()
        except KeyError as e:
            print('Could not start log configuration,'
                  '{} not found in TOC'.format(str(e)))
        except AttributeError:
            print('Could not add Stabilizer log config, bad configuration.')

    def _stab_log_error(self, logconf, msg):
        """Callback from the log API when an error occurs"""
        print('Error when logging %s: %s' % (logconf.name, msg))

    def _stab_log_data(self, timestamp, data, logconf):
        """Callback froma the log API when data arrives"""
        self.f.write('[%d][%s]: %s' % (timestamp, logconf.name, data) + "\n")
        print('[%d][%s]: %s' % (timestamp, logconf.name, data))

    def _connection_failed(self, link_uri, msg):
        """Callback when connection initial connection fails (i.e no Crazyflie
        at the speficied address)"""
        print('Connection to %s failed: %s' % (link_uri, msg))
        self.my_connected = False
        # self.f.close()

    def _connection_lost(self, link_uri, msg):
        """Callback when disconnected after a connection has been made (i.e
        Crazyflie moves out of range)"""
        print('Connection to %s lost: %s' % (link_uri, msg))
        self.my_connected = False
        # self.f.close()

    def _disconnected(self, link_uri):
        """Callback when the Crazyflie is disconnected (called in all cases)"""
        print('Disconnected from %s' % link_uri)
        self.my_connected = False
        self.f.close()

    def disconnect(self):
        """Disconnect everything and stop logging when called"""
        print('Disconnect in 1 second')

        t = Timer(1, self._cf.close_link)
        t.start()