Arduino mega2560 hexapod
- Войдите на сайт для отправки комментариев
Добрый день!
Я пытаюсь сделать робота паука (6 ног, 3 сервопривода на ногу). Для управления используется arduino mega 2560 (без дополнительного сервоконтроллера). Пока сделал движение вперед, назад, поворот влево и вправо. Все это просто подавая нужные значения на нужные сервоприводы. Теперь хочу разобраться и сделать движение используя инверсную кинематику. За основу взял статью https://oscarliang.com/inverse-kinematics-implementation-hexapod-robots/. Там есть excel файл, в котором расписаны все формулы для расчета углов. Я перенес эти формулы в arduino, считает все как в файле.
Теперь я не могу понять что делать дальше. При изменении глобальных координат (центра тела), пересчитываются координаты для каждой ноги (локальные), дальше эти локальные координаты преобразуются в углы. Что дальше делать с этими углами, чтобы реализовать, например, движение вперед? Помогите пожалуйста разобраться.
Спасибо!
Сразу возникает вопрос: а зачем нужно было считать углы?
И почему именно углы?
Робот ведь у Вас на сервах? А у сервы единственная функция - поворачиваться на заданный угол.
Вопрос на засыпку: и что же надо делать с рассчитанными углами?
Вопрос на засыпку: и что же надо делать с рассчитанными углами?
засовывать их в сервы
засовывать их в сервы
Это понятно, но их же надо подавать в определенной последовательности. И двигаться все ноги должны одновременно. В файле с формулами есть Gait table, вот с ней и не могу разобраться. Что это и как её использовать.
Когда углы известны я делал примерно так:
а, нахрена это?
delay(stepDelayValue);
есть у тебя угол, так понимаю, есть у тебя скорость движения сервы speedValue , если я правильно понимаю - воткнул угол и скорость во все сервы и жди, когда оно на ноги встанет
Если тупо подать значения сразу на ВСЕ сервы то никакого движения вперед не будет. Для этого я так понял и сделана в статье таблица Gait table, а у меня используется куча разных конструкций for-map.
А delay(stepDelayValue); это небольшая (5-20 мс) временная задержка, тоже для регулировки скорости движения.
nanotroll, Вы пишете, что у Вас уже есть скетч, двигающий робота. Насколько я понял, в 3-м посте фрагмент именно из него.
Калапуция Вам уже намекнул, скажу еще я открытым текстом:
Начните с того, что перепишите то, что у Вас есть, без использования delay(). Принцип изложен здесь: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay Пока Вы с этим хорошенько не разберетесь, делать что-либо другое бессмысленно.
Начните с того, что перепишите то, что у Вас есть, без использования delay().
Пока переписал только функции "встать" и "сесть" для одного сервопривода, используя millis() . Если возможно, посмотрите пожалуйста код, вроде едет вверх и вниз, но может быть все реализуется проще, чем я понял.
Реализовано неверно.
У Вас из loop управление передается getCommand, а там при наличии команд зависает пока taskState != COMPLETED. Так Вы опять будете двигать сервы по очереди вместо того, чтобы двигать их одновременно. Нельзя при управлении движения использовать цикл while. На каждом проходе loop нужно проанализировать ситуацию, при необходимости осуществить однократное воздействие (возможно, по одному на каждую серву) и тут же вернуть управление. Т.е. управлять нужно всеми серваит одновременно, а как сделали Вы - получается только по очереди.
И двигать сервы шажками по единице - плохая практика. Фактически Вы только существенно снижаете скорость перемещения серв (до менее радиана в секунду), не имея никакого положительного эффекта. Пусть сервы двигаются с максимально допустимой для них скоростью, если это возможно. А если нет - нужно обеспечить синхронное перемещение серв, скорее всего, их придется перемещать с разными шагами, а не с постоянным шагом равным 1.
Добавил переменные
Переделал функцию получения команды и добавил выполнение задачи отдельно, теперь вроде по одному шагу добавляет за заход, циклов нету.
Ну, раз добавили констаны, сразу бы и внесли их в doTask().
А серв - лучше бы сразу завести массив, хотя бы из двух элементов, чтобы уже на этом этапе планировать, как они должны будут управляться.
Спасибо Вам за ответы, еще хотелось бы уточнить несколько моментов.
У меня есть в программе много констант, которые содержат номера пинов, к которым подключены сервы, временные интервалы, разные позиции для каждой сервы. Как их правильно описать? Через const или через define? Я бы хотел их вообще вынести в отдельный файл.
Функция "шаг вперед" состоит из 4 кусков, вроде шагает, но кажется как будто 1 и 2 куски выполняются медленнее, чем 2 и 3.
moveServo() отдельно:
Получается в итоге мне нужно будет углы, которые определены константами заменить на посчитанные из координат?