Version 1.3.1 · översatt artikel
Bygg förstapersonsstyrning för en Arduino-robot
Skärmbilderna är från originalartikeln och har retuscherats så att gränssnittstexten är på svenska. De orörda originalen visar det ryska gränssnittet.
Den senaste versionen av RoboCam kan styra inte bara EV3-robotar utan även robotar byggda på plattformar som Arduino, Raspberry Pi och liknande, där man kan arbeta direkt med data som tas emot och skickas via Bluetooth. Nu kan du hantera RoboCams kommandon precis som du vill.

Den här artikeln beskriver de nya funktionerna i RoboCam version 1.3.1. Alla artiklar om RoboCam finns här. Du kan installera RoboCam från Google Play, eller ladda ner APK-filen och installera den manuellt: den vanliga versionen av RoboCam eller versionen av RoboCam som använder RenderScript (för vissa äldre telefoner); båda är utgåva 1.4.5. Det finns också en APKPure-spegling.
Allt som gjordes för EV3 i de tidigare versionerna är oförändrat. Den nya versionen lägger bara till en drivrutin och inställningar för att arbeta med robotar som kan ta emot kommandon direkt från RoboCam via Bluetooth, bearbeta dem och skicka svar. Sådana robotar kan byggas på olika plattformar (Arduino, Raspberry Pi, PC) och köra olika firmware och operativsystem (standardfirmware för Arduino, Windows, Linux, Android med flera). Programmet som pratar med RoboCam kan också skrivas i olika programmeringsspråk.
Eftersom robotens firmware eller operativsystem kan variera beskriver jag nedan bara protokollet för kommunikation med RoboCam och de nya inställningarna, och ger ett exempelprogram för att styra en hjulrobot med styrbar telefonhållare på Arduino-plattformen.
Robotarna som beskrivs ovan kallas i den här artikeln och i inställningarna icke-standardrobotar.
Här är en video där en Arduino-robot styrs i förstaperson med RoboCam. Längre ner i artikeln beskrivs hur och med vad man bygger en sådan robot.
Så kommunicerar RoboCam och roboten
Det första som behövs för att RoboCam och roboten ska börja kommunicera är att i programvaran ansluta till Bluetooth-modulen och vänta tills data börjar komma från den. Det görs olika på alla system och kan inte beskrivas i en enda artikel. Därför ger jag exempel bara för Arduino-plattformen, och specifikt för konfigurationen Arduino Uno + Bluetooth-modul HC-06. Jag utgår från att HC-06 har standardinställningar (9600 baud) och är ansluten på standardsättet (modulens RX-stift till Arduino Unos TX-stift, och modulens TX-stift till Arduino Unos RX-stift). Vid standardanslutning går allt Bluetooth-arbete på Arduino via serieporten med 9600. I kod ser initieringen av porten ut så här:
Som du ser är det enkelt. Därefter kan du läsa och skicka data via Bluetooth. På Arduino görs det med metoderna i klassen Serial, som read(), write(), available() med flera.
När RoboCam-appen ansluter till ditt program tar den direkt initiativet: RoboCam skickar meddelanden med kommandon, och ditt program bearbetar kommandona och skickar tillbaka meddelanden med svar. Alla kommandon och svar går i sekvens: först kommer ett kommandomeddelande från RoboCam, sedan måste ett svarsmeddelande gå tillbaka, varefter RoboCam skickar nästa kommando, som återigen måste besvaras, och så vidare.
Ditt program bör svara på varje kommandomeddelande så snabbt det kan. Ju längre ditt program tar på sig att svara, desto sämre blir i slutändan robotens respons på användarens handlingar.
Ett svar på varje meddelande förväntas inom en sekund. RoboCam behandlar ett svar som fördröjs mer än en sekund som ett fel.
Varje meddelande är en viss uppsättning byte. De första två byten innehåller ett tal som anger meddelandets storlek i byte. Dessa två första byte räknas inte som en del av meddelandet. Om de första två byten alltså anger 5 följer ytterligare 5 byte, och det är själva meddelandet. Ett meddelande läses därför så här: först läser du de första 2 byten och omvandlar dem till ett teckenlöst tvåbytes heltal, sedan läser du lika många byte till som talet anger. Här är ett exempel på hur man läser meddelandets storlek på en Arduino:
Därefter kan du läsa hela meddelandet till en matris, till exempel så här:
I exemplet ovan lämnas slingan om det inte finns någon data att läsa i serieporten. Vi väntar alltså inte på att meddelandet ska läsas helt. Med det tillvägagångssättet läser vi meddelandet allteftersom data kommer och gör samtidigt något annat i den oändliga slingan i vår Arduino-skiss, i funktionen loop().
När meddelandet har lästs (i exemplet ovan sker det när värdet på readMessageBytes blir lika med värdet på messageSize) kan det tolkas, och efter tolkning och sändning av svaret läser du nästa meddelande, och så vidare.
Ett svarsmeddelande skickas så här: först bygger du meddelandet, till exempel genom att lägga det i en bytematris, sedan räknar du ut storleken på det resulterande meddelandet och skickar den som de första två byten, följt av själva meddelandet, det vill säga den förberedda bytematrisen. Ett exempel på att skicka ett svarsmeddelande på Arduino ser ut så här:
Meddelandenas innehåll
När ditt program har läst ett meddelande till en matris kan meddelandet läsas. Meddelandets första byte innehåller kommandokoden. Alla övriga byte beror på kommandot. Kommandona är:
-
-
-
- 0 – kommandot «Start»;
- 1 – kommandot «Anropssignal»;
- 2 – kommandot «Kontroller»;
- 3 – kommandot «Test»;
- 255 – kommandot «Stopp».
-
-
För enkelhets skull är det bäst att direkt deklarera konstanter för kommandona i ditt program (längre fram i artikeln använder jag namnen på konstanterna för bekvämlighets skull):
Roboten måste svara på varje kommando den tar emot. Som skrivet ovan är svaret också ett meddelande. Meddelandets första byte (naturligtvis efter de två byten med meddelandets storlek) är resultatkoden. Om fler byte följer, och vad de innehåller, beror på kommandot som besvaras.
Resultatbyten kan bara ha två värden:
-
-
-
- 0 – kommandot utfördes framgångsrikt;
- 1 – ett fel uppstod när kommandot utfördes, eller kommandot stöds inte.
-
-
Nu tittar vi närmare på kommandona och svaren på dem.
Kommandot «Start» (CMD_START)
Med det här kommandot börjar samtalet mellan roboten och RoboCam (det sker efter att du tryckt på den mittersta lila knappen i RoboCam och valt en robot i listan). Som svar på kommandot måste roboten returnera ett korrekt svar. Om RoboCam får ett felaktigt svar på kommandot, eller inget svar inom en sekund, bryter RoboCam anslutningen och visar ett fel.
Så här ser byten ut i ett meddelande med kommandot CMD_START:
SSCTV
Här står en bokstav för en byte:
-
-
-
- De första två byten SS är meddelandets storlek, det vill säga antalet byte som följer efter dessa två byte i meddelandet.
- Sedan kommer byten C som innehåller kommandokoden. I vårt fall är den 0, det vill säga kommandot CMD_START.
- Nästa byte T är en kontrollbyte. Dess värde är olika varje gång, i intervallet 0 till 254. Vad man ska göra med värdet står lite längre ner.
- Allra sist kommer byten V med numret på den högsta version av kommunikationsprotokollet som RoboCam stöder. För närvarande är det 1.
-
-
Här är ett exempel på ett meddelande med kommandot CMD_START i oktal form:
030000D101
När din robot tar emot kommandot måste den svara inom 1 sekund. Svaret är också en bytematris och ska se ut så här:
SSRTVC
Även här har jag markerat en byte med en bokstav. Så här ser det ut i byten:
-
-
-
- De första två byten SS är meddelandets storlek. Svaret är också ett meddelande, så även här innehåller de första två byten storleken på matrisen som följer efter dessa två byte.
- Nästa byte R är resultattypen. 0 – roboten utförde kommandot framgångsrikt, 1 – fel. Om du anger 1 här (det vill säga ett fel) behöver de återstående byten i meddelandet inte skickas.
- Byten T är svaret på kontrollbyten. Den ska innehålla ett tal som är 1 större än det du fick med kommandot CMD_START. I exemplet ovan anges talet D1 (209 decimalt), så som svar ska du skicka talet D2 (210).
- Nästa byte V är den version av kommunikationsprotokollet som roboten kommer att använda. Versionsnumret här får inte vara högre än den version du fick med kommandot CMD_START, annars vägrar RoboCam att arbeta med roboten och visar ett fel. För närvarande ska du ange 1 här.
- Den sista byten C är den teckenkodning som strängar överförs i. Det finns bara två alternativ: 0 – US-ASCII (inga ryska bokstäver) och 1 – UTF-8. US-ASCII används på Arduino.
-
-
Här är ett exempel på ett svar på kommandot CMD_START:
040000D20100
Kommandot «Anropssignal» (CMD_CALLSIGN)
När RoboCam får ett felfritt svar på kommandot CMD_START, med kontrollbyten, protokollversionen och teckenkodningen rätt angivna, börjar den fortsatta kommunikationen mellan roboten och RoboCam. Direkt därefter får roboten kommandot CMD_CALLSIGN. Det sker dock bara om en anropssignal och ett svar på den är angivna i RoboCams inställningar. Om ingen anropssignal eller inget svar är angivet skickas inte kommandot. På bilden nedan är till exempel anropssignalen «RoboCam» och svaret «Researcher» angivna i inställningarna.

