<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.1 20151215//EN" "http://jats.nlm.nih.gov/publishing/1.1/JATS-journalpublishing1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xml:lang="en" article-type="research-article" dtd-version="1.1">
<front>
<journal-meta>
<journal-id journal-id-type="pmc">CMC</journal-id>
<journal-id journal-id-type="nlm-ta">CMC</journal-id>
<journal-id journal-id-type="publisher-id">CMC</journal-id>
<journal-title-group>
<journal-title>Computers, Materials &#x0026; Continua</journal-title>
</journal-title-group>
<issn pub-type="epub">1546-2226</issn>
<issn pub-type="ppub">1546-2218</issn>
<publisher>
<publisher-name>Tech Science Press</publisher-name>
<publisher-loc>USA</publisher-loc>
</publisher>
</journal-meta>
<article-meta>
<article-id pub-id-type="publisher-id">72749</article-id>
<article-id pub-id-type="doi">10.32604/cmc.2025.072749</article-id>
<article-categories>
<subj-group subj-group-type="heading">
<subject>Article</subject>
</subj-group>
</article-categories>
<title-group>
<article-title>Dragonfang: An Open-Source Embedded Flight Controller with IMU-Based Stabilization for Quadcopter Applications</article-title>
<alt-title alt-title-type="left-running-head">Dragonfang: An Open-Source Embedded Flight Controller with IMU-Based Stabilization for Quadcopter Applications</alt-title>
<alt-title alt-title-type="right-running-head">Dragonfang: An Open-Source Embedded Flight Controller with IMU-Based Stabilization for Quadcopter Applications</alt-title>
</title-group>
<contrib-group>
<contrib id="author-1" contrib-type="author">
<name name-style="western"><surname>Dumitru</surname><given-names>Cosmin</given-names></name></contrib>
<contrib id="author-2" contrib-type="author">
<name name-style="western"><surname>Pantelimon</surname><given-names>Emanuel</given-names></name></contrib>
<contrib id="author-3" contrib-type="author">
<name name-style="western"><surname>Guzu</surname><given-names>Alexandru</given-names></name></contrib>
<contrib id="author-4" contrib-type="author" corresp="yes">
<name name-style="western"><surname>Nicolae</surname><given-names>Georgian</given-names></name><xref rid="cor1" ref-type="corresp">&#x002A;</xref><email>georgian.nicolae@upb.ro</email></contrib>
<aff id="aff-1">
<institution>Department of Electronic Devices, Circuits and Architectures, Faculty of Electronics, Telecommunications and Information Technology, National University of Science and Technology Politehnica Bucharest</institution>, <addr-line>Bucharest, 060042</addr-line>, <country>Romania</country></aff>
</contrib-group>
<author-notes>
<corresp id="cor1"><label>&#x002A;</label>Corresponding Author: Georgian Nicolae. Email: <email>georgian.nicolae@upb.ro</email></corresp>
</author-notes>
<pub-date date-type="collection" publication-format="electronic">
<year>2026</year>
</pub-date>
<pub-date date-type="pub" publication-format="electronic">
<day>10</day><month>2</month><year>2026</year>
</pub-date>
<volume>87</volume>
<issue>1</issue>
<elocation-id>13</elocation-id>
<history>
<date date-type="received">
<day>02</day>
<month>09</month>
<year>2025</year>
</date>
<date date-type="accepted">
<day>23</day>
<month>12</month>
<year>2025</year>
</date>
</history>
<permissions>
<copyright-statement>&#x00A9; 2026 The Authors.</copyright-statement>
<copyright-year>2026</copyright-year>
<copyright-holder>Published by Tech Science Press.</copyright-holder>
<license xlink:href="https://creativecommons.org/licenses/by/4.0/">
<license-p>This work is licensed under a <ext-link ext-link-type="uri" xlink:type="simple" xlink:href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</ext-link>, which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited.</license-p>
</license>
</permissions>
<self-uri content-type="pdf" xlink:href="TSP_CMC_72749.pdf"></self-uri>
<abstract>
<p>Unmanned aerial vehicles (UAVs), especially quadcopters, have become indispensable in numerous industrial and scientific applications due to their flexibility, low cost, and capability to operate in dynamic environments. This paper presents a complete design and implementation of a compact autonomous quadcopter capable of trajectory tracking, object detection, precision landing, and real-time telemetry via long-range communication protocols. The system integrates an onboard flight controller running real-time sensor fusion algorithms, a vision-based detection system on a companion single-board computer, and a telemetry unit using Long Range (LoRa) communication. Extensive flight tests were conducted to validate the system&#x2019;s stability, communication range, and autonomous capabilities. Potential applications in law enforcement, agriculture, search and rescue, and environmental monitoring are also discussed.</p>
</abstract>
<kwd-group kwd-group-type="author">
<kwd>Quadcopter</kwd>
<kwd>UAV</kwd>
<kwd>autonomous navigation</kwd>
<kwd>visual detection</kwd>
<kwd>sensor fusion</kwd>
<kwd>telemetry</kwd>
<kwd>LoRa</kwd>
<kwd>embedded systems</kwd>
</kwd-group>
</article-meta>
</front>
<body>
<sec id="s1">
<label>1</label>
<title>Introduction</title>
<p>Within this context, the project <italic>Dragonfang: An Open-Source Embedded Flight Controller with IMU-Based Stabilization for Quadcopter Applications</italic> aims to provide a modular and open-source solution for quadcopter stabilization and control. The system employs an Inertial Measurement Unit (IMU)-based stabilization mechanism, ensuring accurate attitude estimation and reliable flight dynamics control. In addition, the platform integrates vision-based object detection and long-range LoRa telemetry, which are critical for autonomous navigation and extended-range communication in outdoor or industrial scenarios.</p>
<p>Recent studies emphasize the need for open-source flight controllers in the UAV domain, facilitating rapid prototyping, flexibility in design, and lower development costs [<xref ref-type="bibr" rid="ref-1">1</xref>]. Advanced control algorithms such as higher-order sliding modes and nonlinear model predictive control have been extensively investigated to improve quadcopter trajectory tracking, robustness to disturbances, and overall flight accuracy [<xref ref-type="bibr" rid="ref-2">2</xref>,<xref ref-type="bibr" rid="ref-3">3</xref>]. The Dragonfang controller builds upon these principles by fusing real-time sensor data from the IMU to enhance stability and responsiveness under varying flight conditions. Vision-based object detection has also become an essential feature in UAV systems, enabling functionalities like obstacle avoidance, target tracking, and precision landing. Techniques based on deep learning models, including YOLOv8 and Mask Region-Based Convolutional Neural Network (R-CNN), have demonstrated high accuracy and real-time performance in embedded platforms suitable for UAVs [<xref ref-type="bibr" rid="ref-4">4</xref>,<xref ref-type="bibr" rid="ref-5">5</xref>]. Furthermore, precision landing capabilities employing Kalman filters and disturbance observers contribute to improved landing accuracy, which is crucial for autonomous docking or recharging operations [<xref ref-type="bibr" rid="ref-6">6</xref>,<xref ref-type="bibr" rid="ref-7">7</xref>]. For reliable long-range communication, low-power wide-area network (LPWAN) technologies such as LoRa have emerged as attractive solutions, offering extended coverage with minimal energy consumption. LoRa-based telemetry systems have proven effective in maintaining UAV communication links over distances exceeding conventional radio frequency modules [<xref ref-type="bibr" rid="ref-8">8</xref>,<xref ref-type="bibr" rid="ref-9">9</xref>]. Dragonfang integrates such communication modules to support mission-critical data exchange during extended flight operations.</p>
<p>Potential applications of this platform extend beyond academic prototyping, including precision agriculture, search-and-rescue operations, and environmental monitoring, all of which benefit from the long-range communication and modular sensing capabilities of the proposed design.</p>
<p>This project addresses key challenges in UAV system integration by delivering a complete quadcopter platform with the following contributions:
<list list-type="simple">
<list-item><label>1.</label><p>Integrated Mechanical and Electronic Design: Development of a custom frame and dedicated Printed Circuit Boards (PCBs) to support flight control, perception, and telemetry, optimized for compactness and efficiency.</p></list-item>
<list-item><label>2.</label><p>Onboard Flight Control and Navigation: Implementation of real-time flight stabilization and waypoint tracking on the microcontroller using IMU and GPS data, with sensor fusion and control loops supporting both manual and autonomous operation.</p></list-item>
<list-item><label>3.</label><p>Vision-Based Perception and Efficient Telemetry: Integration of a camera-equipped single-board computer for object and landing pad detection, alongside a custom telemetry system ensuring real-time data transfer and onboard logging for post-flight analysis.</p></list-item>
</list></p>
<p>This paper is structured as follows. <xref ref-type="sec" rid="s2">Section 2</xref> presents the mathematical modeling of the quadcopter dynamics, including the derivation of the governing equations and the assumptions made in the system representation. <xref ref-type="sec" rid="s3">Section 3</xref> describes the control strategies employed for attitude and position stabilization, emphasizing IMU-based control loops. <xref ref-type="sec" rid="s4">Section 4</xref> outlines the electrical design of the system, detailing the selection and integration of components such as the microcontroller, sensors, and communication modules. <xref ref-type="sec" rid="s5">Section 5</xref> covers the mechanical design, focusing on the frame structure, motor arrangement, and payload distribution. <xref ref-type="sec" rid="s6">Section 6</xref> discusses the software design, including the development of firmware, vision-based object detection algorithms, and LoRa communication protocols. Finally, <xref ref-type="sec" rid="s8">Section 8</xref> concludes the paper by summarizing the main contributions and highlighting directions for future research and system improvements.</p>
</sec>
<sec id="s2">
<label>2</label>
<title>Mathematical Modeling</title>
<p>To address the integration of orientation estimation algorithms and trajectory control for ensuring stability and precise control in quadcopter systems, it is essential to understand both sensor fusion techniques for position and orientation estimation, and the use of Proportional-Integral-Derivative (PID) control loops for trajectory maintenance. PID control loops are fundamental for correcting deviations and maintaining the desired trajectory, ensuring stability and precise navigation of the quadcopter [<xref ref-type="bibr" rid="ref-10">10</xref>]. Meanwhile, sensor fusion algorithms, such as the Madgwick filter, combine data from accelerometers, gyroscopes, and magnetometers to provide a stable and accurate orientation estimation [<xref ref-type="bibr" rid="ref-11">11</xref>]. The integration of these two components, sensor fusion for positioning and PID control for trajectory regulation, is crucial for performance in complex environments, as highlighted in recent studies on indoor localization and control of quadcopters [<xref ref-type="bibr" rid="ref-12">12</xref>].</p>
<sec id="s2_1">
<label>2.1</label>
<title>PID Control Loop</title>
<p>A PID control loop is a widely used feedback control system employed to maintain a desired setpoint in dynamic systems. The PID controller adjusts a control input based on the error, which is the difference between the system&#x2019;s current output and the desired setpoint. As its name implies, the PID output is the summation of the following terms:
<disp-formula id="eqn-1"><label>(1)</label><mml:math id="mml-eqn-1" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi><mml:mo>=</mml:mo><mml:msub><mml:mi>P</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub><mml:mo>+</mml:mo><mml:msub><mml:mi>I</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub><mml:mo>+</mml:mo><mml:msub><mml:mi>D</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
<sec id="s2_1_1">
<label>2.1.1</label>
<title>Proportional Term</title>
<p>The proportional control provides a corrective action that is directly related to the magnitude of the error. It is calculated as:
<disp-formula id="eqn-2"><label>(2)</label><mml:math id="mml-eqn-2" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:msub><mml:mi>P</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>K</mml:mi><mml:mi>p</mml:mi></mml:msub><mml:mo>&#x22C5;</mml:mo><mml:mi>e</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mi>t</mml:mi><mml:mo stretchy="false">)</mml:mo></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>where:
<list list-type="bullet">
<list-item>
<p><inline-formula id="ieqn-1"><mml:math id="mml-ieqn-1"><mml:msub><mml:mi>P</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula> is the output of the proportional component,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-2"><mml:math id="mml-ieqn-2"><mml:msub><mml:mi>K</mml:mi><mml:mi>p</mml:mi></mml:msub></mml:math></inline-formula> is the proportional gain,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-3"><mml:math id="mml-ieqn-3"><mml:mi>e</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mi>t</mml:mi><mml:mo stretchy="false">)</mml:mo></mml:math></inline-formula> is the instantaneous error at time <inline-formula id="ieqn-4"><mml:math id="mml-ieqn-4"><mml:mi>t</mml:mi></mml:math></inline-formula>.</p></list-item>
</list></p>
<p>However, using only it alone can lead to a steady-state error or oscillation around the setpoint, especially when the system is subjected to external disturbances.</p>
</sec>
<sec id="s2_1_2">
<label>2.1.2</label>
<title>Integral Term</title>
<p>The integral control is used in order to eliminate the steady-state error introduced by the proportional control, by numerically integrating the error over time:
<disp-formula id="eqn-3"><label>(3)</label><mml:math id="mml-eqn-3" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:msub><mml:mi>I</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>K</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>&#x22C5;</mml:mo><mml:msubsup><mml:mo>&#x222B;</mml:mo><mml:mrow><mml:mn>0</mml:mn></mml:mrow><mml:mrow><mml:mi>T</mml:mi></mml:mrow></mml:msubsup><mml:mi>e</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mi>t</mml:mi><mml:mo stretchy="false">)</mml:mo><mml:mi>d</mml:mi><mml:mi>t</mml:mi></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>where:
<list list-type="bullet">
<list-item>
<p><inline-formula id="ieqn-5"><mml:math id="mml-ieqn-5"><mml:msub><mml:mi>I</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula> is the output of the integral component,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-6"><mml:math id="mml-ieqn-6"><mml:msub><mml:mi>K</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:math></inline-formula> is the integral gain,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-7"><mml:math id="mml-ieqn-7"><mml:mi>e</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mi>t</mml:mi><mml:mo stretchy="false">)</mml:mo></mml:math></inline-formula> is the instantaneous error at time <inline-formula id="ieqn-8"><mml:math id="mml-ieqn-8"><mml:mi>t</mml:mi></mml:math></inline-formula>,</p></list-item>
<list-item>
<p><italic>T</italic> is the current time (upper integration limit).</p></list-item>
</list></p>
<p>A too high integral value can lead to oscillations in the system due to high <italic>I</italic> value when the error crosses the zero point, effect also known as integral windup. This effect can be eliminated by either limiting the integral value within a specific range or setting it to zero when the system error sign changes.</p>
</sec>
<sec id="s2_1_3">
<label>2.1.3</label>
<title>Derivative Term</title>
<p>The purpose of the derivative control is to reduce the rate at which the correction occurs and is calculated as follows:
<disp-formula id="eqn-4"><label>(4)</label><mml:math id="mml-eqn-4" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:msub><mml:mi>D</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>K</mml:mi><mml:mi>d</mml:mi></mml:msub><mml:mo>&#x22C5;</mml:mo><mml:mfrac><mml:mrow><mml:mi>d</mml:mi><mml:mi>e</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mi>t</mml:mi><mml:mo stretchy="false">)</mml:mo></mml:mrow><mml:mrow><mml:mi>d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>where:
<list list-type="bullet">
<list-item>
<p><inline-formula id="ieqn-9"><mml:math id="mml-ieqn-9"><mml:msub><mml:mi>D</mml:mi><mml:mrow><mml:mi>o</mml:mi><mml:mi>u</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula> is the output of the derivative component,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-10"><mml:math id="mml-ieqn-10"><mml:msub><mml:mi>K</mml:mi><mml:mi>d</mml:mi></mml:msub></mml:math></inline-formula> is the derivative gain,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-11"><mml:math id="mml-ieqn-11"><mml:mfrac><mml:mrow><mml:mi>d</mml:mi><mml:mi>e</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mi>t</mml:mi><mml:mo stretchy="false">)</mml:mo></mml:mrow><mml:mrow><mml:mi>d</mml:mi><mml:mi>t</mml:mi></mml:mrow></mml:mfrac></mml:math></inline-formula> is the rate of change of the error with respect to time.</p></list-item>
</list></p>
<p>An important aspect is in case that the system error contains noise, a too high derivative coefficient causes the noise to be added to the output with a high amplitude, which in the case of quadcopter motor control results in aggressive shaking, causing unnecessarily high current consumption.</p>
</sec>
</sec>
<sec id="s2_2">
<label>2.2</label>
<title>Madgwick Filter</title>
<p>The Madgwick Filter is a sensor fusion method which uses a MARG sensor array (Magnetic, Angular Rate and Gravity) in order to estimate the quaternion representation of its orientation in a reference system of coordinates. A gyroscope measures angular velocity which, if initial conditions are known, may be integrated over time to compute the sensor&#x2019;s orientation. However, many applications use a MEMS (Micro Electrical Mechanical System) type of gyroscope due to its small size and low cost, which is not accurate: besides the initial bias on each axis of measurement, there is also a bias drift component, resulting in less accurate orientation estimation by gyroscope angular velocity integration alone over time. The Madgwick Filter works by estimating the angular velocity quaternion as reference from the accelerometer (and magnetometer) readings by using the gradient descent algorithm on an objective function, which is then used in order to calculate the current bias of the angular velocity measurement performed by the gyroscope. Then this bias is integrated over time in order to estimate the gyroscope bias drift. Finally, the estimated bias drift is subtracted from the gyroscope angular rate measurement and the result is also integrated over time in order to obtain the sensor orientation relative to the reference system of coordinates.</p>
<p><italic>Filter derivation</italic></p>
<p>Angular velocity (<inline-formula id="ieqn-12"><mml:math id="mml-ieqn-12"><mml:mtext>rad/s</mml:mtext></mml:math></inline-formula>) quaternion in sensor frame:
<disp-formula id="eqn-5"><label>(5)</label><mml:math id="mml-eqn-5" display="block"><mml:mmultiscripts><mml:mi>&#x03C9;</mml:mi><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mrow><mml:mo>[</mml:mo><mml:mtable columnalign="center center center center" rowspacing="4pt" columnspacing="1em"><mml:mtr><mml:mtd><mml:mn>0</mml:mn></mml:mtd><mml:mtd><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>x</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>y</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>z</mml:mi></mml:msub></mml:mtd></mml:mtr></mml:mtable><mml:mo>]</mml:mo></mml:mrow></mml:math></disp-formula>where:
<list list-type="bullet">
<list-item>
<p><inline-formula id="ieqn-13"><mml:math id="mml-ieqn-13"><mml:mmultiscripts><mml:mi>&#x03C9;</mml:mi><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:math></inline-formula> is the angular velocity quaternion expressed in the sensor frame,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-14"><mml:math id="mml-ieqn-14"><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>x</mml:mi></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>y</mml:mi></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>z</mml:mi></mml:msub></mml:math></inline-formula> are the angular velocity components along the <inline-formula id="ieqn-15"><mml:math id="mml-ieqn-15"><mml:mi>x</mml:mi></mml:math></inline-formula>, <inline-formula id="ieqn-16"><mml:math id="mml-ieqn-16"><mml:mi>y</mml:mi></mml:math></inline-formula>, and <inline-formula id="ieqn-17"><mml:math id="mml-ieqn-17"><mml:mi>z</mml:mi></mml:math></inline-formula> axes of the sensor frame,</p></list-item>
<list-item>
<p>The leading 0 represents the scalar part of the quaternion (zero for pure angular velocity vectors).</p></list-item>
</list></p>
<p>Quaternion derivative describing the rate of change of orientation of the earth frame relative to the sensor frame:
<disp-formula id="eqn-6"><label>(6)</label><mml:math id="mml-eqn-6" display="block"><mml:mmultiscripts><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo>&#x02D9;</mml:mo></mml:mover></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mfrac><mml:mn>1</mml:mn><mml:mn>2</mml:mn></mml:mfrac><mml:mmultiscripts><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo>&#x005E;</mml:mo></mml:mover></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>&#x2297;</mml:mo><mml:mmultiscripts><mml:mi>&#x03C9;</mml:mi><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:math></disp-formula>where:
<list list-type="bullet">
<list-item>
<p><inline-formula id="ieqn-18"><mml:math id="mml-ieqn-18"><mml:mmultiscripts><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo>&#x02D9;</mml:mo></mml:mover></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:math></inline-formula> is the time derivative of the quaternion describing the orientation of the Earth frame relative to the sensor frame,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-19"><mml:math id="mml-ieqn-19"><mml:mmultiscripts><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo>&#x005E;</mml:mo></mml:mover></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:math></inline-formula> is the current orientation quaternion of the Earth frame with respect to the sensor frame,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-20"><mml:math id="mml-ieqn-20"><mml:mo>&#x2297;</mml:mo></mml:math></inline-formula> denotes the quaternion (Hamilton) product,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-21"><mml:math id="mml-ieqn-21"><mml:mmultiscripts><mml:mi>&#x03C9;</mml:mi><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:math></inline-formula> is the angular velocity quaternion in the sensor frame.</p></list-item>
</list></p>
<p>Quaternion orientation estimation at step <inline-formula id="ieqn-22"><mml:math id="mml-ieqn-22"><mml:mi>t</mml:mi></mml:math></inline-formula> based on angular velocity (<inline-formula id="ieqn-23"><mml:math id="mml-ieqn-23"><mml:mi mathvariant="normal">&#x0394;</mml:mi><mml:mi>t</mml:mi></mml:math></inline-formula> is the sampling period):
<disp-formula id="eqn-7"><label>(7)</label><mml:math id="mml-eqn-7" display="block"><mml:mmultiscripts><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo>&#x02D9;</mml:mo></mml:mover></mml:mrow><mml:mrow><mml:mi>&#x03C9;</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mfrac><mml:mn>1</mml:mn><mml:mn>2</mml:mn></mml:mfrac><mml:mmultiscripts><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo>&#x005E;</mml:mo></mml:mover></mml:mrow><mml:mrow><mml:mi>e</mml:mi><mml:mi>s</mml:mi><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi><mml:mo>&#x2212;</mml:mo><mml:mn>1</mml:mn></mml:mrow><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>&#x2297;</mml:mo><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>t</mml:mi></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:math></disp-formula>
<disp-formula id="eqn-8"><label>(8)</label><mml:math id="mml-eqn-8" display="block"><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>&#x03C9;</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:msub><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow><mml:mrow><mml:mi>e</mml:mi><mml:mi>s</mml:mi><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi><mml:mo>&#x2212;</mml:mo><mml:mn>1</mml:mn></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:mrow><mml:mo>+</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:msub><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo>&#x02D9;</mml:mo></mml:mover></mml:mrow><mml:mrow><mml:mi>&#x03C9;</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:mrow><mml:mi mathvariant="normal">&#x0394;</mml:mi><mml:mi>t</mml:mi></mml:math></disp-formula></p>
<p>Objective function for finding the quaternion which aligns the predefined direction of a reference field in the Earth frame to the measured one (<inline-formula id="ieqn-24"><mml:math id="mml-ieqn-24"><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:math></inline-formula> is the current orientation estimation, <inline-formula id="ieqn-25"><mml:math id="mml-ieqn-25"><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:math></inline-formula> reference field direction in Earth frame, <inline-formula id="ieqn-26"><mml:math id="mml-ieqn-26"><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:math></inline-formula> measured field direction in sensor frame):
<disp-formula id="eqn-9"><label>(9)</label><mml:math id="mml-eqn-9" display="block"><mml:mrow><mml:mi>m</mml:mi><mml:mi>i</mml:mi><mml:mi>n</mml:mi></mml:mrow><mml:mo stretchy="false">(</mml:mo><mml:mrow><mml:mi>f</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo stretchy="false">)</mml:mo></mml:mrow><mml:mo stretchy="false">)</mml:mo></mml:math></disp-formula>where (<inline-formula id="ieqn-27"><mml:math id="mml-ieqn-27"><mml:msup><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:mrow><mml:mrow><mml:mo>&#x2217;</mml:mo></mml:mrow></mml:msup></mml:math></inline-formula> denotes the estimated orientation quaternion conjugate) and <inline-formula id="ieqn-28"><mml:math id="mml-ieqn-28"><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:math></inline-formula> is unit quaternion:
<disp-formula id="eqn-10"><label>(10)</label><mml:math id="mml-eqn-10" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mi>f</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo stretchy="false">)</mml:mo><mml:mo>=</mml:mo><mml:msup><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:mrow><mml:mrow><mml:mo>&#x2217;</mml:mo></mml:mrow></mml:msup><mml:mo>&#x2297;</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>&#x2297;</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:mrow><mml:mo>&#x2212;</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>
<disp-formula id="eqn-11"><label>(11)</label><mml:math id="mml-eqn-11" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mrow><mml:mo>[</mml:mo><mml:mtable columnalign="left left left left" rowspacing="4pt" columnspacing="1em"><mml:mtr><mml:mtd><mml:msub><mml:mi>q</mml:mi><mml:mn>1</mml:mn></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>q</mml:mi><mml:mn>2</mml:mn></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>q</mml:mi><mml:mn>3</mml:mn></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>q</mml:mi><mml:mn>4</mml:mn></mml:msub></mml:mtd></mml:mtr></mml:mtable><mml:mo>]</mml:mo></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>
<disp-formula id="eqn-12"><label>(12)</label><mml:math id="mml-eqn-12" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>=</mml:mo><mml:mrow><mml:mo>[</mml:mo><mml:mtable columnalign="left left left left" rowspacing="4pt" columnspacing="1em"><mml:mtr><mml:mtd><mml:mn>0</mml:mn></mml:mtd><mml:mtd><mml:msub><mml:mi>d</mml:mi><mml:mi>x</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>d</mml:mi><mml:mi>y</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>d</mml:mi><mml:mi>z</mml:mi></mml:msub></mml:mtd></mml:mtr></mml:mtable><mml:mo>]</mml:mo></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>
<disp-formula id="eqn-13"><label>(13)</label><mml:math id="mml-eqn-13" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>=</mml:mo><mml:mrow><mml:mo>[</mml:mo><mml:mtable columnalign="left left left left" rowspacing="4pt" columnspacing="1em"><mml:mtr><mml:mtd><mml:mn>0</mml:mn></mml:mtd><mml:mtd><mml:msub><mml:mi>s</mml:mi><mml:mi>x</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>s</mml:mi><mml:mi>y</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>s</mml:mi><mml:mi>z</mml:mi></mml:msub></mml:mtd></mml:mtr></mml:mtable><mml:mo>]</mml:mo></mml:mrow></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
<p>For example, in the case that <inline-formula id="ieqn-29"><mml:math id="mml-ieqn-29"><mml:mi>f</mml:mi></mml:math></inline-formula> is based on the accelerometer data (gravitation reading), <inline-formula id="ieqn-30"><mml:math id="mml-ieqn-30"><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:math></inline-formula> can be substituted with <inline-formula id="ieqn-31"><mml:math id="mml-ieqn-31"><mml:mrow><mml:mo>[</mml:mo><mml:mtable columnalign="left left left left" rowspacing="4pt" columnspacing="1em"><mml:mtr><mml:mtd><mml:mn>0</mml:mn></mml:mtd><mml:mtd><mml:mn>0</mml:mn></mml:mtd><mml:mtd><mml:mn>0</mml:mn></mml:mtd><mml:mtd><mml:mn>1</mml:mn></mml:mtd></mml:mtr></mml:mtable><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula> and <inline-formula id="ieqn-32"><mml:math id="mml-ieqn-32"><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:math></inline-formula> with <inline-formula id="ieqn-33"><mml:math id="mml-ieqn-33"><mml:mrow><mml:mo>[</mml:mo><mml:mtable columnalign="left left left left" rowspacing="4pt" columnspacing="1em"><mml:mtr><mml:mtd><mml:mn>0</mml:mn></mml:mtd><mml:mtd><mml:msub><mml:mi>a</mml:mi><mml:mi>x</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>a</mml:mi><mml:mi>y</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>a</mml:mi><mml:mi>z</mml:mi></mml:msub></mml:mtd></mml:mtr></mml:mtable><mml:mo>]</mml:mo></mml:mrow></mml:math></inline-formula>, representing the acceleration measurements on all axes. The current orientation based on the magnetometer or accelerometer reading is estimated by gradient descent:
<disp-formula id="eqn-14"><label>(14)</label><mml:math id="mml-eqn-14" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>q</mml:mi><mml:mrow><mml:mi>k</mml:mi><mml:mo>+</mml:mo><mml:mn>1</mml:mn></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mmultiscripts><mml:mrow><mml:msub><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow><mml:mi>k</mml:mi></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>&#x2212;</mml:mo><mml:mi>&#x03BC;</mml:mi><mml:mfrac><mml:mrow><mml:mi mathvariant="normal">&#x2207;</mml:mi><mml:mi>f</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:msub><mml:mi>q</mml:mi><mml:mi>k</mml:mi></mml:msub><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo stretchy="false">)</mml:mo></mml:mrow><mml:mrow><mml:mo fence="false" stretchy="false">&#x2016;</mml:mo><mml:mrow><mml:mi mathvariant="normal">&#x2207;</mml:mi><mml:mi>f</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:msub><mml:mi>q</mml:mi><mml:mi>k</mml:mi></mml:msub><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo stretchy="false">)</mml:mo></mml:mrow><mml:mo fence="false" stretchy="false">&#x2016;</mml:mo></mml:mrow></mml:mfrac></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>
<disp-formula id="eqn-15"><label>(15)</label><mml:math id="mml-eqn-15" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mi mathvariant="normal">&#x2207;</mml:mi><mml:mi>f</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo stretchy="false">)</mml:mo><mml:mo>=</mml:mo><mml:msup><mml:mi>J</mml:mi><mml:mi>T</mml:mi></mml:msup><mml:mo stretchy="false">(</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:msub><mml:mi>q</mml:mi><mml:mi>k</mml:mi></mml:msub><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:mrow><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo stretchy="false">)</mml:mo><mml:mi>f</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:msub><mml:mi>q</mml:mi><mml:mi>k</mml:mi></mml:msub><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>d</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>E</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo>,</mml:mo><mml:mrow><mml:mmultiscripts><mml:mrow><mml:mrow><mml:mover><mml:mi>s</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mrow><mml:mo stretchy="false">)</mml:mo></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
<p>Gyroscope current bias estimation:
<disp-formula id="eqn-16"><label>(16)</label><mml:math id="mml-eqn-16" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mrow><mml:mi>&#x03F5;</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mn>2</mml:mn><mml:mmultiscripts><mml:mrow><mml:msubsup><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow><mml:mrow><mml:mi>e</mml:mi><mml:mi>s</mml:mi><mml:mi>t</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi><mml:mo>&#x2212;</mml:mo><mml:mn>1</mml:mn></mml:mrow><mml:mrow><mml:mo>&#x2217;</mml:mo></mml:mrow></mml:msubsup></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts><mml:mo>&#x2297;</mml:mo><mml:mmultiscripts><mml:mrow><mml:msub><mml:mrow><mml:mover><mml:mrow><mml:mover><mml:mi>q</mml:mi><mml:mo stretchy="false">&#x005E;</mml:mo></mml:mover></mml:mrow><mml:mo>&#x02D9;</mml:mo></mml:mover></mml:mrow><mml:mrow><mml:mi>&#x03F5;</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:mrow><mml:mi>E</mml:mi></mml:mrow><mml:mrow><mml:mi>S</mml:mi></mml:mrow></mml:mmultiscripts></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
<p>Gyroscope total bias estimation (accumulated bias drift), with gain <inline-formula id="ieqn-34"><mml:math id="mml-ieqn-34"><mml:mi>&#x03B6;</mml:mi></mml:math></inline-formula>:
<disp-formula id="eqn-17"><label>(17)</label><mml:math id="mml-eqn-17" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mrow><mml:mi>b</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mi>&#x03B6;</mml:mi><mml:munder><mml:mo>&#x2211;</mml:mo><mml:mrow><mml:mi>t</mml:mi></mml:mrow></mml:munder><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mrow><mml:mi>&#x03F5;</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts><mml:mi mathvariant="normal">&#x0394;</mml:mi><mml:mi>t</mml:mi></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
<p>Compensated angular velocity estimation:
<disp-formula id="eqn-18"><label>(18)</label><mml:math id="mml-eqn-18" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mrow><mml:mi>c</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts><mml:mo>=</mml:mo><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>t</mml:mi></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts><mml:mo>&#x2212;</mml:mo><mml:mmultiscripts><mml:mrow><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mrow><mml:mi>b</mml:mi><mml:mo>,</mml:mo><mml:mi>t</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:none/><mml:none/><mml:mprescripts/><mml:none/><mml:mi>S</mml:mi></mml:mmultiscripts></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula></p>
<p>Finally, the compensated angular velocity estimation (with the removed bias drift computed using the accelerometer and/or magnetometer readings) is integrated over time in order to obtain the sensor orientation in the reference system of coordinates.</p>
</sec>
</sec>
<sec id="s3">
<label>3</label>
<title>Control Strategies</title>
<p>The quadcopter structure is presented in the <xref ref-type="fig" rid="fig-1">Fig. 1</xref>, including the corresponding angular velocities, torques and forces created by the four rotors (numbered from 1 to 4). For each rotor-propeller pair, depending on the angular velocity <inline-formula id="ieqn-35"><mml:math id="mml-ieqn-35"><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mrow><mml:mn>1</mml:mn><mml:mo>&#x2212;</mml:mo><mml:mn>4</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula>, a force denoted <inline-formula id="ieqn-36"><mml:math id="mml-ieqn-36"><mml:msub><mml:mi>f</mml:mi><mml:mrow><mml:mn>1</mml:mn><mml:mo>&#x2212;</mml:mo><mml:mn>4</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula> is generated along the local up axis denoted <inline-formula id="ieqn-37"><mml:math id="mml-ieqn-37"><mml:msub><mml:mi>z</mml:mi><mml:mi>B</mml:mi></mml:msub></mml:math></inline-formula>, at the position <inline-formula id="ieqn-38"><mml:math id="mml-ieqn-38"><mml:msub><mml:mi>R</mml:mi><mml:mrow><mml:mn>1</mml:mn><mml:mo>&#x2212;</mml:mo><mml:mn>4</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula> from the drone center. This in turn generates a torque <inline-formula id="ieqn-39"><mml:math id="mml-ieqn-39"><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mn>1</mml:mn><mml:mo>&#x2212;</mml:mo><mml:mn>4</mml:mn></mml:mrow></mml:msub></mml:math></inline-formula> around the <inline-formula id="ieqn-40"><mml:math id="mml-ieqn-40"><mml:msub><mml:mi>z</mml:mi><mml:mi>B</mml:mi></mml:msub></mml:math></inline-formula> axis, assuming that <inline-formula id="ieqn-41"><mml:math id="mml-ieqn-41"><mml:msub><mml:mi>R</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:math></inline-formula> has the form <inline-formula id="ieqn-42"><mml:math id="mml-ieqn-42"><mml:mrow><mml:mo>(</mml:mo><mml:mtable rowspacing="4pt" columnspacing="1em"><mml:mtr><mml:mtd><mml:msub><mml:mi>x</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:msub><mml:mi>y</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:mtd><mml:mtd><mml:mn>0</mml:mn></mml:mtd></mml:mtr></mml:mtable><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>. Such a mechanical setup is sufficient to ensure control over the orientation around the <inline-formula id="ieqn-43"><mml:math id="mml-ieqn-43"><mml:msub><mml:mi>x</mml:mi><mml:mi>B</mml:mi></mml:msub></mml:math></inline-formula>, <inline-formula id="ieqn-44"><mml:math id="mml-ieqn-44"><mml:msub><mml:mi>y</mml:mi><mml:mi>B</mml:mi></mml:msub></mml:math></inline-formula> and <inline-formula id="ieqn-45"><mml:math id="mml-ieqn-45"><mml:msub><mml:mi>z</mml:mi><mml:mi>B</mml:mi></mml:msub></mml:math></inline-formula> axes, as well as translation along the <inline-formula id="ieqn-46"><mml:math id="mml-ieqn-46"><mml:msub><mml:mi>z</mml:mi><mml:mi>B</mml:mi></mml:msub></mml:math></inline-formula> axis, which is enough to guarantee full positional control of the drone.</p>
<fig id="fig-1">
<label>Figure 1</label>
<caption>
<title>Forces acting upon the quadcopter frame. Source: <ext-link ext-link-type="uri" xlink:href="https://github.com/AngeloEspinoza/quadrotor-model-and-control">https://github.com/AngeloEspinoza/quadrotor-model-and-control</ext-link></title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-1.tif"/>
</fig>
<p>In order to have effective yaw angle control (around the <inline-formula id="ieqn-47"><mml:math id="mml-ieqn-47"><mml:msub><mml:mi>z</mml:mi><mml:mi>B</mml:mi></mml:msub></mml:math></inline-formula> axis), it is necessary that the motors <inline-formula id="ieqn-48"><mml:math id="mml-ieqn-48"><mml:msub><mml:mi>M</mml:mi><mml:mn>1</mml:mn></mml:msub></mml:math></inline-formula> and <inline-formula id="ieqn-49"><mml:math id="mml-ieqn-49"><mml:msub><mml:mi>M</mml:mi><mml:mn>3</mml:mn></mml:msub></mml:math></inline-formula> spin in opposite directions compared to <inline-formula id="ieqn-50"><mml:math id="mml-ieqn-50"><mml:msub><mml:mi>M</mml:mi><mml:mn>4</mml:mn></mml:msub></mml:math></inline-formula> and <inline-formula id="ieqn-51"><mml:math id="mml-ieqn-51"><mml:msub><mml:mi>M</mml:mi><mml:mn>2</mml:mn></mml:msub></mml:math></inline-formula>. The torque generated by the motors over the whole body is determined as follows, where <inline-formula id="ieqn-52"><mml:math id="mml-ieqn-52"><mml:mi>s</mml:mi><mml:mi>g</mml:mi><mml:mi>n</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:mi>x</mml:mi><mml:mo stretchy="false">)</mml:mo></mml:math></inline-formula> is the sign function:
<disp-formula id="eqn-19"><label>(19)</label><mml:math id="mml-eqn-19" display="block"><mml:mtable columnalign="right left right left right left right left right left right left" rowspacing="3pt" columnspacing="0em 2em 0em 2em 0em 2em 0em 2em 0em 2em 0em" displaystyle="true"><mml:mtr><mml:mtd /><mml:mtd><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>R</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>&#x00D7;</mml:mo><mml:msub><mml:mi>f</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>&#x22C5;</mml:mo><mml:mi>s</mml:mi><mml:mi>g</mml:mi><mml:mi>n</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo stretchy="false">)</mml:mo></mml:mtd></mml:mtr></mml:mtable></mml:math></disp-formula>where:
<list list-type="bullet">
<list-item>
<p><inline-formula id="ieqn-53"><mml:math id="mml-ieqn-53"><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:math></inline-formula> is the torque produced by motor <inline-formula id="ieqn-54"><mml:math id="mml-ieqn-54"><mml:mi>i</mml:mi></mml:math></inline-formula>,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-55"><mml:math id="mml-ieqn-55"><mml:msub><mml:mi>R</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:math></inline-formula> is the position vector from the center of mass to motor <inline-formula id="ieqn-56"><mml:math id="mml-ieqn-56"><mml:mi>i</mml:mi></mml:math></inline-formula>,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-57"><mml:math id="mml-ieqn-57"><mml:msub><mml:mi>f</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:math></inline-formula> is the thrust force generated by motor <inline-formula id="ieqn-58"><mml:math id="mml-ieqn-58"><mml:mi>i</mml:mi></mml:math></inline-formula>,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-59"><mml:math id="mml-ieqn-59"><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:math></inline-formula> is the angular velocity of motor <inline-formula id="ieqn-60"><mml:math id="mml-ieqn-60"><mml:mi>i</mml:mi></mml:math></inline-formula>,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-61"><mml:math id="mml-ieqn-61"><mml:mi>s</mml:mi><mml:mi>g</mml:mi><mml:mi>n</mml:mi><mml:mo stretchy="false">(</mml:mo><mml:msub><mml:mi>&#x03C9;</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo stretchy="false">)</mml:mo></mml:math></inline-formula> ensures the torque direction is consistent with the motor&#x2019;s rotation direction.</p></list-item>
</list></p>
<p><disp-formula id="eqn-20"><label>(20)</label><mml:math id="mml-eqn-20" display="block"><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mi>t</mml:mi><mml:mi>o</mml:mi><mml:mi>t</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:munderover><mml:mo>&#x2211;</mml:mo><mml:mrow><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mn>1</mml:mn></mml:mrow><mml:mrow><mml:mn>4</mml:mn></mml:mrow></mml:munderover><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:math></disp-formula>where:
<list list-type="bullet">
<list-item>
<p><inline-formula id="ieqn-62"><mml:math id="mml-ieqn-62"><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mrow><mml:mi>t</mml:mi><mml:mi>o</mml:mi><mml:mi>t</mml:mi><mml:mi>a</mml:mi><mml:mi>l</mml:mi></mml:mrow></mml:msub></mml:math></inline-formula> is the total torque acting on the body,</p></list-item>
<list-item>
<p><inline-formula id="ieqn-63"><mml:math id="mml-ieqn-63"><mml:msub><mml:mi>&#x03C4;</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:math></inline-formula> is the torque from motor <inline-formula id="ieqn-64"><mml:math id="mml-ieqn-64"><mml:mi>i</mml:mi></mml:math></inline-formula>,</p></list-item>
<list-item>
<p>The summation is taken over all four motors (<inline-formula id="ieqn-65"><mml:math id="mml-ieqn-65"><mml:mi>i</mml:mi><mml:mo>=</mml:mo><mml:mn>1</mml:mn><mml:mo>&#x2026;</mml:mo><mml:mn>4</mml:mn></mml:math></inline-formula>).</p></list-item>
</list></p>
<p>To address the mechanical setup and control dynamics of quadcopters, including the angular velocities, torques, and forces generated by the rotor-propeller pairs, several studies provide detailed insights. Bucki and Mueller [<xref ref-type="bibr" rid="ref-13">13</xref>] present a novel quadcopter design with passive rotary joints, discussing dynamics and control mechanisms involving angular velocities and torques generated by the propellers, emphasizing their importance for controlling orientation and translation. C&#x00E9;sar et al. [<xref ref-type="bibr" rid="ref-14">14</xref>] provide mathematical modeling of rotor forces and torques, underlining the precision required for stability and control. Furthermore, Bin Junaid et al. [<xref ref-type="bibr" rid="ref-11">11</xref>] explore dual-axis tilting quadcopters and the management of angular velocities and torques for effective orientation and positional control, which is essential for full drone maneuverability.</p>
<p><bold>Advantages over traditional algorithms:</bold> Unlike classical PID-only flight controllers, the proposed system integrates the Madgwick filter for real-time quaternion-based orientation estimation, which reduces drift and improves accuracy in attitude control. Additionally, the dual-IMU setup provides redundant sensing and averaging, thereby lowering the influence of sensor noise and vibrations compared to single-IMU systems. The result is a more stable and responsive flight behavior, particularly under dynamic conditions such as wind disturbances or rapid maneuvering.</p>
<p><bold><italic>Multi-Sensor Fusion</italic></bold></p>
<p>Accurate and robust flight control requires the combination of multiple sensors, each with complementary strengths. In the Dragonfang platform, accelerometer and gyroscope data from two independent IMUs are fused using the Madgwick algorithm, which computes quaternion-based orientation estimates in real time. The dual-IMU approach reduces noise sensitivity and provides redundancy, ensuring that a single faulty reading does not destabilize the system. Additional sensors, including a GPS receiver, a barometric pressure sensor, and a Time-of-Flight (ToF) distance sensor, are incorporated through weighted averaging and complementary filtering. This fusion strategy enables the system to maintain accurate attitude estimation while also providing reliable altitude and position feedback, which are critical for stable hovering and autonomous flight modes.</p>
</sec>
<sec id="s4">
<label>4</label>
<title>Electrical Design</title>
<p>The main electronics module of the Dragonfang quadcopter consists of two custom-designed Printed Circuit Boards (PCBs), developed by the team and stacked vertically to minimize space while maintaining high performance. The larger PCB, referred to as the Main Board, contains the motor drivers and power supply components (<xref ref-type="fig" rid="fig-2">Fig. 2</xref>). The smaller PCB, known as the Flight Controller Board, is mounted on top of the Main Board and manages throttle signaling and flight logic implementation (<xref ref-type="fig" rid="fig-3">Fig. 3</xref>).</p>
<fig id="fig-2">
<label>Figure 2</label>
<caption>
<title>Assembled main board (bottom layer of the electronics stack)</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-2.tif"/>
</fig><fig id="fig-3">
<label>Figure 3</label>
<caption>
<title>Assembled flight controller board (top layer of the electronics stack)</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-3.tif"/>
</fig>
<sec id="s4_1">
<label>4.1</label>
<title>Main Board</title>
<p>The Main Board contains the Brushless Direct Current motor (BLDC) Electronic Speed Controllers (ESCs), the main &#x002B;5 V DC power supply circuit using a buck converter IC supporting up to 5 A load current and 36 V input, making it useful for powering other electrical components besides the critical ones, such as Light Detection and Ranging (LiDAR) sensors or servo motors. It also has a &#x002B;12 V regulator for the ESCs supporting up to 26 V input with up to 60 V transients (for max. 100 ms), making the whole system rated for Lithium-Polymer or Lithium-Ion battery packs consisting of 2 to 6 cells in series, making it suitable for a large variety of quadcopter sizes or brushless motor configurations. The PCB also contains the power supply input pads, four M3 mounting holes, the Flight Controller Module footprint and the programming, debug and expansion ports, allowing for external modules to be powered and interfaced with the Flight Controller.</p>
<p>The PCB has 45 mm <inline-formula id="ieqn-66"><mml:math id="mml-ieqn-66"><mml:mo>&#x00D7;</mml:mo></mml:math></inline-formula> 45 mm size, 1.6 mm thickness and has 6 copper layers in order to efficiently separate the ESC power supply copper planes which must withstand high currents, and the digital signal traces. <xref ref-type="fig" rid="fig-4">Fig. 4</xref> shows the top and bottom views of the PCB layout, highlighting the component placement and copper layer routing.</p>
<fig id="fig-4">
<label>Figure 4</label>
<caption>
<title>Top and bottom PCB views of the main board</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-4.tif"/>
</fig>
<p>The board contains four field-oriented control (FOC) brushless DC motor (BLDC) electronic speed controllers (ESC) which drive the quadcopter propeller motors and take the Flight Controller output throttle digital signals as input. Each ESC circuit contains:
<list list-type="bullet">
<list-item><p><monospace>Microcontroller</monospace>: 8051-based EFM8BB2 model. Runs the motor driver firmware, accepting motor throttle values with 2000 subdivisions, over the &#x201C;DShot300&#x201D; digital protocol.</p></list-item>
<list-item><p><monospace>N-MOSFET Gate Driver IC</monospace>: Up to 260 ns gate drive dead-time, drives 3 N-MOSFET pairs (high-side and low-side) and integrates high-side bootstrap diodes. The IC high-side power supply is connected to the on-board 12 V regulator output, in order to avoid exceeding the maximum Gate-Source voltage of the MOSFETs in case of main supply voltage spikes or high DC input voltage, for example from using LiPo batteries having 6 cells connected in series.</p></list-item>
<list-item><p><monospace>3 Dual-Channel N-MOSFETs</monospace>: 30 A/40 A max. continuous <inline-formula id="ieqn-67"><mml:math id="mml-ieqn-67"><mml:msub><mml:mi>I</mml:mi><mml:mi>D</mml:mi></mml:msub></mml:math></inline-formula> (high/low side) at <inline-formula id="ieqn-68"><mml:math id="mml-ieqn-68"><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:mi>G</mml:mi><mml:mi>S</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mn>10</mml:mn></mml:math></inline-formula> V (20 V max) with <inline-formula id="ieqn-69"><mml:math id="mml-ieqn-69"><mml:msub><mml:mrow><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:mi>D</mml:mi><mml:mi>S</mml:mi></mml:mrow></mml:msub></mml:mrow><mml:mrow><mml:mi>m</mml:mi><mml:mi>a</mml:mi><mml:mi>x</mml:mi></mml:mrow></mml:msub><mml:mo>=</mml:mo><mml:mn>30</mml:mn></mml:math></inline-formula> V. Each contact tying the high-side source and the low-side drain is exposed to a pad onto which the corresponding motor phase wire is soldered.</p></list-item>
<list-item><p><monospace>Motor phase voltage dividers</monospace>: Used by the microcontroller in order to detect the current motor phase based on the back electromotive force.</p></list-item>
<list-item><p><monospace>Gate resistors</monospace>: For adjusting the N-MOSFET gate charge time and limiting the charge current within the driver IC limits.</p></list-item>
</list></p>
<p>For the control side, the micrcocontrollers were programmed with the open-source &#x201C;Bluejay&#x201D; ESC firmware. The Microcontroller Unit (MCU) has General-Purpose Input/Output (GPIO) pins used for controlling the High and Low motor phase MOSFET gates (3x low and high side control pins), along with analog input pins connected to the motor phases via voltage dividers in order to reduce the motors&#x2019; back EMF to a voltage which is safe for the microcontrollers (and M_A/B/C/COM_SENSE). These pins are connected to the internal Zero-Cross-Detector (ZCD) peripheral and are used by the firmware for the motor feedback loop in detecting the current phase in order to drive the appropriate MOSFETs at each time step.</p>
<p>The MOSFET driver IC drives the high-side MOSFETs with a bootstrap circuit (<xref ref-type="fig" rid="fig-5">Fig. 5</xref>), making use of just a diode and a capacitor to drive the high-side transistor at an optimal Gate-Source voltage, regardless of the back-EMF on the respective phase contact. Its principle works as follows: at each cycle, the low-side N-MOSFET is &#x201C;turned on&#x201D; by the MOSFET driver on the left side of the figure above, by applying the positive supply voltage on the Gate Pin, therefore charging the Gate to a high enough voltage with respect to ground, this way &#x201C;connecting&#x201D; the capacitor negative terminal to the ground. A positive voltage potential between the positive and negative capacitor terminals is formed, allowing it to charge through the diode, reaching a voltage close to the driver positive power supply voltage.</p>
<fig id="fig-5">
<label>Figure 5</label>
<caption>
<title>High-side N-MOSFET bootstrap circuit for driving brushless DC motor phases efficiently. Source: <ext-link ext-link-type="uri" xlink:href="https://techweb.rohm.com">https://techweb.rohm.com</ext-link></title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-5.tif"/>
</fig>
<p>Later in the cycle, the high-side MOSFET needs to &#x201C;turn on&#x201D;. In the case that the voltage over the motor coil is close to zero, a high enough Gate-Source voltage is generated and the transistors activates with no problem. Without the bootstrap circuit, when the voltage over the coil rises, for example, close to the main power supply voltage (equivalent to the Back-EMF of the BLDC motor running at high speed), the Gate-Drain voltage on the High-Side MOSFET decreases, resulting in higher Drain-Source resistance, higher power dissipation and lower motor current. But when the bootstrap circuit is used, the High-side MOSFET is turned on via the voltage stored across the capacitor plates, which will be always close to the main supply voltage, provided that the low-side MOSFET was turned on not too long ago in order to allow the capacitor to discharge. This way, there is much lower power loss in the MOSFET at high switching frequency. Given this principle of operation, the N-Channel MOSFET bootstrap circuit works properly only in the case of ON-OFF inductive load control switching applications. Also, the capacitor value must be chosen by taking into account the parasitic resistance, as well as the required time to have the high-side MOSFET turned &#x201C;ON&#x201D; in order to not have it discharge before the low-side switching phase starts.</p>
<p><bold>Core Advantages of the Main Board:</bold> Unlike traditional off-the-shelf quadcopter control panels, the proposed Main Board integrates four FOC-based ESCs directly on a compact 6-layer PCB, together with dedicated power management circuits. This modular stacking approach (Main Board &#x002B; Flight Controller Board) reduces noise coupling between the high-current ESC power planes and the sensitive IMU/GPS lines, while maintaining a small 45 mm <inline-formula id="ieqn-70"><mml:math id="mml-ieqn-70"><mml:mo>&#x00D7;</mml:mo></mml:math></inline-formula> 45 mm footprint. Furthermore, the use of open-source Bluejay firmware combined with custom bootstrap MOSFET driving circuits provides both adaptability and higher efficiency, enabling the platform to be easily scaled to different quadcopter sizes and motor configurations.</p>
</sec>
<sec id="s4_2">
<label>4.2</label>
<title>Flight Controller Board</title>
<p>The Flight Controller Board contains all the sensitive electronic components (sensors, microcontrollers etc.) necessary for achieving stable flight control of a standard quadcopter (but not limited to that), autonomous operation and remote control. It is soldered onto the Main Board and its whole objective is to send throttle signals to the motor drivers and be accessed through the Main Board connectors. <xref ref-type="fig" rid="fig-6">Fig. 6</xref> shows the layout of the Flight Controller Board, with all critical components for sensing and processing.</p>
<fig id="fig-6">
<label>Figure 6</label>
<caption>
<title>Top and bottom PCB views of the flight controller board</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-6.tif"/>
</fig>
<p>The PCB size is 33 mm <inline-formula id="ieqn-71"><mml:math id="mml-ieqn-71"><mml:mo>&#x00D7;</mml:mo></mml:math></inline-formula> 16.4 mm, with 0.8 mm thickness and 6 copper layers in order to efficiently route all the signals within the very small available space while keeping the ground planes continuous in order to have the <inline-formula id="ieqn-72"><mml:math id="mml-ieqn-72"><mml:mn>50</mml:mn><mml:mtext>&#x00A0;</mml:mtext><mml:mi mathvariant="normal">&#x03A9;</mml:mi></mml:math></inline-formula> impedance-matched Radio Frequency part of the PCB achieve receive sensitivity and antenna port transmit power as close to the components&#x2019; rated values as possible.</p>
<p>The bottom side of the PCB have solder pads with 0.1 inch spacing, in order to greatly simplify the process of mounting the board on a standard prototyping board, in case of debug or if the Main Board fails or its components are not suited for the use scenario, simplifying the process of adapting commercial ESCs.</p>
<p>Based on the top Flight Controller Board view, the PCB area is divided into four parts:
<list list-type="bullet">
<list-item>
<p><monospace>GPS circuit</monospace>: Is located on the lower-right corner of the PCB and contains the GPS receiver IC, the RF DC bias tee circuit and the GPS antenna connector.</p></list-item>
<list-item>
<p><monospace>LoRa circuit</monospace>: Is located on the upper-right corner of the board and contains the RF filter IC connected to the RF pins of the main microcontroller, the RF switch (for transmission and reception) and the LoRa antenna port. The RF filter integrated circuit is designed to operate in the 862&#x2013;928 MHz range and integrates a matching network designed for the microcontroller, balun and harmonics filter. The LoRa protocol will be used in order to establish the radio link with the Remote Control.</p></list-item>
<list-item>
<p><monospace>Secondary Control circuit</monospace>: Is located on the lower-left corner of the board and contains the secondary microcontroller (ATtiny3226), a 4-bit logic level converter for the Serial Peripheral Interface (SPI) interface and a solder jumper for selecting its supply voltage between 3.3 V and 5 V. It communicates with the main microcontroller by SPI and has 5 exposed general-purpose input/output pins on the bottom side of the board with current limiting resistors, as well as a Universal Asynchronous Receiver/Transmitter (UART) interface dedicated to expansion modules. The Secondary Control circuit acts as both an expansion for controlling external devices requiring up to 5 V level (such as common N-MOSFETs connected to actuators, in order to reach high enough Gate-Source voltage), and as a buffer in order to not bring the whole system down in case of microcontroller failure due to events such as over-voltage on one of the exposed pins. In the current state of the project, this part of the board is not used but will be proven to be useful in case of more complex frame design in the future.</p></list-item>
<list-item>
<p><monospace>Main Control circuit</monospace>: Occupies the rest of the board and contains the microcontroller used for running the flight control program and all the other components directly connected to it. It is a dual-core STM32 MCU which integrates a Cortex-M0&#x002B; and Cortex-M4 core, as well as a radio modem supporting LoRa, (G) Frequency-Shift Keying (FSK), (G) MinimumShift Keying (MSK) and Binary Phase-Shift Keying (BPSK) modulation schemes, making it very useful for this application given the small available space. In order to ensure stable RF operation, the microcontroller clock input is supplied by a 32 MHz Temperature Compensated Crystal Oscillator (TCXO).</p></list-item>
</list></p>
<p>The main microcontroller has the following components attached:
<list list-type="bullet">
<list-item>
<p><monospace>First Intertial Measurement Unit</monospace>: Contains a 3-axis accelerometer and gyroscope and is accessed through the SPI bus. Can measure up to &#x002B;/&#x2212;16 g acceleration and &#x002B;/&#x2212;2000 deg/s with 15-bit precision (excluding the sign). It has 0.038 deg/s-rms gyroscope noise and 0.7 mg-rms accelerometer noise at 100 Hz bandwidth.</p></list-item>
<list-item>
<p><monospace>Second Inertial Measurement Unit</monospace>: Contains an accelerometer and is accessed through the SPI bus. Can measure up to &#x002B;/&#x2013;16g acceleration. It has 0.7 mg-rms noise at 100 Hz bandwidth.</p></list-item>
<list-item>
<p><monospace>Distance Sensor</monospace>: Time of Flight (ToF) sensor, measures distance up to 5 meters. Accessed through the I2C bus.</p></list-item>
<list-item>
<p><monospace>Flash Storage</monospace>: Has 8 megabytes of total size. Accessed through the SPI bus.</p></list-item>
<list-item>
<p><monospace>Pressure and Temperature Sensor</monospace>: The pressure sensor has an absolute accuracy of &#x002B;/&#x2212;50 Pa and relative accuracy of &#x002B;/&#x2212;3 Pa, with an output data rate of up to 200 Hz. Accessed through the I2C bus.</p></list-item>
<list-item>
<p><monospace>GPS Receiver</monospace>: Has a sampling data rate of up to 25 Hz and accuracy down to 1.5 m Circular Error Probability (CEP). Accessed through a dedicated UART bus.</p></list-item>
<list-item>
<p><monospace>Secondary Microcontroller</monospace>: Accessed through the SPI bus.</p></list-item>
<list-item>
<p><monospace>Status LED</monospace></p></list-item>
<list-item>
<p><monospace>Debug UART and Programming Connectors</monospace>: Located on the Main Board.</p></list-item>
</list></p>
<p><bold>Core Advantages of the Flight Controller Board:</bold> The integration of dual-core STM32 microcontrollers with built-in LoRa support, together with dual IMUs and modular expansion via a secondary microcontroller, ensures a level of flexibility and robustness rarely found in conventional flight controllers. This design allows precise IMU fusion, long-range telemetry without additional modules, and fault-tolerant extensions for more complex drone architectures.</p>
</sec>
</sec>
<sec id="s5">
<label>5</label>
<title>Mechanical Design</title>
<p>The quadcopter frame is completely 3D printed using PETG filament, with threaded inserts embedded for mounting the Main Board and the Raspberry Pi Zero W. The chassis consists of four structural components, as illustrated in <xref ref-type="fig" rid="fig-7">Figs. 7</xref>&#x2013;<xref ref-type="fig" rid="fig-10">10</xref>:</p>
<fig id="fig-7">
<label>Figure 7</label>
<caption>
<title>Chassis view at 45 degrees from the top</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-7.tif"/>
</fig><fig id="fig-8">
<label>Figure 8</label>
<caption>
<title>Top view of the chassis with the top enclosure installed</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-8.tif"/>
</fig><fig id="fig-9">
<label>Figure 9</label>
<caption>
<title>Side view of the assembled chassis</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-9.tif"/>
</fig><fig id="fig-10">
<label>Figure 10</label>
<caption>
<title>Top view without the top enclosure, revealing internal components</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-10.tif"/>
</fig>
<p><list list-type="bullet">
<list-item>
<p><bold>Base frame:</bold> Contains the motor arms and the outer walls of the internal enclosure. Threaded inserts are fitted for attaching the front camera.</p></list-item>
<list-item>
<p><bold>Bottom enclosure:</bold> Mounted to the base frame. The Main Board is fixed onto it using custom silicone spacers to reduce vibrations that might affect the IMU sensors. It also supports the bottom camera, the Raspberry Pi, and the battery via dedicated inserts.</p></list-item>
<list-item>
<p><bold>Top enclosure:</bold> Also connected to the base frame, it protects the internal electronics and provides mounting for the LoRa and GPS antennas.</p></list-item>
<list-item>
<p><bold>Landing gear:</bold> Attached to the bottom enclosure and serves as the landing surface.</p></list-item>
</list></p>
<p>An overview of the assembled chassis can be seen in <xref ref-type="fig" rid="fig-7">Fig. 7</xref>, which shows the 3D-printed structure at a 45-degree top-down angle. Detailed view of the top side is shown in <xref ref-type="fig" rid="fig-8">Fig. 8</xref>. Additional angles, including a lateral view (<xref ref-type="fig" rid="fig-9">Fig. 9</xref>) and the internal structure without the top enclosure (<xref ref-type="fig" rid="fig-10">Fig. 10</xref>), provide insight into the internal layout.</p>
</sec>
<sec id="s6">
<label>6</label>
<title>Software Design</title>
<p>The software for both the Flight Controller and the Remote Control has been written in the C programming language, and the hardware abstraction layer and component drivers source code has been kept common between those two, since both systems run on the same microcontroller. At the moment, only the Cortex-M4 core of the microcontrollers is being used.</p>
<p>The developed software drivers are:
<list list-type="bullet">
<list-item><p><monospace>Serial port driver</monospace>: Manages a UART peripheral and allows for receive and transmit data streams to run in parallel with the processor, by using the Direct Memory Access (DMA) peripheral and a circular buffer, for each data direction. This driver is used for the debug UART port, the GPS port and the Remote Control telemetry and control channels port.</p></list-item>
<list-item><p><monospace>GPS driver</monospace>: Implements a basic National Marine Electronics Association (NMEA) sentence parser on top of the serial port driver, compatible with the format used by the GPS module to send its state.</p></list-item>
<list-item><p><monospace>LoRa modem driver</monospace>: Implements the required functionality for sending commands and exchanging data with the LoRa modem integrated in the microcontroller.</p></list-item>
<list-item><p><monospace>RF link driver</monospace>: Is built on top of the LoRa modem driver and implements the whole data protocol for the Remote Control and the Flight Controller, allowing for the transfer of telemetry, configuration and real-time control data. The bidirectional attribute of the protocol is implemented as follows: the Remote Control periodically initiates a data transfer cycle by transmitting a radio packet (such as configuration update or joystick positions) to the Flight Controller, then putting the modem into receive mode. The Flight Controller, which initially is in receive mode, will send a data packet (such as current configuration or telemetry) as acknowledge once it receives the packet sent by the remote control, followed by putting the modem back into receive mode. At the other endpoint, if the Remote Control does not receive an acknowledge packet within a specified time window, it will begin to transmit the next data packet and the cycle repeats.</p></list-item>
<list-item><p><monospace>DShot protocol driver</monospace>: Used by the flight control loop to send the throttle values to the four electronic speed controllers present on the Main Board. The implementation is using the DMA peripheral in order to have the protocol cause close to zero processor overhead. The DShot protocol is widely used in commercially available ESCs. A protocol packet consists of 16 bits of data, with the following composition:
<list list-type="simple">
<list-item><label>-</label><p><monospace>Data</monospace>: 11 bits. Values from 0 to 47 represent commands, while values from 48 to 2047 represent throttle percentages from 0% to 100%.</p></list-item>
<list-item><label>-</label><p><monospace>Telemetry request</monospace>: 1 bit. This protocol functionality is never used, so this bit will always be 0.</p></list-item>
<list-item><label>-</label><p><monospace>Checksum</monospace>: 4 bits. Represents the XOR between the nibbles of the data value having the telemetry request bit concatenated to it, totalling to 3 nibbles.</p></list-item>
</list></p>
<p>A 16-bit packet is encoded as a sequence of 16 pulses with equal period, and a duty cycle of 37.425% for transmitting a zero, and 74.85% for transmitting a one. There are three variants of the DShot protocol, namely DShot150, DShot300 and DShot600, where the number determines the number of maximum kilobits transmitted per second. In the current implementation, the ESC firmware accepts the DShot300 protocol, translating to a bit period of approximatively <inline-formula id="ieqn-73"><mml:math id="mml-ieqn-73"><mml:mn>3.33</mml:mn></mml:math></inline-formula> s or <inline-formula id="ieqn-74"><mml:math id="mml-ieqn-74"><mml:mn>53.3</mml:mn><mml:mtext>&#x00A0;</mml:mtext><mml:mrow><mml:mrow><mml:mi mathvariant="normal">&#x0B5;</mml:mi></mml:mrow><mml:mi mathvariant="normal">s</mml:mi></mml:mrow></mml:math></inline-formula> per packet.</p></list-item>
<list-item>
<p><monospace>Remote control graphics driver</monospace>: Implements graphics drawing functions for the monochrome Organic Light-Emitting Diode (OLED) display connected to the Remote Control module, which has a resolution of 128 <inline-formula id="ieqn-75"><mml:math id="mml-ieqn-75"><mml:mo>&#x00D7;</mml:mo></mml:math></inline-formula> 64 pixels. It is responsible for rendering the user interface, displaying quadcopter orientation, and showing the configuration menu for both the Flight Controller and the Remote Control module, as illustrated in <xref ref-type="fig" rid="fig-11">Fig. 11</xref>.</p>
</list-item>
<list-item>
<p><monospace>Other sensor drivers</monospace>: Used to configure and obtain readings from the sensors, such as the angular velocity, local acceleration, air pressure etc.</p></list-item>
</list></p><fig id="fig-11">
<label>Figure 11</label>
<caption>
<title>Remote control OLED display showing telemetry and menu interface</title>
</caption>
<graphic mimetype="image" mime-subtype="tif" xlink:href="CMC_72749-fig-11.tif"/>
</fig>
<p><bold><italic>Flight Control Loop</italic></bold></p>
<p>The flight control loop running on the quadcopter main microcontroller operates at a frequency of 1 KHz, being executed as a timer interrupt in order to minimize jittering. Its role is to determine the orientation of the quadcopter and apply throttle to the motors in order to maintain the drone orientation at the input setpoint, which is determined either by the operator manually via the Remote Control joysticks, or by the waypoint tracking algorithm. It is implemented as following:
<list list-type="bullet">
<list-item>
<p><monospace>0. Initial conditions</monospace>: initialize the Madgwick Filter orientation estimation to the unit quaternion and the gyroscope bias drift to zero.</p></list-item>
<list-item>
<p><monospace>1. (Start) Obtain inertial measurements</monospace>: Read the local angular velocity and acceleration in the sensor frame of coordinates, by sampling two IMU sensors and calculating the mean of the two obtained accelerations.</p></list-item>
<list-item>
<p><monospace>2. Orientation estimation</monospace>: Perform a Madgwick Filter orientation quaternion estimation step, with the obtained Angular Rate and Gravity data. In the current implementation, a magnetometer is not used in order to also compensate for the yaw axis. That step is performed separately, based on the evolution of the GPS-measured latitude and longitude when the quadcopter is in horizontal motion. Therefore, when the quadcopter is stationary, the estimated rotation around the axis of gravity is prone to gyroscope bias drift.</p></list-item>
<list-item>
<p><monospace>3. PID control loop step</monospace>: Update the 3 PID controllers (for roll, pitch and yaw angles of rotation) based on the current estimated orientation and the target orientation.</p>
<p>Representative PID controller parameters used during testing were <inline-formula id="ieqn-76"><mml:math id="mml-ieqn-76"><mml:msub><mml:mi>K</mml:mi><mml:mi>p</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mn>1.2</mml:mn></mml:math></inline-formula>, <inline-formula id="ieqn-77"><mml:math id="mml-ieqn-77"><mml:msub><mml:mi>K</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mn>0.04</mml:mn></mml:math></inline-formula>, and <inline-formula id="ieqn-78"><mml:math id="mml-ieqn-78"><mml:msub><mml:mi>K</mml:mi><mml:mi>d</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mn>0.35</mml:mn></mml:math></inline-formula>. Increasing <inline-formula id="ieqn-79"><mml:math id="mml-ieqn-79"><mml:msub><mml:mi>K</mml:mi><mml:mi>p</mml:mi></mml:msub></mml:math></inline-formula> reduced response time but introduced overshoot, while higher <inline-formula id="ieqn-80"><mml:math id="mml-ieqn-80"><mml:msub><mml:mi>K</mml:mi><mml:mi>d</mml:mi></mml:msub></mml:math></inline-formula> improved damping and stability. These values provided a balance between responsiveness and stability in hover and maneuvering tests.</p></list-item>
<list-item>
<p><monospace>4. Control mixing</monospace>: Map the outputs of the PID controllers to individual motor throttle values, from 0 (idle throttle value) to 1 (maximum throttle value).</p></list-item>
<list-item>
<p><monospace>5. (End) Send throttle values to the ESCs</monospace>.</p></list-item>
</list></p>
<p><bold>Control optimization results:</bold> The optimized sensor fusion and filtering algorithms significantly improved stability compared with conventional PID-only implementations. In practice, this reduced overshoot in roll/pitch angles by approximately 30% and improved heading stability under wind gusts, confirming the advantages of the proposed approach. These results demonstrate that the integration of quaternion-based filtering and dual-sensor fusion leads to measurable performance gains over traditional methods.</p>
<p><bold>Role of sensor fusion in performance:</bold> The integration of multi-sensor fusion proved essential for flight stability. In particular, combining gyroscope and accelerometer data minimized drift, while the use of redundant IMUs improved robustness under vibration. GPS and barometer inputs enhanced altitude hold performance, and the ToF sensor allowed accurate low-altitude stabilization. Together, these results demonstrate the effectiveness of the proposed fusion scheme compared to single-sensor implementations.</p>
</sec>
<sec id="s7">
<label>7</label>
<title>Results and Validation</title>
<p>To complement the description of the development process, this section presents the outcomes of the Dragonfang platform and comparative testing with conventional solutions. The evaluation focused on flight stability, communication performance, and efficiency.</p>
<sec id="s7_1">
<label>7.1</label>
<title>Flight Stability</title>
<p>The quadcopter was tested in hover and during step-response maneuvers. By combining quaternion-based orientation estimation with dual-IMU sensor fusion, the system reduced overshoot in roll and pitch by approximately 20%&#x2013;25% compared with a PID-only baseline implementation. The use of redundant IMUs improved robustness under vibration, ensuring stable control even when one sensor experienced temporary noise spikes. Altitude hold tests further showed that the integration of barometer and ToF measurements maintained vertical error within 10 cm at heights below 3 m.</p>
</sec>
<sec id="s7_2">
<label>7.2</label>
<title>Communication Range</title>
<p>The LoRa-based telemetry link was evaluated in open-field, line-of-sight conditions. Stable communication was maintained up to 2 km, exceeding the range of typical Wi-Fi-based control solutions by more than an order of magnitude. This extended range makes the platform suitable for long-distance monitoring and autonomous navigation scenarios where Wi-Fi links are insufficient.</p>
</sec>
<sec id="s7_3">
<label>7.3</label>
<title>Power Efficiency</title>
<p>Current consumption measurements indicated that the custom bootstrap MOSFET driver circuits improved ESC efficiency. The integrated design showed an average of 8% lower power loss compared with reference ESC configurations without bootstrap optimization. This efficiency gain reduces heating and increases usable flight time.</p>
</sec>
<sec id="s7_4">
<label>7.4</label>
<title>Comparative Testing</title>
<p>When compared against a standard commercial flight controller (Pixhawk Mini), the Dragonfang platform demonstrated comparable stability while offering several unique advantages: a smaller PCB footprint (45 mm <inline-formula id="ieqn-81"><mml:math id="mml-ieqn-81"><mml:mo>&#x00D7;</mml:mo></mml:math></inline-formula> 45 mm), integrated dual-IMU fusion, and long-range LoRa communication without additional modules. These results highlight the benefits of the open-source, modular design in terms of scalability, robustness, and flexibility.</p>
</sec>
</sec>
<sec id="s8">
<label>8</label>
<title>Conclusion</title>
<p>The work presents a complete and well-integrated implementation of an autonomous quadcopter control system, combining IMU-based stabilization, visual detection, and LoRa telemetry communication, all deployed on custom-designed PCBs and dual-core STM32 microcontrollers. The project demonstrates a balanced hardware and software approach, integrating advanced sensor fusion algorithms, such as the Madgwick Filter for orientation estimation, and PID loops for maintaining flight stability. The use of LoRa technology for long-range data transmission offers an efficient and low-power alternative to Wi-Fi or 4G solutions.</p>
<p>The mechanical design is optimized for 3D printing, maximizing structural flexibility while minimizing production costs. Flight tests have validated the overall functionality of the system, confirming the accuracy of state estimation, flight stability, and energy autonomy under real-world conditions.</p>
<p>Potential future developments include the integration of obstacle avoidance modules based on LiDAR or stereo vision, the extension of the software platform to support swarm flight operations, optimization of energy consumption to enable longer autonomy, and the addition of a magnetometer to improve yaw angle estimation when the quadcopter is stationary.</p>
</sec>
</body>
<back>
<ack>
<p>This work has been supported by Department of Electronic Devices, Circuits and Architectures, Faculty of Electronics, Telecommunications and Information Technology, National University of Science and Technology Politehnica Bucharest, Bucharest, Romania.</p>
</ack>
<sec>
<title>Funding Statement</title>
<p>The authors received no specific funding for this study.</p>
</sec>
<sec>
<title>Author Contributions</title>
<p>The authors confirm contribution to the paper as follows: Conceptualization, Cosmin Dumitru and Alexandru Guzu; methodology, Georgian Nicolae, Alexandru Guzu and Cosmin Dumitru; software, Cosmin Dumitru and Emanuel Pantelimon; validation, Alexandru Guzu, Cosmin Dumitru and Emanuel Pantelimon; formal analysis, Alexandru Guzu and Georgian Nicolae; investigation, Cosmin Dumitru and Emanuel Pantelimon; resources, Georgian Nicolae and Alexandru Guzu; data curation, Cosmin Dumitru and Emanuel Pantelimon; writing&#x2014;original draft preparation, Cosmin Dumitru and Alexandru Guzu; writing&#x2014;review and editing, Georgian Nicolae and Alexandru Guzu; visualization, Cosmin Dumitru, Emanuel Pantelimon and Alexandru Guzu; supervision, Georgian Nicolae. All authors reviewed the results and approved the final version of the manuscript.</p>
</sec>
<sec sec-type="data-availability">
<title>Availability of Data and Materials</title>
<p>The files of this open project are openly available in <monospace>dragonfang-fc</monospace> at <ext-link ext-link-type="uri" xlink:href="https://github.com/Kozma04/dragonfang-fc">https://github.com/Kozma04/dragonfang-fc</ext-link>.</p>
</sec>
<sec>
<title>Ethics Approval</title>
<p>Not applicable.</p>
</sec>
<sec sec-type="COI-statement">
<title>Conflicts of Interest</title>
<p>The authors declare no conflicts of interest to report regarding the present study.</p>
</sec>
<glossary content-type="abbreviations" id="glossary-1">
<title>Abbreviations</title>
<def-list>
<def-item>
<term>BPSK</term>
<def>
<p>Binary Phase-Shift Keying</p>
</def>
</def-item>
<def-item>
<term>BLDC</term>
<def>
<p>Brushless Direct Current</p>
</def>
</def-item>
<def-item>
<term>CEP</term>
<def>
<p>Circular Error Probability</p>
</def>
</def-item>
<def-item>
<term>DShot</term>
<def>
<p>Digital ESC Protocol</p>
</def>
</def-item>
<def-item>
<term>DMA</term>
<def>
<p>Direct Memory Access</p>
</def>
</def-item>
<def-item>
<term>EMF</term>
<def>
<p>Electromotive Force</p>
</def>
</def-item>
<def-item>
<term>ESC</term>
<def>
<p>Electronic Speed Controller</p>
</def>
</def-item>
<def-item>
<term>FOC</term>
<def>
<p>Field-Oriented Control</p>
</def>
</def-item>
<def-item>
<term>FSK</term>
<def>
<p>Frequency-Shift Keying</p>
</def>
</def-item>
<def-item>
<term>GPIO</term>
<def>
<p>General-Purpose Input/Output</p>
</def>
</def-item>
<def-item>
<term>GPS</term>
<def>
<p>Global Positioning System</p>
</def>
</def-item>
<def-item>
<term>IC</term>
<def>
<p>Integrated Circuit</p>
</def>
</def-item>
<def-item>
<term>IMU</term>
<def>
<p>Inertial Measurement Unit</p>
</def>
</def-item>
<def-item>
<term>LiDAR</term>
<def>
<p>Light Detection and Ranging</p>
</def>
</def-item>
<def-item>
<term>LiPo</term>
<def>
<p>Lithium-Polymer</p>
</def>
</def-item>
<def-item>
<term>LoRa</term>
<def>
<p>Long Range (LPWAN Protocol)</p>
</def>
</def-item>
<def-item>
<term>LPWAN</term>
<def>
<p>Low-Power Wide-Area Network</p>
</def>
</def-item>
<def-item>
<term>MARG</term>
<def>
<p>Magnetic, Angular Rate and Gravity</p>
</def>
</def-item>
<def-item>
<term>MCU</term>
<def>
<p>Microcontroller Unit</p>
</def>
</def-item>
<def-item>
<term>MEMS</term>
<def>
<p>Micro-Electro-Mechanical Systems</p>
</def>
</def-item>
<def-item>
<term>MSK</term>
<def>
<p>Minimum Shift Keying</p>
</def>
</def-item>
<def-item>
<term>NMEA</term>
<def>
<p>National Marine Electronics Association</p>
</def>
</def-item>
<def-item>
<term>OLED</term>
<def>
<p>Organic Light-Emitting Diode</p>
</def>
</def-item>
<def-item>
<term>PCB</term>
<def>
<p>Printed Circuit Board</p>
</def>
</def-item>
<def-item>
<term>PID</term>
<def>
<p>Proportional&#x2013;Integral&#x2013;Derivative</p>
</def>
</def-item>
<def-item>
<term>RF</term>
<def>
<p>Radio Frequency</p>
</def>
</def-item>
<def-item>
<term>R-CNN</term>
<def>
<p>Region-Based Convolutional Neural Network</p>
</def>
</def-item>
<def-item>
<term>SPI</term>
<def>
<p>Serial Peripheral Interface</p>
</def>
</def-item>
<def-item>
<term>TCXO</term>
<def>
<p>Temperature-Compensated Crystal Oscillator</p>
</def>
</def-item>
<def-item>
<term>ToF</term>
<def>
<p>Time-of-Flight</p>
</def>
</def-item>
<def-item>
<term>UART</term>
<def>
<p>Universal Asynchronous Receiver/Transmitter</p>
</def>
</def-item>
<def-item>
<term>UAV</term>
<def>
<p>Unmanned Aerial Vehicle</p>
</def>
</def-item>
<def-item>
<term>YOLO</term>
<def>
<p>You Only Look Once</p>
</def>
</def-item>
<def-item>
<term>ZCD</term>
<def>
<p>Zero-Cross Detector</p>
</def>
</def-item>
</def-list>
</glossary>
<ref-list content-type="authoryear">
<title>References</title>
<ref id="ref-1"><label>[1]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Allan</surname> <given-names>S</given-names></string-name>, <string-name><surname>Barczyk</surname> <given-names>M</given-names></string-name></person-group>. <article-title>A low-cost experimental quadcopter drone design for autonomous search-and-rescue missions in GNSS-denied environments</article-title>. <source>Drones</source>. <year>2025</year>;<volume>9</volume>(<issue>8</issue>):<fpage>523</fpage>. doi:<pub-id pub-id-type="doi">10.3390/drones9080523</pub-id>.</mixed-citation></ref>
<ref id="ref-2"><label>[2]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Chandra</surname> <given-names>A</given-names></string-name>, <string-name><surname>Lal</surname> <given-names>P</given-names></string-name></person-group>. <article-title>Higher order sliding mode controller for a quadrotor UAV with a suspended load</article-title>. <source>IFAC-PapersOnLine</source>. <year>2022</year>;<volume>55</volume>(<issue>1</issue>):<fpage>610</fpage>&#x2013;<lpage>5</lpage>. doi:<pub-id pub-id-type="doi">10.1016/j.ifacol.2022.04.100</pub-id>.</mixed-citation></ref>
<ref id="ref-3"><label>[3]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Elhesasy</surname> <given-names>M</given-names></string-name>, <string-name><surname>Dief</surname> <given-names>TN</given-names></string-name>, <string-name><surname>Atallah</surname> <given-names>M</given-names></string-name>, <string-name><surname>Okasha</surname> <given-names>M</given-names></string-name>, <string-name><surname>Kamra</surname> <given-names>MM</given-names></string-name>, <string-name><surname>Yoshida</surname> <given-names>S</given-names></string-name>, <etal>et al</etal></person-group>. <article-title>Non-linear model predictive control using CasADi package for trajectory tracking of quadrotor</article-title>. <source>Energies</source>. <year>2023</year>;<volume>16</volume>(<issue>5</issue>):<fpage>2143</fpage>. doi:<pub-id pub-id-type="doi">10.3390/en16052143</pub-id>.</mixed-citation></ref>
<ref id="ref-4"><label>[4]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Lu</surname> <given-names>F</given-names></string-name>, <string-name><surname>Zeng</surname> <given-names>C</given-names></string-name>, <string-name><surname>Shi</surname> <given-names>H</given-names></string-name>, <string-name><surname>Xu</surname> <given-names>Y</given-names></string-name>, <string-name><surname>Fu</surname> <given-names>S</given-names></string-name></person-group>. <article-title>Real-time detection sensor for unmanned aerial vehicle using an improved YOLOv8s algorithm</article-title>. <source>Sensors</source>. <year>2025</year>;<volume>25</volume>(<issue>19</issue>):<fpage>6246</fpage>. doi:<pub-id pub-id-type="doi">10.3390/s25196246</pub-id>; <pub-id pub-id-type="pmid">41095068</pub-id></mixed-citation></ref>
<ref id="ref-5"><label>[5]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Lee</surname> <given-names>HY</given-names></string-name>, <string-name><surname>Ho</surname> <given-names>HW</given-names></string-name>, <string-name><surname>Zhou</surname> <given-names>Y</given-names></string-name></person-group>. <article-title>Deep learning-based monocular obstacle avoidance for unmanned aerial vehicle navigation in tree plantations</article-title>. <source>J Intell Rob Syst</source>. <year>2020</year>;<volume>101</volume>(<issue>1</issue>):<fpage>163</fpage>. doi:<pub-id pub-id-type="doi">10.1007/s10846-020-01284-z</pub-id>.</mixed-citation></ref>
<ref id="ref-6"><label>[6]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><surname>Cutipa</surname> <given-names>J</given-names></string-name>, <string-name><surname>Lizarbe</surname> <given-names>D</given-names></string-name>, <string-name><surname>Nieves</surname> <given-names>A</given-names></string-name>, <string-name><surname>Carrizales</surname> <given-names>J</given-names></string-name>, <string-name><surname>Sampen</surname> <given-names>L</given-names></string-name>, <string-name><surname>Becerra</surname> <given-names>J</given-names></string-name></person-group>. <article-title>Adaptive autonomous landing system for quadcopter drones through descent assisted by visual recognition</article-title>. In: <conf-name>Proceedings of the 2025 IEEE XXXII International Conference on Electronics, Electrical Engineering and Computing (INTERCON); 2025 Aug 20&#x2013;25</conf-name>; <publisher-loc>Arequipa, Peru</publisher-loc>. p. <fpage>1</fpage>&#x2013;<lpage>8</lpage>. doi:<pub-id pub-id-type="doi">10.1109/INTERCON67304.2025.11244630</pub-id>.</mixed-citation></ref>
<ref id="ref-7"><label>[7]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Chen</surname> <given-names>J</given-names></string-name>, <string-name><surname>Sun</surname> <given-names>R</given-names></string-name>, <string-name><surname>Zhu</surname> <given-names>B</given-names></string-name></person-group>. <article-title>Disturbance observer-based control for small nonlinear UAV systems with transient performance constraint</article-title>. <source>Aerosp Sci Technol</source>. <year>2020</year>;<volume>105</volume>(<issue>16</issue>):<fpage>106028</fpage>. doi:<pub-id pub-id-type="doi">10.1016/j.ast.2020.106028</pub-id>.</mixed-citation></ref>
<ref id="ref-8"><label>[8]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Punpigul</surname> <given-names>N</given-names></string-name>, <string-name><surname>Muangkham</surname> <given-names>M</given-names></string-name>, <string-name><surname>Anantachaisilp</surname> <given-names>P</given-names></string-name>, <string-name><surname>Srisuprapreeda</surname> <given-names>S</given-names></string-name>, <string-name><surname>Singhanat</surname> <given-names>K</given-names></string-name></person-group>. <article-title>Long range UAS mission by LPWAN communication</article-title>. <source>IOP Conf Ser Mater Sci Eng</source>. <year>2020</year>;<volume>965</volume>(<issue>1</issue>):<fpage>012039</fpage>. doi:<pub-id pub-id-type="doi">10.1088/1757-899X/965/1/012039</pub-id>.</mixed-citation></ref>
<ref id="ref-9"><label>[9]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Ghazali</surname> <given-names>MHM</given-names></string-name>, <string-name><surname>Teoh</surname> <given-names>K</given-names></string-name>, <string-name><surname>Rahiman</surname> <given-names>W</given-names></string-name></person-group>. <article-title>A systematic review of real-time deployments of UAV-based LoRa communication network</article-title>. <source>IEEE Access</source>. <year>2021</year>;<volume>9</volume>:<fpage>124817</fpage>&#x2013;<lpage>30</lpage>. doi:<pub-id pub-id-type="doi">10.1109/ACCESS.2021.3110872</pub-id>.</mixed-citation></ref>
<ref id="ref-10"><label>[10]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Gowtham</surname> <given-names>G</given-names></string-name>, <string-name><surname>Raj</surname> <given-names>JR</given-names></string-name></person-group>. <article-title>Mathematical modelling and PID control system implementation for quadcopter frame tarot FY650</article-title>. <source>Aircr Eng Aerosp Technol</source>. <year>2024</year>;<volume>96</volume>(<issue>2</issue>):<fpage>273</fpage>&#x2013;<lpage>84</lpage>. doi:<pub-id pub-id-type="doi">10.1108/AEAT-06-2023-0154</pub-id>.</mixed-citation></ref>
<ref id="ref-11"><label>[11]</label><mixed-citation publication-type="journal"><person-group person-group-type="author"><string-name><surname>Bin Junaid</surname> <given-names>A</given-names></string-name>, <string-name><surname>Diaz De Cerio Sanchez</surname> <given-names>A</given-names></string-name>, <string-name><surname>Betancor Bosch</surname> <given-names>J</given-names></string-name>, <string-name><surname>Vitzilaios</surname> <given-names>N</given-names></string-name>, <string-name><surname>Zweiri</surname> <given-names>Y</given-names></string-name></person-group>. <article-title>Design and implementation of a dual-axis tilting quadcopter</article-title>. <source>Robotics</source>. <year>2018</year>;<volume>7</volume>(<issue>4</issue>):<fpage>65</fpage>. doi:<pub-id pub-id-type="doi">10.3390/robotics7040065</pub-id>.</mixed-citation></ref>
<ref id="ref-12"><label>[12]</label><mixed-citation publication-type="book"><person-group person-group-type="author"><string-name><surname>Troll</surname> <given-names>P</given-names></string-name>, <string-name><surname>Szipka</surname> <given-names>K</given-names></string-name>, <string-name><surname>Archenti</surname> <given-names>A</given-names></string-name></person-group>. <chapter-title>Indoor localization of quadcopters in industrial environment</chapter-title>. In: <source>Advances in transdisciplinary engineering</source>. <publisher-loc>Amsterdam, The Netherlands</publisher-loc>: <publisher-name>IOS Press</publisher-name>; <year>2020</year>. p. <fpage>453</fpage>&#x2013;<lpage>64</lpage>. doi:<pub-id pub-id-type="doi">10.3233/ATDE200183</pub-id>.</mixed-citation></ref>
<ref id="ref-13"><label>[13]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><surname>Bucki</surname> <given-names>N</given-names></string-name>, <string-name><surname>Mueller</surname> <given-names>MW</given-names></string-name></person-group>. <article-title>Design and control of a passively morphing quadcopter</article-title>. In: <conf-name>Proceedings of the International Conference on Robotics and Automation (ICRA 2019); 2019 May 20&#x2013;24</conf-name>; <publisher-loc>Montreal, QC, Canada</publisher-loc>. p. <fpage>9116</fpage>&#x2013;<lpage>22</lpage>. doi:<pub-id pub-id-type="doi">10.1109/ICRA.2019.8794373</pub-id>.</mixed-citation></ref>
<ref id="ref-14"><label>[14]</label><mixed-citation publication-type="conf-proc"><person-group person-group-type="author"><string-name><surname>C&#x00E9;sar</surname> <given-names>R</given-names></string-name>, <string-name><surname>Morales</surname> <given-names>C</given-names></string-name>, <string-name><surname>Ospina</surname> <given-names>J</given-names></string-name>, <string-name><surname>Sanchez</surname> <given-names>JF</given-names></string-name>, <string-name><surname>Caro-Ruiz</surname> <given-names>C</given-names></string-name>, <string-name><surname>Grisales</surname> <given-names>V</given-names></string-name>, <etal>et al</etal></person-group>. <article-title>Mathematical modelling and identification of a quadrotor</article-title>. In: <conf-name>Proceedings of 20th International Conference on Computational Science and Its Applications (ICCSA 2020); 2020 Jul 1&#x2013;4</conf-name>; <publisher-loc>Cagliari, Italy</publisher-loc>. p. <fpage>261</fpage>&#x2013;<lpage>75</lpage>. doi:<pub-id pub-id-type="doi">10.1007/978-3-030-58799-4_19</pub-id>.</mixed-citation></ref>
</ref-list>
</back></article>