<phyphox version="1.7">
    <title>Attitude</title>
    <category>Tools</category>
    <description>
        Determine the attitude (absolute rotation) of your device.

        This is based on a virtual sensor provided by your device. It typically uses multiple sensors (i.e. accelerometer, magnetometer and gyroscope) to determine the absolute orientation of the device. Depending on your manufacturer's implementation, this may be subject to drift or exhibit offsets.
    </description>
    <data-containers>
        <container size="0">win</container>
        <container size="0">xin</container>
        <container size="0">yin</container>
        <container size="0">zin</container>
        <container size="0">woff</container>
        <container size="0">xoff</container>
        <container size="0">yoff</container>
        <container size="0">zoff</container>
        <container size="0">w</container>
        <container size="0">x</container>
        <container size="0">y</container>
        <container size="0">z</container>
        <container size="0">t</container>
        <container size="0">direct</container>
        <container size="0">yaw</container>
        <container size="0">pitch</container>
        <container size="0">roll</container>
        <container size="1" init="1">w0</container>
        <container size="1" init="0">x0</container>
        <container size="1" init="0">y0</container>
        <container size="1" init="0">z0</container>
        <container size="1" init="1">wlast</container>
        <container size="1" init="0">xlast</container>
        <container size="1" init="0">ylast</container>
        <container size="1" init="0">zlast</container>
        <container size="1">count</container>
        <container size="1">tmax</container>
    </data-containers>
    <input>
        <sensor type="attitude">
            <output component="x">xin</output>
            <output component="y">yin</output>
            <output component="z">zin</output>
            <output component="abs">win</output>
            <output component="t">t</output>
        </sensor>
    </input>
    <views>
        <view label="Simple">
            <button label="Zero">
                <input>wlast</input>
                <output>w0</output>
                <input>xlast</input>
                <output>x0</output>
                <input>ylast</input>
                <output>y0</output>
                <input>zlast</input>
                <output>z0</output>
            </button>
            <value label="Direct ⍺" unit="°" size="2" precision="1">
                <input>direct</input>
            </value>
            <value label="Yaw ψ" unit="°" size="2" precision="1">
                <input>yaw</input>
            </value>
            <value label="Pitch θ" unit="°" size="2" precision="1">
                <input>pitch</input>
            </value>
            <value label="Roll φ" unit="°" size="2" precision="1">
                <input>roll</input>
            </value>
        </view>
        <view label="Graph">
            <button label="Zero">
                <input>wlast</input>
                <output>w0</output>
                <input>xlast</input>
                <output>x0</output>
                <input>ylast</input>
                <output>y0</output>
                <input>zlast</input>
                <output>z0</output>
            </button>
            <graph label="Direct" labelX="t" unitX="s" labelY="⍺" unitY="°" partialUpdate="true">
                <input axis="x">t</input>
                <input axis="y">direct</input>
            </graph>
            <graph label="Yaw" labelX="t" unitX="s" labelY="ψ" unitY="°" partialUpdate="true">
                <input axis="x">t</input>
                <input axis="y">yaw</input>
            </graph>
            <graph label="Pitch" labelX="t" unitX="s" labelY="θ" unitY="°" partialUpdate="true">
                <input axis="x">t</input>
                <input axis="y">pitch</input>
            </graph>
            <graph label="Roll" labelX="t" unitX="s" labelY="φ" unitY="°" partialUpdate="true">
                <input axis="x">t</input>
                <input axis="y">roll</input>
            </graph>
        </view>
        <view label="Quaternions">
            <graph label="Quaternion w" labelX="t" unitX="s" labelY="w" partialUpdate="true">
                <input axis="x">t</input>
                <input axis="y">w</input>
            </graph>
            <graph label="Quaternion x" labelX="t" unitX="s" labelY="x" partialUpdate="true">
                <input axis="x">t</input>
                <input axis="y">x</input>
            </graph>
            <graph label="Quaternion y" labelX="t" unitX="s" labelY="y" partialUpdate="true">
                <input axis="x">t</input>
                <input axis="y">y</input>
            </graph>
            <graph label="Quaternion z" labelX="t" unitX="s" labelY="z" partialUpdate="true">
                <input axis="x">t</input>
                <input axis="y">z</input>
            </graph>
        </view>
    </views>
    <analysis optimization="true">
        <!-- Store last raw value, so we can use it for the zero button -->
        <append>
            <input clear="false">win</input>
            <output>wlast</output>
        </append>
        <append>
            <input clear="false">xin</input>
            <output>xlast</output>
        </append>
        <append>
            <input clear="false">yin</input>
            <output>ylast</output>
        </append>
        <append>
            <input clear="false">zin</input>
            <output>zlast</output>
        </append>

        <!-- Apply zero offset to new values -->
        <formula formula="abs([1]*[5_]+[2]*[6_]+[3]*[7_]+[4]*[8_])">
            <input clear="false">w0</input>
            <input clear="false">x0</input>
            <input clear="false">y0</input>
            <input clear="false">z0</input>
            <input clear="false">win</input>
            <input clear="false">xin</input>
            <input clear="false">yin</input>
            <input clear="false">zin</input>
            <output clear="true">woff</output>
        </formula>

        <formula formula="([1]*[6_]-[2]*[5_]-[3]*[8_]+[4]*[7_])*sign([1]*[5_]+[2]*[6_]+[3]*[7_]+[4]*[8_])">
            <input clear="false">w0</input>
            <input clear="false">x0</input>
            <input clear="false">y0</input>
            <input clear="false">z0</input>
            <input clear="false">win</input>
            <input clear="false">xin</input>
            <input clear="false">yin</input>
            <input clear="false">zin</input>
            <output clear="true">xoff</output>
        </formula>

        <formula formula="([1]*[7_]+[2]*[8_]-[3]*[5_]-[4]*[6_])*sign([1]*[5_]+[2]*[6_]+[3]*[7_]+[4]*[8_])">
            <input clear="false">w0</input>
            <input clear="false">x0</input>
            <input clear="false">y0</input>
            <input clear="false">z0</input>
            <input clear="false">win</input>
            <input clear="false">xin</input>
            <input clear="false">yin</input>
            <input clear="false">zin</input>
            <output clear="true">yoff</output>
        </formula>

        <formula formula="([1]*[8_]-[2]*[7_]+[3]*[6_]-[4]*[5_])*sign([1]*[5_]+[2]*[6_]+[3]*[7_]+[4]*[8_])">
            <input clear="false">w0</input>
            <input clear="false">x0</input>
            <input clear="false">y0</input>
            <input clear="false">z0</input>
            <input clear="true">win</input>
            <input clear="true">xin</input>
            <input clear="true">yin</input>
            <input clear="true">zin</input>
            <output clear="true">zoff</output>
        </formula>

        <!-- Calculate angles for new values -->

        <formula formula="2*acos([1_])*57.295779513">
            <input clear="false">woff</input>
            <input clear="false">xoff</input>
            <input clear="false">yoff</input>
            <input clear="false">zoff</input>
            <output clear="false">direct</output>
        </formula>

        <formula formula="atan2(2*([1_]*[2_]+[3_]*[4_]),1-2*([2_]*[2_]+[3_]*[3_]))*57.295779513">
            <input clear="false">woff</input>
            <input clear="false">xoff</input>
            <input clear="false">yoff</input>
            <input clear="false">zoff</input>
            <output clear="false">yaw</output>
        </formula>

        <formula formula="asin(2*([1_]*[3_]-[2_]*[4_]))*57.295779513">
            <input clear="false">woff</input>
            <input clear="false">xoff</input>
            <input clear="false">yoff</input>
            <input clear="false">zoff</input>
            <output clear="false">pitch</output>
        </formula>

        <formula formula="atan2(2*([1_]*[4_]+[2_]*[3_]),1-2*([3_]*[3_]+[4_]*[4_]))*57.295779513">
            <input clear="false">woff</input>
            <input clear="false">xoff</input>
            <input clear="false">yoff</input>
            <input clear="false">zoff</input>
            <output clear="false">roll</output>
        </formula>

        <!-- APpend new values (with offset removed) to results -->

        <append>
            <input clear="true">woff</input>
            <output clear="false">w</output>
        </append>
        <append>
            <input clear="true">xoff</input>
            <output clear="false">x</output>
        </append>
        <append>
            <input clear="true">yoff</input>
            <output clear="false">y</output>
        </append>
        <append>
            <input clear="true">zoff</input>
            <output clear="false">z</output>
        </append>

        <!-- Create time axis -->

        <count>
            <input clear="false">w</input>
            <output>count</output>
        </count>
        <formula formula="([1]-1)*0.01">
            <input clear="false">count</input>
            <output>tmax</output>
        </formula>
        <ramp>
            <input as="start" type="value">0</input>
            <input as="stop">tmax</input>
            <input as="length">count</input>
            <output>t</output>
        </ramp>
    </analysis>
    <export>
        <set name="Orientation">
            <data name="Time (s)">t</data>
            <data name="w">w</data>
            <data name="x">x</data>
            <data name="y">y</data>
            <data name="z">z</data>
            <data name="Direct (°)">direct</data>
            <data name="Yaw (°)">yaw</data>
            <data name="Pitch (°)">pitch</data>
            <data name="Roll (°)">roll</data>
        </set>
    </export>
</phyphox>
