Měření rychlosti větru: Počet otáček za čas vs. čas mezi dvěma otáčkami

Pavouk106

  • *****
  • 2 395
    • Zobrazit profil
    • Můj blog
    • E-mail
Zdravím,

jsem tu s docela drsně netypickým dotazem, který ale řeším v Pythonu na RPi, takže vlastně jakožto programátor... ;D

Mám miskový anemometr (kdo neví), který při jedné otáčce jednou sepne kontakt. To snímám v Pythonu na RPi pomocí RPIO (rozpoznávám HIGH/LOW, resp. falling edge).

Jde mi o to, jak naložit s otáčkami. Měl bych si do pole (resp. listu, jsme v Pythonu) ukládat třeba posledních 10 (20, 50?) časů mezi jednotlivými otáčkami (tedy periodu; bavíme se řádově o 20 milisekundách až jednotkách minut, možná déle) a pak udělat průměr NEBO bych měl počítat počet otáček za určitý čas (třeba pět sekund nebo minutu) a pak si z toho spočítat průměr?

První varianta je taková pružnější, mám hodnotu k dispozici vždy (prostě jen udělám průměr hodnot v listu), druhá je zase méně zkreslující (protože když dám jen jednu otáčku za minutu, tak to nebude zkreslené předchozími otáčkami).

Budu z toho tahat průběžná data a ukládat každých pět minut (RRD; tady je lepší druhá varianta), ale budu to mít i na displeji meteostanice (tady je lepší zase první varianta, která dává okamžitá čísla).

Může ještě být třetí varianta, která by vyšla z té první a po určitém čase (třeba 5 sekund? minuta?) vynuluje list (aby při bezvětří vypadla 0).

Ještě dodávám - při rychlosti kolem 80km/h dává anemometr kolem 40 otáček za sekundu... Tak to vzít v úvahu (appendování a přepisování listu a počet jeho prvků tak, aby pokryl nějaký časový interval).

Co myslíte?

Mimochodem: Nárazy větru se prý měří tak, že se vezme nejmenší čas mezi otáčkami za daný čas (tedy nejnižší číslo z listu, pokud bychom brali v úvahu první variantu; v druhé variantě to není úplně jednoduše definovatelné, ale dalo by se to taky v pohodě).


wellczech

Na straně 16 je popsána zajímavá metoda (hledej "These pulse signals are sampled every")
http://www.jma.go.jp/jma/jma-eng/jma-center/ric/Our%20activities/International/CP4-Wind.pdf

Měří počet otáček za čas 0.25s. Vezmou 12 vzorků, ty zprůměrují a říkají tomu okamžitá rychlost, kterou mají každé 3 vteřiny novou.

Když zprůměrují 20x okamžitou rychlost, tak mají rychlost za minutu. Ale pamatují si posledních 10 rychlostí za minutu a z toho teprve dělají průměr.


Pavouk106

  • *****
  • 2 395
    • Zobrazit profil
    • Můj blog
    • E-mail
wellczech: To zní zajímavě. Jen nevím, jestli dokážu dostat rozlišení na 250ms. Resp. interrupt dostávám i 1x za 20ms, ale nevím, jak rychlý je Python a jestli dokážu počítat na tak nízký/rychlý úrovni.

Ale můžu jednoduše sečíst kolik otáček mám za tři sekundy (to bych zobrazoval na meteostanici), ukládat to do listu s 20 položkama (abych pokryl minutu) a minuty si pak ukládat do listu s pěti položkama a až z něj pak spočítat průměrnou rychlost (1x za pět minut).

wellczech

Ten poslední krok s pětiminutovým průměrem bych dělal každou minutu z posledních 5 položek.
V čase 12:05 udělám průměr z časů 12:01, 12:02, 12:03, 12:04 a 12:05.
V čase 12:06 udělám průměr z časů 12:02, 12:03, 12:04, 12:05 a 12:06.

To znamená, že každou minutu mám novou průměrnou rychlost. Rozdíl je v tom, že ten graf je o něco hladší, bez extrémů. Nebo-li, když najednou přestane foukat vítr, tak následující 4 minuty bude průměrná rychlost klesat a 0 uvidím až za 5 minut.

jmeno