Ett meddelande med kommandot CMD_CALLSIGN ser ut så här:
SSCAAA…0
-
-
-
- De första två byten SS innehåller meddelandets storlek, som för de övriga kommandona.
- Nästa byte C är kommandokoden. För kommandot CMD_CALLSIGN är den 1.
- De återstående byten AAA…0 är en sträng avslutad med 0, som innehåller anropssignalen du angav i inställningarna. Strängens teckenkodning motsvarar den du angav i svaret på kommandot CMD_START.
-
-
Ett exempel på ett CMD_CALLSIGN-kommando med anropssignalen «RoboCam» i teckenkodningen US-ASCII ser ut så här:
090001526F626F43616D00
Som svar på kommandot ska du skicka strängen med svaret på anropssignalen som är angiven i RoboCams inställningar. Om någon annan sträng kommer tillbaka bryter RoboCam anslutningen. Svarsmeddelandet ser ut så här:
SSRAAA…0
-
-
-
- De första två byten SS är, som för de övriga svaren, meddelandets storlek.
- Nästa byte R är resultattypen: 0 – anropssignalen godtogs, 1 – fel. Om du returnerar 1 här behöver de återstående byten i meddelandet inte skickas.
- De återstående byten AAA…0 är en sträng avslutad med 0, som innehåller svaret på anropssignalen. Strängens teckenkodning motsvarar den du angav i svaret på kommandot CMD_START.
-
-
Ett exempel med svaret «Researcher» på anropssignalen ser ut så här:
0C00005265736561726368657200
Kommandot «Kontroller» (CMD_CTRL)
När RoboCam har anslutit till ditt program, och efter kommandona CMD_START och CMD_CALLSIGN, börjar CMD_CTRL-kommandon komma. Det är kommandon från kontrollerna som användaren styr roboten med, det vill säga styrspakarna och tangentbordet. Kommandon kommer varje gång koordinaten för punkten där användarens finger rör vid en styrspak ändras, eller en tangents status (nedtryckt/inte nedtryckt) ändras, det vill säga när användaren styr roboten. Kommandon kommer bara om koordinaterna har ändrats eller en tangent på tangentbordet har tryckts ned eller släppts.
Ett meddelande med kommandot CMD_CTRL ser ut så här:
SSCJVJVJV…
-
-
-
- De första två byten SS är meddelandets storlek.
- Byten C är kommandot. För kommandot CMD_CTRL är den 2.
- De följande byten JVJVJV… är information om ändringar i kontrollernas tillstånd. Det kan vara ett eller flera bytepar. Så här tolkas byten i ett par:
- Byten J är kontrollerns identifierare. Det här är värdena byten kan ha och vad de betyder:
- 0 – X-axeln (horisontell axel för styrspak 1);
- 1 – Y-axeln (vertikal axel för styrspak 1);
- 2 – W-axeln (horisontell axel för styrspak 2);
- 3 – Z-axeln (vertikal axel för styrspak 2);
- 4 – A-axeln (horisontell axel för styrspak 3);
- 5 – B-axeln (vertikal axel för styrspak 3);
- 6 – C-axeln (horisontell axel för styrspak 4);
- 7 – D-axeln (vertikal axel för styrspak 4);
- 255 – en tangent nedtryckt;
- 254 – en tangent inte nedtryckt.
- Byten V får ett värde beroende på byten J:
- För en styrspaksaxel (om J är från 0 till 7) innehåller byten V koordinaten för punkten där användaren rör vid styrspaken, i intervallet -100 till 100.
- För en tangent (om J är 255 eller 254) är det tangentkoden. De möjliga tangentkoderna finns i tabellen i slutet av artikeln «RoboCam – styr roboten i förstaperson med datorns tangentbord».
- Byten J är kontrollerns identifierare. Det här är värdena byten kan ha och vad de betyder:
-
-
Ett exempel på ett CMD_CTRL-kommando (kommandot betyder att X-axelns koordinat fick värdet 90, Y-axelns värdet -100 och tangenten med koden 89, det vill säga tangenten Y, trycktes ned):
060002005A019CFF59
För enkelhets skull är det bäst att direkt definiera konstanter för kontrollernas identifierare i koden:
När ditt program tar emot ett CMD_CTRL-kommando får du direkt veta vad som har hänt med styrspakarna och tangenterna. Du kan då genast ändra robotens färdriktning, vrida en servo till rätt vinkel och så vidare. När du har bearbetat kommandot måste du skicka ett svar; det här är byten:
SSR
-
-
-
- SS är meddelandets storlek. Här är den alltid 1, eftersom svaret alltid är en enda byte.
- R är resultatet: 0 – inget fel, 1 – fel. Egentligen ignorerar kommandot CMD_CTRL resultatet men väntar ändå på ett svarsmeddelande. Trots det rekommenderas det att alltid returnera 0 här.
-
-
Svaret ser ut så här:
010000
Kommandot «Test» (CMD_TEST)
Kommandot CMD_TEST skickas ungefär en gång i sekunden för att kontrollera anslutningen. Om roboten inte svarar på kommandot anser RoboCam att förbindelsen med roboten har brutits. Så här ser ett meddelande med kommandot CMD_TEST ut:
SSC
-
-
-
- Byten SS är meddelandets storlek. För kommandot CMD_TEST är storleken alltid 1.
- Byten C är kommandokoden, i det här fallet 3.
-
-
Här är ett exempel på ett meddelande med kommandot CMD_TEST:
010003
Du måste svara på kommandot CMD_TEST inom 1 sekund, annars anser RoboCam att förbindelsen med roboten har brutits. Svarsformatet ska vara följande:
SSR
-
-
-
- Byten SS är meddelandets storlek.
- Byten R är resultatet: 0 – kommandot bearbetades framgångsrikt, 1 – fel. Om du returnerar 1 här anser RoboCam att anslutningen har brutits.
-
-
Här är ett exempel på ett svar på kommandot CMD_TEST:
010000
Kommandot «Stopp» (CMD_STOP)
Kommandot CMD_STOP skickas till roboten när roboten ska stoppas och återgå till utgångsläget. Det skickas om förbindelsen mellan telefonen med styrspakarna och RoboCam bryts, eller om du bryter anslutningen genom att trycka på den mittersta lila knappen i RoboCam. Vid det här kommandot ska roboten sluta röra sig och återställa servomotorerna till utgångsläget. Kommandots format är följande:
SSC
-
-
-
- Byten SS är meddelandets storlek. För kommandot CMD_STOP är storleken alltid 1.
- Byten C är kommandokoden, i det här fallet 255.
-
-
Här är ett exempel på ett meddelande med kommandot CMD_STOP:
0100FF
Svaret som förväntas på kommandot är följande:
SSR
-
-
-
- Byten SS är meddelandets storlek.
- Byten R är resultatet: 0 – kommandot bearbetades framgångsrikt, 1 – fel. Resultatet av svaret på det här kommandot ignoreras men förväntas. Det rekommenderas att alltid returnera 0 här.
-
-
Här är ett exempel på ett svar på kommandot CMD_STOP:
010000
Robotinställningar
Nu när vi har gått igenom kommunikationsprotokollet kan vi titta på de inställningar som tillkommit för icke-standardrobotar. Öppna inställningarna i RoboCam (den grå runda knappen till höger),

