
Всегда был интересен процесс интеграции тех или иных роботов в социальную, городскую сферу.Возникает очень много вопросов, как технического, юридического так и этического характера.
Что будет например если ваша поделка весом под 60 кг сломает, например, кому то ногу.Или собьется GPS-трек и робот спровоцирует ДТП на оживленном пешеходном переходе-перекрестке? Или подарит цветы не той, "незапрограммированной" девушке, ошибется цветом кожи клиента или доставит до адресата пиво теплым а шаурму холодной? Задавшись в один прекрасный момент идеей создания робота своей мечты можно получить ответы на некоторые эти вопросы, заодно, в очередной раз, попробовать перевернуть мир.Собственно под катом описан процесс создания некого универсального робота.Конкретно шасси.
Первые роботы были скорее "пробой пера"
Был такой, 2-х колесный



И такая модификация:

Ну и такая:

После изучения с полсотни вариантов конструкций, как заводских так и самодельных решено было взять за основу простую и изящную конструкцию типа «Краб» от тайландских мастеров газонокошения. Были визуально определены конструкция, механика и кинематика.
Итак, для создания нам понадобится:
- Кучка металлолома:

Колеса.Желательно выбрать с ярко выраженным протектором, параллельным оси колеса, чтобы реализовать грунто-зацеп и танковый разворот.В данном случае используются колеса от мотоблока.
Ведомые звезды.От мотоциклов, мокиков и прочей велосипедятины.
Электродвигатели с редуктором модели MY1016Z2 на 12 вольт.Как выяснилось позже запас магнитного насыщения сердечника и толщина изоляции обмоток такого двигателя позволяют запросто их перегружать напряжением в 24 вольта, повышая ток и мощность.

Мотоциклетная цепь. Была выбрана мотоциклетная цепь под номером 428, для пущей совместимости с большинством зубчатых колес.
Пульт дистанцинного управления.Использовать можно любой, был взят китайский для авиамоделизма, с радиусом действия до 400м.

Микроконтоллер Atmega 8a.
Парочка сборок Дарлингтона для управления электромагнитными реле.К примеру ULN2803AFWG.
Электромагнитные реле и постели для них, применяющиеся преимущественно на автомобилях.

- Свинцовая аккумуляторная батарея.
Спустя пару месяцев махания диском болгарки, росчерка электродами и конструкция из пота, крови и металла была готова.
Ступицы, оси, шайбы и прочие запчасти.Не обошлось без токарных работ по вытачиванию упоров, натяжных роликов для цепей.

Кусок металла и куча проводов:

