Проблема разгрузки и загрузки грузов на дрон без участия человека — это основная проблема автоматизации доставки грузов с помощью дронов. Ключевой этап доставки, который требует присутствия человека, заключается в процессе физической загрузки и разгрузки грузов на дрон. Но у нас есть решение!
Множество разработок имеется на этот счёт, но все они работают или в условиях идеального позиционирования (до 2 см), или не могут долго хранится в плохую погоду (например картонные коробки).
Одним из решений этой проблемы может быть разработка автоматизированной системы для загрузки и разгрузки грузов на дрон. Такая система может быть основана на использовании нашего решения данной проблемы.
Конструкция
Для начала нужно понять, что нам требуется (задачи):
-
Дрон должен иметь возможность «промахнуться» до 10см. (порывы ветра никто не отменял)
-
Конструкция посадочного место не должна затопляться (выше уровня земли/асфальта)
-
Крепление груза должно быть надёжным (мы же не хотим, чтобы наша посылка упала кому-то на голову)
В начале пути, мы определились с формой корпуса и посадочного места, была выбрана форма усечённого конуса (Рис.2), задача данной формы в том, чтобы, при отклонении дрона на дистанцию D (Рис.2), грузовой модуль, прикреплённый к дрону «скатится» в центр посадочного места.
В нашей реализации это выглядит так:
Грузовой контейнер соответственно принял такой внешний вид:
«Убив двух зайцев разом» (задачи 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) # вызываем функцию ответа
Перейдём к результату, для дальнейшего обдумывания.
ссылка на оригинал статьи https://habr.com/ru/articles/751236/
Добавить комментарий