Difference between revisions of "Lego Mindstorms Ev3 Project - Ondrej Slovak"
(27 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
== Príprava == | == Príprava == | ||
− | Budeme používať softvér pre Lego Mindstorms Ev3 od | + | Budeme používať softvér pre Lego Mindstorms Ev3 od open-source projektu leJOS. Na jeho používanie budeme potrebovať nakonfigurovanú micro-SD kartu a vývojové prostredie, ktoré si môžeme nastaviť pomocou nasledujúcich odkazov. |
- https://sourceforge.net/p/lejos/wiki/Windows%20Installation/ | - https://sourceforge.net/p/lejos/wiki/Windows%20Installation/ | ||
Line 13: | Line 13: | ||
Nakonfigurovanú SD kartu vložíme do SD portu Ev3 kocky a spustíme. Softvér od leJOS-u sa automaticky nahrá z karty a bude sa používať ako náhrada za oficiálny softvér, pokiaľ budeme mať vloženú kartu. | Nakonfigurovanú SD kartu vložíme do SD portu Ev3 kocky a spustíme. Softvér od leJOS-u sa automaticky nahrá z karty a bude sa používať ako náhrada za oficiálny softvér, pokiaľ budeme mať vloženú kartu. | ||
− | Ďalej budeme potrebovať nadviazané spojenie pomocou Bluetooth. Toto spojenie sa dá jednoducho nadviazať z PC | + | Ďalej budeme potrebovať nadviazané spojenie pomocou Bluetooth. Toto spojenie sa dá jednoducho nadviazať z PC. V Bluetooth Devices si vieme nájsť Ev3 a nadviazať s ním spojenie. |
== Program == | == Program == | ||
Line 19: | Line 19: | ||
Program bude pozostávať z dvoch základných častí, časť, ktorá bude bežať na robotovi a časť, ktorá bude bežať na PC. | Program bude pozostávať z dvoch základných častí, časť, ktorá bude bežať na robotovi a časť, ktorá bude bežať na PC. | ||
− | Popíšme si najskôr časť, ktorá bude na robotovi. | + | Popíšme si najskôr časť, ktorá bude na '''robotovi'''. |
Program na robotovi sa skladá z viacerých častí. V prvom rade musíme zabezpečiť komunikáciu medzi robotom a PC. Keďže už máme nadviazané spojenie pomocou Bluetooth stačí nám na robotovi vytvoriť server, ktorý bude počúvať na požiadavky od používateľa, v našom prípade PC. Túto komunikáciu sme umiestnili do samostatného threadu aby robot stále počúval na požiadavky z PC. | Program na robotovi sa skladá z viacerých častí. V prvom rade musíme zabezpečiť komunikáciu medzi robotom a PC. Keďže už máme nadviazané spojenie pomocou Bluetooth stačí nám na robotovi vytvoriť server, ktorý bude počúvať na požiadavky od používateľa, v našom prípade PC. Túto komunikáciu sme umiestnili do samostatného threadu aby robot stále počúval na požiadavky z PC. | ||
− | <code> | + | <code> |
− | serv = new ServerSocket(1111); | + | ... |
− | Socket s = serv.accept(); // Wait for Laptop to connect | + | serv = new ServerSocket(1111); |
− | DataInputStream in = new DataInputStream(s.getInputStream()); | + | Socket s = serv.accept(); // Wait for Laptop to connect |
+ | DataInputStream in = new DataInputStream(s.getInputStream()); | ||
+ | ... | ||
+ | |||
+ | |||
+ | ... | ||
+ | String read = in.readUTF(); | ||
+ | switch (read) | ||
+ | ... | ||
</code> | </code> | ||
− | <code> | + | |
− | + | Na meranie vzdialenosti od prekážok budeme používať ultrazvukový senzor, ktorý bude neustále vracať hodnoty. | |
− | + | ||
− | + | <code> | |
− | + | ... | |
− | + | EV3UltrasonicSensor us = new EV3UltrasonicSensor(SensorPort.S4); | |
− | + | ... | |
− | + | ||
− | + | ... | |
− | + | us.enable(); | |
− | + | SampleProvider sampleProvider = us.getDistanceMode(); | |
− | + | while (true) { | |
+ | float[] sample = new float[sampleProvider.sampleSize()]; | ||
+ | sampleProvider.fetchSample(sample, 0); | ||
+ | distance = sample[0]; | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Priestor, v ktorom sa bude robot môcť pohybovať bude označený čiernou páskou. Na zabezpečenie, aby robot nevyšiel z tohto priestoru budeme používať farebný senzor. Na spresnenie údajov z farebného senzora používame triedu na korekciu chyby. Pre presnejšie pracovanie tejto triedy sa vyžaduje kalibrácia, ktorá pozostáva z priloženia čierneho a bieleho objektu. | ||
+ | |||
+ | <code> | ||
+ | ... | ||
+ | EV3ColorSensor colorSensor = new EV3ColorSensor(SensorPort.S3); | ||
+ | ... | ||
+ | |||
+ | ... | ||
+ | SampleProvider redMode = colorSensor.getRedMode(); | ||
+ | SampleProvider reflectedLight = new autoAdjustFilter(redMode); | ||
+ | int sampleSize = reflectedLight.sampleSize(); | ||
+ | float[] sample = new float[sampleSize]; | ||
+ | while (true) { | ||
+ | reflectedLight.fetchSample(sample, 0); | ||
+ | value = sample[0]; | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Na kontrolu robota budeme používať tri správania. Základné správanie sa pohybuje podľa prijatých údajov od používateľa z PC. | ||
+ | |||
+ | <code> | ||
+ | ... | ||
+ | _suppressed = false; | ||
+ | while (!_suppressed) { | ||
+ | switch (BumperCarWithHandling.direction) { | ||
+ | case "prava": | ||
+ | BumperCarWithHandling.rightMotor.stop(); | ||
+ | BumperCarWithHandling.leftMotor.forward(); | ||
+ | break; | ||
+ | case "lava": | ||
+ | BumperCarWithHandling.rightMotor.forward(); | ||
+ | BumperCarWithHandling.leftMotor.stop(); | ||
+ | break; | ||
+ | case "hore": | ||
+ | BumperCarWithHandling.rightMotor.forward(); | ||
+ | BumperCarWithHandling.leftMotor.forward(); | ||
+ | break; | ||
+ | case "dole": | ||
+ | BumperCarWithHandling.rightMotor.backward(); | ||
+ | BumperCarWithHandling.leftMotor.backward(); | ||
+ | break; | ||
+ | case "s": | ||
+ | BumperCarWithHandling.rightMotor.stop(); | ||
+ | BumperCarWithHandling.leftMotor.stop(); | ||
+ | break; | ||
+ | default: | ||
+ | break; | ||
+ | } | ||
+ | Thread.yield(); | ||
+ | } | ||
+ | ... | ||
</code> | </code> | ||
+ | |||
+ | |||
+ | Druhé správanie sa aktivuje ak ultrazvukový senzor detekuje prekážku príliš blízko robota. Toto správanie cúvne a náhodne sa otočí doprava alebo doľava. | ||
+ | |||
+ | <code> | ||
+ | ... | ||
+ | BumperCarWithHandling.leftMotor.rotate(-180, true); | ||
+ | BumperCarWithHandling.rightMotor.rotate(-180, true); | ||
+ | if ((System.currentTimeMillis() & 0x1) != 0) { | ||
+ | BumperCarWithHandling.leftMotor.rotate(-180, true); | ||
+ | BumperCarWithHandling.rightMotor.rotate(180); | ||
+ | } else { | ||
+ | BumperCarWithHandling.rightMotor.rotate(-180, true); | ||
+ | BumperCarWithHandling.leftMotor.rotate(180); | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Posledné správanie sa aktivuje ak farebný senzor detekuje čiernu čiaru vymedzujúcu hranicu priestoru, v ktorom sa môže robot pohybovať. Ak narazí na hranicu tak sa vráti späť. | ||
+ | |||
+ | <code> | ||
+ | ... | ||
+ | BumperCarWithHandling.leftMotor.rotate(-180, true); | ||
+ | BumperCarWithHandling.rightMotor.rotate(-180, true); | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | Na ovládanie týchto troch správaní budeme používať triedu Arbitrator. | ||
+ | |||
+ | <code> | ||
+ | ... | ||
+ | Behavior b1 = new DriveForwardWithHandling(); | ||
+ | Behavior b2 = new DetectWallWithHandling(); | ||
+ | Behavior b3 = new OffTheLineWithHandling(); | ||
+ | Behavior[] behaviorList = { b1, b2, b3 }; | ||
+ | Arbitrator arbitrator = new Arbitrator(behaviorList); | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | Každé správanie obsahuje metódu takeControl(), ktorá určuje kedy sa má dané správanie aktivovať. Naše základné správanie má v tejto metóde return true, pretože chceme aby sa vykonávalo vždy, keďsa nedeje žiadna zo špecifických udalostí (senzor detekuje prekážku alebo čiernu čiaru). Ostatné dve správania preberajú kontrolu v závislosti od nameraných údajov. Každé správanie takisto obsahuje aj metódu suppress(), ktorá sa zavolá ak nastane jedna zo špecifických udalostí a malo by sa ukončiť vykonávanie jedného správania a spustiť druhé. Táto metóda je použitá iba v základnom správaní, pretože iba tam by sa malo ukončiť správanie ak nastane iná udalosť. Správanie, ktoré detekuje prekážky a správanie, ktoré detekuje vychádzanie z vyznačeného priestoru nechceme prerušovať pokiaľ sa nevykoná akcia v tomto správaní. Na takéto ovládanie správaní používame triedu Arbitrator. | ||
+ | |||
+ | |||
+ | |||
+ | Druhá časť programu sa nachádza na '''PC'''. | ||
+ | |||
+ | V tejto časti sa pripájame na server, ktorý sme vytvorili na robotovi a zachytávame stisknuté klávesy. | ||
+ | |||
+ | <code> | ||
+ | ... | ||
+ | Socket s = new Socket("10.0.1.1", 1111); | ||
+ | out = new DataOutputStream(s.getOutputStream()); | ||
+ | ... | ||
+ | |||
+ | ... | ||
+ | public void keyPressed(KeyEvent arg0) { | ||
+ | switch(arg0.getKeyCode()) | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | |||
+ | == Spúštanie == | ||
+ | |||
+ | 1. Spustiť program na robotovi | ||
+ | |||
+ | 2. Nakalibrovať farebný senzor (optional) | ||
+ | |||
+ | 3. Spustiť program na PC | ||
+ | |||
+ | 4. Ovládať robota pomocou programu na PC | ||
+ | |||
+ | == Obrázky == | ||
+ | |||
+ | [[Image:roboticek.jpg]] | ||
+ | |||
+ | [[Image:roboticek2.jpg]] | ||
+ | |||
+ | [[Image:roboticek3.jpg]] | ||
+ | == Video == | ||
+ | |||
+ | <youtube>CINWjDtSwQ8</youtube> | ||
+ | |||
+ | == Zdrojáky == | ||
+ | |||
+ | [[Media:BumperCarWithHandling.java|BumperCarWithHandling]] | ||
+ | |||
+ | [[Media:Ovladanie.java|Ovladanie]] |
Latest revision as of 18:32, 3 July 2014
Zadanie
V tomto projekte si vytvoríme robota zo stavebnice Lego Mindstorms Ev3, ktorý bude ovládaný pomocou klávesnice PC, bude sa vyhýbať prekážkam a zároveň nebude vychádzať z vyznačeného priestoru.
Príprava
Budeme používať softvér pre Lego Mindstorms Ev3 od open-source projektu leJOS. Na jeho používanie budeme potrebovať nakonfigurovanú micro-SD kartu a vývojové prostredie, ktoré si môžeme nastaviť pomocou nasledujúcich odkazov.
- https://sourceforge.net/p/lejos/wiki/Windows%20Installation/
- https://sourceforge.net/p/lejos/wiki/Installing%20the%20Eclipse%20plugin/
Nakonfigurovanú SD kartu vložíme do SD portu Ev3 kocky a spustíme. Softvér od leJOS-u sa automaticky nahrá z karty a bude sa používať ako náhrada za oficiálny softvér, pokiaľ budeme mať vloženú kartu.
Ďalej budeme potrebovať nadviazané spojenie pomocou Bluetooth. Toto spojenie sa dá jednoducho nadviazať z PC. V Bluetooth Devices si vieme nájsť Ev3 a nadviazať s ním spojenie.
Program
Program bude pozostávať z dvoch základných častí, časť, ktorá bude bežať na robotovi a časť, ktorá bude bežať na PC.
Popíšme si najskôr časť, ktorá bude na robotovi.
Program na robotovi sa skladá z viacerých častí. V prvom rade musíme zabezpečiť komunikáciu medzi robotom a PC. Keďže už máme nadviazané spojenie pomocou Bluetooth stačí nám na robotovi vytvoriť server, ktorý bude počúvať na požiadavky od používateľa, v našom prípade PC. Túto komunikáciu sme umiestnili do samostatného threadu aby robot stále počúval na požiadavky z PC.
... serv = new ServerSocket(1111); Socket s = serv.accept(); // Wait for Laptop to connect DataInputStream in = new DataInputStream(s.getInputStream()); ...
... String read = in.readUTF(); switch (read) ...
Na meranie vzdialenosti od prekážok budeme používať ultrazvukový senzor, ktorý bude neustále vracať hodnoty.
... EV3UltrasonicSensor us = new EV3UltrasonicSensor(SensorPort.S4); ...
... us.enable(); SampleProvider sampleProvider = us.getDistanceMode(); while (true) { float[] sample = new float[sampleProvider.sampleSize()]; sampleProvider.fetchSample(sample, 0); distance = sample[0]; } ...
Priestor, v ktorom sa bude robot môcť pohybovať bude označený čiernou páskou. Na zabezpečenie, aby robot nevyšiel z tohto priestoru budeme používať farebný senzor. Na spresnenie údajov z farebného senzora používame triedu na korekciu chyby. Pre presnejšie pracovanie tejto triedy sa vyžaduje kalibrácia, ktorá pozostáva z priloženia čierneho a bieleho objektu.
... EV3ColorSensor colorSensor = new EV3ColorSensor(SensorPort.S3); ...
... SampleProvider redMode = colorSensor.getRedMode(); SampleProvider reflectedLight = new autoAdjustFilter(redMode); int sampleSize = reflectedLight.sampleSize(); float[] sample = new float[sampleSize]; while (true) { reflectedLight.fetchSample(sample, 0); value = sample[0]; } ...
Na kontrolu robota budeme používať tri správania. Základné správanie sa pohybuje podľa prijatých údajov od používateľa z PC.
... _suppressed = false; while (!_suppressed) { switch (BumperCarWithHandling.direction) { case "prava": BumperCarWithHandling.rightMotor.stop(); BumperCarWithHandling.leftMotor.forward(); break; case "lava": BumperCarWithHandling.rightMotor.forward(); BumperCarWithHandling.leftMotor.stop(); break; case "hore": BumperCarWithHandling.rightMotor.forward(); BumperCarWithHandling.leftMotor.forward(); break; case "dole": BumperCarWithHandling.rightMotor.backward(); BumperCarWithHandling.leftMotor.backward(); break; case "s": BumperCarWithHandling.rightMotor.stop(); BumperCarWithHandling.leftMotor.stop(); break; default: break; } Thread.yield(); } ...
Druhé správanie sa aktivuje ak ultrazvukový senzor detekuje prekážku príliš blízko robota. Toto správanie cúvne a náhodne sa otočí doprava alebo doľava.
... BumperCarWithHandling.leftMotor.rotate(-180, true); BumperCarWithHandling.rightMotor.rotate(-180, true); if ((System.currentTimeMillis() & 0x1) != 0) { BumperCarWithHandling.leftMotor.rotate(-180, true); BumperCarWithHandling.rightMotor.rotate(180); } else { BumperCarWithHandling.rightMotor.rotate(-180, true); BumperCarWithHandling.leftMotor.rotate(180); } ...
Posledné správanie sa aktivuje ak farebný senzor detekuje čiernu čiaru vymedzujúcu hranicu priestoru, v ktorom sa môže robot pohybovať. Ak narazí na hranicu tak sa vráti späť.
... BumperCarWithHandling.leftMotor.rotate(-180, true); BumperCarWithHandling.rightMotor.rotate(-180, true); ...
Na ovládanie týchto troch správaní budeme používať triedu Arbitrator.
... Behavior b1 = new DriveForwardWithHandling(); Behavior b2 = new DetectWallWithHandling(); Behavior b3 = new OffTheLineWithHandling(); Behavior[] behaviorList = { b1, b2, b3 }; Arbitrator arbitrator = new Arbitrator(behaviorList); ...
Každé správanie obsahuje metódu takeControl(), ktorá určuje kedy sa má dané správanie aktivovať. Naše základné správanie má v tejto metóde return true, pretože chceme aby sa vykonávalo vždy, keďsa nedeje žiadna zo špecifických udalostí (senzor detekuje prekážku alebo čiernu čiaru). Ostatné dve správania preberajú kontrolu v závislosti od nameraných údajov. Každé správanie takisto obsahuje aj metódu suppress(), ktorá sa zavolá ak nastane jedna zo špecifických udalostí a malo by sa ukončiť vykonávanie jedného správania a spustiť druhé. Táto metóda je použitá iba v základnom správaní, pretože iba tam by sa malo ukončiť správanie ak nastane iná udalosť. Správanie, ktoré detekuje prekážky a správanie, ktoré detekuje vychádzanie z vyznačeného priestoru nechceme prerušovať pokiaľ sa nevykoná akcia v tomto správaní. Na takéto ovládanie správaní používame triedu Arbitrator.
Druhá časť programu sa nachádza na PC.
V tejto časti sa pripájame na server, ktorý sme vytvorili na robotovi a zachytávame stisknuté klávesy.
... Socket s = new Socket("10.0.1.1", 1111); out = new DataOutputStream(s.getOutputStream()); ...
... public void keyPressed(KeyEvent arg0) { switch(arg0.getKeyCode()) ...
Spúštanie
1. Spustiť program na robotovi
2. Nakalibrovať farebný senzor (optional)
3. Spustiť program na PC
4. Ovládať robota pomocou programu na PC
Obrázky
Video