Электронная начинка для теста всей конструкции предельная проста:
Atmega напрямую прикрученная к транзисторной сборке, которая напрямую управляет реле.Реле, надо отметить, коммутируют нагрузку через самодельные дросселя, чтобы немного сгладить якорные токи при пуске двигателей.
Переполюсовка питания двигателей также осуществляется по команде с Atmeg`и через отдельные реле.

Проведя процедуру привязки приемника к пульту, замкнув сервисной перемычкой контакты на приемнике, на сленге "Bind" — можно приступить к программированию управления пультом.
Посмотрим на выходные сигналы с приемника осциллографом:

Ага, в взависимости от положения стика меняется длительность импульса.Можно обработать это микроконтроллером, считывая уровни сигналов, считая такты-длительность.
Пару-десятков тестов для калибровки и код был написан.
Так выглядит исходник по приему сигналов с приемника и управлением роботом.
;by IC ;GK1 ;PC5-муфта ;pc4-контакт 4- реверс правый борт (ВЫХОДНОЙ СИГНАЛ) ;pc3-контакт 3 -реверс левый борт (ВЫХОДНОЙ СИГНАЛ) ;pc2-контакт 2 -мотор-редуктор правый борт (ВЫХОДНОЙ СИГНАЛ) ;pc1-контакт 1 -мотор-редуктор левый борт (ВЫХОДНОЙ СИГНАЛ) ;pc0-ДВС (ВЫХОДНОЙ СИГНАЛ)G ;pb-ВХОДНОЙ СИГНАЛ ПДУ ;ПДУ - канал 4 - левый стик, лево-право ;ПДУ - канал 3 - левый стик, вверх-вниз ;ПДУ - канал 2 - правый стик, вверх-вниз (вниз-скважность уменьшается, вверх- скважность увеличивается) ;ПДУ - канал 1 - правый стик, лево- право (лево-скважность уменьшается, право- скважность увеличивается) ;d7-d8 -нейтраль ;0116h - высоко ;91 - низко rjmp RESET ; Reset Handler rjmp EXT_INT0 ; IRQ0 Handler rjmp EXT_INT1 ; IRQ1 Handler ;rjmp TIM2_COMP ; Timer2 Compare Handler ;rjmp TIM2_OVF ; Timer2 Overflow Handler ;rjmp TIM1_CAPT ; Timer1 Capture Handler ;rjmp TIM1_COMPA ; Timer1 CompareA Handler ;rjmp TIM1_COMPB ; Timer1 CompareB Handler ;rjmp TIM1_OVF ; Timer1 Overflow Handler ;rjmp TIM0_OVF ; Timer0 Overflow Handler ;rjmp SPI_STC ; SPI Transfer Complete Handler ;rjmp USART_RXC ; USART RX Complete Handler ;rjmp USART_UDRE ; UDR Empty Handler ;rjmp USART_TXC ; USART TX Complete Handler ;rjmp ADC ; ADC Conversion Complete Handler ;rjmp EE_RDY ; EEPROM Ready Handler ;rjmp ANA_COMP ; Analog Comparator Handler ;rjmp TWSI ; Two-wire Serial Interface Handler ;rjmp SPM_RDY ; Store Program Memory Ready Handler RESET: cli ldi r17, 0xff out 0x3D, r17 ;инициализация стэка ldi R16, 0b00111111 ;порт С как выход out 0x14, r16 ;настройка через регистр DDRC\ ldi R16, 0x0 ;порт B как вход out 0x17, r16 ;настройка через регистр DDRB ldi R16, 0x0 ;порт D как вход out 0x11, r16 ;настройка через регистр DDRD sbi 0x12, 0 ;устанавливаем бит активации Pull-up в PORTD для пина PD0 sbi 0x12, 1 ;устанавливаем бит активации Pull-up в PORTD для пина PD1 sbi 0x12, 2 ;устанавливаем бит активации Pull-up в PORTD для пина PD2 jmp PDU_mode U_turn_right_PDU: nop CALL R1__LEFT_ON CALL latency_relay_switch CALL M1__LEFT_ON CALL M2__RIGHT_ON nop jmp chanel3 U_turn_left_PDU: nop CALL R2__RIGHT_ON CALL latency_relay_switch CALL M1__LEFT_ON CALL M2__RIGHT_ON nop jmp chanel3 PDU_mode: chanel1: ldi r21, 0 ldi r22, 0 ldi r23, 1 ldi r24, 0 nop get_low: nop sbic 0x10, 0 jmp get_low ;дождались нуля на PD0 get_rising: nop sbis 0x10, 0 jmp get_rising ;дождались HIGH сигнала на PD0 get_falling: nop add r21, r23 ;основной бит adc r22, r24 ;дополнительный sbic 0x10, 0 jmp get_falling ;Сигнал HIGH закончился cpi r22, 1 breq U_turn_right_PDU cpi r21, 0x9f ;a0 brlo U_turn_left_PDU chanel2: ldi r21, 0 ldi r22, 0 ldi r23, 1 ldi r24, 0 nop get_low2: nop sbic 0x10, 1 jmp get_low2 ;дождались нуля на PD0 get_rising2: nop sbis 0x10, 1 jmp get_rising2 ;дождались HIGH сигнала на PD0 get_falling2: nop add r21, r23 ;основной бит adc r22, r24 ;дополнительный sbic 0x10, 1 jmp get_falling2 ;Сигнал HIGH закончился cpi r22, 1 breq Motion_forward_PDU cpi r21, 0x9f ;a0 brlo Motion_backward_PDU nop CALL M1__LEFT_OFF CALL M2__RIGHT_OFF CALL latency_relay_switch CALL R1__LEFT_OFF CALL R2__RIGHT_OFF nop chanel3: ldi r21, 0 ldi r22, 0 ldi r23, 1 ldi r24, 0 get_low3: sbic 0x10, 2 jmp get_low3 ;дождались нуля на PD0 get_rising3: sbis 0x10, 2 jmp get_rising3 ;дождались HIGH сигнала на PD0 get_falling3: add r21, r23 ;основной бит adc r22, r24 ;дополнительный sbic 0x10, 2 jmp get_falling3 ;Сигнал HIGH закончился cpi r22, 1 breq Clutch_ON_PDU CALL Clutch_OFF nop jmp PDU_mode Clutch_ON_PDU: CALL Clutch_ON jmp PDU_mode Motion_forward_PDU: CALL R2__RIGHT_ON CALL latency_relay_switch CALL R1__LEFT_ON CALL latency_relay_switch CALL M1__LEFT_ON CALL M2__RIGHT_ON nop jmp chanel3 Motion_backward_PDU: CALL M1__LEFT_ON CALL M2__RIGHT_ON nop jmp chanel3 LDI R16,2 ; Загружаем адрес нулевой ячейки LDI R17,0 ; EEPROM ;LDI R21, 0x33 ; и хотим записать в нее число cc RCALL EEWrite ; вызываем процедуру записи. LDI R16,1 ; Загружаем адрес нулевой ячейки LDI R17,0 ; EEPROM mov r21, r22 RCALL EEWrite ; вызываем процедуру записи. ldi r25, 1 ;флаг записи епромки LDI R16,3 ; Загружаем адрес нулевой ячейки LDI R17,0 ; EEPROM mov r21, r25 RCALL EEWrite ; вызываем процедуру записи. skip: nop jmp idle EEWrite: SBIC EECR,EEWE ; Ждем готовности памяти к записи. Крутимся в цикле RJMP EEWrite ; до тех пор пока не очистится флаг EEWE CLI ; Затем запрещаем прерывания. OUT EEARL,R16 ; Загружаем адрес нужной ячейки OUT EEARH,R17 ; старший и младший байт адреса OUT EEDR,R21 ; и сами данные, которые нам нужно загрузить SBI EECR,EEMWE ; взводим предохранитель SBI EECR,EEWE ; записываем байт SEI ; разрешаем прерывания RET ; возврат из процедуры EERead: SBIC EECR,EEWE ; Ждем пока будет завершена прошлая запись. RJMP EERead ; также крутимся в цикле. OUT EEARL, R16 ; загружаем адрес нужной ячейки OUT EEARH, R17 ; его старшие и младшие байты SBI EECR,EERE ; Выставляем бит чтения IN R25, EEDR ; Забираем из регистра данных результат RET Motion_forward: CALL latency_relay_switch CALL R2__RIGHT_ON CALL latency_relay_switch CALL R1__LEFT_ON CALL latency_relay_switch CALL M1__LEFT_ON CALL M2__RIGHT_ON CALL latency CALL M1__LEFT_OFF CALL M2__RIGHT_OFF CALL latency_relay_switch CALL R1__LEFT_OFF CALL R2__RIGHT_OFF Motion_backward: CALL latency_relay_switch CALL M1__LEFT_ON CALL M2__RIGHT_ON CALL latency CALL M1__LEFT_OFF CALL M2__RIGHT_OFF U_turn_right: CALL latency_relay_switch CALL R1__LEFT_ON CALL latency_relay_switch CALL M1__LEFT_ON CALL M2__RIGHT_ON CALL latency CALL M1__LEFT_OFF CALL M2__RIGHT_OFF CALL latency_relay_switch CALL R1__LEFT_OFF ;ret U_turn_left: CALL latency_relay_switch CALL R2__RIGHT_ON CALL latency_relay_switch CALL M1__LEFT_ON CALL M2__RIGHT_ON CALL latency CALL M1__LEFT_OFF CALL M2__RIGHT_OFF CALL latency_relay_switch CALL R2__RIGHT_OFF ;ret jmp Motion_forward TEST1: CALL ICE_Start CALL latency CALL ICE_Stop CALL latency CALL M1__LEFT_ON CALL latency CALL M1__LEFT_OFF CALL latency CALL M2__RIGHT_ON CALL latency CALL M2__RIGHT_OFF CALL latency CALL R1__LEFT_ON CALL latency CALL R1__LEFT_OFF CALL latency CALL R2__RIGHT_ON CALL latency CALL R2__RIGHT_OFF CALL latency CALL Clutch_ON CALL latency CALL Clutch_OFF jmp TEST1 idle: ;sbi 0x15, 5 ;PortC, бит 5 nop jmp idle EXT_INT0: sbi 0x15, 5 ;PortC, бит 5 reti EXT_INT1: sbi 0x15, 4 ;PortC, бит 5 reti ;Задержка latency_relay_switch: ;калиброванная задержка для переключения реле ldi r20, 255 ldi r21, 100 ;ldi r22, 1 delay2: subi r20, 1 sbci r21, 0 ;sbci r22, 0 brne delay2 nop ret ;Задержка latency: ldi r20, 255 ldi r21, 255 ldi r22, 12 delay1: subi r20, 1 sbci r21, 0 sbci r22, 0 brne delay1 nop ret ICE_Start: sbi 0x15, 0 ;PortC, бит 0 RET ICE_Stop: cbi 0x15, 0 ;PortC, бит 0 ret M1__LEFT_ON: sbi 0x15, 1 ;PortC, бит 1 ret M1__LEFT_OFF: cbi 0x15, 1 ;PortC, бит 1 ret M2__RIGHT_ON: sbi 0x15, 2 ;PortC, бит 2 ret M2__RIGHT_OFF: cbi 0x15, 2 ;PortC, бит 2 ret R1__LEFT_ON: sbi 0x15, 3 ;PortC, бит 3 ret R1__LEFT_OFF: cbi 0x15, 3 ;PortC, бит 3 ret R2__RIGHT_ON: sbi 0x15, 4 ;PortC, бит 4 ret R2__RIGHT_OFF: cbi 0x15, 4 ;PortC, бит 4 ret Clutch_ON: sbi 0x15, 5 ;PortC, бит 5 ret Clutch_OFF: cbi 0x15, 5 ;PortC, бит 5 ret
После окончательной сборки и с полсотни выездов стало ясно что механика робота работает отлично.Данная телега легко справляется с большинством препятствий, значительными уклонами до 40 ‰, обладает запасом мощности, достаточной маневренностью.
Как видно на видео на некоторых участках местности крутящего момента двигателей явно не хватает.
Не беда — они легко выдерживают 2-х кратную перегрузку с повышением момента и оборотов.Достаточно установить в силовой цепи последовательно еще 1 аккумулятор, но при этом появляется другая большая проблема — залипание контактной части реле, вследствии возрастания тока.Что собственно и произошло — вдруг 60000 грамовая машина потеряв управление понеслась в недопустимую сторону.
Решение проблемы установкой контакторов с дугогашением не рассматривается в принципе — жизнь людей дороже, пусть лучше сгорит транзистор в контроллере электродвигателя.
Вернувшись на "базу" без потерь решено было серьезно доработать схемотехнику и алгоритмы управления роботом, в пользу человечества.Иначе как он сможет автономно развозить шаурму? не привлекая внимания работников правоохранительных органов и не попадать в криминальную сводку местных новостей.
Как можно заметить робот представленный в заголовке статьи и робот описанный в теле статьи несколько отличаются.Это значит лишь то, что не все истории рассказаны.
На робота будут установлены более-менее профессиональные контроллеры электродвигателей с векторным управлением крутящего момента, различными программными функциями типа hard-stop, выполнено дублирование сигналов, установлена датчиковая аппаратура и литиевые аккумуляторы, будет заменен, на более интересный, микропроцессор.
Запись теплового следа и поиск отклонений для фиксаций нарушений охранного периметра и локальных техногенных дефектов.
Подключение робота к купюроприемнику по старому протоколу mdb vending.
Обо всем этом и приключениях робота среди людей в следующих частях.
P.S. Новые законы робототехники не за горами.
P.S.S. Рабочее название проекта "Grass-killer".
