114 lines
4.6 KiB
Plaintext
114 lines
4.6 KiB
Plaintext
\b;Ćwiczenie
|
|
Pokieruj zdalnie robotem podległym bez używania \l;stacji przekaźnikowej informacji\u object\exchange;. Robot powinien przejść przez 6 niebieskich plusów.
|
|
|
|
Dwoma głównymi postaciami tego ćwiczenia są¦:
|
|
1) \l;Transporter na kołach\u object\botgr; bez ogniwa elektrycznego, wobec czego unieruchomiony. Jest to robot nadrzędny, który powinien zostać zaprogramowany aby mógł przesyłać rozkazy do podległego mu robota.
|
|
2) Podległy \l;robot treningowy\u object\bottr;, który jest już zaprogramowany i tylko czeka na rozkazy od robota nadrzędnego.
|
|
|
|
Rozkazy powinny być przechowywane, tak aby robot nadrzędny mógł wysłać wiele rozkazów bez czekania na przetworzenie każdego z nich. Do tego celu należy użyć \l;tablicy\u cbot\array;.
|
|
|
|
\b;Robot podległy
|
|
Najpierw musimy zrozumieć jak działa program robota podległego. \l;Klasa\u cbot\class; \c;order\n; zawiera dwa elementy: \c;m_type\n; jest rozkazem do wykonania (move lub turn), a \c;m_param\n; jest odległością do pokonania lub kątem obrotu¦:
|
|
|
|
\c;\s;\l;public\u cbot\public; \l;class\u cbot\class; order
|
|
\s;{
|
|
\s; \l;int\u cbot\int; m_type;
|
|
\s; \l;float\u cbot\float; m_param;
|
|
\s;}
|
|
\n;
|
|
Druga \l;klasa\u cbot\class; \c;exchange\n; zawiera mechanizm przekazywania rozkazów. Deklarujemy jako \c;\l;static\u cbot\static;\n; element klasy \c;m_fifo\n;, który będzie zawierał listę rozkazów do wykonania. Słowo \c;static\n; zapewnia, że element \c;m_fifo\n; jest współużytkowany przez wszystkie instancje \l;klasy\u cbot\class; exchange.
|
|
|
|
\c;\s;{
|
|
\s; \l;static\u cbot\static; \l;private\u cbot\private; order m_fifo[] = null;
|
|
\n;
|
|
Metoda \c;put\n; będzie używana przez robota nadrzędnego do przesyłania rozkazów. Rozkaz będzie dodawany na końcu tablicy \c;m_fifo\n;:
|
|
|
|
\c;\s; \l;synchronized\u cbot\synchro; void put(order a)
|
|
\s; {
|
|
\s; m_fifo[sizeof(m_fifo)] = a;
|
|
\s; }
|
|
\n;
|
|
Kolejna metoda \c;get\n; będzie używana przez robota podległego do otrzymywania rozkazów. Metoda ta jako wynik zwraca rozkaz do wykonania. Jeśli lista jest pusta, zostanie zwrócona wartość \c;null\n; i robot powinien czekać na więcej rozkazów. W przeciwnym przypadku powinien zostać zwrócony pierwszy rozkaz na liście, a pozostałe muszą zostać "przesunięte". Ponieważ tablica nie może być "skrócona", używamy pomocniczej tablicy \c;copy\n;¦:
|
|
|
|
\c;\s; \l;synchronized\u cbot\synchro; order get()
|
|
\s; {
|
|
\s; if ( sizeof(m_fifo) == 0 ) return null;
|
|
\s;
|
|
\s; order a = m_fifo[0];
|
|
\s; order copy[] = null;
|
|
\s; for ( int i=1 ; i<sizeof(m_fifo) ; i++ )
|
|
\s; {
|
|
\s; copy[i-1] = m_fifo[i];
|
|
\s; }
|
|
\s; m_fifo = copy;
|
|
\s; return a;
|
|
\s; }
|
|
\n;
|
|
Główny program robota podległego zawiera instancję klasy \c;exchange\n; nazwaną \c;list\n;. Po słowie \c;list\n; należy napisać nawiasy (), w celu utworzenia instancji klasy \c;exchange\n;.
|
|
|
|
\c;\s;\l;extern\u cbot\extern; void object::Slave5( )
|
|
\s;{
|
|
\s; exchange list();
|
|
\s; order todo;
|
|
\n;
|
|
Zewnętrzna pętla \c;while\n; działa w nieskończoność. Wewnętrzna pętla \c;while\n; czeka na rozkaz używając metody \c;get\n; z klasy \c;exchange\n;. Pętla zatrzymuje się gdy metoda \c;get\n; zwróci wartość różną od \c;null\n;.
|
|
|
|
\c;\s; \l;while\u cbot\while; ( true )
|
|
\s; {
|
|
\s; \l;while\u cbot\while; ( true )
|
|
\s; {
|
|
\s; todo = list.get();
|
|
\s; if ( todo != null ) break;
|
|
\s; wait(1);
|
|
\s; }
|
|
\n;
|
|
Po otrzymaniu rozkazu w zmiennej \c;todo\n; wystarczy tylko go wykonać:
|
|
|
|
\c;\s; if ( todo.m_type == 1 )
|
|
\s; {
|
|
\s; move(todo.m_param);
|
|
\s; }
|
|
\s; else if ( todo.m_type == 2 )
|
|
\s; {
|
|
\s; turn(todo.m_param);
|
|
\s; }
|
|
\s; else
|
|
\s; {
|
|
\s; message("Nieznany rozkaz");
|
|
\s; }
|
|
\s; }
|
|
\s;}
|
|
\n;
|
|
\b;Robot nadrzędny
|
|
W robocie nadrzędnym należy napisać funkcję nazwaną \c;SendOrder\n;, która wyśle rozkaz do robota podległego:
|
|
|
|
\c;\s;void object::SendOrder(float order, float param)
|
|
\s;{
|
|
\s; exchange list();
|
|
\s; order todo();
|
|
\s;
|
|
\s; todo.m_type = order;
|
|
\s; todo.m_param = param;
|
|
\s; list.put(todo);
|
|
\s;}
|
|
\n;
|
|
Główny program robota nadrzędnego jest bardzo prosty:
|
|
|
|
\c;\s;extern void object::Remote5( )
|
|
\s;{
|
|
\s; SendOrder(1, 20); // move(20);
|
|
\s; SendOrder(2, 90); // turn(90);
|
|
\s; SendOrder(1, 20); // move(20);
|
|
\s; SendOrder(2, 90); // turn(90);
|
|
\s; SendOrder(1, 10); // move(10);
|
|
\s; SendOrder(2, 90); // turn(90);
|
|
\s; SendOrder(1, 10); // move(10);
|
|
\s; SendOrder(2,-90); // turn(-90);
|
|
\s; SendOrder(1, 10); // move(10);
|
|
\s;}
|
|
\n;
|
|
Klawisz \key;\key help;\norm; umożliwia wyświetlenie tych informacji w dowolnej chwili.
|
|
|
|
\t;Zobacz również
|
|
\l;Sterowanie\u command; i \l;programowanie\u cbot;.
|