Робосумо 10×10 — это одно из наиболее популярных соревнований в области робототехники. В этом соревновании роботы размером 10×10 сантиметров сражаются на специальном ринге диаметром 770 сантиметров. Цель роботов — вытолкнуть противника с ринга. Матч продолжается, пока
команда не набирает установленное количество баллов.
Робо сумо 10×10 требует от участников не только создания мощных и быстрых роботов, но также разработки эффективных стратегий борьбы. Роботы обычно оснащены датчиками, моторами и другими устройствами, которые помогают им определять положение соперника, двигаться по рингу и принимать решения в реальном времени.
Соревнования по робо сумо 10×10 проводятся как на уровне школьных и университетских команд, так и на профессиональном уровне. Участие в таких соревнованиях может быть отличной возможностью для студентов и любителей робототехники продемонстрировать свои навыки, обменяться опытом с другими участниками и получить ценный опыт.
Пример программы для робота 10 на 10
Для робота мы будем использовать:
- Мотор-редуктор серии Core 6V 300 об/мин x
- Датчик Micro Line (ML1) x 2
- Датчик ИК sharp340k x 5
- JS2721 Силиконово – алюминиевое колесо x 2
- 3S LiPo аккумулятор емкостью 350 мАч x 1
Подключение датчиков растояния:
- Левый датчик: D0
- Левая диагональ: D1
- Средний датчик: D2
- Датчик правой диагонали: D4
- Правый датчик: A5 (мы будем использовать его в качестве цифрового входа
Подключение датчиков линии:
- Датчик левой линии: A2
- Датчик правой линии: A1
Напишем программу для мини сумо 10 на 10
Перейдём к программированию, но для начала проверим моторы, для этого мы будем используем библиотеку Xmotion. Похожей библиотекой является GyverMotors.
void setup() { } void loop() { xmotion.Forward(30, 1000); // 1 Second (1000ms) Forward xmotion.StopMotors(100); //Stop 100ms xmotion.Right0(40, 100); //Right 0 turn 0.1 second xmotion.StopMotors(100); //Stop 100ms xmotion.Left0(40, 100); //Left 0 turn 0.1 second xmotion.StopMotors(5000); //Stop 5000ms }
Этот код поможет нам проверить работу двигателей. Сначала оба двигателя должны двигаться вперед. Если они вращаются правильно, то один из них должен начать двигаться назад. Если оба двигателя двигаются назад, необходимо перепаять соединения. После этого нужно убедиться, что они корректно поворачиваются как вправо, так и влево. Если двигатели перепутаны местами, они могут двигаться вперед правильно, но поворачивать в противоположные стороны.
Теперь приступим к написанию кода. Давайте начнем с определения того, что у нас есть. У нас есть датчики… Первым делом в коде мы определим эти параметры.
int RightSensor=A5; //Right Opponent Sensor Pin int RightDiagonalSensor=A4; //Right Diagonal Opppnent Sensor Pin int MiddleSensor=2; //Middle Oppoent Sensor Pin int LeftDiagonalSensor=D1; //Left Diagonal Opponent Sensor Pin int LeftSensor=D0; //Left Opponent Sensor Pin int LeftLine=A2; //Left Line Sensor Pin int RightLine=A1; //Right Line Sensor Pin int Start=10; //Start Button Pin
void setup() { xmotion.BlinkDelay(1000); // Blink Delay Function for blinking 2 User Leds pinMode(RightSensor, INPUT); // We declare Digital Inputs and outputs. pinMode(RightDiagonalSensor, INPUT); pinMode(MiddleSensor, INPUT); pinMode(LeftDiagonalSensor, INPUT); pinMode(LeftSensor, INPUT); pinMode(Start, INPUT); }
Здесь важно отметить, что мы не объявили выходные контакты для управления двигателем и пользовательским светодиодом, однако они объявлены в библиотеке xmotion.h. Также мы не настроили аналоговые входы с помощью функции pinMode. Тем не менее, эти выводы уже настроены достаточно.
На традиционных соревнованиях обычно судья дает старт, мы реагируем на сигнал и ждем 5 секунд. В настоящее время часто используются специальные модули для старта, но мы попробуем начать с 5-секундной задержкой.
Мы будем считывать состояние кнопки «Пуск» в цифровом формате. Когда кнопка не нажата, она возвращает значение 0. Давайте добавим оператор while в основной цикл программы для этой функциональности.
void loop() { while (digitalRead(Start) == 0) // Button push is waited. When Button is pushed, it gives 1 value. { xmotion.ToggleLeds(20); //Toggle Both User Leds 20millisecond Intervals. }
Оператор while является мощным инструментом программирования. MCU Xmotion последовательно исполняет код сверху вниз, поэтому когда программа достигает оператора while, она останавливается на нем, ожидая, пока состояние кнопки не изменится. Когда кнопка не нажата, ее вывод равен 0, что интерпретируется как логический 0. При нажатии кнопки значение изменяется на логическую 1 (которая может быть считана как 5V = логическая 1), и программа выходит из цикла while. Таким образом, при нажатии кнопки программа будет ждать 5 секунд. Давайте создадим код, который будет мигать в течение 5 секунд.
for (int i=0; i <= 4; i++){ // For loop counts from 0 to 4 total 5 times loop here. xmotion.UserLed1(500); // 500 ms Light On, 500ms Light Off. }
if (analogRead(LeftLine)<300 && analogRead(RightLine)> 300 ) //Left Line Sensor Saw the Line { xmotion.Backward(100,100); //Backward %100 speed, 100 ms retreat. xmotion.Right0(100,200); //Right Turning %100 speed, 200ms duration. } else if (analogRead(LeftLine)> 300 && analogRead(RightLine)< 300 ) //Right Line Sensor Saw the Line { xmotion.Backward(100,100); //Backward %100 speed, 100 ms retreat. xmotion.Left0(100,200); //Left Turning %100 speed, 200ms duration. } else if (analogRead(LeftLine)< 300 && analogRead(RightLine)< 300 ) //Both Sensor Saw the Line { xmotion.Backward(100,200); //Backward %100 speed, 200 ms retreat. xmotion.Left0(100,300); //Left Turning %100 speed, 200ms duration. }
Давайте перейдем к операторам if. Сначала наш робот будет двигаться назад, а затем поворачиваться в разные стороны. Давайте визуализируем это.
Если у вас есть опыт программирования, вы можете написать код для этого. Но если вы только начинаете, давайте сосредоточимся на основах. Что дальше? Давайте обсудим датчики противника.
Мы продолжаем с оператором else if, потому что нам нужен только один прицел при каждом сканировании, пока не выполнится условие if. У нас есть 5 датчиков противника, поэтому нам нужно написать как минимум 5 условий if.
else if (digitalRead(MiddleSensor) == 1 ) //Middle Sensor see the opponent (0 Not Seen, 1 Seen) { xmotion.Forward(100, 1); // Both Motors Forward %100 Speed, 1 Milliseconds } else if (digitalRead(RightSensor) == 1) //Right Sensor see the opponent { xmotion.Right0(70, 1); // Right Turn %70 Power 1 Milliseconds } else if (digitalRead(LeftSensor) == 1) //Left Sensor see the opponent { xmotion.Left0(70, 1); //LeftTurn %70 Power 1 Milliseconds } else if (digitalRead(LeftDiagonalSensor) == 1) //Left Sensor see the opponent { xmotion.ArcTurn(20,70, 1); // Left Motor %20 Speed, Right %70 Speed 1 ms. } else if (digitalRead(RightDiagonalSensor) == 1) //Left Sensor see the opponent { xmotion.ArcTurn(70,20, 1); // Left Motor %70 Speed, Right %20 Speed 1 ms. }
Мы завершили проверку датчиков противника.
Теперь, когда робот завершил проверку датчиков противника, он продолжает свои размышления. Сначала он осматривает датчики линии, затем датчики противника, и что делать дальше? Если робот не получает никаких сигналов от этих датчиков, какое действие он должен предпринять? Двигаться вперед? Поворачивать или что еще?
Первая идея заключается в том, что движение вперед должно быть немного медленнее, поэтому мы просто добавим эту строку в код.
else { xmotion.Forward(20,1); }
Итак, если робот не видит противника или не видит белой линии, он будет двигаться вперед. Но этого недостаточно!
Если противник не виден, нам нужно закрыть противника, мы должны помнить, каким датчиком последний раз был замечен противник. Поэтому давайте добавим одну целочисленную переменную под названием LastValue и добавим ее в начало секции.
int LastValue=0;
Итак, переменная LastValue будет хранить информацию о том, каким датчиком последний раз был замечен противник. Теперь мы добавим числа к каждому запросу датчика. Вот я обновляю запросы датчиков для обнаружения противника, а затем добавлю дополнительные условия if для проверки значения переменной LastValue.
else if (digitalRead(MiddleSensor) == 1 ) //Middle Sensor see the opponent (0 Not Seen, 1 Seen) { xmotion.Forward(100, 1); // Both Motors Forward %100 Speed, 1 Milliseconds LastValue=0; } else if (digitalRead(RightSensor) == 1) //Right Sensor see the opponent { xmotion.Right0(70, 1); // Right Turn %70 Power 1 Milliseconds LastValue=1; } else if (digitalRead(LeftSensor) == 1) //Left Sensor see the opponent { xmotion.Left0(70, 1); // Left Turn %70 Power 1 Milliseconds LastValue=2; } else if (digitalRead(LeftDiagonalSensor) == 1) //Left Diagonal Sensor see the opponent { xmotion.ArcTurn(20,70, 1); // Left Motor %20 Speed, Right %70 Speed 1 ms. LastValue=2; } else if (digitalRead(RightDiagonalSensor) == 1) //Left Sensor see the opponent { xmotion.ArcTurn(70,20, 1); // Left Motor %70 Speed, Right %20 Speed 1 ms. LastValue=1; } else if LastValue==0 { //Middle Sensor Saw the opponent xmotion.Forward(20,1); } else if LastValue==1 { //Right or Right Diagonal Sensor saw the opponent xmotion.Right0(30, 1); } else if LastValue==2 { //Left or Left Diagonal Sensor saw the opponent. xmotion.Left0(30,1); } }
И завершаем цикл с помощью } Готово
Теперь наш код более логичен. Подумайте так, что если противник быстр и внезапно пропустил его от боковых датчиков, он запомнит последнее значение датчика и продолжит поворачивать или идти вперед в соответствии с этим значением. Но скорости ниже из-за более сбалансированного, неагрессивного поиска.
Как разработать мини-робота сумо?
Здесь я расскажу о механических и электронных разработках. Что касается программного обеспечения, то это будет новая статья.
- Покрасьте своего робота в черный цвет
- Используйте лучшие колеса, лучший клин
- Не совершайте пустых атак.
- Пробуйте что-то новое.
- Сделайте его ровно на 500 граммов. Увеличьте вес.
- Более подробно про механику для сумо