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.
Valore di riferimento e filtraggio, problema numerico?
0
voti
[2] Re: Valore di riferimento e filtraggio, problema numerico?
Non saprei individuare l'errore di troncamento.
Posso suggerire solo qualche punto di indagine:
Se riformuli come axf=(prova-axf)*.001+axf; cambia qualcosa?
Campionare ogni 0,4 ms per realizzare una costante di 0,4 secondi richiede dividere l'errore per 1000, forse si crea un errore di troncamento.
Nyquist richiede di campionare ad almeno il doppio, ma non 1000 volte tanto.
Eseguire i calcoli una volta ogni 10 e dividere poi solo per 100 ?

Ho meditato: è un errore di troncamento.
Anche i numeri in floating point hanno una risoluzione limitata.
Nella versione modificata l'errore è maggiore:
Supponi
axrf = 100
e il valore di ax variabile prossimo a 110, lo filtri con costante di tempo e otterrai
supponiamo 110
poi sottrai 100, ottieni 10.
Nella versione modificata ottieni:
prova=ax-axrf = 110 - 100 = 10
filtrando, per errore di troncamento su un valore di 10 avrai zero
Posso suggerire solo qualche punto di indagine:
Se riformuli come axf=(prova-axf)*.001+axf; cambia qualcosa?
Campionare ogni 0,4 ms per realizzare una costante di 0,4 secondi richiede dividere l'errore per 1000, forse si crea un errore di troncamento.
Nyquist richiede di campionare ad almeno il doppio, ma non 1000 volte tanto.
Eseguire i calcoli una volta ogni 10 e dividere poi solo per 100 ?

Ho meditato: è un errore di troncamento.
Anche i numeri in floating point hanno una risoluzione limitata.
Nella versione modificata l'errore è maggiore:
Supponi
axrf = 100
e il valore di ax variabile prossimo a 110, lo filtri con costante di tempo e otterrai
supponiamo 110
poi sottrai 100, ottieni 10.
Nella versione modificata ottieni:
prova=ax-axrf = 110 - 100 = 10
filtrando, per errore di troncamento su un valore di 10 avrai zero
0
voti
[3] Re: Valore di riferimento e filtraggio, problema numerico?
MarcoD ha scritto:Se riformuli come axf=(prova-axf)*.001+axf; cambia qualcosa?
Non cambia.
Ho anche pensato che il valore iniziale di axf potrebbe avere un ruolo quindi ho provato ad inizializzarlo sia axf=0 che axf=axrf ma non pare che cambi nulla, e anche questo è un po' strano perché dovrebbe invece influire sul transitorio iniziale del filtro.
La situazione poi è complicata ma spero di avere isolato correttamente il problema.
0
voti
[5] Re: Valore di riferimento e filtraggio, problema numerico?
MarcoD ha scritto: è un errore di troncamento
Accetto questa spiegazione per esclusione, forse potrei dire per disperazione, ma non è che mi convinca del tutto.
(Poi ci sono altre stranezze in quanto il programma originale filtrava anche la lettura di un giroscopio con la stessa costante di tempo e poi miscelava le uscite dei due filtri, adesso ho pensato di miscelare prima e poi filtrare per risparmiare due moltiplicazioni floating, ma anche questo non funziona bene.
Il programma originale lo ho fatto io andando in cerca soltanto della massima garanzia di funzionamento, adesso che vorrei razionalizzarlo e magari ottenere un risultato ancora migliore sono tornato in alto mare.)
0
voti
[6] Re: Valore di riferimento e filtraggio, problema numerico?
EcoTan ha scritto:ho pensato di miscelare prima e poi filtrare per risparmiare due moltiplicazioni floating, ma anche questo non funziona bene
Dopo centinaia di prove ho sistemato il modellino e mi sono convinto di quanto segue:
In un calcolo iterativo con diversi loop di regolazione annidati e nodi sommatori anche in cascata fra loro, può avvenire che alcune variabili lentamente divergano mentre il sistema apparentemente continua a funzionare perché altre variabili creano una compensazione, divergendo anch'esse, finché qualcosa va in overflow o in saturazione e il sistema salta. Questo inconveniente ha delle cause un po' misteriose ma non dovrebbe crearsi, credo, se ciascuna parte dell'algoritmo simula correttamente qualcosa di fisicamente reale.
Mi rendo conto che il mio discorso è un po' vago, ma in sostanza è ciò che mi è capitato.
0
voti
[7] Re: Valore di riferimento e filtraggio, problema numerico?
Mi sembra un po' singolare. Se fosse così anche la versione precedente fallirebbe.
Stai usando 2 formule diverse, il risultato non può essere che diverso.
Stai usando 2 formule diverse, il risultato non può essere che diverso.
0
voti
[8] Re: Valore di riferimento e filtraggio, problema numerico?
Il punto è che due calcoli, che dal punto di vista algebrico sarebbero equivalenti, dopo migliaia di iterazioni creano un comportamento diverso. La cosa viene esasperata nel caso della bici perché lì la differenza si rende evidente, o cade o non cade. Non è che sono troppo sicuro ma intanto mi soddisfa.
0
voti
[10] Re: Valore di riferimento e filtraggio, problema numerico?
Hai considerato che prima di entrare nel loop filter: possiamo impostare inizialmente axf=axrf ?
Comunque la questione del primo post è superata dagli sviluppi seguenti, che non ho esposto in dettaglio.
Comunque la questione del primo post è superata dagli sviluppi seguenti, che non ho esposto in dettaglio.

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)



