
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">



<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
<title>IMU Brick – Tinkerforge</title>

<!--<link type="text/css" rel="stylesheet" href="http://www.tinkerforge.com/static/base_tf.css" />-->
<link type="text/css" rel="stylesheet" href="http://www.tinkerforge.com/static/jquery.lightbox-0.5.css" />
<meta name="keywords" content="Tinkerforge, Open Source Hardware, Bricks, Bricklets, USB Controllable, USB Sensing, USB Controlling" />
<meta name="description" content="Easy-to-use open source hardware. Control motors and sense the environment over USB, Ethernet or Wi-Fi/WLAN with C/C++, C#, Delphi/Lazarus, Java, JavaScript, LabVIEW, Mathematica, MATLAB/Octave, Perl, PHP, Python, Ruby, Shell, Visual Basic .NET or directly over TCP/IP." />
<meta name="copyright" content="Tinkerforge GmbH" />
<!--<script type="text/javascript">document.write('<style>.noscript { display: none; }</style>');</script>-->


    
    <link rel="stylesheet" href="../../_static/documentation_tf.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../../',
        VERSION:     '1.0',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/underscore.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <link rel="top" title="Tinkerforge" href="../../index.html" />
    <link rel="up" title="Bricks" href="Bricks.html" />
    <link rel="next" title="Master Brick" href="Master_Brick.html" />
    <link rel="prev" title="Debug Brick" href="Debug_Brick.html" />

<script type="text/javascript" src="http://www.tinkerforge.com/static/jquery.lightbox-0.5.js"></script>
<script type="text/javascript">$(function() { $('#gallery a').lightBox(); });</script>
<script type="text/javascript">$(function() { $(".sphinxsidebarwrapper").filter(function() { return $.trim($(this).text()).length == 0; }).parent().hide(); });</script>


  </head>
  <body>
<div id="wrapper">
	<div id="tfcontent">
		<div class="boxContent3">


<div class="toctree">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../Getting_Started.html">Getting Started</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../Primer.html">Primer</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Tutorials/Tutorials.html">Tutorials</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../FAQ.html">FAQ</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="reference internal" href="../Hardware.html">Hardware</a><ul class="current">
<li class="toctree-l2 current"><a class="reference internal" href="Bricks.html">Bricks</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="DC_Brick.html">DC Brick</a></li>
<li class="toctree-l3"><a class="reference internal" href="Debug_Brick.html">Debug Brick</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="">IMU Brick</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#features">Features</a></li>
<li class="toctree-l4"><a class="reference internal" href="#description">Description</a></li>
<li class="toctree-l4"><a class="reference internal" href="#technical-specifications">Technical Specifications</a></li>
<li class="toctree-l4"><a class="reference internal" href="#resources">Resources</a></li>
<li class="toctree-l4"><a class="reference internal" href="#connectivity">Connectivity</a></li>
<li class="toctree-l4"><a class="reference internal" href="#test-your-imu-brick">Test your IMU Brick</a></li>
<li class="toctree-l4"><a class="reference internal" href="#imu-calibration">IMU Calibration</a></li>
<li class="toctree-l4"><a class="reference internal" href="#quaternions-vs-euler-angles">Quaternions vs Euler Angles</a></li>
<li class="toctree-l4"><a class="reference internal" href="#computation-of-independent-angles">Computation of independent Angles</a></li>
<li class="toctree-l4"><a class="reference internal" href="#how-it-works">How it works</a></li>
<li class="toctree-l4"><a class="reference internal" href="#programming-interface">Programming Interface</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="Master_Brick.html">Master Brick</a></li>
<li class="toctree-l3"><a class="reference internal" href="RED_Brick.html">RED Brick</a></li>
<li class="toctree-l3"><a class="reference internal" href="Servo_Brick.html">Servo Brick</a></li>
<li class="toctree-l3"><a class="reference internal" href="Stepper_Brick.html">Stepper Brick</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Bricklets/Bricklets.html">Bricklets</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Master_Extensions/Master_Extensions.html">Master Extensions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Power_Supplies/Power_Supplies.html">Power Supplies</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Accessories/Accessories.html">Accessories</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Timeline.html">Timeline</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../Software/Software.html">Software</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../Software/Brickd.html">Brick Daemon (brickd)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Software/Brickv.html">Brick Viewer (brickv)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Software/API_Bindings.html">API Bindings</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Software/Firmwares_And_Plugins.html">Firmwares and Plugins</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Software/Device_Identifier.html">Device Identifier</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Source_Code.html">Source Code and Bug Tracking</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Programming_Interface.html">Programming Interface</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../Kits/Kits.html">Starter Kits</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../Kits/WeatherStation/WeatherStation.html">Weather Station</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Kits/HardwareHacking/HardwareHacking.html">Hardware Hacking</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Kits/ServerRoomMonitoring/ServerRoomMonitoring.html">Server Room Monitoring</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Kits/Blinkenlights/Blinkenlights.html">Blinkenlights</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Kits/InternetOfThings/InternetOfThings.html">Internet of Things</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Kits/CameraSlider/CameraSlider.html">Camera Slider</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../Embedded/Boards.html">Embedded Boards</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../Embedded/Raspberry_Pi.html">Raspberry Pi</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../Specifications.html">Specifications</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../Technical_Data.html">Technical Data</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Low_Level_Protocols/TCPIP.html">TCP/IP Protocol</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Low_Level_Protocols/Modbus.html">Modbus Protocol</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../Low_Level_Protocols/Wireshark_Dissector.html">Wireshark Dissector</a></li>
</ul>
</li>
</ul>

