defmodule AugieWeb.OrientationLive do use Phoenix.LiveView alias Augie.Sensor.IMU alias Kinemat.Orientation alias Kinemat.Orientations.Quaternion alias Phoenix.PubSub use Angle @moduledoc false def mount(_params, _context, socket) do if connected?(socket), do: PubSub.subscribe(Augie.PubSub, "telemetry.imu") {:ok, assign(socket, data_ready: false)} end def handle_info(%IMU{} = sample, socket) do euler = Quaternion.init( ~a[#{sample.orientation.w}]r, sample.orientation.x, sample.orientation.y, sample.orientation.z ) |> Orientation.to_euler() orientation = [ roll: to_degrees(euler.x), pitch: to_degrees(euler.y), yaw: to_degrees(euler.z) ] socket = socket |> assign(data_ready: true) |> assign(orientation) {:noreply, socket} end defp to_degrees(angle) do case Angle.to_degrees(angle) do {_, degrees} when is_integer(degrees) -> degrees / 1.0 {_, degrees} when is_float(degrees) -> degrees {_, _} -> 0.0 end end end