2010-05-10 41 views
6

我正在研究一种能够使用网络摄像头进行运动检测的机器人。我正在C#中执行此操作。在C#中运行一段代码一段时间?

机器人移动得太快,所以我想在短时间内打开/关闭它以降低速度。

例如,它将启动发动机,然后等待0.5秒并关闭它,此循环每2秒重复一次。这样,它的速度不会太快。我想包括在一个单一的函数称为移动()

我只是不知道如何做到这一点,特别是因为我的运动检测代码运行像每秒20次。根据障碍物的位置,我可能需要禁用Move()功能并激活让机器人移动到其他方向的其他功能。

关于我应该从哪里开始的任何想法/建议?

非常感谢!

回答

0

您可以尝试使用 -

Thread.Sleep(500); 

这段代码将会把当前正在运行的线程睡眠500毫秒。

0

向工作中添加暂停的一种方式是在呼叫之间添加睡眠。您可以在两次通话之间进行睡眠。睡觉是这样的:System.Threading.Thread.Sleep(5000); 5000是5000毫秒。

5

首先,我们需要确定您的程序如何流动。

它执行一个命令,等待,然后执行下一个命令吗?还是它同时执行命令? (例如,移动并执行其他操作)

我想你会希望它按顺序执行命令,而不是你的电机系统可能不支持的一些复杂的线程。

为了让你的机器人缓慢移动,我建议建立一个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秒暂停半秒钟。

关于你的程序流程的问题,你可能要认为它是指令列表:

向前 STOP 检查对象 旋转,瞄准对象 向前 STOP

所以在你的主程序控制循环,假设调用是同步的(即。它在执行命令时,如上面的Move方法),你的程序停止时,你可以简单地有一堆如果你开始报表(或交换机)

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 
} 

记住更改时态你的动作完成。

这是完全可能的,您将不得不为异步解决方案使用线程,因此从传感器接收反馈的方法不会卡住等待机器人移动,但可以继续轮询。线程超出了这个答案的范围,但是有很多资源。

+0

+1全面解答。 – 2010-05-10 13:11:18

0

听起来你想要主线程定期执行函数。如果您的机器人安装了.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); 
    //... 
} 

但是你的问题是一个非常棘手的问题。你能指定你的机器人有什么样的操作系统或/和环境(库,framworks,...)吗?

0

就运动检测和障碍物检测而言,您的代码应该使用复杂的线程。对于您的电机速度问题,您是否尝试过在单独的线程中执行Move()调用。

并且在for循环中,可以在每次MotorOff()调用后使用Thread.Sleep(2 * 1000)。

问候。

+0

:)我喜欢2 * 1000 bcoz它很容易理解。 2秒= 2 * 1000 .. – 2010-05-10 13:13:16

1

我建议你看看Microsoft Robotics Studio?从来没有使用它,但他们可能实际上解决了这类问题。可能还有其他人还没有遇到过。

另一种选择是使用XNA's timing mechanisms.来编写应用程序只有渲染到屏幕上,而不是渲染到机器人上。

+1

我90%确定Robotics Studio *确实解决了这个问题。定时和并行处理是图书馆的全部内容。 +1 bazillions。 – Randolpho 2010-05-10 13:57:12

2

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

如果程序有多个线程,Thread.Sleep只会暂停该特定线程,而其他线程可以自由处理输入或任何其他线程。 – 2010-05-10 13:48:32

3

你遇到了一个非常普遍的问题,那就是如何控制过程,当你执行器只有ON和OFF状态。您提出的解决方案是一种常见解决方案,即通过开启/关闭电机来设置“占空比”。在大多数情况下,你可以购买马达控制器,这将为你做这个,所以你不必担心细节。一般来说,您希望脉冲发生频率更高,以免运动中出现可观察到的“口吃”。

如果这是一个教育项目,您可能对Motor Controllers有兴趣理论。您可能还想了解有关Control Theory(特别是PID控制)的信息,因为您可以使用其他反馈(您是否有办法感知您的速度?)来自动控制电机以保持所需的速度。

相关问题