</div>



<div id="shoplink_img">
	<a href="../../../shop/bricks/imu-brick.html"><img alt="Shop" width="32" height="40" src="../../_images/Misc/cart-icon.png" /></a>
</div>
<div id="shoplink_a">
	<a href="../../../shop/bricks/imu-brick.html">In Shop</a>
</div>



    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="imu-brick">
<span id="id1"></span><h1>IMU Brick<a class="headerlink" href="#imu-brick" title="Permalink to this headline">¶</a></h1>
{% from "macros.html" import tfdocstart, tfdocimg, tfdocend %}
{{
    tfdocstart("Bricks/brick_imu_tilted_front_350.jpg",
               "Bricks/brick_imu_tilted_front_600.jpg",
               "IMU Brick")
}}
{{
    tfdocimg("Bricks/brick_imu_tilted_back_100.jpg",
             "Bricks/brick_imu_tilted_back_600.jpg",
             "IMU Brick")
}}
{{
    tfdocimg("Bricks/brick_imu_caption_100.jpg",
             "Bricks/brick_imu_caption_600.jpg",
             "IMU Brick with caption")
}}
{{
    tfdocimg("Bricks/brick_imu_top_100.jpg",
             "Bricks/brick_imu_top_600.jpg",
             "IMU Brick top")
}}
{{
    tfdocimg("Bricks/brick_imu_bottom_100.jpg",
             "Bricks/brick_imu_bottom_600.jpg",
             "IMU Brick bottom")
}}
{{
    tfdocimg("Dimensions/imu_brick_dimensions_100.png",
             "Dimensions/imu_brick_dimensions_600.png",
             "Outline and drilling plan")
}}
{{ tfdocend() }}<div class="section" id="features">
<h2>Features<a class="headerlink" href="#features" title="Permalink to this headline">¶</a></h2>
<ul class="simple">
<li>Full fledged IMU/AHRS with 9 degrees of freedom (3-axis each: accelerometer, compass, gyro)</li>
<li>No accumulating errors, no gimbal lock!</li>
<li>Factory calibrated, easy to recalibrate</li>
<li>Calculates quaternions as well as roll, pitch and yaw</li>
<li>Directly readable by USB, extendable by two Bricklet ports</li>
<li>API for many programming languages available</li>
</ul>
</div>
<div class="section" id="description">
<span id="imu-brick-description"></span><h2>Description<a class="headerlink" href="#description" title="Permalink to this headline">¶</a></h2>
<p>The IMU <a class="reference internal" href="../../Primer.html#primer-bricks"><em>Brick</em></a> is equipped with a 3-axis
accelerometer, magnetometer (compass) and gyroscope and works as a <strong>USB</strong>
<a class="reference external" href="http://en.wikipedia.org/wiki/Inertial_measurement_unit">inertial measurement unit</a>.
It can measure 9 degrees of freedom and computes
<a class="reference external" href="http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation">quaternions</a>
as well as <a class="reference external" href="http://en.wikipedia.org/wiki/File:Rollpitchyawplain.png">roll, pitch and yaw</a> information.
It is a complete <a class="reference external" href="http://en.wikipedia.org/wiki/AHRS">attitude and heading reference system</a>.</p>
<p>The API, provided for many <a class="reference internal" href="#imu-brick-programming-interface"><em>programming languages</em></a>,
allows access to the calculated data and also the acceleration, magnetic field
and angular velocity of the three axes. If the quaternion representation is
used, the IMU Brick does not have a
<a class="reference external" href="http://en.wikipedia.org/wiki/Gimbal_lock">gimbal lock</a>,
as known from Euler angles.</p>
<p>Two <a class="reference internal" href="../../Primer.html#primer-bricklets"><em>Bricklet</em></a> ports can be used to extend the
features of this Brick. For Example a <a class="reference internal" href="../Bricklets/GPS.html#gps-bricklet"><em>GPS Bricklet</em></a> can be
attached to get position information.
A
<a class="reference external" href="http://www.youtube.com/watch?v=TaqtzG7lyp0">Youtube video</a> shows, how the
Brick can be used together with a <a class="reference internal" href="../Bricklets/Barometer.html#barometer-bricklet"><em>Barometer Bricklet</em></a>
to gain altitude information.</p>
<p>The IMU Brick can be use together with other Bricks in a
<a class="reference internal" href="../../Primer.html#primer-stack"><em>stack</em></a>. For example an additional
<a class="reference internal" href="Master_Brick.html#master-brick"><em>Master Brick</em></a> with
<a class="reference internal" href="../../Primer.html#primer-master-extensions"><em>Master Extension</em></a> allows to replace the USB
connection by other cable based (<a class="reference internal" href="../Master_Extensions/RS485_Extension.html#rs485-extension"><em>RS485</em></a>,
<a class="reference internal" href="../Master_Extensions/Ethernet_Extension.html#ethernet-extension"><em>Ethernet</em></a>) or wireless (<a class="reference internal" href="../Master_Extensions/WIFI_Extension.html#wifi-extension"><em>WIFI</em></a>)
connections.</p>
</div>
<div class="section" id="technical-specifications">
<h2>Technical Specifications<a class="headerlink" href="#technical-specifications" title="Permalink to this headline">¶</a></h2>
<table border="1" class="docutils">
<colgroup>
<col width="46%" />
<col width="54%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Property</th>
<th class="head">Value</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Acceleration, Magnetic, Angular Velocity Resolution</td>
<td>12bit, 16bit, 16bit</td>
</tr>
<tr class="row-odd"><td>Roll, Pitch, Yaw Resolution</td>
<td>0.01° steps</td>
</tr>
<tr class="row-even"><td>Quaternion Resolution</td>
<td>32bit</td>
</tr>
<tr class="row-odd"><td>Sampling Rate</td>
<td>500Hz</td>
</tr>
<tr class="row-even"><td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>Bricklet Ports</td>
<td>2</td>
</tr>
<tr class="row-even"><td>Dimensions (W x D x H)</td>
<td>40 x 40 x 16mm (1.57 x 1.57 x 0.63&quot;)</td>
</tr>
<tr class="row-odd"><td>Weight</td>
<td>12g</td>
</tr>
<tr class="row-even"><td>Current Consumption</td>
<td>53mA</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="resources">
<h2>Resources<a class="headerlink" href="#resources" title="Permalink to this headline">¶</a></h2>
<ul class="simple">
<li>3-axis Accelerometer/Magnetometer LSM303 datasheet (<a class="reference external" href="https://github.com/Tinkerforge/imu-brick/raw/master/datasheets/LSM303.pdf">Download</a>)</li>
<li>3-axis Gyroscope ITG-3200 datasheet (<a class="reference external" href="https://github.com/Tinkerforge/imu-brick/raw/master/datasheets/ITG3200.pdf">Download</a>)</li>
<li>Schematic (<a class="reference external" href="https://github.com/Tinkerforge/imu-brick/raw/master/hardware/imu-schematic.pdf">Download</a>)</li>
<li>Outline and drilling plan (<a class="reference external" href="../../_images/Dimensions/imu_brick_dimensions.png">Download</a>)</li>
<li>Source code and design files (<a class="reference external" href="https://github.com/Tinkerforge/imu-brick/zipball/master">Download</a>)</li>
</ul>
</div>
<div class="section" id="connectivity">
<h2>Connectivity<a class="headerlink" href="#connectivity" title="Permalink to this headline">¶</a></h2>
<p>The following picture depicts the different connection possibilities of the
IMU Brick.</p>
<a class="reference external image-reference" href="../../_images/Bricks/brick_imu_caption_800.jpg"><img alt="IMU Brick with caption" class="align-center" src="../../_images/brick_imu_caption_600.jpg" style="width: 600.0px; height: 385.0px;" /></a>
</div>
<div class="section" id="test-your-imu-brick">
<span id="imu-brick-test"></span><h2>Test your IMU Brick<a class="headerlink" href="#test-your-imu-brick" title="Permalink to this headline">¶</a></h2>
<p>To test a IMU Brick you need to have <a class="reference internal" href="../../Software/Brickd.html#brickd"><em>Brick Daemon</em></a> and
<a class="reference internal" href="../../Software/Brickv.html#brickv"><em>Brick Viewer</em></a> installed. Brick Daemon acts as a proxy between
the USB interface of the Bricks and the API bindings. Brick Viewer connects
to Brick Daemon. It helps to figure out basic information about the connected
Bricks and Bricklets and allows to test them.</p>
<p>Now connect the Brick to the PC over USB, you should see a new tab named
&quot;IMU Brick&quot; in the Brick Viewer after a moment. Select this tab.</p>
<a class="reference external image-reference" href="../../_images/Bricks/imu_brickv.jpg"><img alt="IMU Brick in Brick Viewer" class="align-center" src="../../_images/imu_brickv.jpg" style="width: 540.0px; height: 315.6px;" /></a>
<p>You can see all of the available data form the IMU Brick. If you hold the
IMU Brick in the orientation as shown in the image and press
&quot;Save Orientation&quot;, the movements that you make with the IMU Brick should be
mirrored in the Brick Viewer. Before you press &quot;Save Orientation&quot; you should
hold the IMU Brick still for about 15 seconds, so it can converge to the
correct position.</p>
<p>After this test you can go on with writing your own application.
See the <a class="reference internal" href="#imu-brick-programming-interface"><em>Programming Interface</em></a>
section for the API of the IMU Brick and examples in different programming
languages.</p>
</div>
<div class="section" id="imu-calibration">
<h2>IMU Calibration<a class="headerlink" href="#imu-calibration" title="Permalink to this headline">¶</a></h2>
<p>The IMU Brick comes factory calibrated and should work out of the box. It is
however easy to recalibrate, if necessary.</p>
<p>The factory calibration has taken place in a room without any significant
interfering magnetic fields. If you want to operate the IMU Brick near something
that has a magnetic field (e.g. near a motor), you will have to recalibrate
the magnetometer in the exact position where it will be used later on!</p>
<p>To calibrate the magnetometer press on &quot;Calibrate&quot; in the Brick Viewer and
choose the &quot;Magnetometer&quot; tab of the new window. Press &quot;Start Calibration&quot;
and now change the orientation of the IMU Brick until the bias and gain values
shown in the GUI do not change anymore. Press &quot;Ready&quot; when this is the case
and you are done.</p>
<p>Accelerometer and gyroscope can be calibrated similarly, follow the
instructions as given by the calibration tool. We recommend that you
export the calibration before you start recalibrating the accelerometer
and the gyroscope, so you are able to go back to the old calibration.</p>
<p>We recommend that you don't try to recalibrate the gyroscope gain, it is not
possible without suitable external machinery.</p>
<p>The factory calibration for your IMU Brick can be found at:</p>
<div class="highlight-python"><div class="highlight"><pre>http://download.tinkerforge.com/imu_calibration/YOUR_IMU_UID.txt
</pre></div>
</div>
<p>Replace <tt class="docutils literal"><span class="pre">YOUR_IMU_UID</span></tt> by the UID of your IMU Brick.
If you accidentally miscalibrated a sensor or you
flashed a new firmware version, you can reimport the factory calibration.
To do so go to the &quot;IMU Brick&quot; in the Brick Viewer, click the &quot;Calibrate&quot;
button and select the &quot;Im/Export&quot; tab. Finally copy and paste the content of
<tt class="docutils literal"><span class="pre">YOUR_IMU_UID.txt</span></tt> to the textbox and click &quot;Import&quot;.</p>
<p>Since Brick Viewer version 1.1.13 you can also click the &quot;Restore Factory
Calibration&quot; button, that automatically downloads and imports the factory
calibration for you.</p>
<p>A video how we calibrate the IMU Bricks can be found:
<a class="reference external" href="http://www.youtube.com/watch?v=JckgemCHvCA">here</a>.</p>
</div>
<div class="section" id="quaternions-vs-euler-angles">
<h2>Quaternions vs Euler Angles<a class="headerlink" href="#quaternions-vs-euler-angles" title="Permalink to this headline">¶</a></h2>
<p>We highly recommend that you use
<a class="reference external" href="http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation">quaternions</a>
in your project rather than Euler angles (<a class="reference external" href="http://en.wikipedia.org/wiki/Yaw,_pitch,_and_roll">yaw, pitch and roll</a>), since the latter
exhibits a <a class="reference external" href="http://en.wikipedia.org/wiki/Gimbal_lock">gimbal lock</a>.</p>
<p>A formula to transform quaternions to rotation matrices can be found in the
API documentation. Note that Euler angles always have an order in which they
are applied. The order for the IMU Brick is: roll, yaw, pitch.</p>
</div>
<div class="section" id="computation-of-independent-angles">
<h2>Computation of independent Angles<a class="headerlink" href="#computation-of-independent-angles" title="Permalink to this headline">¶</a></h2>
<p>It is not possible to get angles for all 3 axis that are completely independent.
At least at the gimbal lock positions there will be jumps of 180° for
some of the angles. This is simply not possible otherwise.</p>
<p>If you want rotation angles for the x, y and z axis for a given base
position, you have to rotate the quaternion according to your base
position and calculate the angles after that. The following Python example
does exactly that and it should be easy to understand and translate in other
languages. Note that there are gimbal locks at +90° and -90° from each of the
angles. The base position will be (0,0,0):</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/env python</span>
<span class="c"># -*- coding: utf-8 -*-</span>

