Система автоматической разгрузки и загрузки дрона(Часть 1)
Проблема разгрузки и загрузки грузов на дрон без участия человека — это основная проблема автоматизации доставки грузов с помощью дронов. Ключевой этап доставки, который требует присутствия человека, заключается в процессе физической загрузки и разгрузки грузов на дрон. Но у нас есть решение!
Множество разработок имеется на этот счёт, но все они работают или в условиях идеального позиционирования (до 2 см), или не могут долго хранится в плохую погоду (например картонные коробки).
Одним из решений этой проблемы может быть разработка автоматизированной системы для загрузки и разгрузки грузов на дрон. Такая система может быть основана на использовании нашего решения данной проблемы.
Конструкция
Для начала нужно понять, что нам требуется (задачи):
Дрон должен иметь возможность «промахнуться» до 10 см. (порывы ветра никто не отменял)
Конструкция посадочного место не должна затопляться (выше уровня земли/асфальта)
Крепление груза должно быть надёжным (мы же не хотим, чтобы наша посылка упала кому-то на голову)
В начале пути, мы определились с формой корпуса и посадочного места, была выбрана форма усечённого конуса (Рис. 2), задача данной формы в том, чтобы, при отклонении дрона на дистанцию D (Рис. 2), грузовой модуль, прикреплённый к дрону «скатится» в центр посадочного места.
Рис. 2 Посадочное место (синий цвет), Грузовой модуль (зелёный цвет)
В нашей реализации это выглядит так:
Рис. 3 Внешний вид посадочного места и грузового модуля
Грузовой контейнер соответственно принял такой внешний вид:
Рис. 4 Грузовой отсек
Рис. 5 Способ открытия грузовой отсека
«Убив двух зайцев разом» (задачи 1 и 2), перейдём к замку (нет, он пока засекречен, к сожалению, пока ждём окончательного оформления патента).
Программирование
Теперь перейдём к дрону, который использовался в данном проекте, это Pioneer max от Geoscan. Было потрачено много времени, для того чтобы его оживить. Для начала мы подключили сервопривод (сразу обращайте внимание, что некоторые пины используются по умолчанию и их использование не даст нормального результат (тряски, ложные срабатывания)). Более подробнее я напишу про этот «танец с бубнами» в будущем, а пока вернёмся к программированию. Тем более мы реализовали полностью автономный полёт!
Ниже представлены программы для работы сервопривода, все коды составлялись на основе документации (Программирование на Lua — Документация Pioneer December update 2022 (geoscan.aero)), НО информация там не вся рабочая, поэтому мы прикрепили свои коды:
-----------------------------------Lua код--------------------------------------------
local uart = Uart.new(4, 57600) -- объявляем uart для общения с pyhon кодом
local servo_stat = 'o' -- статус сервопривода(например 'o'(открыто),'c'(закрыто))
local rc = Sensors.rc -- подключаем пульт
local inp = '' -- переменная для хранения информации для отправки на Python
local rec = '' -- переменная для хранения ответа(для будущего применения)
local function rotate_servo_open() -- функция открытия сервопривода
servo_stat='o'
end
local function rotate_servo_close() -- функция закрытия сервопривода
servo_stat='c'
end
local function main() -- цикл
rc_chans = table.pack(rc()) -- получаем иинформацию с пульта
if rc_chans[8] < -0.8 then --открытие (канал посмотри на пульте)
rotate_servo_open()
elseif rc_chans[8] > 0.8 then --закрытие (канал посмотри на пульте)
rotate_servo_close()
end
inp = servo_stat..'\n' -- пусть разделитель '\n'
uart:write(inp, #inp) -- отправляем на Python
rec = uart:read(20) -- в скобка пишем сколько принимаем байт
end
t = Timer.new(0.08, main) --устанавливаем частоту цикла
---!ВРЕМЯ СИНХРОНИЗАЦИИ ДОЛЖНО БЫТЬ ОДИНАКОВО НА LUA и PYTHON!
t:start() -- начинаем цикл
----------!!!КОВЫЧКИ ОДИНАРНЫЕ ОБЯЗАТЕЛЬНО, ИНАЧЕ РАБОТАТЬ НЕ БУДЕТ !!!---------------
####################################Python код########################################
import serial # библиотека для общения
from time import sleep # библиотека для синхронизации
import RPi.GPIO as GPIO # библиотека для общения
ser = serial.Serial("/dev/ttyS0", 57600, timeout=5) # открываем порт, бездумно не меняй
GPIO.setmode(GPIO.BCM) # объявляем для общения
GPIO.setup(25, GPIO.OUT) # объявляем для общения
sg = GPIO.PWM(25, 50) # объявляем сервопривод
sg.start(8.06) # объявляем задаём начальный угол
servo_opened = True # по умолчанию замок открыт
def uart_read(): # функция чтения с Lua
data = ser.readline().decode().replace('\n', "") # читаем, разделяем, убираем мусор
if ser.in_waiting > 20: # чтобы не зависало, бездумно не меняй
ser.reset_input_buffer() # чтобы не зависало, бездумно не меняй
print('Read data: ') # вывод в терминал
print(data) # вывод в терминал
return data
def uart_write(answer): # функция ответа для Lua
ser.write(answer.encode()) # кодируем, пишем
print('UART writed') # вывод в терминал
def servo_control(event): # функция управления сервоприводом
global servo_opened # подключаем глобальные переменные
global sg # подключаем глобальные переменные
if event == "c" and servo_opened: # закрываем серво если получили 'c'
sg.ChangeDutyCycle(2.5)
servo_opened = False
print('closed')
elif event == "o" and not (servo_opened): # открываем серво если получили 'o'
sg.ChangeDutyCycle(8.06)
servo_opened = True
print('opened') # вывод в терминал
def auto_p_control(data):
servo_event = data[0]
servo_control(servo_event) # вызов функции для поворота сервопривода
print("ANS : " + str(ans)) # вывод в терминал
uart_write(ans) # отправка данных на Lua
sleep(0.08) # синхронизация
while True: # бесконечный цикл
uart_data = uart_read() # вызываем функцию чтения
if uart_data != ['']: #если прочитанные данные не пустые
auto_p_control(uart_data) # вызываем функцию ответа
Перейдём к результату, для дальнейшего обдумывания.