Paketová komunikace
po sériové lince
Tento článek se zabývá posíláním příkazů a zpráv mezi počítačem a jednočipem řídícím robota. Důraz bude kladen na obsah a především strukturu posílaných zpráv, nikoli na konkrétní implementaci na vybraném operačním systému a jednočipu. V tomto článku mluvím sice výhradně o sériové lince (myšleno RS232), podobné poznatky a principy však platí i o dalších podobných komunikačních sběrnicích.
Úvod
Až na nejjednodušší roboty řízené pouze jednočipem, nebo dokonce vůbec, byli
snad všichni roboti, které naše robotická skupina na
Matematicko-fyzikální fakultě Univerzity Karlovy
používala (např. Dana, Daisy,
Ester, roboti týmu MART, Mob2 …), sestaveni podle schématu
na Obr. 1 nebo jeho blízké obdoby. Zdaleka se nejedná o světovou raritu.
Stejným způsobem jsou uspořádáni také roboti Pioneer či tak mohou být řízené
vysavače Roomba. Vyšší řízení robota, jako jsou např. lokalizace a plánování
činnosti, běží na „výkonnějším” počítači, kterým může být třeba PDA, miniITX
deska, nebo celý notebook. Nižší řízení, jako např. PID řízení motorů a čtení
senzorů, jsou přenechány jednočipu, který je pro takovéto úlohy mnohem lépe
uzpůsoben. Výměna informací a pokynů mezi počítačem a jednočipem pak probíhá po
sériové lince. Sériová linka je implementačně jednoduchá a byla až donedávna
přítomna skoro všude. V poslední době sice došlo k jejímu úplnému ústupu z
počítačů a postupně mizí také z robotických desek, je ale nahrazována
převodníky z USB na sériovou linku. Z pohledu operačního systému i jednočipu se
tak nic nemění a obsah tohoto článku zůstává aktuálním. Jak zmiňuji dále, stává
se možná dokonce ještě aktuálnějším, než dříve.
Během desetiletí práce s roboty se sériovou linkou jsme nasbírali různé
zkušenosti, které nás vedou k následujícím východiskům při práci s ní:
- Sériová linka je nespolehlivá. Posílané zprávy mohou dorazit neúplné, poničené a někdy možná dokonce vůbec. Místo nich může přijít komunikační šum (např. signál naindukovaný motory).
- Sériová linka je pomalá.
Mnozí lidé se dušují, že ani jeden z vypsaných bodů není pravda. Naše pracně
získaná zkušenost je ale takováto. A i v případě, kdy pracujete se skvělým
robotem bez těchto neduhů, doporučuji pesimisticky problémy očekávat ("Better
safe than sorry."). Beztak přijdou
Z čeho zmíněné potíže vychází? Nespolehlivost je sériové lince vlastní.
Signálový kabel vedený kdekoli poblíž elektromotoru si o potíže přímo říká.
Navíc, rozhodne-li se váš systém (ať už na počítači nebo na jednočipu), že
zrovna nestíhá a musí řešit něco jiného, nemusí se příchozí zpráva vejít do
bufferu a nestihnete ji přečíst, aniž byste o její část přišli.
Pomalost není ani tak vlastnost samotné sériové linky, jako jejích konkrétních
provedení. Hvězdou tohoto nebe jsou právě různé USB<->RS232 převodníky. Podobně
u převodníků přes bluetooth jsme pozorovali, že jim dělá velké potíže rychlé a
časté přepínání směru komunikace. A to je přesně situace, která nastane na
robotovi, kde posíláte řídící příkazy a očekáváte informace ze senzorů.
Různými řešeními popsaných problémů se zabývá tento článek.
Posílání struktur na robotech typu Daisy
Roboty typu Daisy rozumím především Daisy samotnou. Do této
rodinky ale řadím také několik dalších robotů, především týmu Short Circuits,
kteří dědí z tradice a zdrojových kódů Daisy a jejích předchůdců. Stejný kód,
jak jsem zahlédl na posoutěžním workshopu, používají i další týmy v
Robotour a možná i jinde. Jedná se o dlouho
používaný a prověřený způsob komunikace.
O co jde? Princip je jednoduchý a je podrobně popsán v článku o
atmega8-boardu, proto nepůjdu příliš do hloubky.
Důležitá pro tento článek je především struktura posílaného datového balíčku
(Obr. 2). Každý paket začíná start bytem 0xAB. Následuje byte s délkou zprávy,
zpráva samotná a její checksum.
Kriticky důležitým prvkem je právě checksum na konci paketu. Ta umožňuje
detekci poničených nebo šumových zpráv. Jedná se o implementačně jednoduchý
doplněk k součtu bytů zprávy. Oprava poničeného paketu pomocí korekčních kódů
není cílem a tedy ani možná. Nezbývá, než poničený paket zahodit a čekat na
další.
Komunikace mezi počítačem a jednočipem probíhá plně synchronně: Počítač odešle
jednu řídící zprávu (např. požadovanou rychlost) a očekává jednu odpověď (např.
aktuální rychlost). Poté může dojít k další výměně zpráv (třeba jiného typu).
Potíž nastane v okamžiku, kdy jednočip dostane řídící zprávu poničenou, nebo
dokonce vůbec. V takové chvíli nemá jednočip na co odpovědět a počítač čeká na
odpověď marně. Případně může dojít k neúplnému doručení odpovědi se stejným
důsledkem. Proto musí být do komunikace zabudováno i zpracování timeoutu –
pokud nepřijde odpověď v rozumném časovém intervalu, je komunikace považována
za narušenou a musí dojít k její opětovné synchronizaci.
Pro synchronizaci aktérů se používá synchronizační byte 'D' (jako Daisy). Pokud
čeká jednočip na začátek další zprávy a obdrží 'D', odpoví také 'D'. Pro
opětovnou synchronizaci stačí posílat z PC 'D' tak dlouho, dokud jednočip
neodpoví stejně. Několik prvních 'D' může být jednočipem považováno za konec
předchozí (neplatné) zprávy a na první 'D' při čekání na začátek zprávy je
odpovězeno. Tak se PC dozví, že jednočip už neočekává konec předchozí zprávy.
Při této výměně dat musí PC pomocí timeoutů ošetřit situaci, kdy odesílá 'D',
ale jednočip stále ještě neodpovídá (považuje zaslaná 'D' za konec předchozí
zprávy).
Kvůli nešťastné kombinaci šumu a timeoutů může dojít k situaci, kdy robot
citelně dlouho nedostává řídící pokyny. Tuto situaci je velmi snadné detekovat
a bezpečně ošetřit (např. dočasným zastavením robota).
„Daisy protokol” byl původně navržený na posílání jediné řídící struktury
obsahujících pokyny pro všechny aktuátory a příjem jediné informační struktury
obsahující informace ze všech senzorů. To není u jednodušších robotů problém.
Jak ale roste počet aktuátorů a senzorů robota, roste také délka obou zpráv. A s
délkou zprávy klesá exponenciálně pravděpodobnost, že nebude při přenosu
poničena. Postupně je navíc dosaženo velikosti bufferů na obou stranách linky,
což může způsobit (a způsobí [Murphy]) potíže při jejich nedostatečně rychlém
vyčítání. Proto současná verze protokolu počítá s tím, že prvním datovým bytem
po délce zprávy je identifikátor jejího typu. Různé aktuátory a senzory tak
mohou být zpracovávány nezávisle a délka zprávy opět klesne.
Roboti rodiny RobSys
Roboti z dílny RobSys se tradičně účastní soutěží
Robotour (robot Explorer), Eurobot (robot
Eduro) a jiných. Tato skupina robotů
vznikla zcela nezávisle na vývojové větvi robota Daisy a tak řeší podobné
problémy jiným způsobem. Pro pochopení důvodů, proč a jak vznikl komunikační
protokol na těchto robotech je nutné vědět, jaká je jejich struktura (Obr. 3).
Každý senzor a aktuátor funguje jako zcela samostatný modul. Tyto moduly jsou
navzájem spojeny sběrnicí CAN. Sběrnice CAN se často používá např. v
automobilovém a leteckém průmyslu. Specifikace CAN pamatuje na robustnost
přenosu dat a ukládá způsob, jakým je zaručeno bezchybné doručení všech zpráv.
Robotik může použít snadno dostupné čipy, které implementují podstatnou část
CAN protokolu. O takto obdržené zprávě je možné předpokládat, že je v pořádku a
že žádná předchozí zpráva nebyla vynechána.
S počítačem je CAN spojen převodníkem (interně nazývaný „bridge”), který je
připojen na jedné straně na CAN, na druhé straně na sériový port počítače. Z
důvodu snadné implementace a úplné transparentnosti nezasahuje bridge do obsahu
zpráv a nemusí jim rozumět. Zprávy z jedné strany jsou jednoduše přeposlány na
stranu druhou a je na koncových zařízeních, aby se s obsahem zpráv vypořádala.
Tím je dán formát zpráv: Je dán specifikací CAN. Složitost CAN zpráv, kdy
jeden byte může obsahovat několik typů informace (i zároveň), mi neumožňuje
nakreslit jednoduchý diagram.
Podle konstruktérů z dílny RobSys není u dobře vyrobené sériové linky problém s
její (ne)spolehlivostí. Protože ale pracují jednotlivá zařízení na CAN sběrnici
zcela nezávisle a asynchronně, může na straně přijímacího software nastat
problém s bufferem sériové linky příliš malým na množství zasílaných zpráv a
softwarem příliš pomalu vyčítajícím z tohoto bufferu příchozí data. (Je až
pozoruhodné, jak se hardwaráři a softwaráři shodují, že problém je to druhé.)
Jak o sběrnici CAN, tak o použité sériové lince se předpokládá, že jsou
spolehlivé, a proto neobsahují v současné implementaci posílané zprávy žádnou
checksum. Není proto možné snadno detekovat narušenou komunikaci a taková
situace proto nesmí ani nastat. Problémům je předcházeno tím, že na robotech
běží real-time varianta Linuxového jádra (Xenomai),
jejíž ovladače sériové linky mají zaručit, že nebudou žádná data ztracena kvůli
příliš malému bufferu a vše bude včas přečteno. Aktuální verze použitého
Xenomai již na soutěži
Field Robot Event netrpěla neduhy, které
sužovaly robota Eduro na
Robot Challenge a na
Eurobotu.
Pro začátek komunikace počítače s bridgem, který již v době spuštění počítače
může dávno běžet a posílat zprávy, je implementována synchronizace v principu
velmi podobná Daisy synchronizaci. Počítač nejprve odešle desetkrát byte 0xFF.
Protože maximální délka CAN zprávy je osm bytů a 0xFF je neplatný začátek
zprávy, může bridge snadno detekovat, že se nejedná o platnou datovou zprávu a
může odpovědět sérií deseti (anebo více) bytů 0xFF. Tuto synchronizaci může
vyvolat řídící program i během činnosti robota, když dokáže (nějak) poznat, že
přijímaná data jsou nesmyslná (např. díky neplatným identifikátorům zpráv).
Protokol Mobů
S nákupem robotických platforem Mob2 na naši fakultu
(MFF UK) nastala potřeba implementace řízení nových
robotů a příležitost zvážit dostupné komunikační postupy a případně omezit
některé z potíží, které nastaly během let od robota Daisy na jiných robotech.
Ačkoli jsme v té době měli zatím jen omezené zkušenosti s roboty s CANem z dílny
RobSys, poznatky z jiného robota s touto sběrnicí
dávaly tušit, že pouze synchronní komunikace zahrnutá v Daisy protokolu není
dostatečná. Pro novou generaci robotů jsme chtěli použít novou generaci
protokolu. Takovou, kterou budeme moct snadno přenést i na budoucí roboty.
Nejprve jsme zvažovali rozsáhlejší používání timeoutů, které by umožnily lepší
detekci narušené komunikace a její resetování. Protože ale naše roboty řídíme
z různých operačních systémů, ukázal se tento přístup implementačně příliš
náročný, ne-li dokonce nemožný. Pokus o přiučení se z jiných robotických systémů
(např. iRobot Roomba Serial
Command Interface) nepřinesl kýžené ovoce. Už Daisy protokol je navržen
podstatně robustněji vzhledem k rušivým vlivům. Pro inspiraci jsme museli sáhnout
do ještě vzdálenější historie komunikace po dnes již vlastně prehistorických
sériových linkách.
V předethernetových dobách byly počítače běžně spojovány null-modemem, což není
nic jiného, než vhodně překřížený kabel spojující RS232 porty počítače. Jedná
se tedy o téměř stejnou situaci, ve které jsme s našimi roboty, a již v té
době musel být přenos dat řešen. Pro naše potřeby se jeví velmi vhodným přenos
paketů v Serial Line Internet Protokol
(RFC1055,
SLIP).
SLIP řeší oddělení paketů (a tím i synchronizaci) vyhrazením speciálního bytu
0xC0. Tento byte je odeslán na konci každého přeneseného paketu a označuje
jeho konec. Aby nedošlo ke špatné interpretaci stejného bytu v datové části,
jsou datové byty s hodnotou 0xC0 nahrazeny speciální dvoubytovou sekvencí, ve
které se 0xC0 nevyskytuje a která je u příjemce zpětně nahrazena původním
0xC0. Příjemce si tak může být jist, že 0xC0 ukončuje paket a následuje paket
další. V případě ztracené značky konce paketů dojde k synchronizaci účastníků
na příštím obdrženém 0xC0.
Drobným, ale podstatným, vylepšením je odeslání 0xC0 i na začátku paketu pro
oddělení právě posílaného paketu od šumových dat, která se před ním mohla
objevit na lince. V lepším případě se šumová data neobjevila a příjemce může
vzniklý prázdný paket rovnou zahodit. V horším případě musí vyšší vrstva
zpracování dat detekovat nekonzistenci paketu. Tuto kontrolu nekonzistence
paketová vrstva neřeší a přenechává tuto úlohu vyšší, IP, vrstvě. V našem
případě však nedochází k přenosu IP datagramů a proto si kontrolu konzistence
musíme zařídit sami. V tomto konkrétním případě je na konci každé zprávy
odeslán kontrolní součet, který je roven celkovému XOR předchozích byte zprávy.
XOR celé zprávy včetně checksum tak nabývá hodnoty 0.
Další změnou oproti Daisy protokolu je asynchronnost nového protokolu. Řídící
software musí očekávat, že může v libovolnou chvíli přijít zpráva od
libovolného zařízení. Zároveň se nesmí spolehnout na to, že na poslaný řídící
pokyn přijde odpověď. Každá strana komunikace musí sama detekovat situaci, kdy
určitá zpráva nedorazila příliš dlouho, pokud to potřebuje (např. že nechodí
řídící signál motorům – mohl vypadnout kabel nebo havarovat software). Program
napsaný s ohledem na uvedené body nemusí tuhnout v timeoutech a čekat na
odpověď, která možná nedorazí.
Popsaný protokol neřeší možnost zahlcení sériové linky. To musí být konkrétně
řešeno podle robota a použitého počítače a operačního systému. Jednou z
možností je real-time operační systém. U školních robotů však nemůžeme klást
předpoklady a požadavky na operační systém, když roboty může řídit každý
student z vlastního notebooku. Proto jsou mobi naprogramováni podle vzoru Daisy
a pravidla „mluviti stříbro, mlčeti zlato.” Robot sám o sobě žádné informace
neposílá. Až když dostane pokyn od počítače, odpovídá (ne ale nutně vždy, ne
nutně jedinou zprávou). Pokud tedy řídící software posílá řídící pokyny s
rozumnou kadencí, i odpovědi chodí ve zpracovatelném rytmu. Toto je už ale
vlastnost konkrétního provedení v tomto okamžiku a ne komunikačního protokolu.
Tímto sice ztratíme velmi přesný přehled o aktuální situaci robota, na druhou
stranu se ale velmi zjednoduší implementace a odpadnou potíže s patchováním,
vlastní kompilací a instalací nestandardního jádra. Přibývá možnost spustit
řízení na libovolném počítači a systému. Data se senzorů běžně beztak obsahují
chyby měření a řídící software se s nimi musí vypořádat. A když už se s chybou
vypořádává, neměl by být takový problém, když je informace setinku sekundy
stará. To je pro naše účely dostatečné.
Závěr
V tomto článku jsem popsal naše zkušenosti s přenosem robotických dat po
sériové lince. Věřím, že uvedené poznatky a popsané postupy pomohou dalším
robotikům v návrhu protokolu pro jejich roboty a ušetří jim spoustu práce,
která by mohla vzniknout při použití špatného řešení. Pokud máte vlastní
zkušenosti a návrhy, se kterými byste se rádi svěřili ostatním, neváhejte se
ozvat pomocí kontaktního formuláře.
Komentáře
2017-11-27, Majo B.
Dnes by som jednoznačně doporučil používať CAN a na nej
CANopen
Opensource nástroje na čítanie tejto zbernice
busmaster
A aj prevodníky CAN <-> USB sú v súčasnosti dobre dostupné.
Hardware-support