Выполнение части кода для определенного количества времени в C#?

Я работаю над роботом, который способен к обнаружению движения с помощью веб-камеры. Я делаю это в C#

Робот перемещается слишком быстро, таким образом, я хочу повернуть его вкл\выкл в кратковременных интервалах для сокращения его скорости.

Например, это запустит двигатель, затем ожидают 0,5 секунды и выключают его, этот цикл повторения каждые 2 секунды. Таким образом, его привычка скорости быть слишком быстрым. Я хотел бы включать это в единственную функцию под названием Перемещение ()

Я просто не знаю, как сделать это, особенно потому что мой код обнаружения движения работает как 20 раз в секунду. В зависимости от положения препятствия я, возможно, должен отключить Перемещение (), функционируют и активируют другие функции, которые позволяют роботу переместиться в другие направления.

Какие-либо идеи/предложения о том, где я, как предполагается, запускаюсь?

Большое спасибо!

6
задан NibblyPig 10 May 2010 в 13:21
поделиться

8 ответов

Я бы предложил вам взглянуть на Microsoft Robotics Studio? Никогда не использовал ее, но она может действительно решить подобную проблему. И, возможно, другие, с которыми вы еще не сталкивались.

Другой вариант - написать приложение, используя механизмы синхронизации XNA. Только вместо рендеринга на экран, вы будете рендерить на своего робота, вроде как.

1
ответ дан 9 December 2019 в 22:30
поделиться

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();
  }
}
2
ответ дан 9 December 2019 в 22:30
поделиться

Вы можете попробовать использовать -

Thread.Sleep(500);

Эта часть кода переведет текущий поток в спящий режим на 500 миллисекунд.

0
ответ дан 9 December 2019 в 22:30
поделиться

Похоже, вы хотите, чтобы главный поток периодически выполнял функции. Если на вашем роботе установлен .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);
    //...
}

Но ваш вопрос очень сложный. Не могли бы вы уточнить, какая операционная система или/и среда (библиотеки, фреймворки, ...) установлена на вашем роботе?

.
0
ответ дан 9 December 2019 в 22:30
поделиться

Что касается обнаружения движения и препятствий, ваш код должен использовать сложные потоки. Для проблемы со скоростью двигателя вы пробовали выполнять вызов Move() в отдельном потоке.

и в цикле for вы можете использовать Thread.Sleep(2*1000) после каждого вызова MotorOff().

С уважением.

0
ответ дан 9 December 2019 в 22:30
поделиться

Прежде всего, нам нужно определить, как выполняется ваша программа.

Выполняет ли она одну команду, ждет, затем выполняет следующую команду? Или она выполняет команды одновременно? (например, двигаться и делать что-то еще)

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

Чтобы заставить робота двигаться медленно, я бы предложил создать метод 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
}

Не забудьте изменить состояние, когда ваши действия завершатся.

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

5
ответ дан 9 December 2019 в 22:30
поделиться

Вы столкнулись с очень распространенной проблемой - как управлять процессом, когда ваш привод имеет только состояния ON и OFF. Предложенное вами решение - это обычное решение, которое заключается в установке "рабочего цикла" путем включения/выключения двигателя. В большинстве случаев вы можете приобрести контроллеры двигателей, которые сделают это за вас, так что вам не придется беспокоиться о деталях. Как правило, пульсация должна быть более высокой частоты, чтобы в движении было меньше заметных "заиканий".

Если это образовательный проект, вас может заинтересовать теория по Контроллеры двигателей. Возможно, вы также захотите прочитать о Теории управления (в частности, о ПИД-регулировании), поскольку вы можете использовать обратную связь (есть ли у вас какой-нибудь способ определить свою скорость?) для автоматического управления двигателем, чтобы поддерживать нужную вам скорость.

3
ответ дан 9 December 2019 в 22:30
поделиться

Один из способов добавить приостановку в работу - добавить сон между звонками. Вы можете вводить сон между вызовами. Вставка сна выглядит следующим образом: System.Threading.Thread.Sleep(5000); 5000 - это 5000 миллисекунд.

0
ответ дан 9 December 2019 в 22:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: