Valore di riferimento e filtraggio, problema numerico?
Inviato: 5 ott 2021, 10:34
Mi capita una cosa incredibile, sicuramente sto sbagliando qualcosa ma non capisco cosa.
Ho un accelerometro, con l'asse x orizzontale, usato come inclinometro, facente parte di un modellino funzionante di robot ciclista.
Esso invia la sua lettura in formato Integer con segno a 16 bit a una variabile ax, alla velocità dettata dal protocollo I2C cioè probabilmente poche volte ogni millisecondo ma ciò non dovrebbe influire.
Il Main Program, all'accensione, prende una decina di letture ax a breve intervallo di tempo e ne memorizza la media in una variabile Floating axrf. Questa rappresenta la lettura di riferimento, teoricamente sarebbe zero ed avrà comunque un valore piccolo. Infatti l'accensione deve avvenire con la bici ferma in posizione di equilibrio.
Espletata questa funzione, il main program elabora ax ogni 0,4 msec (forse è un ciclo troppo breve ma dobbiamo considerare che il modellino è piccolo e leggero).
Detta elaborazione prevede per prima cosa che ax venga filtrata con una costante di tempo pari a 0,4 sec e qui avviene il mistero.
Il programma originale filtra prima ax e poi sottrae il valore di riferimento axrf dal valore filtrato, infine moltiplica per un modesto guadagno di 1.25. In tal modo il modellino funziona (con qualche pendolazione ma questo è un altro discorso).
Per ripulire il programma ho provato a sottrarre invece ogni volta axrf dal valore ax e poi filtrare, ma così la bici inesorabilmente cade.
Non è un problema di casting o di confusione fra formati integer e floating in quanto il compilatore C effettua automaticamente le conversioni e poi mi sono accertato che, facendo le conversioni a parte, non cambia nulla.
La versione originale è questa:
int ax; float axf, axrf, out;
filter://ogni 0,4 msec
axf=ax*.001+axf*.999;
out=(axf-axrf)*1.25;
La versione modificata è questa:
int ax; float axf, axrf, out, prova;
filter://ogni 0,4 msec
prova=ax-axrf;
axf=prova*.001+axf*.999;
out=axf*1.25;
Che possa crearsi un problema numerico non lo vedo, e poi sarebbe una notizia alquanto preoccupante per chi programma dei calcoli tecnici.
Ho un accelerometro, con l'asse x orizzontale, usato come inclinometro, facente parte di un modellino funzionante di robot ciclista.
Esso invia la sua lettura in formato Integer con segno a 16 bit a una variabile ax, alla velocità dettata dal protocollo I2C cioè probabilmente poche volte ogni millisecondo ma ciò non dovrebbe influire.
Il Main Program, all'accensione, prende una decina di letture ax a breve intervallo di tempo e ne memorizza la media in una variabile Floating axrf. Questa rappresenta la lettura di riferimento, teoricamente sarebbe zero ed avrà comunque un valore piccolo. Infatti l'accensione deve avvenire con la bici ferma in posizione di equilibrio.
Espletata questa funzione, il main program elabora ax ogni 0,4 msec (forse è un ciclo troppo breve ma dobbiamo considerare che il modellino è piccolo e leggero).
Detta elaborazione prevede per prima cosa che ax venga filtrata con una costante di tempo pari a 0,4 sec e qui avviene il mistero.
Il programma originale filtra prima ax e poi sottrae il valore di riferimento axrf dal valore filtrato, infine moltiplica per un modesto guadagno di 1.25. In tal modo il modellino funziona (con qualche pendolazione ma questo è un altro discorso).
Per ripulire il programma ho provato a sottrarre invece ogni volta axrf dal valore ax e poi filtrare, ma così la bici inesorabilmente cade.
Non è un problema di casting o di confusione fra formati integer e floating in quanto il compilatore C effettua automaticamente le conversioni e poi mi sono accertato che, facendo le conversioni a parte, non cambia nulla.
La versione originale è questa:
int ax; float axf, axrf, out;
filter://ogni 0,4 msec
axf=ax*.001+axf*.999;
out=(axf-axrf)*1.25;
La versione modificata è questa:
int ax; float axf, axrf, out, prova;
filter://ogni 0,4 msec
prova=ax-axrf;
axf=prova*.001+axf*.999;
out=axf*1.25;
Che possa crearsi un problema numerico non lo vedo, e poi sarebbe una notizia alquanto preoccupante per chi programma dei calcoli tecnici.
