2010-05-10 9 views
6

Estoy trabajando en un robot que es capaz de detectar el movimiento usando una cámara web. Estoy haciendo esto en C#¿Estás ejecutando un código durante cierto tiempo en C#?

El robot se mueve demasiado rápido, por lo que quiero activarlo/desactivarlo en intervalos de tiempo cortos para reducir su velocidad.

Por ejemplo, arrancará el motor, luego esperará 0,5 segundos y lo apagará, este ciclo se repite cada 2 segundos. De esta manera, su velocidad no será demasiado rápida. Me gustaría incluir esto en una sola función llamada Mover()

Simplemente no sé cómo hacer esto, especialmente porque mi código de detección de movimiento se ejecuta como 20 veces por segundo. Dependiendo de la posición del obstáculo, es posible que deba desactivar la función Mover() y activar otras funciones que permitan que el robot se mueva en otras direcciones.

¿Alguna idea/sugerencia sobre dónde se supone que debo comenzar?

¡Muchas gracias!

Respuesta

0

Usted puede tratar de usar -

Thread.Sleep(500); 

Esta pieza de código pondrá el hilo se está ejecutando actualmente para dormir durante 500 milisegundos.

0

Una forma de agregar suspensión al trabajo es agregar tiempo entre llamadas. Puedes dormir entre las llamadas. Poner el sueño es así: System.Threading.Thread.Sleep(5000); 5000 es por 5000 milisegundos.

5

Antes que nada, debemos establecer cómo fluye su programa.

¿Ejecuta un comando, espera y luego ejecuta el siguiente comando? ¿O ejecuta comandos simultáneamente? (por ejemplo, mover y hacer otra cosa)

Supongo que querrá que ejecute comandos en secuencia, en lugar de algunos subprocesos complejos que su sistema de motor puede no admitir.

Con el fin de obtener su robot se mueva lentamente, sugeriría la creación de un método Move() que toma un parámetro, la cantidad de tiempo que desea que pasan en movimiento, así:

public void Move(int numberOfSeconds) 
{ 
    while (numberOfSeconds > 0) 
    { 

     myRobot.MotorOn(); 
     Thread.Sleep(2000); 
     myRobot.MotorOff(); 
     Thread.Sleep(500); 

     numberOfSeconds -= 2; 
    } 
} 

¡Es no es exacto, pero esa es una forma de hacerlo.

Si a continuación, llama a Move (10), por ejemplo, su robot se moverá durante 10 segundos, y pausará cada 2 segundos durante medio segundo.

En cuanto a sus preguntas flujo del programa, es posible que desee pensar en ella como una lista de instrucciones:

AVANZAR PARADA VERIFICACIÓN DE OBJETO GIRAR para apuntar a OBJETO AVANZAR PARADA

etc.

Por lo tanto, en su bucle de control de programa principal, suponiendo que las llamadas son síncronas (es decir.el programa se detiene mientras se está ejecutando un comando, al igual que en el método Move arriba), usted puede simplemente tener un montón de IF (o un interruptor)

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); 
    } 
} 

que podría ayudarle a empezar.

Sin embargo, si su robot es asincrónico, es decir, el código se mantiene funcionando mientras el robot está haciendo cosas (como que recibe constantemente retroalimentación de los sensores de movimiento) tendrá que estructurar su programa de manera diferente. El método Move() aún puede funcionar, pero el flujo de tu programa debería ser ligeramente diferente. Se puede utilizar una variable para realizar un seguimiento del estado:

public enum RobotStates 
{ 
    Searching, 
    Waiting, 
    Hunting, 
    Busy, 
} 

Luego, en el bucle principal, se puede examinar el estado:

if (myRobotState != RobotStates.Busy) 
{ 
    // Do something 
} 

Recuerde cambiar el estado cuando sus acciones completa.

Es muy posible que tenga que utilizar el enhebrado para una solución asincrónica, por lo que su método que recibe retroalimentación de su sensor no se atasca esperando a que el robot se mueva, pero puede continuar sondeando. Sin embargo, el enrutamiento está más allá del alcance de esta respuesta, pero hay muchos recursos disponibles.

+0

+1 para una respuesta completa. –

0

Parece que quiere que el hilo principal ejecute funciones periódicamente. Si su robot tiene instalado .NET-Framework, puede usar la biblioteca Threading.

while(condition) 
{ 
    //Wait a number ms (2000 ms = 2 secons) 
    Thread.Sleep(2000); 
    //Do something here, e.g. move 

    Thread.Sleep(500); 
    //... 
} 

Pero la tuya es una pregunta muy difícil. ¿Podría especificar qué tipo de sistema operativo y/o entorno (bibliotecas, marcos de trabajo, ...) tiene su robot?

0

En lo que respecta a la detección de movimiento y la detección de obstáculos, su código debe estar utilizando el enhebrado complejo. Para su problema de velocidad del motor, ¿ha intentado hacer una llamada a Move() en un hilo separado?

y en un bucle for puede usar Thread.Sleep (2 * 1000) después de cada llamada a MotorOff().

Atentamente.

+0

:) me gusta 2 * 1000 bcoz es fácil de entender. 2 segundos = 2 * 1000 .. –

1

Sugiero que lo analice en Microsoft Robotics Studio? Nunca lo usó, pero podrían abordar este tipo de problema. Y probablemente otros que aún no has encontrado.

Otra opción es escribir la aplicación usando XNA's timing mechanisms. Solo en lugar de renderizar en la pantalla, estaría renderizando a su robot, más o menos.

+1

Estoy 90% seguro de que Robotics Studio * * soluciona este problema. El tiempo y el procesamiento paralelo son de lo que se trata la biblioteca. +1 bazillones. – Randolpho

2

Thread.Sleep() no puede ser lo que quiera, porque si su hardware es capaz de, desea mantener la publicación de sus sensores mientras se mueve etc. La primera solución que viene a mi mente es utilizar un temporizador. De esta forma, puede seguir procesando y manejar su movimiento cuando sea necesario.

(havent probado este código, pero se pone la idea a través)

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(); 
    } 
} 
+0

Si el programa tiene más de un hilo, Thread.Sleep solo pausará ese hilo en particular, y otros hilos son libres de procesar la entrada o lo que sea. –

3

le ha surgido un problema muy común, que es la forma de controlar un proceso cuando el actuador sólo se dispone de estados ON y OFF. La solución que ha propuesto es una solución común, que es establecer un "ciclo de trabajo" al encender y apagar un motor. En la mayoría de los casos, puede comprar controladores de motor que lo harán por usted, para que no tenga que preocuparse por los detalles. En general, desea que el pulso sea una frecuencia más alta, de modo que haya menos 'tartamudeo' observable en el movimiento.

Si se trata de un proyecto educativo, puede interesarle la teoría en Motor Controllers. También es posible que desee leer sobre Control Theory (en particular, control PID), ya que puede utilizar otros comentarios (¿tiene alguna forma de detectar su velocidad?) Para controlar automáticamente el motor y mantener la velocidad que desea.

Cuestiones relacionadas