master
zen 3 years ago
parent f56c14e2fe
commit 0b2a8929c6
  1. 383
      README.md
  2. BIN
      pic/CV/HSV_cone.png
  3. BIN
      pic/raspb/rasp14.png
  4. BIN
      pic/raspb/rasp15.png
  5. 2
      python/circul_detect.py

@ -1,11 +1,9 @@
# AlphaBot2
# Изучаем робота AlphaBot2-Pi
---
## Сервис раздел
# TODO ТУТ все про 3й питон, нужно это указать, или что-то придумать, а то парашно получается
- [Страница](https://www.waveshare.com/wiki/AlphaBot2-Pi) с роботом
- [Схема](https://www.waveshare.com/w/upload/9/91/AlphaBot2-Base-Schematic.pdf) части с мотороми и аккумами и контроллером заряда (НИЗ)
- [Схема](https://www.waveshare.com/w/upload/7/72/AlphaBot2-Pi-Schematic.pdf) части с креплением для малины (ВЕРХ)
@ -29,17 +27,19 @@ sshfs pi@raspberrypi:/home/pi/AlphaBot2 tmp/server
code tmp/server
```
---
## Знакомство с роботом AlphaBot2-Pi
![alphabot2-pi](pic/common/alphabot2-pi-3.jpg)
Робот AlphaBot2-Pi состоит из нескольких основных частей:
* База-шасси
* Плата-адаптер
* Одноплатный компьютер Raspberry-Pi
* Камера с поворотным кронштейном
* Ультразвуковой дальномер
- База-шасси
- Плата-адаптер
- Одноплатный компьютер Raspberry-Pi
- Камера с поворотным кронштейном
- Ультразвуковой дальномер
### База-шасси
@ -73,7 +73,7 @@ code tmp/server
6. TLC1543 - 10-битный аналогово0цифровой преобразователь для подключения аналоговых датчиков к Raspberry Pi.
7. PCA9685 - 16-канальный 12-битный ШИМ-модуль для работы с сервомоторами.
8. CP2102 - USB-UART преобразователь.
9. Джостик.
9. Джойстик.
10. Инфракрасный приемник.
11. Пьезодинамик (buzzer).
@ -94,21 +94,21 @@ code tmp/server
![camera2](pic/assembly/camera2.png)
Установите насадку **(c)** на сервопривод в специальную выемку в корпусе. Если она не подходит **(g)** под выемку в корпусе - слегка подрежте ее. Закрепите с помощью винтов **(5)**. Далее установите крестообразную насадку **(b)** в основание стойки. Также при необходимости подрежте. Закрутите винты **(5)** с задней стороны основания стойки.
Установите насадку **(c)** на сервопривод в специальную выемку в корпусе. Если она не подходит **(g)** под выемку в корпусе - слегка подрежете ее. Закрепите с помощью винтов **(5)**. Далее установите крестообразную насадку **(b)** в основание стойки. Также при необходимости подрежете. Закрутите винты **(5)** с задней стороны основания стойки.
![camera3](pic/assembly/camera3.png)
Вставьте в крестообразную насадку сервопривод и закрепите винтом **(1)**. Второй, еще никуда не установленный, сервопривод прикрепите двумя винтами **(7)** к подставке для камеры **(e)** как показано на рисунке ниже. Установите подставку под камеру **(e)** и сервопривод на собранную ранее стойку **(f&g)** и прикрутите насадку к сервоприводу с помощью винте **(1)**.
Вставьте в крестообразную насадку сервопривод и закрепите винтом **(1)**. Второй, еще никуда не установленный, сервопривод прикрепите двумя винтами **(7)** к подставке для камеры **(e)** как показано на рисунке ниже. Установите подставку под камеру **(e)** и сервопривод на собранную ранее стойку **(f&g)** и прикрутите насадку к сервоприводу с помощью винте **(1)**.
![camera4](pic/assembly/camera4.png)
Вставьте двадцатипяти пиновый FFC кабель в соответствующий разъем на модуле камеры для Raspberry Pi и установите модуль в подставку **(e)**.
Вставьте двадцатипяти пиновый FFC кабель в соответствующий разъем на модуле камеры для Raspberry Pi и установите модуль в подставку **(e)**.
![camera5](pic/assembly/camera5.png)
### Финальная сборка робота
Закрепите стойку для камеры на плате-адаптере с помощью винтов и гаек **(I&J)**, как показано на рисунке ниже. Проведите кабели от сервприводов через отверстие в нижней части платы-адаптера и вставьте коннектор в соответствующие пины на обратной стороне платы-адаптора. Через то же отверстие проведите шлейф от камеры и вставьте его в соответствующий разъем на Raspberry Pi.
Закрепите стойку для камеры на плате-адаптере с помощью винтов и гаек **(I&J)**, как показано на рисунке ниже. Проведите кабели от сервоприводов через отверстие в нижней части платы-адаптера и вставьте коннектор в соответствующие пины на обратной стороне платы-адаптера. Через то же отверстие проведите шлейф от камеры и вставьте его в соответствующий разъем на Raspberry Pi.
![final1](pic/assembly/final1.png)
@ -124,16 +124,15 @@ code tmp/server
![final4](pic/assembly/final4.png)
***ОВНИМАНИЕ! РОБОТ МОЖНО СТАВИТЬ НА ЗАРЯДКУ ТОЛЬКО КОГДА ОН ВЫКЛЮЧЕН! ВО ВРЕМЯ ЗАРЯДКИ ТАКЖЕ НЕЛЬЗЯ ПОДКЛЮЧАТЬСЯ К RASPBERRY PI!***
## Установка системы и минимальная настройка.
## Установка системы и минимальная настройка
В этом разделе мы рассмотрим процесс установки операционной системы на Raspberry Pi и рассмотрим способы взаимодействия с ней в операционной системе linux и windows. Предполагается что изучающие это руководство владеют linux консолью, и язаком программирования python. Для того чтобы запустить linux на Raspberry Pi необходимо выполнить следующие действия:
В этом разделе мы рассмотрим процесс установки операционной системы на Raspberry Pi и рассмотрим способы взаимодействия с ней в операционной системе linux и windows. Предполагается что изучающие это руководство владеют linux консолью, и языком программирования python. Для того чтобы запустить linux на Raspberry Pi необходимо выполнить следующие действия:
1. Скачать отсюда (https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit) образ ```Raspberry Pi OS ```. Я рекомендую использовать ```Raspberry Pi OS with desktop and recommended software```, этот образ будет содержать большенство вещей необходимых нам в будующем.
1. Скачать отсюда (https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit) образ ```Raspberry Pi OS ```. Я рекомендую использовать ```Raspberry Pi OS with desktop and recommended software```, этот образ будет содержать большинство вещей необходимых нам в будущем.
2. Распокавать архив, в Windows можно использовать программу Winrar.
2. Распаковать архив, в Windows можно использовать программу Winrar.
3. Записать образ на карту памяти *(обратите внимание, что объем памяти должен быть больше 4Gb)*. Создатели Raspberry Pi советуют использовать для этого программу Etcher (https://www.balena.io/etcher/). Скачиваем ее и устанавливаем себе на компьютер. Нас встретит простой интерфейс. Сначала нужно выбрать образ, потом выбрать карту память на которую мы хотим его записать, и после согласится на запись. Все ваши данные будут удалены с данной карты. Цифрой 1 на изображении указано, где выбирать образ, 2 - где выбирать карту памяти, 3 - начало прошивки.
@ -143,11 +142,10 @@ code tmp/server
![raspb2](pic/raspb/rasp2.png)
После чего необходимо дождатся завершения проверки правильности записанных данных на флеш карту.
После чего необходимо дождаться завершения проверки правильности записанных данных на флеш карту.
![raspb3](pic/raspb/rasp3.png)
![raspb4](pic/raspb/rasp4.png)
4. Для того, чтобы избавиться от необходимости работать с Raspberry Pi, подключая к ней монитор, клавиатуру и мышку, мы будем использовать подключение с удаленного компьютера по ssh. Для этого нам нужно будет прописать некоторые настройки Wi-Fi.
@ -178,11 +176,11 @@ network={
Соглашайтесь. Нажмите правой кнопкой мышки на файл ```wpa_supplicant.conf```, выберите ```Открыть с помощью```, и откройте с помощью блокнота. Добавьте в открывшийся документ строки, указанные выше, заменив название точки доступа и пароль на свои. Сохраните. Содержимое этого файла будет автоматически перенесено в ```/etc/wpa_supplicant/wpa_supplicant.conf``` при старте системы.
5. Запуск робота. Далее извлекаем карту памяти из компьютера, предварительно воспользовавшись функцией безопасного извлечения, после чего вставляем карту в разъем на Rasbperry Pi, установленную в роботе. ``` ВНИМАНИЕ! Для того, чтобы на этом этапе не возникло проблем, убедитесь в том, что аккумуляторы заряжены. Это очень важно, так как отключение питания во время загрузки системы может привести к неправильной настройке системы. Во время работы с Raspberry Pi робот не должен заряжаться!```
Переводим ```PWR SWITCH``` находящийся снизу робота из состояния ```OFF``` в ```ON``` для включения робота, после чего ждем около 3х минут чтобы система успела применить все настройки. Для того, чтобы на этом этапе не возникло проблем убедитесь что аккумуляторы заряжены, это очень важно потомучто робот в неактивном состоянии когда находится на зарядке.
Переводим ```PWR SWITCH``` находящийся снизу робота из состояния ```OFF``` в ```ON``` для включения робота, после чего ждем около 3х минут чтобы система успела применить все настройки. Для того, чтобы на этом этапе не возникло проблем убедитесь что аккумуляторы заряжены, это очень важно потому что робот в неактивном состоянии когда находится на зарядке.
6. Перейдем к подключению к Raspberry Pi. Для этого воспользуемся бесплатной версией программы MobaXterm, которая позволит нам совершить подключение gj практически любому протоколу. (Скачать можно здесь: https://mobaxterm.mobatek.net/). Установите программу на свой компьютер. Для подключения к Raspberry Pi по ssh сделайте следующее:
Нажамите на кнопку Session в левом верхнем углу программы, выбирите пункт ```New session```:
Нажмите на кнопку Session в левом верхнем углу программы, выберите пункт ```New session```:
![rasp8](pic/raspb/rasp8.png)
@ -194,23 +192,54 @@ network={
![rasp10](pic/raspb/rasp10.png)
Стандартный пароль для Raspberry Pi OS - ```raspberry```, введите его. После чего вы можете сохранить данный пароль в системе, если вам будет так удобнее. После чего система предложет вам ввести команды на исполнение:
Стандартный пароль для Raspberry Pi OS - ```raspberry```, введите его. После чего вы можете сохранить данный пароль в системе, если вам будет так удобнее. После чего система предложит вам ввести команды на исполнение:
![rasp11](pic/raspb/rasp11.png)
Если вы видете такой же вывод, что и на изображении выше - значит все заработало. Если нет, это может свидетельствовать о проблемах с сетью. Первым делом подключитесь к роутеру (обычно он находится на адресе http://192.168.0.1/ или http://192.168.1.1/) и посмотрите список подключенных устройств.
Если вы видите такой же вывод, что и на изображении выше - значит все заработало. Если нет, это может свидетельствовать о проблемах с сетью. Первым делом подключитесь к роутеру (обычно он находится на адресе http://192.168.0.1/ или http://192.168.1.1/) и посмотрите список подключенных устройств.
Если это произошло значит все хорошо и все работает если нет, это свидетельствует о проблемах с сетью. Первое что можно сделать это подключится к роутеру (обычно он находится на адресе http://192.168.0.1/или http://192.168.1.1/) и посмотреть там в списках клиентов расбери. На моем роутере это выглядит так:
Если это произошло значит все хорошо и все работает если нет, это свидетельствует о проблемах с сетью. Первое что можно сделать это подключится к роутеру (обычно он находится на адресе http://192.168.0.1/или http://192.168.1.1/) и посмотреть там в списках клиентов Raspberry Pi. На моем роутере это выглядит так:
![rasp12](pic/raspb/rasp12.png)
Оттуда можно узнать IP адрес. Далее повторите действия пункта 6, только вместо хоста с названием raspberrypi используя полученный IP. Если это тоже не работает остается только одно - отсоеденить Raspberry Pi от робота, подключить к монитору и с помощью клавиатуры и мыши через графический интерфейс поключить Raspberry Pi к сети Wi-Fi.
Оттуда можно узнать IP адрес. Далее повторите действия пункта 6, только вместо хоста с названием Raspberry Pi используя полученный IP. Если это тоже не работает остается только одно - отсоединить Raspberry Pi от робота, подключить к монитору и с помощью клавиатуры и мыши через графический интерфейс подключить Raspberry Pi к сети Wi-Fi.
![rasp13](pic/raspb/rasp13.png)
7. Для работы с камерой вам потребуется доступ к рабочему столу Raspberry Pi, для этого нужно до установить необходимые пакеты, чтобы иметь возможность видеть рабочий стол.
> Для Дальнейшей работы с этим сервисом нужно выполнить настройки из следующего раздела ```Настройка робота```.
```bash
sudo apt install realvnc-vnc-server realvnc-vnc-viewer
vncserver
```
После запуска последний команды в терминале появится что-то похожее на это:
```bash
Running applications in /etc/vnc/xstartup
VNC Server catchphrase: "Shampoo canoe Kevin. Little exit druid."
signature: e9-55-a0-df-85-12-3f-d2
Log file is /home/pi/.vnc/raspberrypi:2.log
New desktop is raspberrypi:1 (192.168.2.108:1)
```
Нужно запомнить ```raspberrypi:1``` т.к. это нужно будет использовать как адрес в клиенте.
Потом переходим сюда (https://www.realvnc.com/en/connect/download/viewer/) и качаем оттуда версию для вашей операционной системы.
![rasp14](pic/raspb/rasp14.png)
Вводите туда пароль, нажимаете Enter. После чего вам предложат ввести логин и пароль от Raspberry Pi, напомню это pi а пароль raspberry. После чего вы увидите рабочий стол малины.
![rasp15](pic/raspb/rasp15.png)
## Настройка робота.
Для работы с коботом необходимо выполнить ряд настроек. Для начала их нужно будет сделать в специальной консольной программе для конфигурирования Raspberry Pi - ```raspi-config```, Для чего используем следующую команду:
Для работы с роботом необходимо выполнить ряд настроек. Для начала их нужно будет сделать в специальной консольной программе для конфигурирования Raspberry Pi - ```raspi-config```, Для чего используем следующую команду:
```bash
sudo raspi-config
@ -221,21 +250,22 @@ sudo raspi-config
![robot2](pic/robot/robot2.png)
*Если вам будет удобнее, терминад можно открепить от программы ModaXterm и перенести в любую область рабочего стола - просто нажмите левой кнопкой мыши на вкладку с терминалом и перетащите в свободную область рабочего стола.*
*Если вам будет удобнее, терминал можно открепить от программы ModaXterm и перенести в любую область рабочего стола - просто нажмите левой кнопкой мыши на вкладку с терминалом и перетащите в свободную область рабочего стола.*
Навигация в данном режиме очень проста. Стрелками вверх и вниз мы выбираем нужный пункт меню, enter позволяект пройти в подпункты выбранного пункта или выбрать конкретную настройку. Стрелки вправо и влево позволяют выбрать один из пунктов, находящихся внизу (Select и Finish на изображении выше). Ниже перечислено, какие настройки необходимо сделать:
Навигация в данном режиме очень проста. Стрелками вверх и вниз мы выбираем нужный пункт меню, enter позволяет пройти в подпункты выбранного пункта или выбрать конкретную настройку. Стрелки вправо и влево позволяют выбрать один из пунктов, находящихся внизу (Select и Finish на изображении выше). Ниже перечислено, какие настройки необходимо сделать:
```bash
Interface Options -> Camera -> Yes -> OK
Interface Options -> SPI -> Yes -> OK
Interface Options -> I2C -> Yes -> OK
Interface Options -> Serial Port -> No -> Yes -> OK
Interface Options -> VNC -> YES
```
После завершения настройки выберите finish и система предложет вам перезарузить Raspberry Pi, на что соглашаемся. Подключится можно будет способом описанным выше, либо нажать кнопку R и MobaXterm автоматически постарается переподключится к роботу.
После завершения настройки выберите finish и система предложит вам перезагрузить Raspberry Pi, на что соглашаемся. Подключится можно будет способом описанным выше, либо нажать кнопку R и MobaXterm автоматически постарается переподключиться к роботу.
После того как система загрузится установите пакеты, необходимые для работы с перефирией робота. Для этого сначала обнавляем систему, потом ставим все необходимое:
После того как система загрузится установите пакеты, необходимые для работы с периферией робота. Для этого сначала обновляем систему, потом ставим все необходимое:
```bash
sudo apt update && sudo apt dist-upgrade -y
@ -245,45 +275,42 @@ sudo pip install RPi.GPIO spidev rpi_ws281x
Исполнение первой команды может занять достаточно длительное время.
## Упровление компонентами робота.
## Упровление компонентами робота
Для управления роботом предлагается использовать библиотеку bsp.py. Для того, чтобы воспользоваться ей, ее нужно поместить в папку с вашим проектом и добавить ее в ваш код следующим образом:
Для упровления роботом предлагается использовать библиотеку bsp.py. Для того, чтобы воспользоваться ей, ее нужно поместить в папку с вашим проектом и добавить ее в ваш код следующим образом:
```python
import bsp
```
Рассмотрим все компоненты робота и то, как ими можно управлять, какие данные с них можно получить.
### Управление моторами
Рассмотрим управление моторами в роботе. Для этого на плате-шасси установлен двухканальный мостовой драйвер моторов TB6612FNG. На изображении ниже вы видите часть принципиальной схемы платы-шасси, отвечающей за управление моторами:
Рассмотрим управление моторами в роботе. Для этого на плате-шасси установлен двухканальный мостовой драйвер (2 Н-моста) моторов TB6612FNG. На изображении ниже вы видите часть принципиальной схемы платы-шасси, отвечающей за управление моторами:
![motor](pic/bsp/motor.png)
Рассмотрим назначение выходов микросхемы:
* PWMA\PWMB - вход для управления скоростью вращения мотора, для канала A и В (соответственно, для первого и второго мотора) с помощью ШИМ (*англ. PWM*);
* AIN1\AIN2 - входы полумостов канала A;
* BIN1\BIN2 - входы полумостов канала B;
* А01\А02 - выходы полумостов канала А;
* В01\В02 - выходы полумостов канала В;
* STBY - включение микросхемы;
* VM - вход питания силовой части микросхемы, двигателей;
* VCC - вход питания логической части микросхемы;
* GND - земля.
---
- PWMA\PWMB - вход для управления скоростью вращения мотора, для канала A и В (соответственно, для первого и второго мотора) с помощью ШИМ (*англ. PWM*);
- AIN1\AIN2 - входы полумостов канала A;
- BIN1\BIN2 - входы полумостов канала B;
- А01\А02 - выходы полумостов канала А;
- В01\В02 - выходы полумостов канала В;
- STBY - включение микросхемы;
- VM - вход питания силовой части микросхемы, двигателей;
- VCC - вход питания логической части микросхемы;
- GND - земля.
***Н-мост***
Н-мост (англ. H-bridge) - это схема, позволяющая приложить напряжение к нагрузке в разных направлениях.
Н-мост (англ. H-bridge) - это схема, позволяющая приложить напряжение к нагрузке в разных направлениях.
![H-bridge](pic/bsp/H-bridge.png)
H-мост состоит из четырех переключателей, котороми могут быть, наппример, транзисторы или реле. Когда ключи S1 и S4 замкнуты, а S2 и S3 разомкнуты, мотор крутится в одну сторону, если же замкнуть S2 и S3, а S4 и S1 разомкнуть - мотор будет крутиться в другую сторону.
H-мост состоит из четырех переключателей, которыми могут быть, например, транзисторы или реле. Когда ключи S1 и S4 замкнуты, а S2 и S3 разомкнуты, мотор крутится в одну сторону, если же замкнуть S2 и S3, а S4 и S1 разомкнуть - мотор будет крутиться в другую сторону.
---
---
***ШИМ***
ШИМ (широтно-импульсная модуляция, англ. PWM) - способ управления мощностью на нагрузке с помощью изменения скважности импульсов при постоянной амплитуде и частоте импульсов.
@ -292,17 +319,14 @@ H-мост состоит из четырех переключателей, ко
Основные параметры ШИМ-сигнала:
* Ui - мплитуда импульсов;
* Ui - амплитуда импульсов;
* Ton - время, когда сигнал включен;
* Toff - время, когда сигнал отключен;
* Tpwm - время периода ШИМ;
Мощность на нагрузке пропорциональна времени включенного и отключенного сигнала.
---
Вернемся к части принципиальной схемы, отвечающей за управление моторам. Видно, что оно осуществляется с помощью четырех пинов GPIO, которые задают напрвление вращения двух моторов (AIN1\AIN2, BIN1\BIN2) и двух пинов с функцией ШИМ (PWMA\PWMB), которые задают скорость вращения.
Вернемся к части принципиальной схемы, отвечающей за управление моторам. Видно, что оно осуществляется с помощью четырех пинов GPIO, которые задают направление вращения двух моторов (AIN1\AIN2, BIN1\BIN2) и двух пинов с функцией ШИМ (PWMA\PWMB), которые задают скорость вращения.
В библиотеке bsp.py реализован функционал, который позволит вам просто объявить объект-мотор, задать скорость и направление вращения:
@ -319,15 +343,15 @@ m.setMotor(10, 20) # Выставить скорость (ШИМ) 10 на ле
# Скорость может быть от -100 до 100, знак определяет направление
```
### Взаимодействие с пьезодинамиком (buzzer):
### Взаимодействие с пьезодинамиком (buzzer)
Пьезодинамик (англ. buzzer) - устройство на основе обратного пьезоэлектрического эффекта, который заключается в механической деформации пьезоэлектрика под воздействием электрического поля. Простыми словами - при подаче напряжения на пьезодинамик, устройство переводит его в колебание мембраны динамика.
Пьезодинамик (англ. buzzer) - устройство на основе обратного пьезоэлектрического эффекта, который заключается в механической деформации пьезоэлектрика под воздействием электрического поля. Простыми словами - при подаче напряжения на пьезодинамик, устройство переводит его в колебание мембраны динамика.
![buzzer](pic/bsp/buzzer.jpg)
![buzzer_shem](pic/bsp/buzzer.png)
Взаимодествие с пьезодинамиком с помощью библиотеки bsp.py реализовано следующим образом:
Взаимодействие с пьезодинамиком с помощью библиотеки bsp.py реализовано следующим образом:
```python
b = beep()
@ -335,9 +359,9 @@ b.on() # Включить пищалку
b.off() # Выключить пищалку, пищит до тех пор пока не выключите
```
### Джойстик:
### Джойстик
На верхней плате-адаптере робота распположен джойстик. На изображении он обведен в красный кружок. Джойстик может возвращать информацию об отклонении его влево, вправо, вперед и вназад, а так же о центральном расположении.
На верхней плате-адаптере робота расположен джойстик. На изображении он обведен в красный кружок. Джойстик может возвращать информацию об отклонении его влево, вправо, вперед и назад, а так же о центральном расположении.
![joystick1](pic/bsp/joystick1.png)
@ -347,11 +371,11 @@ b.off() # Выключить пищалку, пищит до тех
```python
j = joystick()
j.check_ctr() # Вернет еденицу если нажата крестовина
j.check_a() # == нажата A
j.check_b() # == нажата B
j.check_c() # == нажата C
j.check_d() # == нажата D
j.check_ctr() # Вернет единицу если нажата крестовина
j.check_a() # Вернет единицу если нажата A
j.check_b() # Вернет единицу если нажата B
j.check_c() # Вернет единицу если нажата C
j.check_d() # Вернет единицу если нажата D
```
Рассмотрим пример взаимодействия с джойстиком с помощью bsp.py:
@ -381,11 +405,11 @@ while True: # В бесконечном цикле проверяем н
```python
IR = IR_controll()
key = IR.getkey() # Присваеваем переменной key номер нажатой кнопки на пульте
key = IR.getkey() # Присваиваем переменной key номер нажатой кнопки на пульте
# Метод вернет None если не одна кнопка не нажата, или вернет код кнопки если ее нажали в данный момент, и repeat до тех пор пока кнопку не отпустят
```
Пример использования - программа которая выводит код нажатой кнпки:
Пример использования - программа которая выводит код нажатой кнопки:
```python
ir = ir_controll()
@ -407,11 +431,11 @@ while True:
```python
b = ir_bumper()
l = b.check_l() # Вернет 1 если препятствие зафиксированно левым датчиком
r = b.check_r() # Вернет 1 если препятствие зафиксированно правым датчиком
l = b.check_l() # Вернет 1 если препятствие зафиксировано левым датчиком
r = b.check_r() # Вернет 1 если препятствие зафиксировано правым датчиком
```
Пример кода для работы с инфракрасными датчиками. В консоль выводится информация о сенсорах, которые фиксируют обьект:
Пример кода для работы с инфракрасными датчиками. В консоль выводится информация о сенсорах, которые фиксируют объект:
```python
b = ir_bumper()
@ -424,7 +448,7 @@ while True:
time.sleep(0.3)
```
### Ультрозвуковой дальномер
### Ультразвуковой дальномер
Для обнаружения препятствий и определения расстояний до них можно воспользоваться ультразвуковым дальномером.
@ -434,23 +458,20 @@ while True:
Ультразвуковой датчик в формате модуля установлен в специальный разъем на плате-шасси робота.
---
***Ультразвуковой дальномер***
Ультразвуковой дальномер генерирует звуковые импульсы и слушает эхо. Замеряя время, за которое отраженная звуковая волна вернется обратно можно определить расстояние до объекта.
Ультразвуковой дальномер генерирует звуковые импульсы и слушает эхо. Замеряя время, за которое отраженная звуковая волна вернется обратно можно определить расстояние до объекта.
В отличие от инфракрасных датчиков, рассмотренных выше, мы можем получить информацию о расстоянии до объекта, так же такому сенсору будут нестрашны засветы от солнца, но он может плохо работать с очень тонкими и пушистыми предметами.
---
Средствами bsp.py вы можете взаимодействовать с ультразвуковыми датчиками следующим образом:
```python
u = us_sensor()
k = u.dist() # Вернет расстояние до обьекта, считанное сенсором
k = u.dist() # Вернет расстояние до объекта, считанное сенсором
```
Пример кода который будет выводить расстояние до обьекта до тех пор, пока не будет нажато сочетание клавиш ```Ctrl+C```:
Пример кода который будет выводить расстояние до объекта до тех пор, пока не будет нажато сочетание клавиш ```Ctrl+C```:
```python
u = us_sensor()
@ -462,9 +483,9 @@ except KeyboardInterrupt:
GPIO.cleanup()
```
### RGB диоды.
### RGB диоды
Для работы с RGB необходимо внести некотрые изменения в конфиг запуска расбери, т.к. такие светодиоды WS2812B требуют очень специфического сигнала управления. Реолизовать его средствами linux не возможно, поэтому на помощь нам приходят такие модули как DMA и PWM. DMA позволяет передовать данные на светодиоды минуя центральный процуссор, а PWM через управление скважностью позволяет передвать данные от DMA в требуемом формате. Но затакую реализацию нужно платить, поэтому одновременно со светодиодами нельзя использовать аудиокарту встроенную в малину. Собственно для ее отключения нам и нужно исправить настройки запуска, для чего:
Для работы с RGB необходимо внести некоторые изменения в конфиг запуска расбери, т.к. такие светодиоды WS2812B требуют очень специфического сигнала управления. Реализовать его средствами linux не возможно, поэтому на помощь нам приходят такие модули как DMA и PWM. DMA позволяет передавать данные на светодиоды минуя центральный процессор, а PWM через управление скважностью позволяет передрать данные от DMA в требуемом формате. Но за такую реализацию нужно платить, поэтому одновременно со светодиодами нельзя использовать аудиокарту встроенную в малину. Собственно для ее отключения нам и нужно исправить настройки запуска, для чего:
```bash
sudo nano /boot/config.txt
@ -477,7 +498,7 @@ hdmi_force_hotplug=1
hdmi_force_edid_audio=1
```
Также необходимо закоментировать эту строку:
Также необходимо закомментировать эту строку:
```txt
dtparam=audio=on
@ -496,7 +517,7 @@ sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel
sudo python3 -m pip install --force-reinstall adafruit-blinka
```
Для примера попробуем установть разные цвета на диоды:
Для примера попробуем установить разные цвета на диоды:
```python
r = rgb_led()
@ -506,7 +527,7 @@ r.color(2, 0, 255, 0)
r.color(3, 255, 0, 0)
```
Такого-же эффекта можно добится если указать не якость каждого отдельного цвета, а применить название соответствующего цвета.
Такого-же эффекта можно добиться если указать не яркость каждого отдельного цвета, а применить название соответствующего цвета.
```python
r = rgb_led()
@ -527,7 +548,7 @@ r.color(3, "Red")
- White
- Yellow
## Датчики линии.
## Датчики линии
Для отслеживания линии в нижней части робота есть 5 оптических датчиков. Для простого примера можно просто считать с них значения:
@ -538,11 +559,11 @@ while True:
time.sleep(0.2)
```
Если поставить робота на трассу (ее можно найти в папке docs), то маленикие значения (< 200) будут полученны с сенсора который находится над черной линией, а большие (> 800) над беым участком трассы.
Если поставить робота на трассу (ее можно найти в папке docs), то меленькие значения (< 200) будут получены с сенсора который находится над черной линией, а большие (> 800) над белым участком трассы.
## Управление положением камеры
Для управлением полужением камеры (2мя сервоприводами) здесь отвечает специальная микросхема - PCA9685, её необходимо задать угол поворота камеры и она будет его поддерживать, пока мы не передадим новое значение угла. Для реализации данного функцилнала можно воспользоваться следующей функцией:
Для управлением положением камеры (2мя сервоприводами) здесь отвечает специальная микросхема - PCA9685, её необходимо задать угол поворота камеры и она будет его поддерживать, пока мы не передадим новое значение угла. Для реализации данного функционала можно воспользоваться следующей функцией:
```python
c = CameraAngle()
@ -551,7 +572,7 @@ c.setCameraAngle(30, 90)
Установит на 30 градусов по вертикальной оси и 90 градусов по горизонтальной.
Пример программы которая двигает камерой впрово и влево, а так-же вверх и низ:
Пример программы которая двигает камерой вправо и влево, а так-же вверх и низ:
```python
c = CameraAngle()
@ -566,9 +587,9 @@ while True:
time.sleep(0.02)
```
# Примеры простых программ:
# Примеры простых программ
Для примера работы с роботом давайте реализуем программу движения по линии, по датчикам линии. Данная программа позволит двигатся роботу по замкнотуму контуру который можно получить распечатав страницы 2,2,2,2,3,3,3,3,11 из документа с элементами трассы.
Для примера работы с роботом давайте реализуем программу движения по линии, по датчикам линии. Данная программа позволит двигаться роботу по замкнутому контуру который можно получить распечатав страницы 2,2,2,2,3,3,3,3,11 из документа с элементами трассы.
```python
from bsp import rgb_led, line_sensor, motor
@ -605,66 +626,185 @@ while True:
m.setMotor(10, 10)
```
В данном примере робот ездиет по черной линии, также светодтодами подсвечивается сенсор под которым обнаружина линия. delta_sensor это пороговое значения срабатывания сенсора, оно может менятся в зависимости от освещения. Это значение можно узнать если воспользоватся примером выше который считывает значения с сенсоров.
В данном примере робот ездит по черной линии, также светодиодами подсвечивается сенсор под которым обнаружена линия. delta_sensor это пороговое значения срабатывания сенсора, оно может меняться в зависимости от освещения. Это значение можно узнать если воспользоваться примером выше который считывает значения с сенсоров.
## Компьютерное зрение
В рамках данного блока я предлогаю рассмотреть пример который позволит распознать зеленый круг, а также взаимодействавать с ним. Этот процесс состоит из 2х этапов, первое это подбор параметров, а второе это пепосредственная работа с программой по распознованию. Для риализации нужно сделать следующее:
1. нужно доустановить необходимые пакеты, для того что-бы мы могли подключится к пишке, и видить экран, чтобы иметь возможность видеть рабочий стол.
```bash
sudo apt install realvnc-vnc-server realvnc-vnc-viewer
sudo raspi-config
# Interfacing Options -> VNC -> YES
vncserver
```
В рамках данного блока я предлагаю рассмотреть пример который позволит распознать зеленый круг, а также взаимодействовать с ним. Этот процесс состоит из 2х этапов, первое это подбор параметров, а второе это непосредственная работа с программой по распознаванию.
Потом переходим сюда (https://www.realvnc.com/en/connect/download/viewer/) и качаем оттуда версию для винды.
Для реализации нужно сделать следующее:
2. Поставим пакеты для работы с компьютерным зрением:
1. Поставим пакеты для работы с компьютерным зрением:
```bash
sudo apt install libatlas-base-dev
pip3 install numpy opencv-python
```
3. Далее запускаем скрипт предназначенный для подбора параметров.
2. Далее запускаем скрипт предназначенный для подбора параметров.
```python
find_filter.py
import cv2
import numpy as np
if __name__ == '__main__':
def nothing(*arg):
pass
h1_old = 0
s1_old = 0
v1_old = 0
h2_old = 0
s2_old = 0
v2_old = 0
cv2.namedWindow( "result" ) # создаем главное окно
cv2.namedWindow( "settings" ) # создаем окно настроек
cam = cv2.VideoCapture(0)
# создаем 6 бегунков для настройки начального и конечного цвета фильтра
cv2.createTrackbar('h1', 'settings', 0, 255, nothing)
cv2.createTrackbar('s1', 'settings', 0, 255, nothing)
cv2.createTrackbar('v1', 'settings', 0, 255, nothing)
cv2.createTrackbar('h2', 'settings', 255, 255, nothing)
cv2.createTrackbar('s2', 'settings', 255, 255, nothing)
cv2.createTrackbar('v2', 'settings', 255, 255, nothing)
crange = [0,0,0, 0,0,0]
while True:
flag, img = cam.read()
# Перевод изображения в HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# считываем значения бегунков
h1 = cv2.getTrackbarPos('h1', 'settings')
s1 = cv2.getTrackbarPos('s1', 'settings')
v1 = cv2.getTrackbarPos('v1', 'settings')
h2 = cv2.getTrackbarPos('h2', 'settings')
s2 = cv2.getTrackbarPos('s2', 'settings')
v2 = cv2.getTrackbarPos('v2', 'settings')
# формируем начальный и конечный цвет фильтра
h_min = np.array((h1, s1, v1), np.uint8)
h_max = np.array((h2, s2, v2), np.uint8)
# накладываем фильтр на кадр в модели HSV
thresh = cv2.inRange(hsv, h_min, h_max)
cv2.imshow('result', thresh)
ch = cv2.waitKey(5)
if h1 != h1_old or s1 != s1_old or v1 != v1_old \
or h2 != h2_old or s2 != s2_old or v2 != v2_old :
print ("resault: (%d,%d,%d),(%d,%d,%d)"%(h1,s1,v1,h2,s2,v2))
h1_old = h1
s1_old = s1
v1_old = v1
h2_old = h2
s2_old = s2
v2_old = v2
if ch == 27:
break
cam.release()
cv2.destroyAllWindows()
```
Интерфейс программы выглядит так:
![cv1](pic/CV/cv_1.png)
Наша задача подобрать минимальное и максимальное значения для 3х парматров h, s, v. Сначало нужно подобрать нижнюю границу параметра h (h1) Для этого нужно двигать первый ползунок до тех пор пока круг не станет быть виден. потом подгоняем максимальное значение h (h2) так чтобы круз все еще отчетливо был виден. Потом также подгоняем второй параметр s и третий v. В итоге должно получится что-то похожее на это:
Суть происходящего в том что для того чтобы определить объект на фото или видео нам нужно выделить его контур, а для этого необходимо знать его цвет. Также для более удобной работы мы переводим цвет в HSV (тон, насыщенность, значение) представление.
![cv0](pic/CV/HSV_cone.png)
Наша задача подобрать минимальное и максимальное значения для 3х параметров h, s, v. Сначала нужно подобрать нижнюю границу параметра тона h (h1). По сути это и есть выбор того цвета который мы хоти распознать. Для этого нужно двигать первый ползунок до тех пор пока круг не станет быть виден. потом подгоняем максимальное значение h (h2) так чтобы круг все еще отчетливо был виден, но при этом эти 2 ползунка были максимально близки. Потом также подгоняем второй параметр s - это насыщенность, чем больше этот параметр, тем «чище» цвет, а чем ближе этот параметр к нулю, тем ближе цвет к нейтральному серому. Третий v - это яркость.
В итоге должно получится что-то похожее на это:
![cv2](pic/CV/cv_2.png)
Далее нужно сожранить последнее значение распечатанное в консоле, там будет что-то похожее на это:
Далее нужно сохранить последнее значение распечатанное в консоль, там будет что-то похожее на это:
```txt
(96, 175,70),(85,255,117)
```
Эти числа нам потребуются далее для работы с распознованием обьекта.
Эти числа нам потребуются далее для работы с распознаванием объекта.
Далее запустим пример который распознает круг.
Далее рассмотрим пример который распознает круг.
```python
circul_detect.py
import cv2
import numpy as np
# Подключаемся к камере
cam = cv2.VideoCapture(0)
while True:
_, frame = cam.read()
# Перевод изображения в HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Немного размываем изображение
hsv = cv2.blur(hsv,(5,5))
# Задаем параметр из прошлого примера
mask = cv2.inRange(hsv, (78,154,93),(86,224,255))
# С помощью специального алгоритма ищем контур обьекта
(contours, hierarchy) = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Отрисовывем найденый контур чтобы его было видно на экране
cv2.drawContours(frame, contours, -1, (255,0,0), 3, cv2.LINE_AA, hierarchy, 1 )
max_radius = 0
center = (0,0)
# Находим контур с максимальным радиусом
for contour in contours:
(x,y),radius = cv2.minEnclosingCircle(contour)
if max_radius < int(radius):
max_radius = int(radius)
center = (int(x),int(y))
# Описываем максимальный контур кругом
frame = cv2.circle(frame,center,max_radius,(0,255,0),2)
S = 3.1415 * max_radius * max_radius
# Выводим на эран площадь круга
cv2.putText(frame, str(S), (30, 30),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 10, 10), 2)
# Выводим сообщение если круг слишком близко или далеко
if S > 100:
if S > 10000:
cv2.putText(frame, "UP", (30, 60),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 10, 10), 2)
elif S < 5000:
cv2.putText(frame, "DOWN", (30, 60),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 10, 10), 2)
# Промежуточные изображения
#cv2.imshow("Image with opening", mask)
#cv2.imshow("Image with closing", hsv)
# выводим то что получилось вместе с текстом и контуром
cv2.imshow("Image", frame)
k = cv2.waitKey(2)
if k == 27:
cv2.destroyAllWindows()
break
```
![cv3](pic/CV/cv_3.png)
TODO: Написть че вообще происходит.
В чем тут идея, изображение полученное с камеры проходит несколько этапов преобразования для того чтобы мы могли распознать на нем объект. Сначала мы преобразуем изображение в HSV формат который мы использовали в предыдущим примере. Потом с помощью алгоритма определяющего контур ищем объект нужного цвета. Вот тут и нужны параметры полученные в прошлом примере, из-за того что у вас может отличатся освещение или камера то эти параметры всегда нужно подбирать экспериментально. Этот контур можно увидеть на скриншоте ниже, от состоит из синих точек. Далее мы ищем 2 самые удаленные друг от друга точки и строим вокруг них окружность. Далее определяем площадь этой окружности, выводя сообщение о том что она слишком близка или далека от камеры. Тут вы можете проявить изобретательность и добавить например движение робота за объектом если он далеко и от него если близко, так же можно определить положение объекта на экране таким образом заставив робота следовать за объектом.
## Машинное обучение
Тут в качкстве примера я предложу вам обучить свою нейронную серь на открытом датасете который содержит тысячи изображений цифр - MNIST. Этот датасет уже встроен в библиотеку keras.
Тут в качестве примера я предложу вам обучить свою нейронную серь на открытом датасете который содержит тысячи изображений цифр - MNIST. Этот датасет уже встроен в библиотеку keras.
Для того чтобы использовать нейронную сеть ее нужно сначала обучить, для этого я предлагаю использовать сервис google colaboratiry - https://colab.research.google.com/notebooks/intro.ipynb, потомучто обучение сетей требует значительных вычислительных мощностей, а гугл готов нам предоставить их бесплатно в образовательных целях. Данный сервис представляет из себя страницу jupiter noutbook код в которой исполняется поблочно. давайте рассмотрим блоки которые нам необходимы для получения обученной сети:
Для того чтобы использовать нейронную сеть ее нужно сначала обучить, для этого я предлагаю использовать сервис google colaboratiry - https://colab.research.google.com/notebooks/intro.ipynb, потому что обучение сетей требует значительных вычислительных мощностей, а гугл готов нам предоставить их бесплатно в образовательных целях. Данный сервис представляет из себя страницу jupiter noutbook код в которой исполняется поблочно. давайте рассмотрим блоки которые нам необходимы для получения обученной сети:
1) Импорт библиотек
@ -677,31 +817,28 @@ from tensorflow.keras import layers
2) Скачивание датасета и преобразованиего в необходимый формат:
```python
# Model / data parameters
# Параметры модели и данных
num_classes = 10
input_shape = (28, 28, 1)
# the data, split between train and test sets
# Разделяем данные на тестовые и обучающие
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Scale images to the [0, 1] range
# Масштабируем изображения до диапазона цветов 0..1
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
# Make sure images have shape (28, 28, 1)
# Меняем размер изображения (28, 28, 1)
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")
# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
```
3) Создание нейронной сети:
TODO: написать что-то про то откуда взялись эти слои
3) Создание нейронной сети, прописываем слои из которых мы хотим чтобы состояла наша сетка.
```python
model = keras.Sequential(
@ -720,7 +857,7 @@ model = keras.Sequential(
model.summary()
```
В резулитате можно увидить структуру созданой сети:
В результате можно увидить структуру созданой сети:
```txt
Model: "sequential"
@ -767,7 +904,9 @@ print("Test loss:", score[0])
print("Test accuracy:", score[1])
```
После этого нужно будет перести файл ```mnist_trained_model.h5``` на вышу малину.
После этого нужно будет перести файл ```mnist_trained_model.h5``` на вашу raspberry.
Для создания скрипта уже на самом роботе нужно сделать следующее:
Даллее для того чтобы запустить это на пишки нужно доставить еще пакеты:

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

@ -1,8 +1,6 @@
import cv2
import numpy as np
# IT IS WORK !!!!!!
cam = cv2.VideoCapture(0)
while True:

Loading…
Cancel
Save