välj sedan «Robot».

Robotinställningarna öppnas. Som du ser visar listan nu både inställningar för EV3-robotar och för icke-standardrobotar.

För att ändra inställningar du skapat tidigare väljer du dem helt enkelt i listan; för att lägga till nya inställningar för en icke-standardrobot trycker du på knappen «Lägg till» och väljer menyalternativet «Icke-standardrobot».

Om du bestämmer dig för att skapa nya inställningar får du en tom inställningsskärm.

I artikeln beskriver jag inställningarna med utgångspunkt i inställningar jag skapat tidigare för att styra roboten du såg i videon högst upp i artikeln. Allra först anges robotens namn, som syns i listan över inställningar och på RoboCams huvudskärm om inställningarna är de aktuella. Därefter kommer en beskrivning, som bara syns i listan över inställningar.

Om «Visa felsökningsinformation» är markerad visar klienten styrspakens koordinater medan den används, samt koderna för nedtryckta tangenter.
Om «Dölj styrspakar vid tangentbordsanvändning» är markerad försvinner styrspakarna på klienten, som i EV3-inställningarna, så fort någon tangent trycks ned på klienten. Så fort du klickar på skärmen med musen visas styrspakarna igen.
Därefter kommer inställningarna för anropssignal och svar. Texten som anges här används för kommandot CMD_CALLSIGN som beskrevs ovan.
Nedanför finns inställningarna för RoboCams 4 styrspakar. Inställningarna är desamma för alla styrspakar, så vi tittar på dem med den första styrspaken som exempel. Den första kryssrutan, «Synlighet», styr styrspakens synlighet; om den är avmarkerad visas styrspaken inte på klienten och fungerar inte.