v rychlosti pythonu urcite problem nebude :)


pb.

wellczech: To zní zajímavě. Jen nevím, jestli dokážu dostat rozlišení na 250ms. Resp. interrupt dostávám i 1x za 20ms, ale nevím, jak rychlý je Python a jestli dokážu počítat na tak nízký/rychlý úrovni.

Neznám detailně Rpi, ale nejde tam namuxovat nějaký timer, kterým by se dal měřit čas o několik řádů přesněji? Pracuji s BeagleBone Black, tam jsou timery na konektoru tuším čtyři, případně bych použil PRU s časovým rozlišením v řádu desítek nanosekund. PRU je realtime procesor v ARM procesoru BeagleBone, který se dá programovat "instrukce po instrukci" a umožňují velmi přesné časování.

Pokud budete měřit čas v Pythonu, budete narážet na obrovské nepředvídatelné nepřesnosti, když se systém rozhodne něco zalogovat, poslat po síti, odpovědět na webový požadavek a podobně.




Youda

Se s tim seres.
Tyhle typy udaju se meri klouzavym prumerem, stejne jako je v linuxu average load avg 1, 5 a 15 minut.

Kratsi avg zachyti poryvy, delsi meri prumerny vitr.

pb.

Se s tim seres.

Tihle se s tím nemazali (tlak jak v oku hurikánu):
https://www.in-pocasi.cz/meteostanice/stanice.php?stanice=roznov

Tyhle typy udaju se meri klouzavym prumerem, stejne jako je v linuxu average load avg 1, 5 a 15 minut.

Problém bych viděl jinde:
20, 30, 25, 40, 60, 20, 3350 (Rpi ukládá na SD kartu), 30, 20...

Při měření času běžnými prostředky Linuxu jsou podobné excesy neodhalitelné.

Lol Phirae

Tihle se s tím nemazali (tlak jak v oku hurikánu):
https://www.in-pocasi.cz/meteostanice/stanice.php?stanice=roznov

Tos asi ještě dole minul kolonku nejnižší tlak. Jen nevím, jak se ty tisíce mrtvých povedlo ututlat.  ;D ;D ;D

Pavouk106

  • *****
  • 2 395
    • Zobrazit profil
    • Můj blog
    • E-mail
Je to samozřejmě hobby projekt, takže mi nejde až tak o úplně přesné časování, spíš o něco přijatelně obtížně napsatelného :-)

RPi nebude ukládat na kartu, ale bude odpovídat na webové požadavky (předání naměřených hodnot). Ve chvíli předání se předávají dříve naměřené hodnoty, takže mi ani tak nevadí případně lehké zpoždění v měření/vynechání několika otáček. Další dotaz na data přijde později a to už to bude zase "vyžehlené" v průměru.

Klouzavej průměr je to, co hledám. Jde mi víceméně ale o nějaké časy, které použít.Když se navalí pořádná bouřka, která ale potrvá jen 20 minut, tak 1/5/15 mi bude docela k ničemu. Tam by bylo vhodnější mít kratší... Možná to udělám tak, jak jsem psal výše 3 sekundy/1 minuta/5 minut. 3 sekundy budou poryv/náraz, 1 minutu možná v logování vynechám a 5 minut bude dlouhodobá ustálená rychlost. Možná ale udělám dlouhodoubou už z jedné minuty.

Jenda

20, 30, 25, 40, 60, 20, 3350 (Rpi ukládá na SD kartu), 30, 20...

Při měření času běžnými prostředky Linuxu jsou podobné excesy neodhalitelné.

Zápis na kartu nezastaví ostatní thready a RPi je čtyřjádro. A pokud to potřebuješ ještě lépe, tak můžeš pomocí parametru isolcpus kernelu a následného taskset vyhradit jedno jádro tvému programu.

Teoreticky by to mělo jít i s interrupty, ale nezkoušel jsem to:
[cite]
Myslím, že i non-RT kernel má /proc/irq/$IR­Q/smp_affinity, kam lze zapsat CPU mask. Kernel s RT-Preempt navíc vytváří pro každý interrupt handler vlastní kernel thread, kterému lze nastavit RT scheduling class a RT prioritu přes chrt, a případně na něj použít taskset (to ale možná není ani potřeba, když už je nastaveno smp_affinity).

