tags:

views:

165

answers:

9

Hi

I am working on a robot that is capable of motion detection using a webcam. I am doing this in C#

The robot moves too fast, so I want to turn it on/off at short time intervals in order to reduce its speed.

For example, it will start the engine then wait 0.5 second and turn it off, this cycle repeats every 2 seconds. This way, its speed wont be too fast. I would like to include this in a single function called Move()

I just don't know how to do this, especially because my motion detection code runs like 20 times a second. Depending on the position of the obstacle, I may need to disable the Move() function and activate other functions that let the robot move into other directions.

Any ideas/suggestions on where am I supposed to start?

Thanks a lot!

A: 

You can try using -

Thread.Sleep(500);

This piece of code will put the currently running thread to sleep for 500 milliseconds.

Kirtan
A: 

One way of adding suspension to work is to add sleep in between calls. You can put sleep in between calls. Putting sleep is like this: System.Threading.Thread.Sleep(5000); 5000 is for 5000 milliseconds.

Kangkan
+4  A: 

First of all, we need to establish how your program flows.

Does it execute one command, wait, then execute the next command? Or does it execute commands simultaneously? (for example, move and do something else)

I imagine you will want it to execute commands in sequence, rather than some complex threading which your motor system may not support.

In order to get your robot to move slowly, I would suggest creating a Move() method that takes a parameter, the amount of time you want it to spend moving, like this:

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

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

      numberOfSeconds -= 2;
   }
}

It's not exact, but that is one way of doing it.

If you then call Move(10) for example, your robot will move for 10 seconds, and pause every 2 seconds for half a second.

Regarding your program flow questions, you may want to think of it as a list of instructions:

MOVE FORWARD STOP CHECK FOR OBJECT ROTATE TO AIM AT OBJECT MOVE FORWARD STOP

etc.

So in your main program control loop, assuming the calls are synchronous (ie. your program stops while it is executing a command, like in the above Move method), you could simply have a bunch of IF statements (or a 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);
   }
}

That might help you get started.

If however, your robot is asynchronous, that is, the code keeps running while the robot is doing things (such as you constantly getting feedback from the motion sensors) you will have to structure your program differently. The Move() method may still work, but your program flow should be slightly different. You can use a variable to keep track of the state:

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

Then in your main loop, you can examine the state:

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

Remember to change the state when your actions complete.

It's entirely possible you will have to use threading for an asynchronous solution, so your method that receives feedback from your sensor doesn't get stuck waiting for the robot to move, but can continue to poll. Threading is beyond the scope of this answer though, but there are plenty of resources out there.

SLC
+1 for comprehensive answer.
David Neale
A: 

It sounds like you want the main thread to execute functions periodically. If your robot has the .NET-Framework installed, you can use the Threading library.

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

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

But yours is a very difficult question. Could you please specify what kind of operating system or/and environment (libraries, framworks, ...) your robot has?

Simon
A: 

As far a motion detection and obstacle detection is concerned, your code should be using complex threading. For you motor speed problem have you tried doing Move() call in a separate thread.

and in a for loop you can use Thread.Sleep(2*1000) after every MotorOff() call.

Regards.

Shoaib Shaikh
:) i like 2*1000 bcoz its easy to understand. 2 secs = 2*1000..
Shoaib Shaikh
+1  A: 

I'd suggest you look into Microsoft Robotics Studio? Never used it, but they might actually address this kind of issue. And probably others you haven't encountered yet.

Another option is to write the app using XNA's timing mechanisms. Only instead of rendering to the screen, you'd be rendering to your robot, sort of.

Will
I'm 90% certain Robotics Studio *does* address this problem. Timing and parallel processing are what the library is all about. +1 bazillions.
Randolpho
+1  A: 

Thread.Sleep() may not be what you want because if your hardware is able to, you want to keep running your sensors while moving etc. The first solution that comes to mind for me is to use a timer. That way you can keep processing and handle your movement when needed.

(havent tested this code, but it gets the idea across)

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();
  }
}
Josh Sterling
If the program has more than one thread, Thread.Sleep will only pause that particular thread, and other threads are free to process input or whatever.
Henry Jackson
+1  A: 

You've encountered a very common problem, which is how to control a process when your actuator only has ON and OFF states. The solution you've proposed is a common solution, which is to set a 'duty cycle' by switching a motor on/off. In most cases, you can buy motor controllers that will do this for you, so that you don't have to worry about the details. Generally you want the pulsing to be a higher frequency, so that there's less observable 'stutter' in the motion.

If this is an educational project, you may be interested in theory on Motor Controllers. You might also want to read about Control Theory (in particular, PID control), as you can use other feedback (do you have some way to sense your speed?) to automatically control the motor to maintain the speed you want.

Dan Bryant
A: 

WOW! too many answers in a short period of time!

I have no problem with communicating with the robot [ I use Parallel Port for that], but my problem is the logic.

I will try: System.Threading.Thread.Sleep(5000);

and see what happens.

Thanks a lot!

Hazem
I did that in a simple application to see what happens.I have a form and a button. When the thread sleeps, the whole form disappears, I don't think I want that to happen to my robot app.Any solutions?
Hazem