<span class="kn">from</span> <span class="nn">tinkerforge.ip_connection</span> <span class="kn">import</span> <span class="n">IPConnection</span>
<span class="kn">from</span> <span class="nn">tinkerforge.brick_imu</span> <span class="kn">import</span> <span class="n">IMU</span>

<span class="kn">import</span> <span class="nn">math</span>
<span class="kn">import</span> <span class="nn">time</span>

<span class="k">class</span> <span class="nc">Q</span><span class="p">:</span>
    <span class="n">HOST</span> <span class="o">=</span> <span class="s">&quot;localhost&quot;</span>
    <span class="n">PORT</span> <span class="o">=</span> <span class="mi">4223</span>
    <span class="n">UID</span> <span class="o">=</span> <span class="s">&quot;9yEBJVEHaem&quot;</span> <span class="c"># Change to your UID</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">base_x</span> <span class="o">=</span> <span class="mf">0.0</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">base_y</span> <span class="o">=</span> <span class="mf">0.0</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">base_z</span> <span class="o">=</span> <span class="mf">0.0</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">base_w</span> <span class="o">=</span> <span class="mf">0.0</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">ipcon</span> <span class="o">=</span> <span class="n">IPConnection</span><span class="p">()</span> <span class="c"># Create IPconnection</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">imu</span> <span class="o">=</span> <span class="n">IMU</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">UID</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ipcon</span><span class="p">)</span> <span class="c"># Create device object</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">ipcon</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">HOST</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">PORT</span><span class="p">)</span> <span class="c"># Connect to brickd</span>

        <span class="c"># Wait for IMU to settle</span>
        <span class="k">print</span> <span class="s">&#39;Set IMU to base position and wait for 10 seconds&#39;</span>
        <span class="k">print</span> <span class="s">&#39;Base position will be 0 for all angles&#39;</span>
        <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
        <span class="n">q</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">imu</span><span class="o">.</span><span class="n">get_quaternion</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">set_base_coordinates</span><span class="p">(</span><span class="n">q</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">q</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">q</span><span class="o">.</span><span class="n">z</span><span class="p">,</span> <span class="n">q</span><span class="o">.</span><span class="n">w</span><span class="p">)</span>

        <span class="c"># Set period for quaternion callback to 10ms</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">imu</span><span class="o">.</span><span class="n">set_quaternion_period</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>

        <span class="c"># Register quaternion callback</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">imu</span><span class="o">.</span><span class="n">register_callback</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">imu</span><span class="o">.</span><span class="n">CALLBACK_QUATERNION</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">quaternion_cb</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">quaternion_cb</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">,</span> <span class="n">w</span><span class="p">):</span>
        <span class="c"># Use conjugate of quaternion to rotate coordinates according to base system</span>
        <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">,</span> <span class="n">w</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">make_relative_coordinates</span><span class="p">(</span><span class="o">-</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="n">y</span><span class="p">,</span> <span class="o">-</span><span class="n">z</span><span class="p">,</span> <span class="n">w</span><span class="p">)</span>

        <span class="n">x_angle</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">atan2</span><span class="p">(</span> <span class="mf">2.0</span><span class="o">*</span><span class="p">(</span><span class="n">y</span><span class="o">*</span><span class="n">z</span> <span class="o">-</span> <span class="n">w</span><span class="o">*</span><span class="n">x</span><span class="p">),</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="mf">2.0</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="o">*</span><span class="n">y</span><span class="p">))</span><span class="o">*</span><span class="mi">180</span><span class="o">/</span><span class="n">math</span><span class="o">.</span><span class="n">pi</span><span class="p">)</span>
        <span class="n">y_angle</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">atan2</span><span class="p">(</span><span class="o">-</span><span class="mf">2.0</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">z</span> <span class="o">+</span> <span class="n">w</span><span class="o">*</span><span class="n">y</span><span class="p">),</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="mf">2.0</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="o">*</span><span class="n">y</span><span class="p">))</span><span class="o">*</span><span class="mi">180</span><span class="o">/</span><span class="n">math</span><span class="o">.</span><span class="n">pi</span><span class="p">)</span>
        <span class="n">z_angle</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">atan2</span><span class="p">(</span><span class="o">-</span><span class="mf">2.0</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">y</span> <span class="o">+</span> <span class="n">w</span><span class="o">*</span><span class="n">z</span><span class="p">),</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="mf">2.0</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">*</span><span class="n">x</span> <span class="o">+</span> <span class="n">z</span><span class="o">*</span><span class="n">z</span><span class="p">))</span><span class="o">*</span><span class="mi">180</span><span class="o">/</span><span class="n">math</span><span class="o">.</span><span class="n">pi</span><span class="p">)</span>

        <span class="k">print</span> <span class="s">&#39;x: {0}, y: {1}, z: {2}&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">x_angle</span><span class="p">,</span> <span class="n">y_angle</span><span class="p">,</span> <span class="n">z_angle</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">set_base_coordinates</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">,</span> <span class="n">w</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">base_x</span> <span class="o">=</span> <span class="n">x</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">base_y</span> <span class="o">=</span> <span class="n">y</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">base_z</span> <span class="o">=</span> <span class="n">z</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">base_w</span> <span class="o">=</span> <span class="n">w</span>

    <span class="k">def</span> <span class="nf">make_relative_coordinates</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">,</span> <span class="n">w</span><span class="p">):</span>
        <span class="c"># Multiply base quaternion with current quaternion</span>
        <span class="k">return</span> <span class="p">(</span>
            <span class="n">w</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_x</span> <span class="o">+</span> <span class="n">x</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_w</span> <span class="o">+</span> <span class="n">y</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_z</span> <span class="o">-</span> <span class="n">z</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_y</span><span class="p">,</span>
            <span class="n">w</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_y</span> <span class="o">-</span> <span class="n">x</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_z</span> <span class="o">+</span> <span class="n">y</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_w</span> <span class="o">+</span> <span class="n">z</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_x</span><span class="p">,</span>
            <span class="n">w</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_z</span> <span class="o">+</span> <span class="n">x</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_y</span> <span class="o">-</span> <span class="n">y</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_x</span> <span class="o">+</span> <span class="n">z</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_w</span><span class="p">,</span>
            <span class="n">w</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_w</span> <span class="o">-</span> <span class="n">x</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_x</span> <span class="o">-</span> <span class="n">y</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_y</span> <span class="o">-</span> <span class="n">z</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_z</span>
        <span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
    <span class="n">q</span> <span class="o">=</span> <span class="n">Q</span><span class="p">()</span>

    <span class="nb">raw_input</span><span class="p">(</span><span class="s">&#39;Press key to exit</span><span class="se">\n</span><span class="s">&#39;</span><span class="p">)</span> <span class="c"># Use input() in Python 3</span>
    <span class="n">q</span><span class="o">.</span><span class="n">ipcon</span><span class="o">.</span><span class="n">disconnect</span><span class="p">()</span>
</pre></div>
</div>
<p>Paul Balzer from MechLab Engineering has additional <a class="reference external" href="https://github.com/MechLabEngineering/TinkerforgeAttitude">code on GitHub</a> that uses the
quaternions to calculate yaw, pitch and roll in a vehicle coordinate system according
to DIN70000. It is notably consistently a right-handed coordinate system.</p>
</div>
<div class="section" id="how-it-works">
<h2>How it works<a class="headerlink" href="#how-it-works" title="Permalink to this headline">¶</a></h2>
<p>With the sensor data gathered by the IMU Brick (angular velocity, acceleration and
magnetic field), it is possible to apply sensor fusion to acquire an absolute
orientation.</p>
<p>For this process often a
<a class="reference external" href="http://en.wikipedia.org/wiki/Kalman_filter">Kalman Filter</a> is used.
The filter that is used in the IMU Brick is based on
<a class="reference external" href="http://www.x-io.co.uk/res/doc/madgwick_internal_report.pdf">this paper</a>
by <a class="reference external" href="http://www.x-io.co.uk/open-source-imu-and-ahrs-algorithms/">S. O. Madgwick</a>.
In our tests this new state of the art filter
could achieve significantly better results than a Kalman Filter. Madgwick
describes the approach of his filter as follows:</p>
<blockquote>
<div>[...] the filter calculates the orientation by numerically integrating the
estimated orientation rate. It is computed as the rate of change of
orientation measured by the gyroscopes. The magnitude of the gyroscope
measurement error is removed in the direction of the estimated error,
which is computed from accelerometer and magnetometer measurements.</div></blockquote>
<p>The following image shows the different steps of the filter:</p>
<a class="reference external image-reference" href="../../_images/Bricks/imu_math_magic.png"><img alt="Block diagram of orientation filter from S. O. Madgwick: &quot;An efficient orientation filter for inertial and inertial/magnetic sensor arrays&quot;, University of Bristol, April 2010." class="align-center" src="../../_images/imu_math_magic.png" style="width: 900.0px; height: 555.0px;" /></a>
<p>Image and explanation from S. O. Madgwick: &quot;An efficient orientation filter
for inertial and inertial/magnetic sensor arrays&quot;, University of Bristol,
April 2010.</p>
</div>
<div class="section" id="programming-interface">
<span id="imu-brick-programming-interface"></span><h2>Programming Interface<a class="headerlink" href="#programming-interface" title="Permalink to this headline">¶</a></h2>
<p>See <a class="reference internal" href="../../Programming_Interface.html#programming-interface"><em>Programming Interface</em></a> for a detailed description.</p>
<table border="1" class="docutils">
<colgroup>
<col width="45%" />
<col width="18%" />
<col width="18%" />
<col width="18%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Language</th>
<th class="head">API</th>
<th class="head">Examples</th>
<th class="head">Installation</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Modbus</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Modbus.html#imu-brick-modbus-api"><em>API</em></a></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class="row-odd"><td>TCP/IP</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_TCPIP.html#imu-brick-tcpip-api"><em>API</em></a></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr class="row-even"><td>C/C++</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_C.html#imu-brick-c-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_C.html#imu-brick-c-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_C.html#api-bindings-c"><em>Installation</em></a></td>
</tr>
<tr class="row-odd"><td>C#</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_CSharp.html#imu-brick-csharp-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_CSharp.html#imu-brick-csharp-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_CSharp.html#api-bindings-csharp"><em>Installation</em></a></td>
</tr>
<tr class="row-even"><td>Delphi/Lazarus</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Delphi.html#imu-brick-delphi-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Delphi.html#imu-brick-delphi-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_Delphi.html#api-bindings-delphi"><em>Installation</em></a></td>
</tr>
<tr class="row-odd"><td>Java</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Java.html#imu-brick-java-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Java.html#imu-brick-java-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_Java.html#api-bindings-java"><em>Installation</em></a></td>
</tr>
<tr class="row-even"><td>JavaScript</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_JavaScript.html#imu-brick-javascript-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_JavaScript.html#imu-brick-javascript-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_JavaScript.html#api-bindings-javascript"><em>Installation</em></a></td>
</tr>
<tr class="row-odd"><td>LabVIEW</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_LabVIEW.html#imu-brick-labview-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_LabVIEW.html#imu-brick-labview-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_LabVIEW.html#api-bindings-labview"><em>Installation</em></a></td>
</tr>
<tr class="row-even"><td>Mathematica</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Mathematica.html#imu-brick-mathematica-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Mathematica.html#imu-brick-mathematica-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_Mathematica.html#api-bindings-mathematica"><em>Installation</em></a></td>
</tr>
<tr class="row-odd"><td>MATLAB/Octave</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_MATLAB.html#imu-brick-matlab-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_MATLAB.html#imu-brick-matlab-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_MATLAB.html#api-bindings-matlab"><em>Installation</em></a></td>
</tr>
<tr class="row-even"><td>Perl</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Perl.html#imu-brick-perl-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Perl.html#imu-brick-perl-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_Perl.html#api-bindings-perl"><em>Installation</em></a></td>
</tr>
<tr class="row-odd"><td>PHP</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_PHP.html#imu-brick-php-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_PHP.html#imu-brick-php-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_PHP.html#api-bindings-php"><em>Installation</em></a></td>
</tr>
<tr class="row-even"><td>Python</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Python.html#imu-brick-python-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Python.html#imu-brick-python-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_Python.html#api-bindings-python"><em>Installation</em></a></td>
</tr>
<tr class="row-odd"><td>Ruby</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Ruby.html#imu-brick-ruby-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Ruby.html#imu-brick-ruby-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_Ruby.html#api-bindings-ruby"><em>Installation</em></a></td>
</tr>
<tr class="row-even"><td>Shell</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Shell.html#imu-brick-shell-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_Shell.html#imu-brick-shell-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_Shell.html#api-bindings-shell"><em>Installation</em></a></td>
</tr>
<tr class="row-odd"><td>Visual Basic .NET</td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_VBNET.html#imu-brick-vbnet-api"><em>API</em></a></td>
<td><a class="reference internal" href="../../Software/Bricks/IMU_Brick_VBNET.html#imu-brick-vbnet-examples"><em>Examples</em></a></td>
<td><a class="reference internal" href="../../Software/API_Bindings_VBNET.html#api-bindings-vbnet"><em>Installation</em></a></td>
</tr>
</tbody>
</table>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
		<div id="tf_license">
			<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">
				<img alt="Creative Commons Licence" width="88" height="31" style="border-width:0" src="/static/images/cc_license_logo.png" />
			</a>
			The content of this page is licensed under
			<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution 3.0 Unported License</a>.
		</div>
		</div>
	</div>
</div>

    <div class="footer">
        &copy; Copyright 2011-2015, Olaf Lüke (olaf@tinkerforge.com).
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2.2.
    </div>
  </body>
</html>