Měření nízké rychlosti z enkodérů
Re: Měření nízké rychlosti z enkodérů
Já zatím došel k tomu že zkusím Kalman filter co bude udržovat odhad rychlosti (a pozice, v podstatě přesně totéž co tenhle příklad z Wikipedie) a podle toho odhadu řídit PWM pro ten motor. Už jsem to nějak začal klohnit, snad se to podaří dotáhnout o víkendu. Dám pak vědět jak to funguje.
Re: Měření nízké rychlosti z enkodérů
Tak se mi ten víkend nějak protáhnul 
Docela dost jsem s tím experimentoval, Kalman filter moc dobře nefungoval, měl pomalé reakce.
Nakonec jsem došel k tomuhle:
1. Vzorkuju na pravidelném intervalu (100Hz)
2. Z rozdílů mezi po sobě jdoucími měřeními enkodéru počítám "hrubou" rychlost.
3. Hrubé rychlosti cpu do kruhového bufferu (max 64 položek)
4. Skrz rychlosti v tom bufferu prokládám metodou nejmenších čtverců přímku
5. Dokud root mean squared chyba toho proložení je přes nějakou mez, tak zahazuju nejstarší položku v bufferu a goto 4.
Tenhle postup poskytuje odhad rychlosti a zrychlení, pokud robot jede konstantním zrychlením, tak se to vyhlazuje z posledních 64 měření a má to slušnou přesnost i v malých rychlostech.
Krok 5 způsobuje že jakmile ta historie začne být dramatičtější, tak se velice rychle zahodí a počítá se jen z pár posledních měření, takže to má i slušně rychlou reakci na změnu režimu.
Všechny kroky jsou v O(1), ale v 5. se algoritmus může zacyklit a vymazat až celou historii (O(n)). Ale protože aby něco smazal, tak to tam musel předtím přidat, tak amortizovaná složitost je pořád O(1).
Pokud by to někoho zajímalo, tak tady je kód:
- EncoderObserver.h
- EncoderObserver.cpp
- unit test
V unit testech to reaguje moc pěkně, při krátkém testování na stole to vypadalo taky ok.
Chtěl jsem to trochu důkladněji otestovat na nějakém náročnějším ježdění a se statistikami, ale bohužel mi utekl magický kouř a až mi z číny přivezou nový, tak s ním rovnou dostanu i ty vyšší převodové poměry a tenhle druh triků už nebudu tolik potřebovat.

Docela dost jsem s tím experimentoval, Kalman filter moc dobře nefungoval, měl pomalé reakce.
Nakonec jsem došel k tomuhle:
1. Vzorkuju na pravidelném intervalu (100Hz)
2. Z rozdílů mezi po sobě jdoucími měřeními enkodéru počítám "hrubou" rychlost.
3. Hrubé rychlosti cpu do kruhového bufferu (max 64 položek)
4. Skrz rychlosti v tom bufferu prokládám metodou nejmenších čtverců přímku
5. Dokud root mean squared chyba toho proložení je přes nějakou mez, tak zahazuju nejstarší položku v bufferu a goto 4.
Tenhle postup poskytuje odhad rychlosti a zrychlení, pokud robot jede konstantním zrychlením, tak se to vyhlazuje z posledních 64 měření a má to slušnou přesnost i v malých rychlostech.
Krok 5 způsobuje že jakmile ta historie začne být dramatičtější, tak se velice rychle zahodí a počítá se jen z pár posledních měření, takže to má i slušně rychlou reakci na změnu režimu.
Všechny kroky jsou v O(1), ale v 5. se algoritmus může zacyklit a vymazat až celou historii (O(n)). Ale protože aby něco smazal, tak to tam musel předtím přidat, tak amortizovaná složitost je pořád O(1).
Pokud by to někoho zajímalo, tak tady je kód:
- EncoderObserver.h
- EncoderObserver.cpp
- unit test
V unit testech to reaguje moc pěkně, při krátkém testování na stole to vypadalo taky ok.
Chtěl jsem to trochu důkladněji otestovat na nějakém náročnějším ježdění a se statistikami, ale bohužel mi utekl magický kouř a až mi z číny přivezou nový, tak s ním rovnou dostanu i ty vyšší převodové poměry a tenhle druh triků už nebudu tolik potřebovat.