Linux má v tomhle ale pořád ještě rezervy, jeden z největších problémů je, že na všech CPU (i těch vyjmenovaných v isolcpus) se spouští nějaké servisní operace s periodou CONFIG_HZ. Nějakou dobu je k dispozici NO_HZ_FULL option, ale to si podle našich zkušeností moc nerozumí s RT-Preempt, a stejně to funguje jen když je na daném CPU jen jeden thread - viz https://lwn.net/Articles/549580/. Kromě toho pomáhá ještě kernel option rcu_nocbs=<cpu­list>. Na ARM Cortex-A9 se nám ještě osvědčila konfigurace L2 cache CPU locking, tedy pevné vyhrazení části L2 cache pro CPU s realtime tasky. Jak moc je tohle zdokumentované u RPi jsem zatím nezkoumal. Ta izolace ale pořád není úplně dokonalá, zejména při vytváření nových procesů na non-realtime CPU dochází k drobnému "zakopnutí", jehož příčina mi zatím není úplně jasná, možná něco s TLB.
[/cite]

pb.

Je to samozřejmě hobby projekt, takže mi nejde až tak o úplně přesné časování, spíš o něco přijatelně obtížně napsatelného :-)

To je mi celkem jasné, že jde o hobby projekt. Takových mám taky spoustu. Přišlo by mi však škoda toho nevyužít nenaučit se nové techniky, porvat se nějak s tím, že běžný Linux a realtime aplikace nejdou úplně dohromady.

U mě mnoho takových projektů později skončí v komerčním nasazení. Tam už by taková drobnost mohla být hodně nepříjemná.

Pavouk106

  • *****
  • 2 395
    • Zobrazit profil
    • Můj blog
    • E-mail
20, 30, 25, 40, 60, 20, 3350 (Rpi ukládá na SD kartu), 30, 20...

Při měření času běžnými prostředky Linuxu jsou podobné excesy neodhalitelné.

Zápis na kartu nezastaví ostatní thready a RPi je čtyřjádro. A pokud to potřebuješ ještě lépe, tak můžeš pomocí parametru isolcpus kernelu a následného taskset vyhradit jedno jádro tvému programu.
Běží to na Pi Zero W... Jsem jaksi nenapsal... Nicméně tam jede jen jeden Python skript a jeden HTTP server (Apache). Pak základní služby systému (NTP, SSH, ...), nic víc. Pokud mi jednou za měsíc zrovna nevyjde výpočet (něco se pozastaví kvůli něčemu jinýmu) a vysype mi to nějakou blbost, svět se nezboří.

pb.: Pokud by to mělo být opravdu RT a bez zpoždění, vyrobím to s Arduinem, které by nic jiného na práci nemělo. Chci to ale mít cenově dostupné a uživatelsky přívětivé (tzn. neřeším spojení se "sběračem dat", dodatečné úpravy kódu a jeho složité nahrávání přes kabel apod.). Že mi někde něco bude žrát 1W mi nevadí (Arduino, resp. možná i ATTiny by ušetřilo cca 90% nákladů na provoz, ale v absolutních číslech je to už jedno).

Kit

pb.: Pokud by to mělo být opravdu RT a bez zpoždění, vyrobím to s Arduinem, které by nic jiného na práci nemělo. Chci to ale mít cenově dostupné a uživatelsky přívětivé (tzn. neřeším spojení se "sběračem dat", dodatečné úpravy kódu a jeho složité nahrávání přes kabel apod.). Že mi někde něco bude žrát 1W mi nevadí (Arduino, resp. možná i ATTiny by ušetřilo cca 90% nákladů na provoz, ale v absolutních číslech je to už jedno).

ATtiny by na tuto úlohu v pohodě stačilo, při připojení na USB (raději přes hub) je vyřešeno napájení i přenos dat.

aaa158

  • ***
  • 238
    • Zobrazit profil
    • E-mail
Ja by som to samploval agresivnejsie do rrd. rrdtool ma rrdcached demona ktory sa da nastavit aby vykonaval flush kazdych x sekund / minut / ... tj riesi problem casteho zapisu na sd kartu.