The values of log variables are transferred from the Crazyflie using CRTP
packets, where all variables belonging to one logging configuration are
transferred in the same packet. A CRTP packet has a maximum data size of 30
bytes, which sets an upper limit to the number of variables that can be used
in one logging configuration. If the desired log variables do not fit in one
logging configuration, a second configuration may be added.


![](/advisor/images/snyk-icon-github.svg) [ GitHub
](https://github.com/bitcraze/crazyflie-clients-python)


connectors for other accessories, such as a GPS receiver, battery voltage and current monitor, buzzer,
chaotic pulse position modulation (CPPM) receiver, or I2C communication protocol [30]. The connections of the BigQuad deck are seen in Figure 54 with the final assembly seen in Figure 55.
Unfortunately, the BigQuad deck is not compatible with the Flow deck without modifying the firmware and components of the hardware. As a result, the control and stabilisation is slightly more difficult and requires a different method based on measurements relative to the target detection. Moreover,
the original internal cascading PID controllers for attitude flight control of position and velocity are
tuned for the original frame, rotor motors, propellers, and battery, so it might be necessary to re-tune
the controller gain values if the flight is found to be unstable or unresponsive.
ESC ESC
ESC ESC
Motor
One
Motor
Two
Motor
Three
Motor
Four
Top View Bottom View
LiPo Battery
Signals
From
Process
MicroController
25mm 25mm
40mm
Figure 54: Schematic (left) and photographs (right) showing the Bitcraze BigQuad expansion deck
and connections to the EMAX Bullet 30A ESCs and EMAX RSII 2206-1700KV rotor motors [31].
3D
Printed
Stand
3D
Printed
Base
Raspberry Pi
Pi Camera Crazyflie,
BigQuad
Propeller
Motor
Power
Distribute
Battery


27.3 823 30.1 0.033
25.0 753 30.1 0.033
25.5 766 30.0 0.033
C
22.3 280 12.6 0.080
17.5 217 12.4 0.081
28.1 355 12.6 0.079
D
21.6 542 25.1 0.040
22.6 561 24.8 0.040
23.8 585 24.6 0.041
E
22.0 249 11.3 0.088
23.5 267 11.4 0.088
24.7 275 11.1 0.090
2. 320px By 240px
Record Time [s]
Total Frames [fr]
Average FPS [fr/s]
Average SPF [s/fr]
A
20.3 217 10.7 0.094
21.2 233 11.0 0.091
23.6 261 11.1 0.090
B
17.9 149 8.33 0.120
22.4 191 8.53 0.117
25.3 214 8.46 0.118
C
17.8 60 3.37 0.296
18.5 65 3.52 0.284
27.7 96 3.47 0.288
D
17.5 116 6.63 0.151
14.5 94 6.49 0.154
27.2 181 6.66 0.150
E
28.5 92 3.23 0.310
22.2 72 3.25 0.308
28.4 93 3.28 0.305


###  PositionHlCommander


Shouldnt the voltage level reduce with time? it just repeats the above cycle.


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


The operating system has been optimised for best performance on the Raspberry Pi and will be used
to run the control script for visual servoing while issuing setpoints to control the Crazyflie through the
installation of Python 3.7.3 and the required libraries. It also allows for interfacing with the ground
control laptop using the wireless LAN 802.11n of the Raspberry Pi and local network created by the
ground control laptop, where a remote desktop protocol (RDP) or secure shell (SSH) session is used
for remote login through a graphical user interface (GUI) or the command line respectively.
4.6.4 ARDUINO
The Arduino IDE offers a means to program the target using C++ with special rules of code structuring, and it compiles the script when uploading to the controller (any programming language with
a compiler to produce binary machine code could actually be used, but it will be most convenient to
use the Arduino IDE). Since the Dagu Controller is compatible with the Arduino IDE, the motors
can then be controlled using PWM signals to produce voltages between 0V and 5V corresponding to
duty cycles linearly represented by values between 0 (0%) and 255 (100%). The following Arduino
commands will primarily be used to control the motors and corresponding motion of the target:
• pinMode: Configure a pin to behave as either an INPUT (high-impedance state) or OUTPUT (lowimpedance state). This is used to initially set the direction pin of each motor as an output.
• digitalWrite: Write a HIGH (5V) or LOW (0V) value to a digital pin. This is applied on the
direction pin for the respective motor and used to set the direction in which the motor must turn.
• analogWrite: Write an analog value to a pin for a duty cycle represented between 0 (0%) and
255 (100%). This is applied to the signal pin for the respective motor and used to set the speed
in terms of a PWM value at which the motor must turn based on a voltage between 0V and 5V.
• servo.write: Instruct the servo motor to rotate to the passed angle between 0o
and 180o
(servo
is the name assigned to the pin on which the servo motor is attached).
30
5 METHODOLOGY
After preparatory development with the apparatus to gain an improved understanding, the proposed
methodology can be divided into parts including camera compensation and calibration; initial Crazyflie considerations; target detection through processing the images from the camera; target tracking
through issuing command setpoints to autonomously move the Crazyflie based on the location of the
target; overall communication between the Raspberry Pi, Crazyflie, ground control laptop, and motion capture system; and motions of the target with different paths. Importantly, it is also required to
monitor and store the position of the target and Crazyflie in real-time during execution using the motion capture system which will be examined to validate success or failure. A complete risk assessment
for the operators, supervisors, and nearby bystanders has also been included in Appendix D.
5.1 INITIAL CAMERA CONSIDERATIONS
Firstly, it is necessary to confirm there is no significant fish-eye distortion, blurring, or effects from
rolling shutter. This will be done by taking a series of sample images of a chessboard template and
measuring whether the straight lines in the template appear straight in the images, where the measurement will be conducted by digitally overlaying straight lines over the captured image to observe
any deviations. This also serves as a means to ensure the camera is not faulty.
Before the Raspberry Pi and Pi Camera can be used for target detection and tracking, it is necessary
to evaluate the real-time performance for the image processing. This will be assessed by recording
a short clip of approximately 15s to 30s with resolutions of 160px by 120px, 320px by 240px, and
640px by 480px to determine which resolutions provide a sufficiently high frames rate with less


[13]. Blurring can also be performed through convolving the image with a low-pass filter, which is
usually employed to aid in noise reduction [13]. Thresholding aims to provide a simple method of
segmenting a grayscale image, where a binary image is created using only 0 as black, which is applied
when the value of a pixel is below a threshold value, and 1 as white, which is applied when the value
of a pixel is above a threshold value [13]. After applying a threshold, a morphology transformation
can be performed to further noise reduction - this uses an erosion transformation to remove noise of
white value or dilation transformation to connect regions of white value [13].
To develop basic target detection and shape analysis, there are existing algorithms for detecting edges
using high-pass or gradient filters, such as the Canny edge detection which is a multi-stage algorithm
with noise reduction, gradient intensity finding, non-maximum suppression, and hysteresis thresholding [13]. Alternatively, it is possible to implement contour finding to locate curves joining the continuous points which have the same colour or intensity along a boundary - these curves can then be
used to analyse the centroid, area, orientation, and other characteristics of the target [13]. The level
of image processing can vary depending on the situation, where minimal processing will reduce the
delay before the response commands can be executed, but excessive processing will be more reliable
with more computational effort and heavier algorithms for more accurate results [14].
12
Original Colour Grayscale Smooth Blur Binary Threshold
Morphology Transform Edge Detection Contour Finding
R: 73, G: 62, B: 128
R: 190
G: 182
B: 145
R: 96
G: 153
B: 172
R: 191
G: 136
B: 142
R: 184
G: 137
B: 173
Figure 12: Example of an image from a camera in original colour and with processing through grayscaling, blurring, thresholding, morphology transforming, edge detecting, and contour finding.
For more specific target detection, target recognition is considered to be concerned with recognising the designated target based on learnt features. There are common algorithms which include
colour-based matching, template matching, meanshift, camshift (continuously adaptive meanshift),
and corner detection. The overall techniques and methods of these algorithms are briefly explored:
• The colour-based matching algorithm simply compares the colour in patches of an image against
a specific colour range for the target in an attempt to find a match within the range [13, 14]. This
algorithm usually requires for the target to be a single colour and may produce false-positives
when there are other objects of similar colours within the image [13, 14].
• The template matching algorithm compares patches of an image against a specific template for
the target in an attempt to find a match based on a flexible threshold for success [13, 14]. For


Figure 49: Relevant results against time throughout the second trial of the yaw orientation test.
Yaw Orientation - Trial 1
Yaw Orientation - Trial 2
Combined Motion - Trial 1
Combined Motion - Trial 2
Circular Motion - Trial 1
Circular Motion - Trial 2
Rectilinear Motion - Trial 1
Rectilinear Motion - Trial 2
Average
Max.
Min.
Average
Max.
Min.
Max.
Min.
Average
Max.
Min.
Average
Max.
Min.
Max.
Min.
Average Average
Max.
Min.
Average
Max.
Min.
Average
Figure 50: Deviations with adjustments for average lag in the translation and rotation tests.
To isolate the altitude behaviour, the average altitude at each part of the flight was shown on the
altitude plots for each trial. As mentioned, the initial behaviour during take off is partially unstable
with repeated overshooting, where the actual and magnitude percentage differences in the overshoot
can be compared, with Equation 29 and Equation 30 respectively, using the average altitude over the
following part of the flight. The compiled altitude results are included in Table 5.
Table 5: Outline of the altitude of the Crazyflie for each of the translation and rotation tests. Initial Overshoot [mm] First Minimum [mm] First Average [mm] First Maximum [mm] Second Minimum [mm] Second Average [mm] Second Maximum [mm] Actual Overshoot [%] Mag. Overshoot [%]
Rectilinear


Open menu  Open navigation  [ ](/) Go to Reddit Home


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


value = get_value(complete_name)


Note that this command implements a motor lock mechanism that is intended to
avoid flyaway when connecting a gamepad. You must send one command with thrust
= 0 in order to unlock the command. This unlock procedure needs to be repeated
if the watchdog described above kicks-in.


To send a new control set-point use the following:


where damages may have occurred in previous tests, and the correct blades must be installed on
the correct rotors for clockwise or counter-clockwise rotation. For the Crazyflie, A, A1, or A2
indicate clockwise rotation and B, B1, or B2 indicate counter-clockwise rotation.
• At the start of a test, the battery of the Crazyflie should always be fully charged. If so, it must
also be ensured that the battery installation is correct and secure to the frame without metal or
sharp parts contacting the battery and without any possibility of a short-circuit occurring.
• Once the Crazyflie is placed on solid ground and powered on, the status LEDs should be check
for any errors detected while the firmware performs internal self-checks during start-up. For the
Crazyflie, the LEDs labelled M1 and M4 will indicate the result of the self-checks, where the M4
LED rapidly blinks green five times if the self-checks are passed or the M1 LED rapidly blinks
red five times then pauses and repeats again if the self-checks are failed. After the self-checks
have passed, the M1 LED should blink twice per second if the sensors are calibrated or the M1
LED will blink once every two seconds if the calibration failed (for calibration, the Crazyflie
must be still and the ground should be level). If the M4 LED is constantly red, the battery is low
and the Crazyflie should not be flown. The M2 and M3 LEDs should be constantly blue and are
not related to the self-checks (used to indicate orientation), unless in a different state for charging
or firmware flashing. The motors will also initially rotate in sequence to indicate operation.
• The control scripts on the Raspberry Pi must be checked and free from errors and warnings
before connecting to the Crazyflie. If unsure, the Crazyflie can be connected and the control
82
scripts can be run while there are no propellers attached to the rotors or while safely holding the
Crazyflie to observe if there will be any unexpected behaviour (the Crazyflie should be gripped
firmly at the bottom of the frame to avoid the propellers).
• When it is ready for a test, the Crazyflie should be placed on solid and level ground with the
forward direction pointing away from the operators, supervisors, and nearby bystanders.
• When it begins flying for a test, the Crazyflie should start the motors, take off vertically, and
hover at a fixed position to ensure correct, controlled, and stable operation before continuing.
• Once the test is complete and the Crazyflie has landed with inactivity, the Raspberry Pi should be
disconnected and the battery of the Crazyflie should be removed (do not pull the battery cables).
The risks involved in the experiment have been identified and evaluated. This involved categorizing
the severity, likelihood, and type of the risks, and proposing precautionary actions to further prevent
the risks. The complete risk assessment is seen in Table 6 and the official standard operating procedure
in the motion capture facilities for quadrotor experiments is seen in Figure 51.
Table 6: Evaluation of the potential risks involved in the experiment.
Activity:
Venue:
Risk Type Risk Description Severity Likelihood Risk Score Action Type Action
Mechanical Due to a loss of control or unpredictable
behaviour, the Crazyflie may collide with
an operator or person in the vicinity of the


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


Infinitesimal
Point Apeture
Optical
Centre
Virtual
Image
Plane
Target
Point
Plane
f = Focal Length
z = Altitude
Figure 10: Geometric relationships resulting from the pinhole camera model.
10
u = f
x
z
(10)
v = f
y
z
(11)
Where f , focal length, px; z, altitude, m; u, virtual image latitude coordinate, px; x, actual latitude
coordinate, m; v, virtual image longitude coordinate, px; and y, actual longitude coordinate, m.
If the pinhole model is valid, straight lines in reality are projected as straight lines on the imaging
sensor - rectilinearity is preserved [2]. If the pinhole model is not valid due to excessive distortions,
these distortions will create radial and tangential inaccuracies in the image. The radial inaccuracies
result in straight lines appearing curved, while the tangential inaccuracies occur because the lens is
not aligned perfectly parallel to the imaging plane so some areas in the image appear nearer than
expected. It is most common for fish-eye distortion with large radial exaggerations towards the edges
of the field of view, as described by Figure 11, where this distortion is usually more pronounced on
wide angle lenses with large fields of view which capture a greater portion of the environment [2].
The distortion present in the actual images will need to be tested with the camera and deemed to be
insignificant without the need for compensation or significant with the need for compensation.
ra = Realistic Radial Distance From Principal Point
rd = Distorted Radial Distance From Principal Point
Significant Fish-Eye Distortion
Focal
Length
Projection


    # Set accelerometer logging config
            accel_log_conf = LogConfig("Accel", 10)
            accel_log_conf.addVariable(LogVariable("acc.x", "float"))
            accel_log_conf.addVariable(LogVariable("acc.y", "float"))
            accel_log_conf.addVariable(LogVariable("acc.z", "float"))

            # Now that the connection is established, start logging
            self.accel_log = self.crazyflie.log.create_log_packet(accel_log_conf)

            if self.accel_log is not None:
                self.accel_log.dataReceived.add_callback(self.log_accel_data)
                self.accel_log.start()
            else:
                print("acc.x/y/z not found in log TOC")

            motor_log_conf = LogConfig("Motor", 10)
            motor_log_conf.addVariable(LogVariable("motor.m1", "int32_t"))
            motor_log_conf.addVariable(LogVariable("motor.m2", "int32_t"))
            motor_log_conf.addVariable(LogVariable("motor.m3", "int32_t"))
            motor_log_conf.addVariable(LogVariable("motor.m4", "int32_t"))

            # Now that the connection is established, start logging
            self.motor_log = self.crazyflie.log.create_log_packet(motor_log_conf)

            if self.motor_log is not None:
                self.motor_log.dataReceived.add_callback(self.log_motor_data)
                self.motor_log.start()
            else:
                print("motor.m1/m2/m3/m4 not found in log TOC")


improved performance, multiple scaled and rotated templates of the target may be considered
[13, 14]. However, this is likely to be ineffective when the orientation and size of the target
constantly changes since many templates and increased computational effort will be required.
• The meanshift and camshift algorithms use an initial region of interest of the target separated
from the background in colour mode and then this region is shifted in subsequent frames based on
a local maximum of a probability distribution for the changes in the target location, orientation,
and size [13, 14]. The camshift algorithm essentially builds on the meanshift algorithm with the
use of an adaptive probability distribution to better account for changes in the orientation and
size of the target (the meanshift algorithm uses a static probability distribution) [13, 14].
13
• A corner detection algorithm basically considers the change in gradient intensity where corner
or blob points can be uniquely identified [2, 13]. There are various flavours of corner detection
algorithms, such as the Harris, Shi-Tomasi, scale-invariant feature transform (SIFT), speeded-up
robust features (SURF), or feature from accelerated segment test (FAST) [2, 13].
However, besides the colour-based matching algorithm, these algorithms generally require a large
amount of computational effort and iterations with multiple frames for success and it is usually not
possible to perform this processing on low-end hardware while achieving real-time performance [14].
Regardless of the detection or recognition algorithm, it is essential for the detection algorithm to
have repeatability, where the same features of the target should be consistently detected in consecutive frames; distinctiveness, where the features of the target can easily be distinguished using their
appearance; robustness, where detection is still possible in the presence of distortion or noise; low
computational effort, where the processing must be as fast as possible for real-time operation; scale
invariance, where the size of the target does not affect detection (with regards to a reasonable limit);
illumination invariance, where the lighting or photometry from the environment does not affect detection; and orientation invariance, where the rotation of the target does not affect detection [2].
An additional computer vision technique which should be acknowledged is the use of optical flow.
Instead of directly detecting a specific target, optical flow is concerned with motion detection and
the changes in the patterns of features in the environment due to apparent motion caused by relative
motion between the camera and environment [13]. Although it may not be useful in target detection,
an optical flow sensor can be utilised to stabilise a quadrotor by discerning necessary adjustments.
2.6 LOCATION ESTIMATION
The attitude of the quadrotor refers to the angular orientation in three-dimensions and, along with
the location in three-dimensions, the state of the quadrotor can then be described by the vertical
altitude, position in the horizontal plane, and angular arrangement for movement. With regards to
target tracking, the primary concerns are the three translational degrees of freedom, such that the
desired altitude and position of the quadrotor relative to the altitude and position of the target can be
determined through position-based visual servoing by processing the captured frame.
So, the captured and subsequent frames can be processed to detect the target and find the approximate
area and centroid of the target as measured in terms of pixels in the frames. Thus, through a pinhole
camera model, a reconstruction of the three-dimensional locations can be applied as a method to
estimate the desired altitude for the quadrotor and current position of the target in terms of distances.
This can be pursued with an arrangement similar to that displayed in Figure 13 - although the method


The ` SyncLogger ` class wraps setting up, as well as starting/stopping
logging. It works both for Crazyflie and ` SyncCrazyflie ` instances. To get
the log values, iterate the instance.


89
90 # Combine the processed frames into a single frame.
91 if np.size (mode) == res_x * res_y:
92 mode = cv.merge ([mode, mode, mode])
93 elif np.size (mode) == res_x * res_y * 3:
94 mode = cv.cvtColor (mode, cv.COLOR_HLS2BGR)
95 mode = cv.bitwise_and (mode, mode, mask = morphology)
96 threshold = cv.merge ([threshold, threshold, threshold])
97 morphology = cv.merge ([morphology, morphology, morphology])
98 if len (contours) != 0:
99 cv.drawContours (morphology, contours, -1, (255, 0, 0), 2)
100 output = np.zeros ((res_y * 2, res_x * 2, 3), dtype = "uint8")
101 output [0:res_y, 0:res_x] = frame
102 output [0:res_y, res_x:(res_x * 2)] = mode
103 output [res_y:(res_y * 2), 0:res_x] = threshold
104 output [res_y:(res_y * 2), res_x:(res_x * 2)] = morphology
105
106 # Record (optional) and display the combined output.
107 if record == "Y":
108 video.write (output)
109 cv.imshow ("Combined Output", output)
110
111 # ----------------------------------------------------------------------------------
112 # Define Variables
113 # ----------------------------------------------------------------------------------
114
115 # Set the variables for target detections.
116 print ("Setting the variables to be used.")
117 res_x = 160 # 320 # 640
118 res_y = 120 # 240 # 480
119 fps = 30
120
121 # Find basic requirements from the user.
122 record = input ("Must the source be recorded as a video? [Y/N] ")
123 if record == "Y":
124 version = input ("Must basic [B] or combined [C] output be recorded? [B/C] ")
125 if version != "B" and version != "C":
126 print ("! The input for the version is invalid. Quitting the program.")
127 raise SystemExit
128 elif record != "N":


##  Top Posts


![python](/advisor/images/snyk-icon-pypi.svg) PyPI


Operations on the link and connection will return immediately and will call
the following callbacks when events occur:


  * [ cfclient.config_path  ](/advisor/python/cfclient/functions/cfclient.config_path)
  * [ cfclient.module_path  ](/advisor/python/cfclient/functions/cfclient.module_path)
  * [ cfclient.ui  ](/advisor/python/cfclient/functions/cfclient.ui)
  * [ cfclient.ui.dialogs.about.AboutDialog  ](/advisor/python/cfclient/functions/cfclient.ui.dialogs.about.AboutDialog)
  * [ cfclient.ui.dialogs.bootloader.BootloaderDialog  ](/advisor/python/cfclient/functions/cfclient.ui.dialogs.bootloader.BootloaderDialog)
  * [ cfclient.ui.pluginhelper  ](/advisor/python/cfclient/functions/cfclient.ui.pluginhelper)
  * [ cfclient.ui.pluginhelper.cf  ](/advisor/python/cfclient/functions/cfclient.ui.pluginhelper.cf)
  * [ cfclient.ui.tab.Tab  ](/advisor/python/cfclient/functions/cfclient.ui.tab.Tab)
  * [ cfclient.ui.tabs.ServiceTab.UIState  ](/advisor/python/cfclient/functions/cfclient.ui.tabs.ServiceTab.UIState)
  * [ cfclient.ui.widgets.ai.AttitudeIndicator  ](/advisor/python/cfclient/functions/cfclient.ui.widgets.ai.AttitudeIndicator)
  * [ cfclient.utils.config.Config  ](/advisor/python/cfclient/functions/cfclient.utils.config.Config)
  * [ cfclient.utils.config_manager.ConfigManager  ](/advisor/python/cfclient/functions/cfclient.utils.config_manager.ConfigManager)
  * [ cfclient.utils.guiconfig.GuiConfig  ](/advisor/python/cfclient/functions/cfclient.utils.guiconfig.GuiConfig)
  * [ cfclient.utils.input.JoystickReader  ](/advisor/python/cfclient/functions/cfclient.utils.input.JoystickReader)
  * [ cfclient.utils.input.JoystickReader.ASSISTED_CONTROL_HEIGHTHOLD  ](/advisor/python/cfclient/functions/cfclient.utils.input.JoystickReader.ASSISTED_CONTROL_HEIGHTHOLD)
  * [ cfclient.utils.input.JoystickReader.ASSISTED_CONTROL_HOVER  ](/advisor/python/cfclient/functions/cfclient.utils.input.JoystickReader.ASSISTED_CONTROL_HOVER)
  * [ cfclient.utils.input.JoystickReader.ASSISTED_CONTROL_POSHOLD  ](/advisor/python/cfclient/functions/cfclient.utils.input.JoystickReader.ASSISTED_CONTROL_POSHOLD)
  * [ cfclient.utils.logconfigreader.LogConfig  ](/advisor/python/cfclient/functions/cfclient.utils.logconfigreader.LogConfig)
  * [ cfclient.utils.logconfigreader.LogVariable  ](/advisor/python/cfclient/functions/cfclient.utils.logconfigreader.LogVariable)
  * [ cfclient.VERSION  ](/advisor/python/cfclient/functions/cfclient.VERSION)


        crazyflie = Crazyflie()
        crazyflie.connected.add_callback(crazyflie_connected)


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


* [ Reddit  reReddit: Top posts of August 4, 2023


PID Proportional-Integral-Derivative
PBVS Position-Based Visual Servoing
PPE Personal Protective Equipment
PRX Primary Receiver Mode
PTX Primary Transmitter Mode
PWM Pulse Width Modulation
QTM Qualisys Track Manager
RAM Random Access Memory
RDP Remote Desktop Protocol
RGB Red, Green, and Blue
RTOS Real-Time Operating System
SD Secure Digital
SIFT Scale-Invariant Feature Transform
SPF Seconds Per Frame
SPI Serial Peripheral Interface
SRAM Static Random Access Memory
SSH Secure Shell
SURF Speeded-Up Robust Features
ToF Time-of-Flight
UART Universal Asynchronous Receiver/Transmitter
UAV Unmanned Aerial Vehicle
USB Universal Serial Bus
WiFi Wireless Fidelity
Throughout the report, the relevant description is displayed with the first appearance of uncommon
acronyms. If the acronym is commonly known or may be better known by the acronym itself, the
acronym is used directly with the first appearance, such is the case for USB and HDMI as examples.
xiii
1 INTRODUCTION
In industries requiring dynamic surveillance, inspection, or exploration, it is often useful to accurately
track moving targets with an unmanned aerial vehicle (UAV) using visual servoing. These industries
include activities involving photography, cinematography, traffic and transportation, surveying, mapping, search and rescue, navigation, and agriculture, with increasing presence in the evolution of the
fourth industrial revolution [1]. So, it is necessary to establish an initial basis for visual servoing using
an UAV and infer if there are reasons for further investigation into moving target tracking.
1.1 BACKGROUND
A multirotor is generally regarded as an unmanned rotorcraft or rotary-wing aircraft which generates
thrust and motion using two or more fixed-pitch rotors as actuators and allows for simpler rotor mechanics required for flight control using sensors, as compared to other types of aircraft [2]. A quadrotor
is a multirotor with four rotors and propellers, where the size may typically vary with propeller diameters from 45mm for small aircraft to 480mm for large aircraft and the cost may relatively vary from
economical for hobbies to extravagant for specialised activities [2]. A variety of multirotor layouts,
including a quadrotor, are seen in Figure 1. (Occasionally, the terms “multicopter” and “quadcopter”
are used to refer to a multirotor or quadrotor respectively, but from linguistic perspectives and origins,


  * The variable is changed by the Crazyflie and not by the client
  * The variable is updated at high rate and you want to read the value periodically


> **Note 1** If you call ` set_value() ` and then directly call ` get_value()
> ` for a parameter, you might not read back the new value, but get the old
> one instead. The process is asynchronous and ` get_value() ` will not return
> the new value until the parameter value has propagated to the Crazyflie and
> back. Use the callback method if you need to be certain that you get the
> correct value after an update.


322 strikes = 0
323 if source.isOpened == False:
324 print ("! The source is not open. Trying to open the source.")
325 source.Open ()
326 if source.isOpened == False:
327 print ("The source is not open.")
328 active == False
329 elif source.isOpened == True:
330 print ("The source is open and available.")
331
332 # Check that the source is operating correctly.
333 print ("Checking that the source is operating correctly.")
334 check = input ("Should the source be checked to be capturing correctly? [Y/N] ")
335 if check == "Y":
78
336 correct, frame = source.read ()
337 if correct == False:
338 print ("A frame could not be read correctly.")
339 correct = "N"
340 elif correct == True:
341 cv.imshow ("Image Test", frame)
342 cv.waitKey (1)
343 correct = input ("Is the capture displayed correctly? [Y/N] ")
344 if correct == "N":
345 print ("! The capture is not operating correctly.")
346 active = False
347 cv.destroyAllWindows ()
348
349 # --------------------------------------------------------------------------------
350 # Main Project Loop
351 # --------------------------------------------------------------------------------
352
353 # Execute the functions to perform visual servoing and target tracking.
354 if __name__ == "__main__":
355
356 # Initialize the low-level drivers (do not list the debug drivers).
357 cflib.crtp.init_drivers (enable_debug_driver = False)
358
359 # Initialise the SyncCrazyflie class for function blockings.
360 with SyncCrazyflie (uri, cf = crazyflie) as crazyflie_sync:


  * [ The Real Housewives of Atlanta  ](https://reddit.com/t/the_real_housewives_of_atlanta/)
  * [ The Bachelor  ](https://reddit.com/t/the_bachelor/)
  * [ Sister Wives  ](https://reddit.com/t/sister_wives/)
  * [ 90 Day Fiance  ](https://reddit.com/t/90_day_fiance/)
  * [ Wife Swap  ](https://reddit.com/t/wife_swap/)
  * [ The Amazing Race Australia  ](https://reddit.com/t/the_amazing_race_australia/)
  * [ Married at First Sight  ](https://reddit.com/t/married_at_first_sight/)
  * [ The Real Housewives of Dallas  ](https://reddit.com/t/the_real_housewives_of_dallas/)
  * [ My 600-lb Life  ](https://reddit.com/t/my_600lb_life/)
  * [ Last Week Tonight with John Oliver  ](https://reddit.com/t/last_week_tonight_with_john_oliver/)


        with SyncCrazyflie(URI) as scf:
            # We take off when the commander is created
            with MotionCommander(scf) as mc:
                # Move one meter forward
                mc.forward(1)
                # Move one meter back
                mc.back(1)
                # The Crazyflie lands when leaving this "with" section
            # When leaving this "with" section, the connection is automatically closed


  * [ Cardano  ](https://reddit.com/t/cardano/)
  * [ Dogecoin  ](https://reddit.com/t/dogecoin/)
  * [ Algorand  ](https://reddit.com/t/algorand/)
  * [ Bitcoin  ](https://reddit.com/t/bitcoin/)
  * [ Litecoin  ](https://reddit.com/t/litecoin/)
  * [ Basic Attention Token  ](https://reddit.com/t/basic_attention_token/)
  * [ Bitcoin Cash  ](https://reddit.com/t/bitcoin_cash/)


[ stickgamerhd ](/user/stickgamerhd/)


###  Other commander setpoints sending


[ Home ](/) / Documentation / [ Repository overview
](/documentation/repository/) / crazyflie-lib-python / [ master
](/documentation/repository/crazyflie-lib-python/master/) / [ User guides
](/documentation/repository/crazyflie-lib-python/master/user-guides/) / The
Crazyflie Python API explanation


##  Synchronous API


The library is asynchronous and based on callbacks for events. Functions like
` open_link ` will return immediately, and the callback ` connected ` will be
called when the link is opened. The library doesn't contain any threads or
locks that will keep the application running, it's up to the application that
is using the library to do this.


####  Package Health Score


Skip to main content


Community about the CrazyFlie micro UAV platform


  * [ Partners ](https://snyk.io/partners/)
  * [ Developers & DevOps Features ](https://snyk.io/product/)
  * [ Enterprise Features ](https://snyk.io/product/enterprise/)
  * [ Pricing ](https://snyk.io/plans/)
  * [ API Status ](https://snyk.statuspage.io/)


        my_cf = Crazyflie(rw_cache='./cache')
        with SyncCrazyflie(uri, cf=my_cf) as scf:
            # The my_cf is now connected
            # Do useful stuff
            # When leaving the "with" section, the connection is automatically closed


    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)
                    newVar = LogVariable(completeName,
                                         fetchAs=varType,
                                         storedAs=varType)
                    logconfig.addVariable(newVar)
            return logconfig


is clear from static and dynamic obstacles for both the target and Crazyflie.
Initially, the strength of the PWM signals for each motor will be calibrated in preparatory development. To evaluate different motion characteristics, three tests will be performed and aimed at validating rectilinear motion with primary movements along latitudinal and longitudinal lines, circular
motion with primary movements across latitudinal and longitudinal lines, and a combination of rectilinear and circular motions in a seemingly random manner. Throughout the motions, the target will
move at various speeds up to 0.20m/s as well as being stationary for sporadic periods of time, where
the Crazyflie will be required to hover at a fixed position above the target. Moreover, an additional
test will be performed for the yaw orientation, where the target is rotated both clockwise and counterclockwise between 90o
and 90o
at about 10o
/s. The planned path for these tests are annotated in
Figure 32 - although the actual paths may slightly differ due to inconsistencies between the motors of
the target, which is not an issue as these paths are essentially arbitrary and the Crazyflie must track
the target regardless of the path. Each test will be performed two times to ensure repeatable results.
The altitude of the camera will also be altered for each of the tests and, for the rectilinear and circular motion tests, the target will actually stop at a midpoint and the altitude of the camera will be
increased or decreased manually with the tripod. Over all of the tests, the variety of altitudes to be
examined specifically include 380mm, 480mm, 580mm, and 780mm with the corresponding tests
related in Figure 32. The respective fields of view from the camera at each altitude are measured to be
approximately 520mm by 390mm, 660mm by 500mm, 800mm by 600mm, and 1050mm by 800mm.
5.7 DATA MONITORING
As mentioned in Figure 31, the current view from the camera will be displayed by the Raspberry Pi
which is then streamed to the ground control laptop for live monitoring during the tests. It is also
possible to immediately terminate the execution of the control script and land the Crazyflie, which is
included for safety so a test can be cancelled if unexpected or unsafe behaviour is observed.
To validate the tests as successes or failures, the motion capture system will store the position of the
target and Crazyflie in real-time at 100fr/s, such that any relative deviation between the current position of the target (which is the desired position of the Crazyflie) and actual position of the Crazyflie
can be exactly quantified. Using the motion capture system is also more accurate than logging variables measured on-board the Crazyflie. The QTM will mostly handle running of the motion capture
system, apart from starting the capture and defining which markers form rigid bodies for the target
and Crazyflie, but it is necessary to initially calibrate the cameras with the following procedure:
1. Ensure there are no markers or reflective surfaces in view of the cameras. If there are reflective
surfaces outside of the operating area which cannot be moved or covered, apply an auto-mask to
digitally block these areas in the views of the camera.
39
2. Position the calibration L-tool in the centre of the operating area, where the corner will define
the origin, the long axis will form the x-axis, and the short axis will form the y-axis.
3. Select the 300mm carbon fibre calibration kit under Project Options with a wand-tool length of
300.8mm and begin the calibration in QTM for a time of about 20s to 30s.
4. While the calibration is running, proceed to wave the wand-tool completely around the perimeter,
inside of the operating area, and through different orientations until the calibration is complete.
5. Ensure the results of the calibration are successful, the resulting residuals for each camera are
similar, and the standard deviation for the markers on the calibration tools is low.
6 DATA ANALYSIS AND RESULTS


Before the library can be used the link drivers have to he initialized. This
will search for available drivers and instantiate them.


    if len(available) > 0:
        le = LoggingExample(available[0][0])
    else:
        print('No Crazyflies found, cannot run example')


[ __ ](https://github.com/bitcraze) [ __ ](https://fosstodon.org/@bitcraze) [
__ ](https://twitter.com/bitcraze_se) [ __ ](https://instagram.com/bitcraze) [
__ ](https://www.linkedin.com/company/bitcraze-ab/) [ __
](https://www.facebook.com/bitcraze) [ __ ](/feed/)


  * The maximum length for a log packet is 26 bytes. This, for for example, allows to log 6 floats and one uint16_t (6*4 + 2 bytes) in a single packet.
  * The minimum period of a for a log configuration is multiples of 10ms


##  Parameters


V2 expansion deck, Bitcraze Crazyradio PA, Raspberry Pi Zero W 1.1, and Raspberry Pi Camera
Module 2.1 are open-source, the electronic schematics for the hardware are freely available and have
been compiled with these other online resources if reference is desired.
B CONTROL SCRIPTS
Firstly, the installation of the required packages is as follows for Raspbian (and other similar Debianbased linux distributions with the Apt 1.8.2 package manager) before utilising the Crazyflie Python
API library, Crazyflie graphical client, and OpenCV Python API library. (The Raspberry Pi must be
booted with the Crazyradio inserted otherwise it will not be detected correctly).
sudo apt install python3
sudo apt install python3-pip
sudo apt install python3-libusb1
sudo apt install python3-pyqt5
pip3 install numpy # sudo apt install python3-numpy
pip3 install opencv-python # sudo apt install python3-opencv
pip3 install cflib
pip3 install PyUSB
pip3 install appdirs
pip3 install PyYAML
The subsequent Python script with OpenCV was used to evaluate the real-time performance for image
processing by comparing resolutions of 160px by 120px, 320px by 240px, and 640px by 480px with
both grayscale and colour processing. The presented form of the code is for the maximum grayscale
processing - for the other processing tests, the relevant lines marked with ## must be uncommented.
As discussed, a resolution around 160px by 120px was only suitable with the Raspberry Pi.
1 # **********************************************************************************
2 # Date: 2019-09-30. Author: Edward Rycroft. Description: This program is used to
> evaluate the grayscale and colour image processing at different resolutions.
3 # **********************************************************************************
4
5 # ----------------------------------------------------------------------------------
6 # Import Files
64
7 # ----------------------------------------------------------------------------------
8
9 # Import the necessary libraries (note the changes of names).
10 import time
11 import numpy as np
12 import cv2 as cv
13
14 # ----------------------------------------------------------------------------------
15 # Target Detection Functions
16 # ----------------------------------------------------------------------------------


from a user. This is a difficult challenge as it requires the extraction of three-dimensional information from a two-dimensional vantage point. Moreover, a significant focus of published research into
computer vision is only involved with isolating or segmenting targets for detection, while the more
specific research into end-point open-loop control has been to integrate flight control and indirect
computer vision techniques using motion capture systems with multiple cameras triangulating position, which can be expensive and difficult to access, and utilises systems with excess computational
effort for image processing without taking into account the possibility of substantial limits on the
available computational effort [1, 8, 9]. This is discussed by Mahony et al. [3] using a Vicon motion
capture system requiring considerable resources for state estimation of an Ascending Technologies
2
quadrotor; and Dunkley [2] and Mack et al. [10] utilised a Microsoft Kinect as an economic alternative to detect and control a Bitcraze Crazyflie quadrotor, but this features two cameras and a depth
sensor while still accessing excess computational effort on their ground control laptops - unlike most
of the end-point closed-loop control studies, these studies do not consider tracking moving targets.
Furthermore, a critical disadvantage of end-point open-loop control is the requirement for the external
cameras to already be set up, where this would present an obstacle if operating in an unfamiliar
environment since the setting up of multiple cameras may be tedious or inapplicable, but the use of
a single camera would be much more efficient. Thus, there is a need to investigate the detection and
tracking of a moving target using end-point open-loop control with only a single camera, which will
reinforce the success of published research with fundamental similarities as a consequence.
1.3 PROBLEM STATEMENT
It is necessary to develop and assess the effectiveness of a control system using end-point open-loop
visual servoing with a single camera to autonomously perform real-time moving target tracking. The
camera is to be fixed in the surroundings and the tests should be initially performed in a controlled
indoor environment. The detection of the target will be carried out using computer vision through
various techniques, but this needs to be processed using hardware with limited or marginal computational effort which will likely require a self-derived algorithm utilising lightweight image processing.
The tracking of the target will be performed such that a quadrotor effectively follows or mirrors the
movement of the target in a manner where the position of the target can be seen to be mapped directly
by the position of the quadrotor. This tracking should focus on the three degrees of translational freedom, but it may be possible to also track the orientation of the target with regards to yaw or rotation in
the horizontal plane, depending on the arrangement. The relative distance error between the position
of the target and position of the quadrotor should be minimised within an acceptable range for successful implementation. The effectiveness can then be measured based on the lag time, robustness,
relative distance fluctuations, and ability to track the target at varying speeds. For supplement, this
should be achieved using mostly inexpensive and open-source hardware and software.
Thus, a research question is proposed: is it possible to implement end-point open-loop visual servoing
in a three-dimensional space using a fixed single camera for moving target tracking with limited
computational effort for image processing and a quadrotor following the movements of the target?
2 LITERATURE REVIEW
To establish a basis from which to progress, existing research and resources for quadrotors and computer vision with regards to visual servoing for target tracking needs to be reviewed and documented.
It is also essential to understand certain theory and ideas behind the apparatus and methodology which
will be used, such that these concepts can be identified if they do arise even though they are not expected to be direct factors during the tests and in the results. Although many of the concepts discussed
3
are generally applicable to visual servoing through other means as well, it should be noted that the
information will be presented primarily in relation to quadrotors and target tracking.


    * [ Positioning Systems Overview ](/documentation/system/positioning/ "Positioning Systems Overview")
    * [ Loco Positioning deck ](/products/loco-positioning-deck/ "Loco Positioning deck")
    * [ Loco Positioning node ](/products/loco-positioning-node/ "Loco Positioning node")
    * [ Lighthouse positioning deck ](/products/lighthouse-positioning-deck/ "Lighthouse positioning deck")
    * * * *


1
2
3
W H
Orientation
Desired Coordinate System
0o
 = Starting Direction
90o
 = Clockwise
90o
 = Counter-Clockwise
Figure 30: Explanation of the initial yaw orientation (left) and desired coordinate system (right). (It
should be emphasised that this is only the coordinate system for the Crazyflie, and the target will use
a conventional coordinate system between 0o
and 180o
as presented in Figure 32).
Subsequently, the sequence in which setpoints will be generated for target tracking is summarised:
1. Following the target detection, the found centroid of the target contour will be transformed into
the desired coordinate system with the centre of the camera view as the origin.
2. The pinhole camera model will be used to convert the found area and transformed centroid of
the target contour into position coordinates for the desired altitude and position of the Crazyflie.
3. The desired altitude and position of the Crazyflie will then be sent to the Crazyflie as a setpoint
for the Crazyflie to move to this location, relative to its initial location as the origin.
4. This process repeats with each frame captured by the camera for as long as the target is moving.
5.5 CONTROL AND COMMUNICATION
To clearly describe the overall processes of target tracking, the flow diagram in Figure 31 is developed.
In this diagram, the general idea for performing target tracking and open-loop control of the Crazyflie
is depicted which is fully implemented in the final control script presented in Appendix B.
36
Import the necessary
Crazyflie and
OpenCV libraries.
Assign the resolution
for use in OpenCV.
Init. the parameters
for the Crazyradio
and Crazyflie.
Must the
captured output be


(32)
Where m, arbitrary virtual image distance, px; f , focal length, px; n, arbitrary actual distance, m; z,
altitude, m; m˙ , arbitrary virtual image velocity, px/s; and n˙, arbitrary, actual velocity, m/s.
For the yaw orientation test, the relevant results for each trial are divided into the angle of the yaw
orientation for the target and Crazyflie, deviation between the relative angle of the yaw orientation for
the target and Crazyflie as determined with Equation 33, and altitude of the Crazyflie. These factors
are plotted against time and analysed in Figure 48 and Figure 49. A lag between the Crazyflie and
target was still observed, although the average values were particularly less prominent. As outlined
51
Table 3: Outline of the lag and position deviation of the Crazyflie in the x-y-plane for the translation
tests, with comparison for the deviation after adjustment accounting for the average lag.
Lag Time [s] Original Dxy [mm] Adjusted Dxy [mm]
Total Time [s]
Minimum
Average
Maximum
Minimum
Average
Maximum
Minimum
Average
Maximum
Rectilinear
Trial 1 116.1 0.18 0.96 1.60 3.82 81.2 194 9.50 58.9 132
Trial 2 80.60 0.46 1.02 1.79 2.24 95.9 269 2.94 56.0 136
Circular
Trial 1 95.15 0.39 0.78 1.23 2.06 94.6 194 8.77 67.2 138
Trial 2 91.88 0.22 0.86 1.80 0.659 80.2 241 0.482 63.8 135
Combined
Trial 1 64.65 0.19 0.74 2.18 8.02 73.3 133 1.15 39.0 129
Trial 2 62.29 0.31 0.67 2.61 10.2 75.1 145 2.14 39.3 117
Overall Averages - 0.292 0.838 1.87 4.50 83.4 196 4.16 54.0 131
in Table 4, this lag results in an angular deviation between the yaw orientation of the target and
Crazyflie (for discussion, the minimum and maximum values are more relevant since the direction
of the deviation is included). The position deviation in the translation tests and angular deviation in
these yaw orientation tests while compensating for the average lag are seen in Figure 50.
Dψ = ψt − ψq (33)
Where Dψ, yaw orientation deviation, o
; ψt
, target yaw angle, o


The library doesn't continuously update the parameter values, this should only
be done once after connecting. After each write to a parameter the firmware
will send back the updated value and this will be forwarded to callbacks
registered for reading this parameter.


#  How to use the  cfclient.utils.logconfigreader.LogConfig  function in [
cfclient ](/advisor/python/cfclient)


By implementing the methodology, the appropriate data is to be obtained in a primitive form. This
data can then be processed with an analysis for meaningful results. Ultimately, this allows for the
experimental application to be judged against the objectives to form conclusions. There are also
minor justifications submitted for certain decisions, but these are further discussed in Section 7.
6.1 CAMERA OBSERVATIONS
Firstly, the fish-eye distortion is evaluated using the template similar to that on a chessboard. From
a photograph of this pattern shown in Figure 33, it is seen that the distortion present in the image
from the Pi Camera is inconsequential with insignificant distortion towards the edges. Thus, it can
be initially assumed that the pinhole camera model is valid, especially near the central region of the
image, and it is not necessary to implement compensation for distortion.
From Figure 33 and monitoring while the target was moving, it was evident that there was occasionally slight blurring of the captured image with the Pi Camera being unable to auto-focus. However,
due to the methods for image processing, this is not concerning as the effects have no meaningful
impact on the target detection since adequate noise reduction is applied.
Fish-Eye Test Template
Negligible Fish-Eye Distortion
Figure 33: Photograph and evaluation of the fish-eye distortion in the Pi Camera. (The image was
aligned with the pattern as best as manually possible but this may not be absolutely perfect).
40
6.2 IMAGE PROCESSING
Using the Raspberry Pi and Pi Camera, the collected data from the preliminary image processing
to determine the most suitable resolution for acceptable real-time performance is shown in Table 2,
and example frames illustrating the available detail at each resolution with grayscale and colour processing are seen in Figure 34. Based on the desired criteria, it is clear that a resolution of 160px
by 120px and grayscale processing attains the best performance with an average frame rate around
30.1fr/s and time of 33ms between frames, although colour processing would still be sufficient if
desired. The higher resolutions result in unacceptable frame rates and a noticeable lag was also
observed between the displayed frame and real-time arrangement. This enables setpoints to be generated at about 30.1Hz which should allow for smooth flight without instability - although this may
be slightly decreased due to the lightweight but noteworthy processing to control the Crazyflie.
Table 2: Evaluation of the most suitable resolution for acceptable real-time performance, comparing
various levels of no image processing, grayscale processing, and colour processing with resolutions
of 160px by 120px (left), 320px by 240px (middle), and 640px by 480px (right).
1. 160px By 120px
Record Time [s]
Total Frames [fr]
Average FPS [fr/s]
Average SPF [s/fr]
A
18.9 588 31.1 0.032
22.9 707 30.9 0.032
24.7 772 31.2 0.032
B


2018. URL: https://www.ensta-bretagne.fr/jaulin/rapport2018_poirier.pdf.
[5] M. G. Popova. Visual Servoing For A Quadrotor UAV In Target Tracking. University of Toronto,
Nov. 2015. URL: https://tspace.library.utoronto.ca/handle/1807/70520.
[6] C. Karlsson. Vision Based Control And Landing Of Micro Aerial Vehicles. Karlstad University,
June 2019. URL: http://urn.kb.se/resolve?urn=urn:nbn:se:kau:diva-73225.
[7] A. Kendall, N. Salvapantula and K. Stol. ‘On-Board Object Tracking Control Of A Quadcopter With Monocular Vision’. In: International Conference on Unmanned Aircraft Systems
(ICUAS), Institute of Electrical and Electronics Engineers (IEEE) (Apr. 2014), pp. 404–411.
DOI: 10.1109/ICUAS.2014.6842280. URL: https://ieeexplore.ieee.org/document
/6842280 or https://alexgkendall.com/media/papers/ICUAS_Kendall_2014.pdf.
[8] J. Forster. ¨ System Identification Of The Crazyflie 2.0 Nano Quadrocopter. Swiss Federal Institute Of Technology, Zurich, Aug. 2015. DOI: 10.3929/ethz-b-000214143. URL: https
://www.research-collection.ethz.ch/handle/20.500.11850/214143.
[9] L. Adrjanowicz, M. Kubanek and J. Bobulski. ‘Single Camera Based Location Estimation
With Dissimilarity Measurement’. In: 2013 6th International Conference On Human System
Interactions (HSI) (June 2013), pp. 241–246. DOI: 10 . 1109 / HSI . 2013 . 6577830. URL:
https://ieeexplore.ieee.org/document/6577830.
[10] B. Mack, C. Noe and T. Rice. Formation Control Of Crazyflies. Bradley University, Peoria,
May 2018. URL: http://cegt201.bradley.edu/projects/proj2018/crazy/resourc
es/bu_crazyflie_final_report.pdf and http://cegt201.bradley.edu/projects
/proj2018/crazy/deliverables/deliverables.html.
[11] L. O. G. Lobo E Silva. Attitude Control Of A Quadrotor. Ministerio Da Defesa Instituto Militar
De Engenharia (IME), Rio de Janeiro, Sept. 2016. URL: http://mecatrime.org/wp-cont
ent/uploads/2017/05/Luis_mestrado_dissertacao_final.pdf.
61
[12] C.-K. Liang, L.-W. Chang and H. H. Chen. ‘Analysis And Compensation Of Rolling Shutter
Effect’. In: Institute of Electrical and Electronics Engineers (IEEE) Transactions On Image
Processing Vol. 17. (8) (Aug. 2008), pp. 1323–1330. DOI: 10.1109/TIP.2008.925384.
URL: https://ieeexplore.ieee.org/document/4549748.
[13] OpenCV and Doxygen. OpenCV 4.1.1 Documentation Modules - Python Tutorials. Open
Source Computer Vision. Online. 26th July 2019. URL: https : / / docs . opencv . org / 4
.1.1/d6/d00/tutorial_py_root.html (visited 18th Sept. 2019).
[14] K. V. Patil. Object Tracking Using A Quadcopter. Indian Institude of Technology (IIT), Bombay, July 2015. URL: https://www.ee.iitb.ac.in/student/~kalpesh.patil/mater
ial/navstik_report.pdf.
[15] J. Pedro. MECN4029 - Mechatronics II - Lecture Series And Notes. University of The Witwatersrand, Johannesburg, 2019.
[16] W. Honig and N. Ayanian. ‘Flying Multiple UAVs Using ROS’. In: ¨ Robot Operating System
(ROS): The Complete Reference. Ed. by A. Koubaa. Vol. 2. Springer International Publishing,
Cham, May 2017, pp. 83–118. ISBN: 978-3-319-54927-9. DOI: 10.1007/978-3-319-5492
7-9_3. URL: https://link.springer.com/chapter/10.1007%2F978-3-319-54927-
9_3 or http://act.usc.edu/publications/Hoenig_Springer_ROS2017.pdf.
[17] K. Richardsson et al. Crazyflie 2.1. Bitcraze. Online. 2019. URL: https://store.bitcraz
e.io/products/crazyflie-2-1 (visited 16th Sept. 2019).


reference system with an extended Kalman filter to provide a fairly reliable estimation of the current
state of the quadrotor with regards to position, velocity, angular arrangement, and stability [4, 16].
19
Top View Bottom View
56.56mm 56.56mm
56.56mm
Motor Port
Motor Port
Motor Port Coordinate
Systems
Motor Port
Battery
Wires
LED M4 LED M1
LED M3 LED M2
Forward
Indicator Switch
Pin Holes Pin Holes
Radio Controller
Processor
Controller
Forward
Indicator
Pin Holes
Pin Holes
Battery
Wires
Figure 18: Schematics (top) and photographs (bottom) showing the top and bottom views of the
Bitcraze Crazyflie 2.1 control board with the arrangement of the various sensors [18].
The Crazyflie is capable of a maximum speed up to 1.41m/s, although oscillations may be introduced
if the Crazyflie needs to stop suddenly at a specific location. To achieve steady flight control and
maintain its orientation, the control board implements internal cascading PID controllers for attitude
control of position and velocity. In the cascade, there is an inner loop operating at 500Hz to control
the thrust and angular velocity of roll, pitch, and yaw, and there is an outer loop operating at 250Hz
to control the roll, pitch, and yaw angles for altitude and position control with stabilisation [2, 6, 16].
These controllers are conventionally described by Equation 13 and Equation 14, and have been tuned
with default values based on the common construction of the Crazyflie for stable and agile flight.
The on-board sensors are sufficient to stabilise the orientation of the Crazyflie, but there will be a
large uncertainty in position - in other words, it is possible for the on-board gyroscope and accelerometer to maintain the orientation and the on-board barometer could be used to estimate the altitude
relative to sea level with Equation 15 based on pressure and temperature measurements, but this is


##  Utilities


        crazyflie = Crazyflie()
        crazyflie.connected.add_callback(crazyflie_connected)
        crazyflie.open_link("radio://0/10/2M")


207
208 # E: Maximum colour processing with complete video capture.
209 ##frame, mode, threshold, morphology = processing_colour (frame)
210 ##frame, contours, centroid_x, centroid_y = target_detection (frame, morphology)
211 ##record_maximum (frame, mode, threshold, morphology, record, contours)
212
213 # Look for the designated key to terminate the capture.
214 key = cv.waitKey (1)
215 if key == ord ("Q"):
216 active = False
217
218 time_end = time.time ()
219
220 # ----------------------------------------------------------------------------------
69
221 # Finishing Commands
222 # ----------------------------------------------------------------------------------
223
224 # Terminate the capture and release the source.
225 print ("Terminating the capture and releasing the source.")
226 source.release ()
227 if record == "Y":
228 print ("The output video is ’Out.avi’ in the current directory.")
229 video.release ()
230 cv.destroyAllWindows ()
231
232 # Review the details of the captured output.
233 if record == "Y":
234 print ("Review of the details of the capturing process:")
235 video = cv.VideoCapture ("Out.avi")
236 time_record = (time_end - time_start)
237 total_frames = int (video.get (cv.CAP_PROP_FRAME_COUNT))
238 print (" Horizontal Resolution:", res_x, "pixels.")
239 print (" Vertical Resolution:", res_y, "pixels.")
240 print (" Total Recording Time:", "{0:.2f}".format (time_record), "seconds.")
241 print (" Total Frames:", total_frames, "frames.")
242 try:
243 fps_avg = total_frames / time_record
244 spf_avg = 1 / fps_avg
245 print (" Average FPS: ", "{0:.2f}".format (fps_avg), "frames per second.")


ADMIN  MOD


angles described by Figure 7 to produce a rotation matrix in Equation 8 [2, 6, 11].
D =




cos(θ) cos(ψ) cos(θ) sin(ψ) − sin(θ)
sin(φ) sin(θ) cos(ψ) − cos(θ) sin(ψ) sin(φ) sin(θ) sin(ψ) + cos(φ) cos(ψ) sin(φ) cos(θ)
cos(φ) sin(θ) cos(φ) + sin(φ) sin(ψ) cos(φ) sin(θ) sin(ψ) − sin(φ) cos(ψ) cos(φ) cos(θ)




(8)
Where θ, pitch rotation, rad or o
; ψ, yaw rotation, rad or o
; and φ, roll rotation, rad or o
.
x1
y1
z Translational 1
Transformation
Rotational
Transformation
z
y
x y
z
x1
y1
z1
x2
y2
z2
x2
y2
z2
x
x, y, z
Figure 7: Demonstration of the conversion between two reference frames with translation (left) and


There's are few limitations that need to be taken into account:


Read more


18 from cflib.crazyflie.syncLogger import SyncLogger
19
20 # --------------------------------------------------------------------------------
21 # Target Detection And Tracking Functions
22 # --------------------------------------------------------------------------------
23
24 # Function to perform grayscale image processing.
25 def processing_gray (frame):
26
27 # Convert the frame to grayscale, apply a threshold or mask with the limit
> tuned for the target, and apply an open morphology transformation.
28 mode = cv.cvtColor (frame, cv.COLOR_BGR2GRAY)
29 #mode = cv.blur (mode, (5, 5))
30 ret, threshold = cv.threshold (mode, 200, 255, cv.THRESH_BINARY)
31 kernel = np.ones ((5, 5), np.uint8)
32 morphology = cv.morphologyEx (threshold, cv.MORPH_OPEN, kernel)
33
34 # Return the relevant variables to store.
35 return frame, mode, threshold, morphology
71
36
37 # Function to perform colour image processing.
38 def processing_colour (frame):
39
40 # Convert the frame to hue-lightness-saturation, apply a threshold or mask with
> the limits tuned for the target, and apply an open morphology transformation.
41 mode = cv.cvtColor (frame, cv.COLOR_BGR2HLS)
42 #mode = cv.blur (mode, (5, 5))
43 lower_colour = np.array ([150, 40, 40])
44 upper_colour = np.array ([210, 250, 250])
45 threshold = cv.inRange (mode, lower_colour, upper_colour)
46 kernel = np.ones ((5, 5), np.uint8)
47 morphology = cv.morphologyEx (threshold, cv.MORPH_OPEN, kernel)
48
49 # Return the relevant variables to store.
50 return frame, mode, threshold, morphology
51
52 # Function to detect the centroid and area of the target.
53 def target_detection (frame, morphology, time_start, res_x, res_y):
54


The ` PositionHlCommander ` is intended to simplify basic autonomous flight,
where all the high level commands exist inside the Crazyflie firmware. The
Crazyflie takes off when entering the âwithâ section, and lands when
exiting. It has functions for basic movements that are blocking until the
motion is finished.


###  Parameters


[ Full package analysis ](/advisor/python/cfclient)


        add_callback(cb)
            """ Register cb as a new callback. Will not register duplicates. """

        remove_callback(cb)
            """ Un-register cb from the callbacks """

        call(*args)
            """ Call the callbacks registered with the arguments args """


    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


Change
Jitter
Deviation
Figure 42: Relevant results against time throughout the first trial of the rectilinear motion test.
When the altitude was being changed in the rectilinear and circular motion tests, the Crazyflie jittered
irregularly in the latitude and longitude positions due to the manual adjustment of the camera, where
the camera could not be kept at a constant position during this adjustment. However, once the succeeding altitude was reached, the Crazyflie was able to continue to operate without a distinct overshoot or
any perceivable repercussions. There was also a slight lag throughout the tests between the actions
48
Deviation
Overshoot
First
Average
Second
Average
Average
Min.
Max.
Altitude
Change
Jitter
Altitude
Change
Jitter
Figure 43: Relevant results against time throughout the second trial of the rectilinear motion test.
Max. Overshoot
Min.
First
Average
Second
Average
Average
Altitude
Change
Jitter
Altitude
Change
Jitter
Deviation
Figure 44: Relevant results against time throughout the first trial of the circular motion test.


![](/advisor/images/snyk-icon-licence.svg) GPL-2.0


I am trying to get the battery percentage and voltage level from my crazyflie
drone using


Visual Serviong
Image-Based
Visual Serviong
Figure 3: Comparison between the basic methods of position-based visual servoing (top) and imagebased visual servoing for an image - this process is then repeated for each frame in a sequence.
4
2.2 QUADROTOR DYNAMICS
As briefly mentioned, a quadrotor is a rotorcraft with four rotors which have fixed pitches and are
used to create motion by varying the thrust generated at each rotor [2]. The rotors usually consist of
propellers or blades in the form of aerofoils which are mounted on high-speed direct current (DC) motors, while the other parts of a typical quadrotor include a battery as the power source, various sensors
to estimate real-time position or velocity, cross frame holding the parts, and flight controller for stabilisation [2]. The very basic sensors include an inertial measurement unit, where a gyroscope stabilises
rotational motion and an accelerometer detects the current orientation - although these sensors alone
may lead to cumulative errors over time which will result in drifting with an ever-increasing difference between the estimated state and actual state [2]. More advanced and accurate sensors include
on-board ultrasonic or laser range finders to measure distances, GPS for precise location, barometers
to measure air pressure changes with altitude, magnetometers to determine which direction is north,
and monocular or stereo camera for measurements relative to the environment being observed [2].
With these parts, a quadrotor is able to vertically take-off and land with exceptional abilities to hover
at a fixed position and simultaneously manoeuvre vertically, latitudinally, and longitudinally.
With regards to the motion of the quadrotor, there are three degrees of freedom for translational displacement, which include forward or backward, left or right, and up or down; and three degrees of
freedom for rotational displacement, which include roll, pitch, and yaw. These motions can be illustrated on a conventional coordinate system relative to the quadrotor, as shown in Figure 4, where
translation along the x-axis, y-axis, and z-axis correspond to the translation displacements respectively
and rotation about the x-axis, y-axis, and z-axis correspond to the rotational displacements respectively. Thus, there is a total of six degrees of freedom for the quadrotor.
Yaw Rotation
Up / Down
Roll Rotation
Forward /
Backward
Pitch Rotation
Left / Right
x
z
y
Yaw Rotation
Up / Down
Roll Rotation
Forward /
Backward
Pitch Rotation
Left / Right
x
z


    * [ AI deck 1.1 ](/products/ai-deck/ "AI deck 1.1")
    * [ LED-ring deck ](/products/led-ring-deck/ "LED-ring deck")
    * [ Qi 1.2 charger deck ](/products/qi-1_2-charger-deck/ "Qi 1.2 charger deck")
    * [ Buzzer deck ](/products/buzzer-deck/ "Buzzer deck")
    * [ BigQuad deck ](/products/bigquad-deck/ "BigQuad deck")
    * [ Micro SD card deck ](/products/micro-sd-card-deck/ "Micro SD card deck")
    * [ Prototyping deck ](/products/prototyping-deck/ "Prototyping deck")
    * [ Breakout deck ](/products/breakout-deck/ "Breakout deck")
    * [ Z-ranger deck v2 ](/products/z-ranger-deck-v2/ "Z-ranger deck v2")
    * [ Flow deck v2 ](/products/flow-deck-v2/ "Flow deck v2")
    * [ Multi-ranger deck ](/products/multi-ranger-deck/ "Multi-ranger deck")
    * [ Active marker deck ](/products/active-marker-deck/ "Active marker deck")
    * [ Motion capture marker deck ](/products/motion-capture-marker-deck/ "Motion capture marker deck")
    * * * *


The serial driver is disabled by default and has to be enabled to be used.
Enable it in the call to ` init_drivers() ` .


The parameter reading is done using callbacks. When a parameter is updated
from the host (using the code above) the parameter will be read back by the
library and this will trigger the callbacks. Parameter callbacks can be added
at any time (you don't have to be connected to a Crazyflie).


The ` MotionCommander ` is using velocity set points and does not have a
global coordinate system, all positions are relative. It is mainly intended to
be used with a Flow deck.


17
18 # Function to perform grayscale image processing.
19 def processing_gray (frame):
20
21 # Convert the frame to grayscale, apply a threshold or mask with the limit
> tuned for the target, and apply an open morphology transformation.
22 mode = cv.cvtColor (frame, cv.COLOR_BGR2GRAY)
23 #mode = cv.blur (mode, (5, 5))
24 ret, threshold = cv.threshold (mode, 150, 255, cv.THRESH_BINARY)
25 kernel = np.ones ((5, 5), np.uint8)
26 morphology = cv.morphologyEx (threshold, cv.MORPH_OPEN, kernel)
27
28 # Return the relevant variables to store.
29 return frame, mode, threshold, morphology
30
31 # Function to perform colour image processing.
32 def processing_colour (frame):
33
34 # Convert the frame to hue-lightness-saturation, apply a threshold or mask with
> the limits tuned for the target, and apply an open morphology transformation.
35 mode = cv.cvtColor (frame, cv.COLOR_BGR2HLS)
36 #mode = cv.blur (mode, (5, 5))
37 lower_colour = np.array ([150, 40, 40])
38 upper_colour = np.array ([210, 250, 250])
39 threshold = cv.inRange (mode, lower_colour, upper_colour)
40 kernel = np.ones ((5, 5), np.uint8)
41 morphology = cv.morphologyEx (threshold, cv.MORPH_OPEN, kernel)
42
43 # Return the relevant variables to store.
44 return frame, mode, threshold, morphology
45
46 # Function to detect the centroid of the target.
47 def target_detection (frame, processed):
48
65
49 # Find and identify the contours within the current frame.
50 image, contours, hierarchy = cv.findContours (threshold, cv.RETR_TREE,
> cv.CHAIN_APPROX_SIMPLE) # This line should be used for OpenCV Python 3.X.
51 #contours, hierarchy = cv.findContours (processed, cv.RETR_TREE,
> cv.CHAIN_APPROX_SIMPLE) # This line should be used for OpenCV Python 4.X.


  * [ Kim Kardashian  ](https://reddit.com/t/kim_kardashian/)
  * [ Doja Cat  ](https://reddit.com/t/doja_cat/)
  * [ Iggy Azalea  ](https://reddit.com/t/iggy_azalea/)
  * [ Anya Taylor-Joy  ](https://reddit.com/t/anya_taylorjoy/)
  * [ Jamie Lee Curtis  ](https://reddit.com/t/jamie_lee_curtis/)
  * [ Natalie Portman  ](https://reddit.com/t/natalie_portman/)
  * [ Henry Cavill  ](https://reddit.com/t/henry_cavill/)
  * [ Millie Bobby Brown  ](https://reddit.com/t/millie_bobby_brown/)
  * [ Tom Hiddleston  ](https://reddit.com/t/tom_hiddleston/)
  * [ Keanu Reeves  ](https://reddit.com/t/keanu_reeves/)


The parameter framework is used to read and set parameters. This functionality
should be used when:


If you are interested in more details look in the PyDoc in the code or:


The ` SyncCrazyflie ` class wraps a Crazyflie instance and mainly simplifies
connect/disconnect.


###  Variable and parameter names


logconf.add_variable('stateEstimate.z', 'float')


y
M1 M2
M4 M3
M1
M2
M3
M4
Figure 4: Coordinate system relative to the quadrotor showing the three translational and three rotational displacements. The quadrotor may operate in a plus-mode (+) (left) or cross-mode (×) (right).
5
The quadrotor is then able to generate these degrees of freedom by varying the thrust generated by
each of the four rotors, as seen in Figure 5 and Figure 6, such that a simple mechanical design can be
used with a complex controller design. With regards to forces, each rotor produces an upwards thrust,
torque about the centre of rotation, and drag opposite to the motion of the quadrotor. To move up or
down along the z-axis, the thrust simply needs to be increased or decreased respectively. To move
forward or backward along the x-axis, the thrust needs to be maintained while pitching clockwise
or counter-clockwise about the y-axis respectively. To move left or right along the y-axis, the thrust
needs to be maintained while rolling counter-clockwise or clockwise about the x-axis respectively.
The roll and pitch control will depend on whether the quadrotor is using a plus-mode (+) or crossmode (×), but the manner of operation is identical where a resultant torque is produced to induce
rolling or pitching. Considering a plus-mode, the roll with rotation about the x-axis is controlled by
the left and right rotors, where the left rotor thrust needs to be greater than the right rotor thrust to
roll clockwise and the right rotor thrust needs to be greater than the left rotor thrust to roll counterclockwise; and the pitch with rotation about the y-axis is controlled by the front and rear rotors, where
the rear rotor thrust needs to be greater than the front rotor thrust to pitch clockwise and the front rotor
thrust needs to be greater than the rear rotor thrust to pitch counter-clockwise (clockwise and counterclockwise directions are taken relative to the perspective of the quadrotor along the x-axis for rolling
and y-axis for pitching). For the cross-mode, the side selection of rotors for rolling and pitching is
identical, but the rotors will be used in pairs without intermediate rotors.
Finally, yawing with rotation about the z-axis is created using the resulting torque produced from the
rotors spinning against the air, where the direction of this torque is in the opposite direction to the
direction of the combined angular velocity from the rotors - for flight without yawing, this effect is
Medium Speed
Stationary Hover Move Up Move Down
Pitch Forward Pitch Backward Roll Left Roll Right Yaw Left
Yaw Right
Low Speed
Forward Direction
Left Direction
High Speed
M1
M2
M3
M4


###  SyncLogger


This command will set the attitude controller setpoint for the next 500ms.
After 500ms without next setpoint, the Crazyflie will apply a setpoint with
the same thrust but with roll/pitch/yawrate = 0, this will make the Crazyflie
stop accelerating. After 2 seconds without new setpoint the Crazyflie will cut
power from the motors.


        cflib.crtp.init_drivers()
        available = cflib.crtp.scan_interfaces()
        for i in available:
            print "Interface with URI [%s] found and name/comment [%s]" % (i[0], i[1])


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


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


        with SyncCrazyflie(uri) as scf:
            # A Crazyflie instance is created and is now connected. If the connection fails,
            # an exception is raised.

            # The underlying crazyflie object can be accessed through the cf member
            scf.cf.param.set_value('kalman.resetEstimation', '1')

            # Do useful stuff
            # When leaving the "with" section, the connection is automatically closed


    # The Crazyflie lib doesn't contain anything to keep the application alive,
    # so this is where your application should do something. In our case we
    # are just waiting until we are disconnected.
    while le.is_connected:
        time.sleep(1)


####  Security


##  Connection- and link-callbacks


The ` MotionCommander ` class is intended to simplify basic autonomous flight,
where the motion control is done from the host computer. The Crazyflie takes
off and makes when entering the âwithâ section, and lands when exiting. It
has functions for basic movements that are blocking until the motion is
finished.


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


#  incorrect battery voltage level & battery percentage when motors are on


If this is not the case then the parameter framework should be used instead.


Currently we have _radio_ , _serial_ , _usb_ , _debug_ , _udp_ interfaces.
Here are some examples:


It is also possible to get the current value of a parameter (when connected)
without using a callback


quality and reliable battery must be used
from the Crazyflie suppliers.
Ergonomic The thrust of the Crazyflie may pick up
dust, which may be breathed in by or enter
the eyes of the operator or personnel in
the operating vicinity.
Minor Rare 3 Elimination It should be ensured that the motion
capture facilities and operating vicinity
are sufficiently clean and dust-free.
Ergonomic To place the target and Crazyflie on the
floor, the operator is required to bend
down multiple times
Minor Rare 3 Procedure The operator must correctly bend with
their knees, instead of their back, to
avoid straining muscles.
Ergonomic The black mats in the motion capture
facilities form an uneven surface with the
ground, which lead to tripping.
Minor Rare 3 Procedure The operator must take care when
moving around the motion capture
facilities to avoid tripping.
Signed: Edward Rycroft Date: 2019/10/28
Quadrotor Visual Servoing For Moving Target Tracking
North West Engineering Laboratory, Robotics Lab
83
Figure 51: Standard operating procedure in the motion capture facilities for quadrotor experiments.
E BIGQUAD DEVELOPMENT
To complement the end-point open-loop control, an investigation into end-point closed-loop control
was initially performed using a larger quadrotor, on-board camera with the Pi Camera, and on-board
processing with the Raspberry Pi. However, it was not possible for the quadrotor to fly safely due
to the risk of damaging the exposed LiPo battery, so focus was shifted to more in-depth end-point
open-loop control only. The partial development is included as a reference for future progress.
E.1 END-POINT CLOSED-LOOP CONTROL
For end-point closed-loop control, the basic arrangement for location estimation is essentially the
same as for end-point open-loop control, except the camera would be mounted to the quadrotor instead
of being fixed in the surroundings. This is illustrated in Figure 52, with similarity to Figure 13.
It might be necessary to investigate compensation to stabilize the on-board camera while rolling and
pitching, as seen in Figure 53, where the field of view becomes inaccurately distorted with incorrect
measurements of the position of the target. Compensation could be implemented using mechanical
compensation, where the on-board camera is mounted with a two degree-of-freedom gimbal which


[ Sign Up ](https://app.snyk.io/login/?cta=sign-up&loc=nav&page=undefined)


####  Company


Z t
0
e(t) dt + KD
de(t)
dt
(13)
f(t) ≈ KPe(t) + KI
Xt
τ=0
e(τ) + KD
e(t) − e(t − ∆t)
∆t
(14)
Where e(t), error signal; r(t), reference signal; b(t), feedback signal; f(t), control signal; t, time, s;
KP, proportional gain; KI
, integral gain; KD, derivative gain; and τ, incremental time placeholder, s.
A quadrotor is a multiple-input multiple-output (MIMO) non-linear system with a high degree of
coupling between the input and output variables, multiple aerodynamic effects which are difficult to
measure or model precisely, and a time-varying nature as the battery is discharged and the voltage
decreases [11]. Also, from the perspective of control systems, quadrotors are relatively complex to
stabilise due to noise in sensors, model uncertainty, and other external disturbances [11]. Thus, it is a
challenge to design a flight controller for a quadrotor and it is usually required for cascading or nested
loops of multiple PID controllers directly monitoring and calculating the roll, pitch, yaw, and thrust
with required operation at frequencies above 100Hz as a minimum criteria.
Without external sensors, it has also been shown that it is practically impossible to obtain stable
control of a quadrotor, outside of simulations [11]. For unreliable control, the very basic sensors
through an inertial measurement unit, including a gyroscope and accelerometer, are sufficient but
the measurements from these sensors are usually noisy and inaccurate with large fluctuations and
uncertainties. As a result, these basic sensors will not be able to completely compensate for drift
from factors interfering with stability like wind and unbalanced weight distribution [2, 11]. For
reliable control, it is required for a more advanced sensor which will be able to provide more accurate
measurements of the state of the quadrotor, such as the mentioned sensors in the form of an external
motion capture system, optical flow sensor, ultrasonic or laser range finder, GPS, or on-board camera.
3 OBJECTIVES
The primary objectives are defined as follows, with relation to the available apparatus in Section 4:
• Validate the accuracy of the pinhole camera model, with compensation for major distortions if
required by the camera. (This will be done with a Raspberry Pi Camera Module 2.1).
17
• Compare target detection through grayscale and colour processing on low-end hardware with
marginal computational effort. (A Raspberry Pi Zero W 1.1 will be used as a prime example).


import cflib.crtp  # noqa
from cflib.crazyflie import Crazyflie
from cflib.crazyflie.log import LogConfig


πv
2/4
= f
r
Axy
Auv
≡ kA−0.5
uv where k = f
p
Axy (16)
z = f
x
u
= f
y
v
−→ z = f
r
xy
uv
= f
r
Axy
Auv
≡ kA−0.5
uv where k = f
p
Axy (17)
∴ z ∝
1
u
and z ∝
1
v
and z
2 ∝
1
Auv
or z ∝
1


off due to the mentioned irregularities. Unfortunately, there was a slight delay in the first trial of the
rectilinear test when manually raising the tripod which contributed to an extended total time, but there
was no meaningful impact on the results. (As mentioned, the exact uncertainty of the motion capture
is not precisely known but it is anticipated to be on the order of millimetres).
Figure 39: Position of the markers in the first (top) and second (bottom) trials of the rectilinear test.
The trials for the yaw orientation tests were also completed fairly successfully. The primary results
are given in Section 6.5.2 with the analysis, since the three-dimensional position of the target and
Crazyflie is mostly irrelevant when considering the yaw orientation, but it was observed that the
Crazyflie would slightly tremor with periods of minor instability as it tried to maintain a fixed position
while only yawing (as expected, the target simply rotated without translational motion).
46
Figure 40: Position of the markers in the first (top) and second (bottom) trials of the circular test.
Figure 41: Position of the markers in the first (top) and second (bottom) trials of the combined test.
6.5.2 RESULTS ANALYSIS
For the translation tests, the relevant results for each trial are divided into the latitude and longitude
position of the target and Crazyflie, magnitude of the deviation between the relative position of the
target and Crazyflie as determined with Equation 31, and altitude of the Crazyflie. These factors are
plotted against time and analysed in Figure 42 to Figure 47 for each of the translation tests.
Dxy =
q
(xt − xq)
2 + (yt − yq)
2
(31)
Where Dxy, latitude and longitude position deviation, m; xt
, target latitude position, m; xq, quadrotor
latitude position, m; yt
, target longitude position, m; and yq, quadrotor longitude position, m.
Overshoot
First
Average
Second
Average
Average
Min.
Max.
Altitude
Change
Jitter
Altitude


* Television


The logging framework is used to enable the "automatic" sending of variable
values at specified intervals to the client. This functionality should be used
when:


r/CrazyFlie  A chip  A close button


361
362 # Set the parameters for control and rest the extended Kalman filter.
363 crazyflie = crazyflie_sync.cf
364 set_initial_position_origin (crazyflie)
365 reset_estimator (crazyflie)
366 #crazyflie.param.set_value ("posCtlPid.xyVelMax", "velocity_max")
367 #crazyflie.param.set_value ("posCtlPid.zVelMax", "velocity_max")
368 #crazyflie.commander.set_client_xmode (True)
369
370 # Load the current frame from the source and process the image. This is not
> for target detection, but acts as a buffer to load the video window.
371 correct, frame = source.read ()
372 frame, mode, threshold, morphology = processing_gray (frame)
373 frame, contours, centroid_x, centroid_y, area = target_detection (frame,
> morphology, time_start, res_x, res_y)
374 monitor_minimum (frame, record)
375 cv.waitKey (200)
376
377 # Record the current time as the start of the test.
79
378 time_start = time.time ()
379
380 # Take off to an altitude of approximately 0.4m.
381 take_off (crazyflie, altitude)
382
383 # Begin capture of the video frames and image processing.
384 print ("Beginning capture of the video frames and image processing.")
385 print ("To terminate the capture, press [Q] in the video window.")
386 print ("Alternatively, press [ctrl+c] in the shell window.")
387 try:
388 while active == True:
389
390 # Load the current frame from the source.
391 correct, frame = source.read ()
392
393 # Minimum grayscale processing with results video capture.
394 frame, mode, threshold, morphology = processing_gray (frame)
395 frame, contours, centroid_x, centroid_y, area = target_detection
> (frame, morphology, time_start, res_x, res_y)
396 ##frame, orientation = target_detection_orientation (frame,


* [ Communities  ](https://www.reddit.com/best/communities/1/)
* [ Best of Reddit  ](https://www.reddit.com/posts/2024/global/)
* [ Topics  ](https://www.reddit.com/topics/a-1/)


        # Called when new logging data arrives
        data_received_cb = Caller()
        # Called when there's an error
        error_cb = Caller()
        # Called when the log configuration is confirmed to be started
        started_cb = Caller()
        # Called when the log configuration is confirmed to be added
        added_cb = Caller()

        add_variable(name, fetch_as=None)
            """Add a new variable to the configuration.

            name - Full name of the variable in the form group.name
            fetch_as - String representation of the type the variable should be
                       fetched as (i.e uint8_t, float, FP16, etc)

            If no fetch_as type is supplied, then the stored type will be used
            (i.e the type of the fetched variable is the same as it's stored in the
            Crazyflie)."""

        start()
            """Start the logging for this entry"""

        stop()
            """Stop the logging for this entry"""

        delete()
            """Delete this entry in the Crazyflie"""


* TOPICS


send_hover_setpoint(self, vx, vy, yawrate, zdistance)


crazyflie.log.add_config([logconf1, logconfig2])


[ ![github](/advisor/images/snyk-icon-github.svg) bitcraze / crazyflie-
clients-python / lib / cfclient / ui / tabs / FlightTab.py  View on Github
![external](/advisor/images/snyk-icon-external.svg)
](https://github.com/bitcraze/crazyflie-clients-
python/blob/0b64640096567992bb6d0820dd1cb47cfe1dbc6a/lib/cfclient/ui/tabs/FlightTab.py#L230)


        add_update_callback(group, name=None, cb=None)
            """
            Add a callback for a specific parameter name or group. If name is not specified then
            all parameters in the group will trigger the callback. This callback will be executed
            when a new value is read from the Crazyflie.
            """

        request_param_update(complete_name)
            """ Request an update of the value for the supplied parameter. """

        set_value(complete_name, value)
            """ Set the value for the supplied parameter. """


Thrust is an integer value ranging from 10001 (next to no power) to 60000
(full power). It corresponds to the mean thrust that will be applied to the
motors. There is a battery compensation algorithm applied to make the thrust
mostly independent of battery voltage. Roll/pitch are in degree and yawrate is
in degree/seconds.


  * float
  * uint8_t and int8_t
  * uint16_t and int16_t
  * uint32_t and int32_t
  * FP16: 16bit version of floating point, allows to pack more variables in one packet at the expense of precision.


[ View all cfclient analysis ](/advisor/python/cfclient)


print('Connecting to %s' % link_uri)


Check the camera is
open and display a
frame to the user.
No
No
Convert the BGR
colour frame into a
HLS colour frame.
Do a binary threshold
with lower and upper
bounds for the colour.
*1
*2
*1Processing Grayscale
*2Processing Grayscale
Colour
Processing
Colour
Processing
Alt. Image Processing Figure 31: High-level flow diagram of the control flow for the moving target detection and tracking
with regards to three degrees of translational freedom and a degree of rotational freedom as yaw
orientation. (The suitable HLS colour bounds for the dark red are (150, 40, 40) and (210, 250, 250)).
For communication between the Crazyflie and Raspberry Pi with the Crazyradio, a radio frequency of
2.480GHz will be used with a data rate of 2MB/s and radio address of 0xE7E7E7E7E8 (change from
the default radio address of 0xE7E7E7E7E7 to avoid interference from other Crazyflies). Because the
control scripts will be running on the Raspberry Pi, a RDP is used to control the Raspberry Pi from
the ground control laptop, such that the control scripts can be executed and terminated when desired.
5.6 TARGET MOTION
Throughout the tracking, the target will remain on the ground and can move in any direction on this
plane at any moment. The target can also be seen to move from a starting point to reach a destination
point along a path which mimics movement according to independent intentions without influence
from the camera or Crazyflie - in other words, the target is unaware of the tracking and will not
Camera Altitude
Increased Manually
Camera View
480mm 780mm
~660mm
~500mm
Camera View
~1050mm


[ ![](/advisor/images/footer-community-banner.svg)
](https://www.devseccon.com/)


        # Called on disconnect, no matter the reason
        disconnected = Caller()
        # Called on unintentional disconnect only
        connection_lost = Caller()
        # Called when the first packet in a new link is received
        link_established = Caller()
        # Called when the user requests a connection
        connection_requested = Caller()
        # Called when the link is established and the TOCs (that are not cached)
        # have been downloaded
        connected = Caller()
        # Called when the the link is established and all data, including parameters have been downloaded
        fully_connected = Caller()
        # Called if establishing of the link fails (i.e times out)
        connection_failed = Caller()
        # Called for every packet received
        packet_received = Caller()
        # Called for every packet sent
        packet_sent = Caller()
        # Called when the link driver updates the link quality measurement
        link_quality_updated = Caller()


##  Sending control setpoints with the commander framework


        logconf = LogConfig(name="Logging", period_in_ms=100)
        logconf.add_variable("group1.name1", "float")
        logconf.add_variable("group1.name2", "uint8_t")
        logconf.add_variable("group2.name1", "int16_t")


Members  Online


© 2023 [ Bitcraze AB ](/) [ ![Bitcraze logo](/images/footerLogo.png) ](/)


    lg.addVariable(LogVariable("motor.m1", "uint32_t"))
            lg.addVariable(LogVariable("motor.m2", "uint32_t"))
            lg.addVariable(LogVariable("motor.m3", "uint32_t"))
            lg.addVariable(LogVariable("motor.m4", "uint32_t"))

            self.log = self.helper.cf.log.create_log_packet(lg)
            if (self.log is not None):
                self.log.dataReceived.add_callback(self._motor_data_signal.emit)
                self.log.error.add_callback(self.loggingError)
                self.log.start()
            else:
                logger.warning("Could not setup logconfiguration after "
                               "connection!")

            # BARO
            lg = LogConfig("Baro", 50)
            lg.addVariable(LogVariable("baro.asl", "float"))
            lg.addVariable(LogVariable("baro.aslLong", "float"))
            lg.addVariable(LogVariable("baro.aslRaw", "float"))
            lg.addVariable(LogVariable("baro.temp", "float"))

            self.log = self.helper.cf.log.create_log_packet(lg)
            if (self.log is not None):
                self.log.dataReceived.add_callback(self._baro_data_signal.emit)
                self.log.error.add_callback(self.loggingError)
                self.log.start()
            else:
                logger.warning("Could not setup logconfiguration after "
                               "connection!")
            # HOVER
            lg = LogConfig("Hover", 50)
            lg.addVariable(LogVariable("hover.target", "float"))


* Crypto


Hi,


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


the slower speed of the target in terms of pixels in the rotation tests compared to the translation tests.
Elaborating, the maximum speed of the target was 0.215m/s in the translation tests which converts to
50.8px/s at an altitude of 480mm or 31.3px/s at an altitude of 780mm; and the maximum speed of
the target was 10o
/s in the rotation tests which converts to 24.8px/s at an altitude of 380mm. Notably,
the speed of the target in both cases is appropriately less than the 1.41m/s maximum speed of the
Crazyflie, so the lag was not influenced by the target moving faster than the Crazyflie is capable.
Due to the lag between the Crazyflie and target, there were substantial deviations in position or yaw
orientation experienced. The maximum position deviation reached 269mm with an average deviation of 83.4mm considering the translation tests, and the minimum and maximum yaw orientation
deviations reached 9.54o
and 9.87o
respectively considering the rotation tests. However, for a fair
conclusion, the deviations in position and yaw orientation should be compared after the lag has been
compensated. As a result, the maximum position deviation is reduced to 138mm with an average deviation of 54.0mm, and the minimum and maximum yaw orientation deviations are also diminished
considerably to 4.76o
and 4.46o
respectively. While viewing the plots of the position of the target
and Crazyflie in Figure 42 to Figure 49 for subsequent trials, it is also evident that there is repeatable
performance from the control script with consistent performance across each of the tests.
57
With regards to altitude, the Crazyflie maintained average altitudes of 373mm, 496mm, 558mm, and
787mm, for the expected altitudes of 380mm, 480mm, 580mm, and 780mm respectively (although
the expected altitudes were not measured during operation). During each of the tests, the Crazyflie
performed well in sustaining these average altitude with minor variances, where the typical minimum
bound was only as low as 3.75% below the average value and the typical maximum bound was only
as high as 3.98% above the average value based on an average of actual percentage differences.
7.3 OTHER FINDINGS AND REMARKS
There are multiple sources causing minor uncertainty in the results, such as the slight inaccuracy
in measuring the target dimensions at ±1mm, discretization error and noise from the low resolution
of the captured frames, altitude measurement error in calibrating the Pi Camera at ±5mm, use of
underlying velocity setpoints by the Crazyflie to accomplish position setpoints, and reconstruction
of the target position which consisted of error accumulation from its interdependent sources. The
primary contributor to uncertainty is the measurement accuracy of the motion capture system, where
the exact uncertainty is not precisely known but it is on the order of millimetres. For consolation, the
important results are several orders of magnitude above this scale and can reasonably be assumed to
be mostly insensitive to discrepancies presented by the motion capture system.
Although there were many sources of uncertainty, the control script was found to be reasonably
robust, as long as the target is the largest contour within the captured frame for grayscale processing
or no similar colours appeared within the captured frame for colour processing. With very minimal
modification to its current form, the control script can also be suitable for an implementation of