2010-05-10 59 views
6

Tôi đang làm việc trên rô bốt có khả năng phát hiện chuyển động bằng webcam. Tôi đang làm điều này trong C#Chạy một đoạn mã trong một khoảng thời gian nhất định trong C#?

Robot di chuyển quá nhanh, vì vậy tôi muốn bật/tắt nó trong khoảng thời gian ngắn để giảm tốc độ của nó.

Ví dụ, nó sẽ khởi động động cơ sau đó chờ 0,5 giây và tắt nó đi, chu trình này lặp lại sau mỗi 2 giây. Bằng cách này, tốc độ của nó sẽ không quá nhanh. Tôi muốn bao gồm điều này trong một chức năng duy nhất được gọi là Move()

Tôi chỉ không biết cách thực hiện điều này, đặc biệt là vì mã phát hiện chuyển động của tôi chạy như 20 lần mỗi giây. Tùy thuộc vào vị trí của chướng ngại vật, tôi có thể cần phải tắt chức năng Move() và kích hoạt các chức năng khác cho phép robot di chuyển sang các hướng khác.

Bất kỳ ý tưởng/đề xuất nào về nơi tôi phải bắt đầu?

Cảm ơn rất nhiều!

Trả lời

0

Bạn có thể thử sử dụng -

Thread.Sleep(500); 

Đoạn mã này sẽ đưa các chủ đề hiện đang chạy để ngủ cho 500 mili giây.

0

Một cách để thêm tính năng tạm ngừng hoạt động là thêm ngủ giữa các cuộc gọi. Bạn có thể đặt ngủ giữa các cuộc gọi. Ngủ như sau: System.Threading.Thread.Sleep(5000); 5000 là 5000 mili giây.

5

Trước hết, chúng tôi cần thiết lập cách chương trình của bạn luân chuyển.

Thực hiện một lệnh, chờ, sau đó thực hiện lệnh tiếp theo? Hoặc nó thực hiện lệnh đồng thời? (ví dụ, di chuyển và làm điều gì đó khác)

Tôi tưởng tượng bạn sẽ muốn nó thực hiện các lệnh theo thứ tự, thay vì một số luồng phức tạp mà hệ thống động cơ của bạn có thể không hỗ trợ.

Để có được robot của bạn để di chuyển chậm, tôi sẽ khuyên bạn nên tạo một phương pháp Move() mà phải mất một tham số, số lượng thời gian bạn muốn nó dành di chuyển, như thế này:

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

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

     numberOfSeconds -= 2; 
    } 
} 

Đó là không chính xác, nhưng đó là một cách để làm điều đó.

Nếu sau đó bạn gọi Move (10) chẳng hạn, rô bốt của bạn sẽ di chuyển trong 10 giây và tạm dừng sau mỗi 2 giây trong nửa giây.

Về câu hỏi lưu lượng chương trình của bạn, bạn có thể muốn nghĩ về nó như một danh sách các hướng dẫn:

tiến DỪNG KIỂM TRA CHO OBJECT XOAY ĐỂ AIM AT OBJECT tiến DỪNG

v.v.

Vì vậy, trong vòng điều khiển chương trình chính của bạn, giả sử các cuộc gọi là đồng bộ (ví dụ:chương trình của bạn dừng lại trong khi nó đang thực hiện một lệnh, như trong Di chuyển phương pháp trên), bạn chỉ có thể có một loạt các IF báo cáo (hoặc một 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); 
    } 
} 

Điều đó có thể giúp bạn bắt đầu.

Nếu tuy nhiên, rô bốt của bạn không đồng bộ, tức là mã tiếp tục chạy trong khi robot đang làm việc (chẳng hạn như bạn liên tục nhận phản hồi từ cảm biến chuyển động), bạn sẽ phải cấu trúc chương trình của mình theo cách khác. Phương thức Move() có thể vẫn hoạt động, nhưng luồng chương trình của bạn sẽ hơi khác một chút. Bạn có thể sử dụng một biến để theo dõi các tiểu bang:

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

Sau đó, trong vòng lặp chính của bạn, bạn có thể kiểm tra nhà nước:

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

