Я работаю над роботом, который способен к обнаружению движения с помощью веб-камеры. Я делаю это в C#
Робот перемещается слишком быстро, таким образом, я хочу повернуть его вкл\выкл в кратковременных интервалах для сокращения его скорости.
Например, это запустит двигатель, затем ожидают 0,5 секунды и выключают его, этот цикл повторения каждые 2 секунды. Таким образом, его привычка скорости быть слишком быстрым. Я хотел бы включать это в единственную функцию под названием Перемещение ()
Я просто не знаю, как сделать это, особенно потому что мой код обнаружения движения работает как 20 раз в секунду. В зависимости от положения препятствия я, возможно, должен отключить Перемещение (), функционируют и активируют другие функции, которые позволяют роботу переместиться в другие направления.
Какие-либо идеи/предложения о том, где я, как предполагается, запускаюсь?
Большое спасибо!
Я бы предложил вам взглянуть на Microsoft Robotics Studio? Никогда не использовал ее, но она может действительно решить подобную проблему. И, возможно, другие, с которыми вы еще не сталкивались.
Другой вариант - написать приложение, используя механизмы синхронизации XNA. Только вместо рендеринга на экран, вы будете рендерить на своего робота, вроде как.
Thread.Sleep () может быть не тем, что вам нужно, потому что если ваше оборудование способно, вы хотите продолжать работу ваши датчики во время движения и т. д. Первое решение, которое мне приходит в голову, - это использовать таймер. Таким образом, вы можете обрабатывать и обрабатывать свое движение, когда это необходимо.
(не тестировал этот код, но он передаёт идею)
System.Timers.Timer Timer = new Timer();
bool Moving;
void init()
{
Timer.AutoReset = false;
Timer.Elapsed += OnMoveTimerEvent;
Moving = false;
}
void MainLoop()
{
//stuff
if(should move)
{
timer.start();
}
if(should stop moving)
{
timer.stop();
}
}
void OnMoveTimerEvent(object source, ElapsedEventArgs e)
{
if (!Moving)
{
//start motor
Timer.Interval = 500;
Moving = true;
Timer.Start();
}
else
{
//stop motor
Moving = true;
Timer.Interval = 2000;
Timer.Start();
}
}
Вы можете попробовать использовать -
Thread.Sleep(500);
Эта часть кода переведет текущий поток в спящий режим на 500 миллисекунд.
Похоже, вы хотите, чтобы главный поток периодически выполнял функции. Если на вашем роботе установлен .NET-Framework, вы можете использовать библиотеку Threading.
while(condition)
{
//Wait a number ms (2000 ms = 2 secons)
Thread.Sleep(2000);
//Do something here, e.g. move
Thread.Sleep(500);
//...
}
Но ваш вопрос очень сложный. Не могли бы вы уточнить, какая операционная система или/и среда (библиотеки, фреймворки, ...) установлена на вашем роботе?
.Что касается обнаружения движения и препятствий, ваш код должен использовать сложные потоки. Для проблемы со скоростью двигателя вы пробовали выполнять вызов Move() в отдельном потоке.
и в цикле for вы можете использовать Thread.Sleep(2*1000) после каждого вызова MotorOff().
С уважением.
Прежде всего, нам нужно определить, как выполняется ваша программа.
Выполняет ли она одну команду, ждет, затем выполняет следующую команду? Или она выполняет команды одновременно? (например, двигаться и делать что-то еще)
Я полагаю, что вы хотите, чтобы программа выполняла команды последовательно, а не в виде сложных потоков, которые ваша двигательная система может не поддерживать.
Чтобы заставить робота двигаться медленно, я бы предложил создать метод Move(), который принимает параметр - количество времени, которое вы хотите, чтобы он потратил на движение, например, так:
public void Move(int numberOfSeconds)
{
while (numberOfSeconds > 0)
{
myRobot.MotorOn();
Thread.Sleep(2000);
myRobot.MotorOff();
Thread.Sleep(500);
numberOfSeconds -= 2;
}
}
Это не точно, но это один из способов сделать это.
Если вы вызовете, например, Move(10), то ваш робот будет двигаться 10 секунд и делать паузу каждые 2 секунды на полсекунды.
Что касается вопросов о потоке программы, вы можете думать о нем как о списке инструкций:
ДВИГАТЬСЯ ВПЕРЕД ОСТАНОВИТЬСЯ ПРОВЕРИТЬ НАЛИЧИЕ ОБЪЕКТА ПОВЕРНУТЬ, ЧТОБЫ НАВЕСТИСЬ НА ОБЪЕКТ ДВИГАТЬСЯ ВПЕРЕД СТОП
и т.д.
Таким образом, в основном цикле управления вашей программы, если предположить, что вызовы синхронны (т.е. ваша программа останавливается во время выполнения команды, как в приведенном выше методе Move), вы можете просто иметь кучу операторов IF (или switch)
public void Main()
{
// What calculations should the robot do?
If (someCalculations == someValue)
{
// Rotate the robot to face the object
robot.RotateRight(10);
}
else if (someOtherCalculation == someValue)
{
// We are on course, so move forward
Move(10);
}
}
Это может помочь вам начать.
Однако если ваш робот асинхронный, то есть код продолжает выполняться, пока робот что-то делает (например, вы постоянно получаете обратную связь от датчиков движения), вам придется по-другому структурировать свою программу. Метод Move() может по-прежнему работать, но поток вашей программы должен быть немного другим. Вы можете использовать переменную для отслеживания состояния:
public enum RobotStates
{
Searching,
Waiting,
Hunting,
Busy,
}
Затем в главном цикле вы можете исследовать состояние:
if (myRobotState != RobotStates.Busy)
{
// Do something
}
Не забудьте изменить состояние, когда ваши действия завершатся.
Вполне возможно, что для асинхронного решения вам придется использовать потоки, чтобы ваш метод, получающий обратную связь от датчика, не застрял в ожидании движения робота, а продолжал опрашивать. Использование потоков выходит за рамки данного ответа, но есть много ресурсов.
Вы столкнулись с очень распространенной проблемой - как управлять процессом, когда ваш привод имеет только состояния ON и OFF. Предложенное вами решение - это обычное решение, которое заключается в установке "рабочего цикла" путем включения/выключения двигателя. В большинстве случаев вы можете приобрести контроллеры двигателей, которые сделают это за вас, так что вам не придется беспокоиться о деталях. Как правило, пульсация должна быть более высокой частоты, чтобы в движении было меньше заметных "заиканий".
Если это образовательный проект, вас может заинтересовать теория по Контроллеры двигателей. Возможно, вы также захотите прочитать о Теории управления (в частности, о ПИД-регулировании), поскольку вы можете использовать обратную связь (есть ли у вас какой-нибудь способ определить свою скорость?) для автоматического управления двигателем, чтобы поддерживать нужную вам скорость.
Один из способов добавить приостановку в работу - добавить сон между звонками. Вы можете вводить сон между вызовами. Вставка сна выглядит следующим образом: System.Threading.Thread.Sleep(5000);
5000 - это 5000 миллисекунд.