LeJOS NXT Программирование Sonic Sensor

Я пытаюсь сделать робота NXT, к которому прикреплен ультразвуковой датчик. Он должен проехать до расстояния 15, а затем двигатели должны остановиться. После того, как он останавливается, он должен повернуться, но он не работает.

import lejos.nxt.*;

public class test {
    public static void main(String [] args) throws InterruptedException {
        UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
        for (int i = 0; i < 5; i++) {       
            try {
                Motor.B.rotate(-1500 , true);
                Motor.C.rotate(-1500 , true);
            } catch (Exception E){}

            while ( ultra.getDistance() < 15 ) {
                Motor.B.backward();
                Motor.C.backward();
            }

            LCD.clear();
            LCD.drawString("Distance : "+ultra.getDistance(), 0, 0);
        } 

        Button.waitForAnyPress();
    }
}

Мой старый код, который также не работал:

import lejos.nxt.*;

public class test {

public static void main(String [] args) throws InterruptedException {
    UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
    try {
        Motor.B.rotate(-720);
        Motor.C.rotate(-720);

         } catch (Exception E){}

    for (int i = 0; i < 5; i++)
    {
    LCD.drawString("Distance : "+ultra.getDistance(), 0, i);
              Thread.sleep(2000);
         int maxDistance = ultra.getDistance();
         if (maxDistance < 15){
             Motor.B.stop();
             Motor.C.stop();
         }
    }
    Button.waitForAnyPress();
}
}

1 ответ

Решение

Предположения

Хорошо, судя по всему, ваш код, вероятно, не выполняет то, что вы хотите. (В будущем, при написании вопроса о переполнении стека, просьба подробно уточнить, каково ожидаемое поведение, а также какое ошибочное поведение вы видите. Во всяком случае, это обычно первые два вопроса, которые мы зададим вам.)

Прежде всего, вы захотите убедиться, что ваш комплект NXT настроен правильно, с двумя двигателями на B и C и датчиком на S1. Если это так, продолжайте читать.

Интерпретация кода

Моторные команды:

try {
    Motor.B.rotate(-1500, true);
    Motor.C.rotate(-1500, true);
} catch (Exception E) {}

похоже, что они действительные моторные команды... но подождите! Вы используете двухколесного робота с двигателями, соединенными с двумя колесами, которые указывают в противоположных направлениях? Но вы используете то же расстояние и направление для предельного угла вашего двигателя! Если ваши колеса противостоят друг другу, то это не сделает ничего, кроме того, что робот будет вращаться по кругу.

ПРИМЕЧАНИЕ. Так как ваши двигатели настроены правильно, как написано в ваших комментариях, игнорируйте эту часть.

робот вращается по кругу

Если вы измените направление одного из двигателей, изменив положительное на отрицательное, вы оба будете работать в унисон, чтобы продвинуть своего робота вперед (или назад, если вы измените неправильный!)

Кроме того, имейте в виду, что прохождение true в качестве второго аргумента в

Motor.B.rotate(-1500, true);
Motor.C.rotate(-1500, true);

делает эту функцию очень специфическим способом, согласно Javadoc (выделено мной):

Если immediateReturn Значение true, метод возвращается немедленно, и двигатель останавливается сам по себе.

Если какой-либо метод двигателя вызывается до достижения предела, вращение отменяется.

Первое предложение означает, что это делает то, что мы хотим: оно говорит нашему мотору, чтобы он сам нашел правильный предельный угол, но не заставляет нашу программу ждать его. Тем не менее, второе предложение означает, что если будут вызваны любые другие моторные команды, он перестанет двигаться к заданному предельному углу. Да, это так. Следующие несколько строк заставляют нас прекратить движение двигателей и делать то, что они говорят вместо этого.

Теперь этот код проблематичен по двум причинам:

while (ultra.getDistance() < 30) {
    Motor.B.backward();
    Motor.C.backward();
}

Во-первых, эти команды НЕМЕДЛЕННО останавливают выполнение наших предыдущих двух команд двигателя, что в основном означает, что двигатели будут прыгать прямо к движению "назад" и циклически, пока датчик расстояния не будет больше или равен 30, Это на самом деле то, что мы хотим, но нам нужно немного больше...

Во-вторых, после того, как ваш датчик читает расстояние больше, чем 30, ваши моторы никогда не говорят, чтобы остановить! Так что даже когда ваша программа показывает вам расстояние и ожидает нажатия вашей кнопки, она все равно будет двигаться!

Решение

Хорошо, есть несколько вещей, которые нужно изменить:

  • Ваша начальная команда двигателя блокируется более поздними командами, которые сообщают ей, чтобы она двигалась в правильное положение.
  • Ваши моторы не останавливаются, когда они должны.

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

import lejos.nxt.*;

public class test {
    public static void main(String [] args) throws InterruptedException {
        UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
        for (int i = 0; i < 5; i++) {

            // No initial motor movement (because it did nothing anyway)

            // We change this to approach from either direction.
            while (ultra.getDistance() != 30) {
                // Check whether it's behind or ahead of it.
                // Assuming that B- and C- increase distance, and B+ and C+ decrease it (depends on robot configuration).
                // This is called a feedback loop, by the way.
                if (ultra.getDistance() < 30) { // Move forward (distance+)
                    Motor.B.backward();
                    Motor.C.backward();
                } else { // Move backward (distance-)
                    Motor.B.forward();
                    Motor.C.forward();
                }
            }

            // We only get here when the distance is right, so stop the motors.
            Motor.B.stop();
            Motor.C.stop();               

            LCD.clear();
            LCD.drawString("Distance : "+ultra.getDistance(), 0, 0);
        }
        Button.waitForAnyPress();
    }
}

Теперь этот код не идеален; он может иметь тенденцию колебаться между передним и задним ходом на скользких поверхностях (что может слегка повернуть его влево или вправо из-за различий в прилагаемом крутящем моменте), или если датчик не попадает в правильное положение, и робот его отклоняет.

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

Чтобы исправить эти недостатки, вам понадобится более продвинутый тип обратной связи, который учитывает ускорение и проскальзывание, и вам нужно подождать, пока робот стабилизируется в правильном положении в течение короткого периода времени, прежде чем останавливать двигатели.

Однако это должно заставить вас двигаться в правильном направлении, так сказать.

РЕДАКТИРОВАТЬ Исправлена ​​направленность двигателя привода, как указано в комментариях.

Другие вопросы по тегам