Hãy nhớ để thay đổi trạng thái khi hành động của bạn hoàn tất. Hoàn toàn có thể bạn sẽ phải sử dụng luồng cho một giải pháp không đồng bộ, do đó phương pháp nhận phản hồi từ cảm biến của bạn không gặp khó khăn khi chờ robot di chuyển, nhưng có thể tiếp tục thăm dò ý kiến. Tuy nhiên, luồng thông tin nằm ngoài phạm vi của câu trả lời này, nhưng có rất nhiều tài nguyên ngoài kia.

+0

+1 để có câu trả lời toàn diện. –

0

Có vẻ như bạn muốn chuỗi chính thực thi các chức năng định kỳ. Nếu robot của bạn đã cài đặt .NET-Framework, bạn có thể sử dụng thư viện Threading.

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

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

Nhưng bạn là một câu hỏi rất khó. Bạn có thể vui lòng chỉ định loại hệ điều hành hoặc/và môi trường nào (thư viện, framworks, ...) mà rô bốt của bạn có?

0

Cho đến nay một phát hiện chuyển động và phát hiện trở ngại là có liên quan, mã của bạn nên được sử dụng luồng phức tạp. Đối với bạn vấn đề tốc độ động cơ có bạn đã cố gắng làm Move() gọi trong một chủ đề riêng biệt.

và trong vòng lặp for bạn có thể sử dụng Thread.Sleep (2 * 1000) sau mỗi cuộc gọi MotorOff().

Trân trọng.

+0

:) tôi thích 2 * 1000 bcoz dễ hiểu. 2 giây = 2 * 1000 .. –

1

Tôi khuyên bạn nên xem xét Microsoft Robotics Studio? Không bao giờ sử dụng nó, nhưng chúng thực sự có thể giải quyết loại vấn đề này. Và có lẽ những người khác bạn chưa gặp phải.

Tùy chọn khác là viết ứng dụng bằng cách sử dụng XNA's timing mechanisms. Chỉ thay vì hiển thị trên màn hình, bạn sẽ hiển thị cho rô bốt của mình.

+1

Tôi là một trong số 90% Robotics nhất định * làm * giải quyết vấn đề này. Thời gian và xử lý song song là những gì thư viện là tất cả về. +1 bazillions. – Randolpho

2

Thread.Sleep() có thể không phải là những gì bạn muốn bởi vì nếu phần cứng của bạn có thể, bạn muốn tiếp tục chạy cảm biến của bạn trong khi di chuyển vv Giải pháp đầu tiên mà tôi nghĩ là sử dụng bộ hẹn giờ. Bằng cách đó bạn có thể tiếp tục xử lý và xử lý chuyển động của mình khi cần.

(havent kiểm tra mã này, nhưng nó được ý tưởng trên)

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

Nếu chương trình có nhiều hơn một luồng, Thread.Sleep sẽ chỉ tạm dừng chủ đề cụ thể đó, và các luồng khác được tự do xử lý đầu vào hoặc bất kỳ thứ gì. –

3

Bạn đã gặp phải một vấn đề rất phổ biến, đó là làm thế nào để kiểm soát một quá trình khi thiết bị truyền động của bạn chỉ có ON và OFF bang. Giải pháp mà bạn đã đề xuất là một giải pháp phổ biến, đó là để thiết lập một 'chu kỳ nhiệm vụ' bằng cách bật/tắt động cơ. Trong hầu hết trường hợp, bạn có thể mua bộ điều khiển động cơ sẽ làm điều này cho bạn, để bạn không phải lo lắng về chi tiết. Nói chung, bạn muốn các xung được một tần số cao hơn, do đó, có ít quan sát 'nói lắp' trong chuyển động.

Nếu đây là một dự án giáo dục, bạn có thể quan tâm đến lý thuyết trên Motor Controllers. Bạn cũng có thể muốn đọc về Control Theory (đặc biệt là điều khiển PID), vì bạn có thể sử dụng phản hồi khác (bạn có cách nào để cảm nhận tốc độ của mình không?) Để tự động điều khiển động cơ để duy trì tốc độ bạn muốn.

Các vấn đề liên quan