Дисплей¶
Дисплей позволяет выводить изображения с программы на подключенный к квадрокоптеру экран.
Инициализация¶
Сначала создайте объект Clover2, а затем подключитесь к драйверу дисплея.
from clover2 import Clover2
drone = Clover2()
# или с именем ноды:
drone = Clover2("my_drone")
display = drone.display()
if display is None:
raise RuntimeError("Драйвер дисплея недоступен")
Clover2 — обертка над ROS 2 Node. При создании объекта Clover2 создается нода и запускается фоновый поток для работы ROS 2.
По умолчанию клиент подключается к драйверу по пути /display. Если драйвер находится по другому пути, передайте его в display():
display = drone.display("/my_display")
Информация о дисплее¶
При создании клиента программа получает характеристики дисплея. Используйте их при подготовке изображения:
print(f"Разрешение: {display.width}x{display.height}")
print(f"Максимальная частота: {display.max_fps} FPS")
print(f"Поддерживаемые кодировки: {display.supported_encodings}")
Основные свойства клиента:
Свойство |
Описание |
|---|---|
|
|
|
ширина изображения в пикселях |
|
высота изображения в пикселях |
|
максимальная частота отправки кадров |
|
список поддерживаемых кодировок ROS-изображений, например |
Внимание
Размер кадра должен точно совпадать с display.width и display.height, а значение image.encoding должно входить в display.supported_encodings. Не отправляйте кадры чаще, чем позволяет display.max_fps.
Отправка изображения¶
Для отправки изображения создайте сообщение sensor_msgs.msg.Image и передайте его в send_image().
from sensor_msgs.msg import Image
image = Image()
image.width = display.width
image.height = display.height
image.encoding = "mono8"
image.is_bigendian = False
image.step = image.width
image.data = bytearray(image.width * image.height)
display.send_image(image)
В этом примере используется кодировка mono8. Она использует один байт для каждого пикселя: значение 0 соответствует черному цвету, а 255 — белому.
Дисплей SSD1306 физически отображает только черный и белый цвета. Поэтому изображение с полутонами перед отправкой нужно преобразовать в черно-белое.
Перед использованием mono8 убедитесь, что эта кодировка есть в display.supported_encodings.
Загрузка в формате JPEG или PNG¶
Вы можете загрузить изображение в формате JPEG или PNG с помощью OpenCV, преобразовать его в подходящий формат и отправить на дисплей.
import cv2
from clover2 import Clover2
drone = Clover2()
display = drone.display()
if display is None or not display.valid:
raise RuntimeError("Драйвер дисплея недоступен")
if "mono8" not in display.supported_encodings:
raise RuntimeError(
f"Дисплей не поддерживает mono8: {display.supported_encodings}"
)
frame = cv2.imread("image.jpg") # также можно указать путь к PNG
if frame is None:
raise RuntimeError("Не удалось загрузить изображение")
# SSD1306 отображает только черный и белый цвета.
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.resize(gray, (display.width, display.height))
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
display.send_cv_image(binary, encoding="mono8")
Программа выполняет следующие действия:
Подключается к дисплею.
Проверяет, доступен ли драйвер.
Проверяет поддержку кодировки
mono8.Загружает изображение с помощью
OpenCV.Преобразует изображение в оттенки серого.
Изменяет размер изображения под разрешение дисплея.
Преобразует изображение в черно-белое.
Отправляет изображение на дисплей.
Значение 127 в функции cv2.threshold() задает порог бинаризации. Пиксели со значением меньше 127 станут черными, а остальные — белыми. При необходимости измените это значение в зависимости от изображения.
send_cv_image() не изменяет размер и не преобразует кодировку изображения автоматически. Перед отправкой задайте размер массива display.width × display.height и используйте кодировку, которую поддерживает дисплей.
Пример: тестовое изображение¶
Вы можете создать изображение непосредственно в программе и отправить его на дисплей. В этом примере программа рисует белую рамку и две диагонали на черном фоне.
from clover2 import Clover2
from sensor_msgs.msg import Image
def make_test_image(width: int, height: int) -> Image:
image = Image()
image.width = width
image.height = height
image.encoding = "mono8"
image.is_bigendian = False
image.step = width
pixels = bytearray(width * height)
for y in range(height):
for x in range(width):
if (
x == 0
or x == width - 1
or y == 0
or y == height - 1
or x == y
or x == width - y - 1
):
pixels[y * width + x] = 255
image.data = pixels
return image
drone = Clover2()
display = drone.display()
if display is None or not display.valid:
raise RuntimeError("Драйвер дисплея недоступен")
if "mono8" not in display.supported_encodings:
raise RuntimeError(
f"Дисплей не поддерживает mono8: {display.supported_encodings}"
)
display.send_image(make_test_image(display.width, display.height))
Функция make_test_image() создает изображение размером с дисплей. Каждый пиксель хранится как отдельный байт: 0 соответствует черному цвету, а 255 — белому.
Полученное изображение можно использовать для проверки подключения и работы дисплея.