I listan «Form» kan du välja styrspakens form. Formerna är: vertikal, horisontell, rund, kvadratisk, pilar, vertikala pilar och horisontella pilar. Så här ser styrspakar av de beskrivna formerna ut:

Hur styrspakarna fungerar beror på formen och beskrivs redan i artikeln «Styra en LEGO Mindstorms EV3-robot i förstaperson».
De följande två listorna väljer hur styrspakarna beter sig när du slutar röra vid dem. Det finns bara två alternativ: «Återgå till noll» och «Behåll position». I det första fallet återgår styrspaken till utgångsläget, det vill säga till noll, när du «släpper» den; i det andra stannar den där den är. Beteendet kan anges separat för styrspakens vertikala och horisontella axel.
Allra längst ner ställs tangenterna in. Kryssrutan «Aktiv» slår på eller av RoboCam-klientens känslighet för tangenttryckningar. Om du inte planerar att styra med tangentbordet rekommenderas det att avmarkera den för att spara batteri på klientenheten.
Lite längre ner kan du, om du trycker på inställningen «Tangenter», välja de tangenter vars tillstånd du tänker följa.

Sammantaget finns det mycket färre inställningar för en icke-standardrobot än för en EV3-robot, men de som finns fungerar som för EV3-roboten, så läs de tidigare artiklarna om RoboCam för mer detaljer.
Bygga Arduino-roboten
För att göra Arduino-roboten som styrs i förstaperson med RoboCam, som du ser i videon nedan, använde jag utbildningssatsen från Amperka samt ytterligare komponenter och delar: en Bluetooth-modul HC-06, extra plastdistanser, muttrar och brickor, två 3D-utskrivna delar för att hålla servomotorn, ett gem och två gummiband (sådana som används för sedlar).
Byggprocessen visas i snabbspolning i videon. Det är inget komplicerat med den. Om du bygger en sådan robot av Amperkas utbildningssats följer en bok med som beskriver hur man ansluter motorerna och hur man bygger en robot som följer en linje. Min robot är likadan som den i boken, men utan linjesensorer.
Jag bestämde mig för att fästa telefonen på enklaste sätt: nedtill är två distanser med skruvar fastskruvade och telefonen hålls mot dem med ett gummiband. Upptill hålls telefonen mot en skena, som den återigen är fäst vid med ett gummiband. Skenans andra ände är fäst vid en servo. I videon syns att telefonen lutar små vinklar, men genom att förlänga hävarmen kan du, om du vill, öka telefonens lutningsvinklar.
De färdiga modellerna för 3D-utskrift av servohållaren och skenan finns listade nedan:
| Servohållare (3D-modell) | |
Servohållare (3D-modell) för en robot byggd av Amperkas utbildningssats.
|
|
| Datum: 06.10.2017 · Filstorlek: 76.41 KB |
| Skena (3D-modell) | |
Skena (3D-modell) för en robot byggd av Amperkas utbildningssats.
|
|
| Datum: 06.10.2017 · Filstorlek: 56.08 KB |
Om din robotplattform är en annan blir din telefonhållare också en annan. I så fall är det inget problem att tillverka en egen hållare om du kan 3D-skriva ut. Mina egna 3D-modeller av servohållaren och skenan skapade jag i den molnbaserade 3D-editorn Tinkercad. Jag har redan beskrivit hur man arbetar med den i artikeln «Tinkercad – ett enkelt webbverktyg för 3D-konstruktion och 3D-utskrift» (på ryska).
För att upprepa mitt experiment behöver du också Arduino-skissen och RoboCam-inställningarna:
| Arduino Explorer Version: från 10.09.2017 | |
En skiss för att styra en hjulburen Arduino-robot med styrbar telefonhållare med hjälp av RoboCam. |
|
| Datum: 10.09.2017 · Filstorlek: 15.07 KB |
| RoboCam-inställningar för att styra Arduino Explorer Version: från 10.09.2017 | |
RoboCam-inställningar för att styra Arduino Explorer. |
|
| Datum: 11.09.2017 · Filstorlek: 448 B |
Alla RoboCam-versioner
- v1.4.2 Förvandla en smartphone till fjärrkontroll för roboten med RoboCam
- v1.3.1 Bygg förstapersonsstyrning för en Arduino-robotdu är här
- v1.2 RoboCam – styr roboten i förstaperson med datorns tangentbord
- v1.1 Importera, exportera, kopiera och skicka robotinställningar i RoboCam
- v1.0 Styr en LEGO Mindstorms EV3-robot i förstaperson

