Документация Engee
Notebook

Визуализация показаний приборов дрона

В данном примере реализованы алгоритмы визуализации данных о полёте, записанных с датчиков дрона.

Цель данной демонстрации – показать различные возможности отображения данных, включая их привязку ко времени.

Начнём с чтения записанных данных из файла CSV.

In [ ]:
using CSV

# Читаем данные из файла data.csv
df_read = CSV.read("$(@__DIR__)/data.csv", DataFrame)

# Проверка первых строк
first(df_read, 5)
Out[0]:
5×3 DataFrame
RowВремяВысотаУгол
Int64Float64Float64
100.0-4.0
213.0-5.0
325.0-3.0
438.0-3.0
5410.0-3.0

Как мы можем видеть, таблица содержит 3 поля, временные отсчёты, значения высоты и угол наклона дрона относительно горизонта.

In [ ]:
max_idx = 350;
t = df_read.Время[1:max_idx]
heights = df_read.Высота[1:max_idx]
angles = df_read.Угол[1:max_idx]

H = plot(t, heights, title="Высота")
A = plot(t, angles, title="Угол наклона")
plot(H, A, layout=(2, 1), legend=false)
Out[0]:

Опираясь на визализацию значений датчиков, мы видим, что дрон постипенно набирал высоту и изменял угол наклона, облетая какое-то препятствие. Также мы видим колебания отклонения относительно горизонта, которые скорее всего связаны с тем, что дрон летал в ветренную погоду.

Далее объявим статические переменные, которые не требуют обновления в цикле.

In [ ]:
max_y_h = maximum(heights)+10

# Уравнение единичной окружности
θ = range(0, 2π, length=100)
x_circle = cos.(θ)
y_circle = sin.(θ)
x = [-1, 1]

using Images
# Загрузка изображения дрона
drone_img = load("$(@__DIR__)/drone.jpg") 
Out[0]:
No description has been provided for this image

Теперь перейдём к самому циклу визуализации данных. Его можно условно разделить на три части.

  1. Отображение высоты. Для каждого момента времени строится график высоты в виде красной точки. Ограничения по осям устанавливаются так, чтобы показать область вокруг текущего времени ±10 секунд. Заголовок графика показывает текущее значение высоты и стрелку вверх/вниз в зависимости от того, увеличивается высота или уменьшается.
  2. График тангажа. График тангажа показывает угол отклонения дрона относительно горизонта. Используются функции cosd и sind для построения линии угла наклона. Заголовок содержит значение угла тангажа в градусах.
  3. Поворот изображения дрона и визуализация, Изображение дрона поворачивается на определенный угол (значение тангажа + 90 градусов). Функция channelview преобразует изображение в вид, удобный для дальнейшей обработки. Используется маска для удаления черных пикселей.

В итоги все три графика собираются в единный кадр который и формирует кадры GIF.

In [ ]:
@gif for i in 1:length(t)
    ti = t[i]
    ai = angles[i]
    hi = heights[i]

    # Высота
    h_plt = scatter([ti], [hi], 
        markershape=:circle, markersize=15, markercolor=:red, framestyle=:box, 
        xlims = (ti-10, ti+10), ylims = (0, max_y_h), 
        legend=false, grid=false, 
        title="Высота: $hi m $((i == 1 || heights[i] > heights[i-1]) ? "↑" : "↓")")

    # Тангаж
    tang = plot([x_circle, (cosd(-ai) .* x)], [y_circle, (sind(-ai) .* x)], 
        linewidth=3, color=:black, framestyle=:none, 
        title="Отклонение: $(ai)°")

    # Дрон
    rotated_array = channelview(Gray.(imrotate(drone_img, π*(ai+90)/ 180)))
    rotated_array[rotated_array .== 0] .=  1

    dron = plot(framestyle=:none, grid=false, title = "Время: $(t[i])sec")
    # Отображаем повернутое изображение дрона
    heatmap!(
        1:size(rotated_array, 2), 1:size(rotated_array, 1),
        permutedims(rotated_array, (2, 1)),
        colorbar=false, c=:grays
    )
    Tng_Dr = plot(dron, tang, layout = grid(2, 1, heights=[0.8, 0.2]))
    grup = plot(Tng_Dr, h_plt, layout= grid(1, 2, width = [0.75, 0.25]), legend=false)
end
[ Info: Saved animation to /user/my_projects/Winter_school/Юре_зимняя_школа_комментарии/Dron/tmp.gif
Out[0]:
No description has been provided for this image

Вывод

Как мы можем наблюдать, опираясь на результаты GIF, мы получаем достаточно информативное представление данных во времени. Такой подход можно применять давольно часто, особенно в случаях описания поведения реального физического объекта.