Ho imparato a mie spese che non tutte le batterie LiPo hanno la polarita' connessa nello stesso modo al connettore JST
Come si vede nella foto sottostante una LiPo e' connessa in modo corretto ad una Arduino MKR (positivo a sinistra) Nella stessa foto si vede il connettore di un'altra batteria con positivo a destra ...e meno male che non si' bruciata la scheda
In ogni caso i connettori JST con un po' di pazienza di possono smontare ed invertire i cavi
Avevo la necessita' di unire due file csv (misura di tempo; misura del sensore) ma i due sensori hanno avuto dei fermi per cui non era sufficiente mettere le colonne affiancate ed era necessaria una inner join (ma sulla macchine di lavoro non ho accesso un sql server) ..sono oltre 85000 dati quindi e' escluso fare a mano
Uno dei problemi maggiori dell'uso dei tag aruco in esterno per misurare distanze e' che le condizioni di illuminazione solare sono molto variabili e la compressione jpg completa l'opera aggiungendo rumore su rumore
Per cercare di limitare il problema ho provato a fare image stacking sovrapponendo 8 foto (una ogni ora dalle 09 alle 16) con lo script al link https://github.com/maitek/image_stacking ed applicando il programma visto qui
Il miglioramento non e' trascurabile perche' la standard deviation e' passata
3.1 m => da 0.19% a 0.16% (0.5 cm)
5.4 m => da 0.35% a 0.28% (1.5 cm)
7.6 m => da 0.71% a 0.38% (2.8 cm)
9.6 m => da 0.5% a 0.41% (4.8 cm)
import os import cv2 import numpy as np from time import time
# Align and stack images with ECC method # Slower but more accurate def stackImagesECC(file_list): M = np.eye(3, 3, dtype=np.float32)
first_image = None stacked_image = None for file in file_list: image = cv2.imread(file,1).astype(np.float32) / 255 print(file) if first_image is None: # convert to gray scale floating point image first_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) stacked_image = image else: # Estimate perspective transform s, M = cv2.findTransformECC(cv2.cvtColor(image,cv2.COLOR_BGR2GRAY), first_image, M, cv2.MOTION_HOMOGRAPHY) w, h, _ = image.shape # Align image to first image image = cv2.warpPerspective(image, M, (h, w)) stacked_image += image
if first_image is None: # Save keypoints for first image stacked_image = imageF first_image = image first_kp = kp first_des = des else: # Find matches and sort them in the order of their distance matches = matcher.match(first_des, des) matches = sorted(matches, key=lambda x: x.distance)
src_pts = np.float32( [first_kp[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2) dst_pts = np.float32( [kp[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)
Usando gli Aruco tag in ambiente esterno con illuminazione solare a diverse ore e in diversi periodi dell'anno ho trovato un errore nella stima della distanza tra due tag compresi tra 0.7% e 1.3% della distanza misurata. La domanda e' stata: e' possibile ridurre l'errore ?
Ho provato ad applicare il filtro Kalman per condizioni statiche (le distanze tra i tag nel tempo non sono variate) usando usando il codice a questo indirizzo
Nel grafico sottostante i punti blu sono i dati non filtrati, in linea continua blu i dati filtrati, in linea rossa il valore reale della misura di distanza
questo il codice impiegato con modestissime modifiche rispetto a quello di esempio
import numpy as np import matplotlib.pyplot as plt import pandas as pd
def kalman_1d(x, P, measurement, R_est, Q_est): x_pred = x P_pred = P + Q_est K = P_pred / (P_pred + R_est) x_est = x_pred + K * (measurement - x_pred) P_est = (1 - K) * P_pred return x_est, P_est
def plot_1d_comparison(measurements_made, estimate, true_value, axis): axis.plot(measurements_made ,'k+' ,label='measurements' ,alpha=0.3) axis.plot(estimate ,'-' ,label='KF estimate') if not isinstance(true_value, (list, tuple, np.ndarray)): # plot line for a constant value axis.axhline(true_value ,color='r' ,label='true value', alpha=0.5) else: # for a list, tuple or array, plot the points axis.plot(true_value ,color='r' ,label='true value', alpha=0.5) axis.legend(loc = 'lower right') axis.set_title('Estimated position vs. time step') axis.set_xlabel('Time') axis.set_ylabel('$x_t$')
def plot_1d_error(estimated_error, lower_limit, upper_limit, axis): # lower_limit and upper_limit are the lower and upper limits of the vertical axis axis.plot(estimated_error, label='KF estimate for $P$') axis.legend(loc = 'upper right') axis.set_title('Estimated error vs. time step') axis.set_xlabel('Time') axis.set_ylabel('$P_t$') plt.setp(axis ,'ylim' ,[lower_limit, upper_limit])
#11 5.38 #15 3.39 #25 7.46 #40 4.26 mu = 4.26 # Actual position R = 0.1 # Actual standard deviation of actual measurements (R) # Generate measurements #n_measurements = 1000 # Change the number of points to see how the convergence changes #Z = np.random.normal(mu, np.sqrt(R), size=n_measurements) Z = df[df.columns[2]].to_numpy() # Estimated covariances Q_est = 1e-4 R_est = 2e-2 # initial guesses x = 5.1 # Use an integer (imagine the initial guess is determined with a meter stick) P = 0.04 # error covariance P KF_estimate=[] # To store the position estimate at each time point KF_error=[] # To store estimated error at each time point for z in Z: x, P = kalman_1d(x, P, z, R_est, Q_est) KF_estimate.append(x) KF_error.append(P)