2010-05-10 10 views
6

Pracuję nad robotem zdolnym do wykrywania ruchu za pomocą kamery internetowej. Robię to w C#Uruchamianie kodu przez określony czas w języku C#?

Robot porusza się zbyt szybko, więc chcę go włączyć/wyłączyć w krótkich odstępach czasu w celu zmniejszenia jego prędkości.

Na przykład uruchomi silnik, a następnie odczeka 0,5 sekundy i wyłączy, cykl powtarza się co 2 sekundy. W ten sposób jego szybkość nie będzie zbyt szybka. Chciałbym włączyć to w jedną funkcję o nazwie Move()

Po prostu nie wiem, jak to zrobić, zwłaszcza, że ​​mój kod wykrywania ruchu działa 20 razy na sekundę. W zależności od położenia przeszkody, może zajść potrzeba wyłączenia funkcji Move() i aktywowania innych funkcji, które pozwolą robotowi przejść w inne kierunki.

Wszelkie pomysły/sugestie na temat, gdzie mam zacząć?

Wielkie dzięki!

Odpowiedz

0

Można spróbować użyć -

Thread.Sleep(500); 

Ten fragment kodu będzie umieścić aktualnie uruchomiony wątek spać przez 500 milisekund.

0

Jednym ze sposobów dodawania zawieszenia do pracy jest dodanie trybu uśpienia pomiędzy połączeniami. Możesz przesypiać między rozmowami. Uśpienie jest takie: System.Threading.Thread.Sleep(5000); 5000 jest przez 5000 milisekund.

5

Przede wszystkim musimy ustalić, w jaki sposób płynie Twój program.

Czy wykonuje jedno polecenie, czekaj, a następnie wykonaj następne polecenie? Czy może jednocześnie wykonywać polecenia? (na przykład: przenieś i zrób coś innego)

Wyobrażam sobie, że będziesz chciał, aby wykonywał polecenia w sekwencji, a nie skomplikowane wątki, które twój układ motoryczny może nie obsługiwać.

Aby dostać robota poruszać się powoli, chciałbym zaproponować stworzenie metody Move(), która przyjmuje parametr, ilość czasu chcesz go spędzić w ruchu, na przykład:

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

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

     numberOfSeconds -= 2; 
    } 
} 

Nadszedł nie dokładny, ale jest to jeden ze sposobów robienia tego.

Jeśli na przykład wywołasz Move (10), robot porusza się na 10 sekund, a pauza co 2 sekundy przez pół sekundy.

Odnośnie pytania przebiegu programu, może warto pomyśleć o tym, jak listy instrukcji:

naprzód STOP SPRAWDZIĆ NA PRZEDMIOT obracać zmierzać PRZEDMIOT naprzód STOP

itp.

Tak więc w głównej pętli sterowania programem, zakładając, że połączenia są synchroniczne (tj.Twój program zatrzymuje się, gdy jest on wykonaniem polecenia, jak w powyższej metodzie ruchu), można po prostu mieć kilka IF zaczniesz oświadczenia (lub przełącznik)

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

To może pomóc.

Jeśli jednak twój robot jest asynchroniczny, to znaczy, że kod działa nadal, podczas gdy robot robi różne rzeczy (na przykład ciągle otrzymuje informacje zwrotne od czujników ruchu), będziesz musiał inaczej skonstruować swój program. Metoda Move() może nadal działać, ale Twój przepływ programu powinien być nieco inny. Można użyć zmiennej aby śledzić stan:

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

Następnie w pętli głównej, można sprawdzić stan:

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

Pamiętaj, aby zmienić stan, gdy wasze działania kompletne.

Jest całkowicie możliwe, że będziesz musiał używać wątku dla asynchronicznego rozwiązania, więc twoja metoda, która otrzyma informację zwrotną od twojego czujnika, nie utknie, czekając na ruch robota, ale może kontynuować odpytywanie. Jednak wątek wykracza poza zakres tej odpowiedzi, ale istnieje wiele zasobów.

+0

+1 za kompleksową odpowiedź. –

0

Wygląda na to, że główny wątek ma wykonywać okresowe funkcje. Jeśli twój robot ma zainstalowaną platformę .NET-Framework, możesz skorzystać z biblioteki Threading.

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

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

Ale twoje pytanie jest bardzo trudne. Czy mógłbyś określić, jakiego rodzaju system operacyjny i/lub środowisko (biblioteki, framworks, ...) ma twój robot?

0

Jeśli chodzi o wykrywanie ruchu i wykrywanie przeszkód, kod powinien wykorzystywać złożone wątki. Dla ciebie problem z szybkością silnika próbowałeś wykonać wywołanie Move() w osobnym wątku.

oraz w pętli for można użyć Thread.Sleep (2 * 1000) po każdym wywołaniu MotorOff().

Pozdrawiam.

+0

:) lubię 2 * 1000 bcoz jego łatwe do zrozumienia. 2 secs = 2 * 1000 .. –

1

Proponuję zaglądnąć w Microsoft Robotics Studio? Nigdy z niego nie korzystałem, ale mogą one rozwiązać ten problem. I prawdopodobnie inne, których jeszcze nie spotkałeś.

Inną opcją jest napisanie aplikacji przy użyciu XNA's timing mechanisms. Tylko zamiast renderowania na ekranie, renderowałbyś się do swojego robota, w pewnym sensie.

+1

Jestem w 90% pewien Robotics Studio * nie * rozwiązuje ten problem. Czas i przetwarzanie równoległe są tym, o czym jest cała biblioteka. +1 miliardy. – Randolpho

2

Thread.Sleep() może nie być tym, czego potrzebujesz, ponieważ jeśli twój sprzęt jest w stanie, chcesz nadal uruchamiać czujniki podczas przenoszenia itp. Pierwsze rozwiązanie, które przychodzi mi na myśl, to użycie timera. W ten sposób możesz kontynuować przetwarzanie i obsługiwać ruch w razie potrzeby.

(przystań przetestowane ten kod, ale robi się pomysł poprzek)

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

Jeśli program zawiera więcej niż jeden wątek, Thread.Sleep wstrzyma tylko ten wątek, a inne wątki mogą przetwarzać dane wejściowe lub cokolwiek innego. –

3

pan napotkał bardzo powszechny problem, który jest, jak kontrolować proces, gdy siłownik ma tylko włączony oraz wyłączony. Proponowane rozwiązanie jest powszechnym rozwiązaniem, które polega na ustawianiu "cyklu pracy" poprzez włączanie/wyłączanie silnika. W większości przypadków można kupić sterowniki silników, które zrobią to za Ciebie, abyś nie musiał się martwić o szczegóły. Generalnie chcesz, aby pulsowanie było wyższą częstotliwością, aby w ruchu zaobserwować mniej "zauważalnego" jąkania.

Jeśli jest to projekt edukacyjny, może zainteresować Cię teoria na temat Motor Controllers. Możesz również przeczytać o Control Theory (w szczególności kontroli PID), ponieważ możesz użyć innych informacji zwrotnych (czy masz jakiś sposób, aby wyczuć swoją prędkość?), Aby automatycznie sterować silnikiem, aby utrzymać żądaną prędkość.

Powiązane problemy