SunFounder PiCar-X 2.0 – это роботизированный автомобиль с искусственным интеллектом и автономным управлением, использующий Raspberry Pi 3/4 в качестве основной платы обработки. Он оснащен модулем камеры, перемещаемым сервоприводом с 2 осями для поворота или наклона камеры, ультразвуковым модулем для обнаружения удаленных объектов и модулем детектирования линии. Робот PiCar-X также способен выполнять задачи компьютерного зрения: распознавание цветов, обнаружение лиц, детектирование дорожных знаков, автоматическое избегание препятствий и автоматическое следование по линии.
Программирование PiCar-X возможно на двух языках: с помощью визуальной среды Ezblock Studio на основе Blockly (методом перетаскивания блоков) и на Python. Робот работает с библиотекой компьютерного зрения OpenCV и TensorFlow для задач ИИ. Дополнительно управление осуществляется через мобильное приложение SunFounder Controller. Компания предоставила нам образец Picar-X 2.0 для обзора, поэтому приступим.
Обзор робота SunFounder PiCar-X 2.0
Комплект робота PiCar-X включает несколько компонентов: конструкционный корпус, электродвигатели постоянного тока, колеса, плату расширения RoboHat, ультразвуковой сенсор, датчик линии, сервопривод, аккумулятор и набор гаек/винтов для сборки. Поскольку устройство поставляется в виде набора, учащимся предстоит самостоятельно собрать его, изучая процесс сборки роботов и подключения проводов. Детали и инструкции доступны в документации . Наш комплект также включал Raspberry Pi 4 с 4 ГБ ОЗУ.
Плата расширения SunFounder PiCar-X Robot HAT
Плата расширения SunFounder PiCar-X Robot HAT содержит выключатель питания, два порта для подключения двигателей (левый/правый) и двенадцать портов для сервоприводов, управляющих колесами автомобиля и поворотным механизмом камеры. Дополнительно плата включает динамик для воспроизведения звуковых эффектов, голосовой обратной связи или MP3-музыки. Имеются расширительные порты ADC, PWM и I2C, а для питания используется аккумулятор 7-12 В, подключаемый через 2-контактный разъем PH2.0. Зарядка осуществляется через USB-C с LED-индикацией статуса.
Характеристики Robot HAT:
- Порты двигателей (левый/правый) – 2 канала XH2.54: GPIO 4 (левый), GPIO 5 (правый)
- 2x I2C-пина Raspberry Pi
- PWM – 12 каналов (P0-P11)
- 4x ADC-пина (A0-A3)
- 4x цифровых пина (D0-D3)
- Индикаторы состояния батареи
- LED 2 активен при напряжении >7.8 В
- LED 1 активен при напряжении 6.7–7.8 В
- Оба LED отключены при напряжении <6.7 В
- Напряжение питания – 7–12 В постоянного тока через 2-контактный PH2.0 (одновременно питает Raspberry Pi)
Установка (пользовательской) ОС Raspberry Pi
ОС для PiCar-X 2.0 устанавливается на microSD-карту с помощью программы Raspberry Pi Imager .
Доступны два образа ОС:
- Для программирования на Python используйте Raspberry Pi OS (Legacy)
- Для IDE Ezblock Studio скачайте RaspiOS-xxx_EzBlockOS-xxx.img – базовый образ Raspberry Pi OS с предустановленной Ezblock Studio. Нажмите CHOOSE OS , выберите Use Custom, укажите скачанный файл, отметьте устройство хранения, нажмите WRITE и дождитесь завершения.
Загрузка Raspberry Pi OS на SunFounder PiCar-X 2.0
Извлеките microSD-карту из компьютера, вставьте в Raspberry Pi. Подключите кабель аккумулятора и переведите выключатель на Robot HAT в положение ON.
После загрузки Raspberry Pi OS проверьте установку, подключив монитор HDMI, клавиатуру и мышь – система должна работать как автономный одноплатный компьютер.
Начало работы с EzBlock Studio для PiCar-X 2.0
EzBlock Studio – визуальная среда программирования от SunFounder для новичков, поддерживающая Blockly (сборка программ из блоков) с конвертацией в Python-код. Загрузка программ на Raspberry Pi выполняется по Bluetooth или Wi-Fi.
Скачайте приложение в App Store (iOS) или Google Play (Android) по запросу «Ezblock Studio» либо перейдите на http://ezblock.cc/ezblock-studio для работы в браузере. Примечание: с 28 февраля EzBlock Studio V3.2 перейдет в офлайн-режим (проекты сохраняются локально, без облачного хранилища).
Создайте проект через раздел New Project .
Выберите продукт PiCar-X:
Нажмите Connect .
Программа отобразит IP-адрес робота – подтвердите кнопкой Confirm .
При успешном соединении отобразятся данные робота: уровень заряда батареи, напряжение, версия ПО.
Установка Python-библиотек и модулей
Запустите терминал в Raspberry Pi OS для обновления системы:
1 2 |
sudo apt update sudo apt upgrade |
Установите библиотеку SunFounder PICAR-X Robot Hat:
1 2 3 4 |
cd ~/ git clone -b v2.0 https://github.com/sunfounder/robot-hat.git cd robot-hat sudo python3 setup.py install |
Затем скачайте и установите модуль Vilb:
1 2 3 4 |
cd ~/ git clone -b picamera2 https://github.com/sunfounder/vilib.git cd vilib sudo python3 install.py |
Повторите для модуля Picar-X:
1 2 3 4 |
cd ~/ git clone -b v2.0 https://github.com/sunfounder/picar-x.git cd picar-x sudo python3 setup.py install |
Запустите скрипт i2samp.sh для установки драйвера I2S-усилителя:
1 2 |
cd ~/picar-x sudo bash i2samp.sh |
Введите «y» для подтверждения установки:
И снова для активации фонового воспроизведения /dev/zero…
Перезагрузите систему по запросу.
Активация интерфейса I2C
Введите команду для настроек Raspberry Pi OS:
1 |
sudo raspi-config |
Выберите Interface Options…
→ I2C →
…подтвердите «Yes«.
Перезагрузите систему по запросу для завершения.
Установка сервопривода на 0° для упрощения сборки
Диапазон угла сервопривода PiCar-X: -90°–90°, но на заводе угол не калиброван (возможны 0° или 45°). Сборка при случайном угле ≠0° может повредить сервопривод. Перед установкой на робота задайте всем сервоприводам угол 0°. Для центрирования выполните команду:
1 2 |
cd ~/picar-x/example sudo python3 servo_zeroing.py |
Затем подключите кабель сервопривода к порту P11, и вы увидите, как рычаг сервопривода повернётся в позицию (это положение 0°). Далее установите рычаг сервопривода согласно инструкции по сборке.
Калибровка робота PiCar-X 2.0 (Python)
Из-за возможных отклонений при сборке PiCar-X или ограничений сервоприводов углы установки могут быть слегка смещены. Для коррекции запустите программу calibration.py:
1 2 |
cd /home/pi/picar-x/example/calibration sudo python3 calibration.py |
Запустится помощник калибровки PiCar-X с меню, как показано ниже.
Клавиша R проверяет работоспособность сервопривода управления передними колёсами. Нажмите 1 для выбора сервопривода передних колёс, затем клавишами W/S отрегулируйте положение колёс строго прямо без смещения влево/вправо.
Теперь нажмите 2 для выбора сервопривода камеры №1 (поворот по горизонтали), затем клавишами W/S отрегулируйте поворотную платформу строго вперёд без смещения влево/вправо.
Повторите для сервопривода камеры №2 (наклон по вертикали), выбрав 3 и регулируя клавишами W/S положение платформы строго вперёд без наклона вверх/вниз.
При возможном обратном подключении моторов нажмите E для проверки движения вперёд. При некорректной работе выберите левый/правый мотор клавишами 4/5, затем клавишей Q откалибруйте направление вращения.
По завершении калибровки нажмите Пробел для сохранения параметров. Подтвердите действие вводом «y», затем нажмите ESC или Ctrl+C для выхода.
Калибровка робота PiCar-X 2.0 (EzBlock Studio)
Альтернативно калибровку можно выполнить через веб-интерфейс EzBlock Studio. После подключения нажмите кнопку Settings .
Затем выберите Calibrate.
В открывшемся окне выберите сервоприводы для калибровки: поворотно-наклонного механизма камеры или рулевых колёс.
Начните с калибровки сервоприводов поворотно-наклонного механизма. Кнопками управления отрегулируйте положение камеры вверх/вниз (наклон) и влево/вправо (поворот). После выравнивания камеры нажмите Confirm .
Аналогично откалибруйте рулевые колёса, регулируя их положение влево/вправо. После выравнивания нажмите Confirm .
Тестирование движения робота PiCar-X 2.0
Запрограммируем движение робота по S-траектории с последующей остановкой. Пример реализации на Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
from picarx import Picarx import time if __name__ == "__main__": try: px = Picarx() px.forward(30) time.sleep(0.5) for angle in range(0,35): px.set_dir_servo_angle(angle) time.sleep(0.01) for angle in range(35,-35,-1): px.set_dir_servo_angle(angle) time.sleep(0.01) for angle in range(-35,0): px.set_dir_servo_angle(angle) time.sleep(0.01) px.forward(0) time.sleep(1) for angle in range(0,35): px.set_camera_servo1_angle(angle) time.sleep(0.01) for angle in range(35,-35,-1): px.set_camera_servo1_angle(angle) time.sleep(0.01) for angle in range(-35,0): px.set_camera_servo1_angle(angle) time.sleep(0.01) for angle in range(0,35): px.set_camera_servo2_angle(angle) time.sleep(0.01) for angle in range(35,-35,-1): px.set_camera_servo2_angle(angle) time.sleep(0.01) for angle in range(-35,0): px.set_camera_servo2_angle(angle) time.sleep(0.01) finally: px.forward(0) |
… и в EzBlock Studio.
Тест объезда препятствий
Робот оснащён ультразвуковым сенсором HC-SR04 с диапазоном 0-400 см. Демо-программа поворачивает колёса на -35° при обнаружении объекта ближе 25 см, иначе поддерживает угол 0°. Тестирование подтвердило работоспособность в Python и EzBlock Studio.
Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
from picarx import Picarx def main(): try: px = Picarx() # px = Picarx(ultrasonic_pins=['D2','D3']) # tring, echo px.forward(30) while True: distance = px.ultrasonic.read() print("distance: ",distance) if distance > 0 and distance < 300: if distance < 25: px.set_dir_servo_angle(-35) else: px.set_dir_servo_angle(0) finally: px.forward(0) if __name__ == "__main__": main() |
EzBlock Studio:
Программа следования по линии для PiCar-X 2.0
Робот использует «3-канальный датчик серой шкалы SunFounder», выдающий аналоговые значения для каждого выхода. Алгоритм предусматривает три условия:
- Движение вперёд на скорости 10% с углом сервопривода 0° по умолчанию.
- При обнаружении чёрной линии левым сенсором установите угол сервопривода 12°.
- При обнаружении линии правым сенсором установите угол -12°.
- При отсутствии условий 2 и 3 верните угол 0°.
Программа на Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
from picarx import Picarx if __name__=='__main__': try: px = Picarx() # px = Picarx(grayscale_pins=['A0', 'A1', 'A2']) px_power = 10 while True: gm_val_list = px.get_grayscale_data() print("gm_val_list:",gm_val_list) gm_status = px.get_line_status(gm_val_list) print("gm_status:",gm_status) if gm_status == 'forward': print(1) px.forward(px_power) elif gm_status == 'left': px.set_dir_servo_angle(12) px.forward(px_power) elif gm_status == 'right': px.set_dir_servo_angle(-12) px.forward(px_power) else: px.set_dir_servo_angle(0) px.stop() finally: px.stop() |
Эквивалентная визуальная реализация в EzBlock Studio.
Озвучивание текста через встроенный динамик
Используем технологию Text-to-Speech (TTS) для воспроизведения фразы «Hello!» через динамик. После установки драйвера i2samp.sh создайте программу:
1 2 3 4 5 6 7 8 |
from robot_hat import TTS if __name__ == "__main__": words = ["Hello", "Hi", "Good bye", "Nice to meet you"] tts_robot = TTS() for i in words: print(i) tts_robot.say(i) |
Аналогичный пример в EzBlock Studio использует распознавание лиц через камеру для фразы «Hello, nice to meet you!»
Компьютерное зрение на Raspberry Pi 4
Распознавание лиц — лишь одна из задач, выполняемых Raspberry Pi 4 через 5Мп камеру SunFounder на сенсоре OV5647 Full HD. Рассмотрим другие примеры машинного зрения.
Распознавание цвета
Для теста используйте цветные круги. Распечатайте шаблон из этого PDF-файла .
Программа определяет цвет круга, обводит его зелёным прямоугольником и подписывает цвет в левом верхнем углу.
Код распознавания цвета на Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
import cv2 from picamera.array import PiRGBArray from picamera import PiCamera import numpy as np import time color_dict = {'red':[0,4],'orange':[5,18],'yellow':[22,37],'green':[42,85],'blue':[92,110],'purple':[115,165],'red_2':[165,180]} #Here is the range of H in the HSV color space represented by the color kernel_5 = np.ones((5,5),np.uint8) #Define a 5×5 convolution kernel with element values of all 1. def color_detect(img,color_name): # The blue range will be different under different lighting conditions and can be adjusted flexibly. H: chroma, S: saturation v: lightness resize_img = cv2.resize(img, (160,120), interpolation=cv2.INTER_LINEAR) # In order to reduce the amount of calculation, the size of the picture is reduced to (160,120) hsv = cv2.cvtColor(resize_img, cv2.COLOR_BGR2HSV) # Convert from BGR to HSV color_type = color_name mask = cv2.inRange(hsv,np.array([min(color_dict[color_type]), 60, 60]), np.array([max(color_dict[color_type]), 255, 255]) ) # inRange():Make the ones between lower/upper white, and the rest black if color_type == 'red': mask_2 = cv2.inRange(hsv, (color_dict['red_2'][0],0,0), (color_dict['red_2'][1],255,255)) mask = cv2.bitwise_or(mask, mask_2) morphologyEx_img = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_5,iterations=1) # Perform an open operation on the image # Find the contour in morphologyEx_img, and the contours are arranged according to the area from small to large. _tuple = cv2.findContours(morphologyEx_img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # compatible with opencv3.x and openc4.x if len(_tuple) == 3: _, contours, hierarchy = _tuple else: contours, hierarchy = _tuple color_area_num = len(contours) # Count the number of contours if color_area_num > 0: for i in contours: # Traverse all contours x,y,w,h = cv2.boundingRect(i) # Decompose the contour into the coordinates of the upper left corner and the width and height of the recognition object # Draw a rectangle on the image (picture, upper left corner coordinate, lower right corner coordinate, color, line width) if w >= 8 and h >= 8: # Because the picture is reduced to a quarter of the original size, if you want to draw a rectangle on the original picture to circle the target, you have to multiply x, y, w, h by 4. x = x * 4 y = y * 4 w = w * 4 h = h * 4 cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) # Draw a rectangular frame cv2.putText(img,color_type,(x,y), cv2.FONT_HERSHEY_SIMPLEX, 1,(0,0,255),2)# Add character description return img,mask,morphologyEx_img with PiCamera() as camera: print("start color detect") camera.resolution = (640,480) camera.framerate = 24 rawCapture = PiRGBArray(camera, size=camera.resolution) time.sleep(2) for frame in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):# use_video_port=True img = frame.array img,img_2,img_3 = color_detect(img,'red') # Color detection function cv2.imshow("video", img) # OpenCV image show cv2.imshow("mask", img_2) # OpenCV image show cv2.imshow("morphologyEx_img", img_3) # OpenCV image show rawCapture.truncate(0) # Release cache k = cv2.waitKey(1) & 0xFF # 27 is the ESC key, which means that if you press the ESC key to exit if k == 27: break print('quit ...') cv2.destroyAllWindows() camera.close() |
Более простая реализация в EzBlock Studio требует всего двух блоков.
Функция распознавания лиц
В тесте динамика мы кратко проверили распознавание лиц, но рассмотрим детали. Метод основан на каскадных классификаторах Хаара — эффективной технологии обнаружения объектов, разработанной Полом Виолой и Майклом Джонсом (2001).
Алгоритм: преобразование изображения в градации серого, обнаружение лиц через модель классификаторов Хаара, рисование прямоугольников вокруг лиц на исходном изображении.
Код на Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
import cv2 from picamera.array import PiRGBArray from picamera import PiCamera import time def human_face_detect(img): resize_img = cv2.resize(img, (320,240), interpolation=cv2.INTER_LINEAR) # In order to reduce the amount of calculation, resize the image to 320 x 240 size gray = cv2.cvtColor(resize_img, cv2.COLOR_BGR2GRAY) # Convert to grayscale faces = face_cascade.detectMultiScale(gray, 1.3, 2) # Detect faces on grayscale images face_num = len(faces) # Number of detected faces if face_num > 0: for (x,y,w,h) in faces: x = x*2 # Because the image is reduced to one-half of the original size, the x, y, w, and h must be multiplied by 2. y = y*2 w = w*2 h = h*2 cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) # Draw a rectangle on the face return img with PiCamera() as camera: print("start human face detect") camera.resolution = (640,480) camera.framerate = 24 rawCapture = PiRGBArray(camera, size=camera.resolution) time.sleep(2) for frame in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True): # use_video_port=True img = frame.array img = human_face_detect(img) cv2.imshow("video", img) #OpenCV image show rawCapture.truncate(0) # Release cache k = cv2.waitKey(1) & 0xFF # 27 is the ESC key, which means that if you press the ESC key to exit if k == 27: break print('quit ...') cv2.destroyAllWindows() camera.close() |
Эквивалентный пример в EzBlock Studio.
Видеообзор PiCar-X 2.0
Заключение
SunFounder PiCar-X 2.0 — роботизированная платформа с ИИ для изучения Raspberry Pi, компьютерного зрения и робототехники. Робот программируется для объезда препятствий, следования по линии и автономного движения с функциями распознавания лиц/цветов.
Комплект предназначен для образовательных учреждений и энтузиастов. Полный перечень функций (распознавание QR-кодов, отслеживание лиц, игра «Бой быков» и др.) доступен в документации .
Благодарим SunFounder за предоставленный комплект PiCar-X 2.0. Комплект с аккумулятором и зарядным устройством доступен за $81.99 ($154.99 с Raspberry Pi 4 4ГБ в фирменном магазине; $74.99 и $145.10 на Amazon с учётом скидки $15).
CNXSoft: Обзор переведён с оригинальной публикации CNX Software Thailand авторства Kajornsak Janjam под редакцией Suthinee Kerdkaew .
Выражаем свою благодарность источнику, с которого взята и переведена статья, сайту cnx-software.com.
Оригинал статьи вы можете прочитать здесь.