Tengo un sistema que está muestreando dos ondas sinusoidales de 50Hz a 1kHz. ¿Cuál es la mejor manera de estimar el cambio de fase entre los dos?
Las mediciones son algo ruidosas y el período de muestreo no es muy uniforme. Conozco los tiempos de muestra a alta resolución, pero no puedo controlarlos para que estén espaciados uniformemente. El cambio de fase debe estimarse en partes de datos que cubren aproximadamente un segundo.
El ruido de medición hace que el método de cruce por cero no sea confiable; si el ruido hace que una señal medida cruce cero dos veces en un cruce "real" de cero, el algoritmo se rompe un poco.
Actualmente estoy haciendo algo como esto (código de Python):
t, v, a = [NumPY arrays of samples]
p_inst = v * a
s = numpy.sign(p_inst)
s_avg = numpy.trapz(s, x=t) / (t[-1] - t[0])
shift_fraction = s_avg / 2 + 0.5
shift_angle = (1 - shift_fraction) * numpy.pi
Aquí s
es el signo del producto de las dos ondas sinusoidales. Encontrar el promedio de esto usando numpy.trapz
da un valor que representa con qué frecuencia las dos señales tienen el mismo signo, con 1 que significa "todo el tiempo", -1 que significa "ninguna de las veces" y cero que significa "la mitad del tiempo" ". Esto se convierte a una fracción del tiempo en que las señales tienen el mismo signo ( shift_fraction
) y se convierte a un ángulo de cambio de fase.
El mayor problema con esto es que no te dice si la diferencia de fase es adelantada o retrasada.
¿Alguien tiene un método mejor?
Editar Para aquellos que sugieren encontrar el pico de correlación, ¿tengo razón al pensar que, con 20 muestras por ciclo, ese método limitará necesariamente la resolución de la estimación a 18 grados? ¿Qué pensarías en lugar de calcular numpy.correlate(v, -a)
, encontrar el primer cruce por cero y luego interpolar para estimar el punto cero real? Creo que, para las señales sinusoidales, la correlación también debería ser sinusoidal, por lo que la aproximación de ángulo pequeño debería hacer que la interpolación sea razonablemente buena.
¿Puede alguien comparar los métodos de correlación y demodulación?
Edición adicional Y, para aquellos que proporcionan el método de demodulación, tengo razón al pensar que si no me importa la diferencia de fase real, solo el factor de potencia, puedo hacer esto:
s = sin(t * 2 * pi * f)
c = sin(t * 2 * pi * f)
a_s_d = s * a
v_s_d = s * v
a_c_d = c * a
v_c_d = c * v
s_a = numpy.trapz(a_s_d, t)
c_a = numpy.trapz(a_c_d, t)
s_v = numpy.trapz(v_s_d, t)
c_v = numpy.trapz(v_c_d, t)
# cos ( a - b ) = cos a * cos b + sin a * sin b
power_factor = c_a * c_v + s_a * s_v
¿O no puedo confiar en 0 < s_a, c_a, s_v, c_v < 1
?