2010-05-10 76 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控制)的信息,因爲您可以使用其他反饋(您是否有辦法感知您的速度?)來自動控制電機以保持所需的速度。

相關問題