48 lines
1.1 KiB
Elixir
48 lines
1.1 KiB
Elixir
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, "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
|