universidad nacional de ingenierÍa -...

167
UNIVERSIDAD NACIONAL DE INGENIERÍA FACULTAD DE INGENIERÍA ELÉCTRICA Y ELECTRÓNICA ANÁLISIS E IMPLEMENTACIÓN DE UN ALGORITMO DE MITIGACIÓN DEL EFECTO DOPPLER PARA RECEPTORES GPS, EN UN ARREGLO DE COMPUERTAS LÓGICAS PROGRAMABLES EN CAMPO (FPGA), UTILIZANDO EL PROCESADOR SOFT LEON TESIS PARA OPTAR EL TÍTULO PROFESIONAL DE: INGENIERO DE TELECOMUNICACIONES PRESENTADO POR: JEAN GERARD LEÓN HUACA PROMOCIÓN 2011-I LIMA – PERÚ 2015

Upload: dodang

Post on 21-Oct-2018

216 views

Category:

Documents


0 download

TRANSCRIPT

UNIVERSIDAD NACIONAL DE INGENIERÍA

FACULTAD DE INGENIERÍA ELÉCTRICA Y ELECTRÓNICA

ANÁLISIS E IMPLEMENTACIÓN DE UN ALGORITMO DE MITIGACIÓN DEL EFECTO DOPPLER PARA RECEPTORES GPS, EN UN ARREGLO DE

COMPUERTAS LÓGICAS PROGRAMABLES EN CAMPO (FPGA), UTILIZANDO EL PROCESADOR SOFT LEON

TESIS

PARA OPTAR EL TÍTULO PROFESIONAL DE:

INGENIERO DE TELECOMUNICACIONES

PRESENTADO POR:

JEAN GERARD LEÓN HUACA

PROMOCIÓN

2011-I

LIMA – PERÚ 2015

ANÁLISIS E IMPLEMENTACIÓN DE UN ALGORITMO DE MITIGACIÓN DEL EFECTO DOPPLER PARA

RECEPTORES GPS, EN UN ARREGLO DE COMPUERTAS LÓGICAS PROGRAMABLES EN CAMPO (FPGA),

UTILIZANDO EL PROCESADOR SOFT LEON

Dedicatoria:

Agradezco a mis seres queridos como a

mis padres y hermanos. De la misma

manera agradezco el apoyo

proporcionados por mi asesor y el Dr.

Emmanuel Boutillón.

SUMARIO

La presente tesis trata sobre el análisis e implementación de un algoritmo de mitigación del

efecto Doppler para receptores GPS, en un Arreglo de Compuertas Lógicas Programables

en Campo (FPGA), utilizando el procesador Soft LEON, el cual ha sido realizado en base a

los conocimientos actuales sobre los algoritmos de seguimiento. Este algoritmo sigue la

señal adquirida y de esa forma realiza una correcta demodulación de la señal.

Este algoritmo consta de varios filtros de seguimiento de fase, frecuencia Doppler y retardo

del código PRN lo cual permite procesar la información y correge las señales recibidas.

Finalmente, la señal corregida es demodulada y es usada para la detección de la posición

del receptor orbitando en el espacio.

La implementación del algoritmo es fácilemente mejorada, debido a su programación en

lenguaje C, y como está embebido en un procesador para uso aero espacial, este tiene

robustez en caso de falla en el espacio.

ÍNDICE SUMARIO...…......................................................................................................................v

CAPÍTULO I

INTRODUCCIÓN ............................................................................................................... 1

1.1 Planteamiento del problema de tesis ...................................................................... 1

1.2 Objetivo general ....................................................................................................... 2

1.3 Objetivos específicos ................................................................................................ 2

1.4 Justificación .............................................................................................................. 2

1.5 Alcances y delimitaciones ........................................................................................ 3

1.6 Recapitulación .......................................................................................................... 3

CAPÍTULO II CONCEPTOS DE SISTEMA DE POSICIONAMIENTO GLOBAL ............................ 5

2.1 Introducción ............................................................................................................. 5

2.2 Componentes de un sistema GNSS ........................................................................ 5

2.3 Posicionamiento del sistema .................................................................................... 6

2.4 Fundamentos de espectro ensanchado ................................................................... 7

2.5 Señales del Sistema GPS ......................................................................................... 8

2.5.1 GPS L1 C/A .............................................................................................................. 8

2.5.2 GPS L5 .................................................................................................................... 10

2.5.3 Generación de los códigos C/A para GPS ............................................................ 10

2.6 Señales del Sistema Galileo ................................................................................... 10

2.6.1 Galileo E1 OS ......................................................................................................... 11

2.6.2 Galileo E5a ............................................................................................................. 11

2.6.3 Densidad Espectral de Potencia ........................................................................... 12

vii

2.7 Desafíos de la implementación en el espacio de un receptor GNSS .................. 12

2.7.1 Efecto Doppler ....................................................................................................... 12

2.7.2 Multitrayecto .......................................................................................................... 14

2.7.3 Interferencia ........................................................................................................... 14

2.7.4 Centelleo ionosférico .............................................................................................. 15

2.8 Procesamiento de la señal GNSS recibida ........................................................... 16

2.8.1 Principio de adquisición ........................................................................................ 17

2.8.2 Principio de seguimiento ....................................................................................... 18

CAPÍTULO III

ANALISIS DEL ALGORITMO DE MITIGACION DEL EFECTO DOPPLER PARA GPS PROPUESTO ................................................................................................ 21

3.1 Introducción ........................................................................................................... 21

3.2 Filtro de entrada .................................................................................................... 21

3.3 Correlación e integración ...................................................................................... 21

3.4 Lazo de seguimiento en fase y frecuencia ............................................................ 23

3.4.1 Discriminador de fase ............................................................................................ 24

3.4.2 Discriminador de frecuencia ................................................................................. 25

3.4.3 Filtro de lazo ........................................................................................................... 26

3.4.4 Oscilador controlado digitalmente (NCO) .......................................................... 27

3.5 Lazo de seguimiento del retardo de código ......................................................... 28

3.5.1 Discriminador de código ....................................................................................... 29

3.5.2 Factor de escala ...................................................................................................... 30

3.5.3 Oscilador controlado digitalmente (NCO) ........................................................... 31

3.6 Generador de códigos réplica ............................................................................... 31

3.7 Detectores de bloqueo ............................................................................................ 31

3.7.1 Detector de bloqueo de fase .................................................................................. 32

3.7.2 Detector de bloqueo de código .............................................................................. 32

3.7.3 Detector de bloqueo falso ...................................................................................... 34

viii

3.8 Detección de la transición de los bits de datos .................................................... 35

3.9 Demodulación de la señal ...................................................................................... 36

CAPÍTULO IV

IMPLEMENTACIÓN DEL ALGORITMO DE MITIGACIÓN DEL EFECTO DOPPLER PARA GPS EN UN FPGA ............................................................................ 37

4.1 Introducción ........................................................................................................... 37

4.2 El Procesador LEON ............................................................................................. 37

4.3 Arquitectura del Procesador LEON .................................................................... 39

4.3.1 El procesador LEON con arquitectura SPARC V8 ........................................... 39

4.3.2 Interfaces de memoria ........................................................................................... 39

4.3.3 Registro de estado del AHB .................................................................................. 40

4.3.4 Enlaces SpaceWire ................................................................................................. 40

4.3.5 Unidad temporizadora .......................................................................................... 40

4.3.6 Control de interrupción ........................................................................................ 40

4.3.7 UART ...................................................................................................................... 40

4.3.8 Puerto entrada/salida de propósito general ........................................................ 40

4.3.9 Ethernet .................................................................................................................. 41

4.3.10 Controlador de Área de Red (CAN-2.0) .............................................................. 41

4.3.11 Controlador VGA .................................................................................................. 41

4.3.12 Interfaz de teclado PS/2 ......................................................................................... 41

4.3.13 Generador de reloj ................................................................................................. 41

4.4 Características del Procesador LEON ................................................................. 41

4.4.1 Tolerancia a fallas .................................................................................................. 41

4.4.2 Librería GRLIB ..................................................................................................... 41

4.4.3 Creación de Código C ............................................................................................ 42

4.5 Entorno de desarrollo ............................................................................................ 42

4.5.1 Plugin del Procesador LEON para el entorno Eclipse ....................................... 42

4.5.2 GRMON (Gaisler Research Monitor) ................................................................. 42

ix

4.6 Arquitectura propuesta ......................................................................................... 44

4.7 Escenario de pruebas ............................................................................................. 45

4.7.1 Herramientas utilizadas ........................................................................................ 45

4.7.2 Síntesis del Procesador LEON en el FPGA ......................................................... 46

4.7.3 Configuración de la transmisión serial ................................................................ 48

4.7.4 Generación de la señal GPS desde el computador .............................................. 54

CAPÍTULO V

ANÁLISIS DE RESULTADOS ........................................................................................ 59

5.1 Síntesis del Procesador LEON en la Tarjeta Digilent Spartan 3E-1600

Development Board ........................................................................................................... 59

5.2 Implementación del algoritmo de seguimiento en el Procesador LEON .......... 59

CONCLUSIONES Y RECOMENDACIONES .............................................................. 63

ANEXO A

HOJA DE DATOS DE LA DIGILENT SPARTAN 3E-1600 DEV. BOARD .............. 64

ANEXO B

CÓDIGO BARE C DEL ALGORITMO DE SEGUIMIENTO GNSS ........................ 66

ANEXO C

CÓDIGO C DEL GENERADOR DE SEÑALES GPS ................................................ 135

ANEXO D

CÓDIGO C DE LA TRANSMISIÓN SERIAL ............................................................ 145

BIBLIOGRAFÍA ............................................................................................................. 151

ÍNDICE DE FIGURAS Figura 2.1 Componentes de un sistema GNSS 6

Figura 2.2 Proceso de generación de la señal con espectro ensanchado 8

Figura 2.3 Constelación del sistema GPS 9

Figura 2.4 DEP de la señal GPS L1 C/A 9

Figura 2.5 Generador de código C/A 10

Figura 2.6 Densidad espectral de potencia para BOC(1,1) 13

Figura 2.7 Frecuencia Doppler recibida por un receptor GNSS 14

Figura 2.8 Señal reflejada y bloqueada por un satélite (obstáculo) 15

Figura 2.9 Distribución Nakagami-m para m=2 17

Figura 2.10 Proceso de adquisición de la señal 18

Figura 2.11 Primer método del algoritmo de adquisición 19

Figura 2.12 Segundo método del algoritmo de adquisición 19

Figura 2.13 Sistema de seguimiento típico 20

Figura 3.1 Etapa de correlación 22

Figura 3.2 Correlación e integración de la señal 23

Figura 3.3 Salida de los diferentes discriminadores del filtro de lazo Costas 24

Figura 3.4 Comparación de la salida de los diferentes discriminadores de frecuencia 26

Figura 3.5 Filtro de lazo para el filtrado de señal y frecuencia 27

Figura 3.6 Diagrama del cálculo de la banda de ruido 27

Figura 3.7 Sistema global de filtro de fase y frecuencia 28

Figura 3.8 NCO de la portadora 28

Figura 3.9 Comparación de la salida de los diferentes discriminadores de código 30

Figura 3.10 Salida completa del discriminador de código 30

Figura 3.11 Generación del factor de escala 31

Figura 3.12 Generación de ����� a través de un oscilador controlado

digitalmente (NCO) 31

Figura 3.13 Generación de los códigos PRN 32

xi

Figura 3.14 Detector de bloqueo de fase 33

Figura 3.15 Detector de bloqueo de código 34

Figura 3.16 Relación entre el valor de bloqueo y la tasa C/N0 estimada. 34

Figura 3.17 Demodulación de la señal 36

Figura 4.1 Diagrama de bloques del procesador LEON3 para una tarjeta

Spartan3 1500 39

Figura 4.2 Entorno de desarrollo de una aplicación para el procesador LEON

en Eclipse. 43

Figura 4.3 Conexión al procesador LEON a través de un puerto serial utilizando

GrmonRCP 43

Figura 4.4 Arquitectura propuesta para el sistema de seguimiento 44

Figura 4.5 Diagrama del escenario de pruebas del algoritmo de seguimiento 45

Figura 4.6 Escenario de pruebas del algoritmo de seguimiento 46

Figura 4.7 Ventana principal de la configuración del Procesador LEON 46

Figura 4.8 Ventana de configuración de la unidad de punto flotante. 47

Figura 4.9 Ventana de Xilinx ISE 48

Figura 4.10 Opción Synthesize-XST en Xilinx ISE 48

Figura 4.11 Diagrama de bloques del APBUART 49

Figura 4.12 Registro de datos del APBUART 49

Figura 4.13 Registro de estado del APBUART 50

Figura 4.14 Registro de control del APBUART 51

Figura 4.15 Registro escalador del APBUART 51

Figura 4.16 Trama de datos de un envío serial para una tramas de datos sin

paridad (a) y con paridad (b) 52

Figura 4.17 Configuración del puerto serial en el computador 54

Figura 4.18 Salida del programa de adquisición de señales GNSS 56

Figura 4.19 Detección del desfasaje y la frecuencia Doppler para la señal

con PRN 1 57

Figura 4.20 Detección del desfasaje y la frecuencia Doppler para la señal

con PRN 2 57

Figura 4.21 Detección del desfasaje y la frecuencia Doppler para la señal

con PRN 15 58

Figura 5.1 Seguimiento de la frecuencia 61

xii

Figura 5.2 Gráfica desviación estándar de la frecuencia Doppler (Hz)

vs el valor C/N0 estimado (dB-Hz) 62

Figura 5.3 Gráfica desviación estándar del retardo (us) vs el valor C/N0

estimado (dB-Hz) 62

ÍNDICE DE TABLAS Tabla 2.1 Tamaño de los códigos para la señal Galileo E5a 12

Tabla 3.1 Discriminadores de fase para un filtro de lazo Costas 24

Tabla 3.2 Discriminadores de frecuencia 25

Tabla 3.3 Discriminadores de código 29

Tabla 4.1 Registros del APBUART 49

Tabla 4.2 Valores a ingresar en el archivo “Parameters.txt” 55

Tabla 4.3 Señales GPS de prueba 56

Tabla 5.1 Resultados de la síntesis del Procesador LEON 59

Tabla 5.2 Parámetros de la prueba 60

Tabla 5.3 Resultados de la implementación del algoritmo de seguimiento en el

Procesador LEON 60

CAPÍTULO I INTRODUCCIÓN

1.1 Planteamiento del problema de tesis

Un satélite posee una posición en el espacio, es decir el lugar donde se encuentra, y una

actitud, la cual es la rotación de objeto específico respecto a un objeto de referencia el cual

ha sido bien definido en el espacio [1]. La actitud es determinada por el satélite gracias a

los giroscopios, sensores de luz y tierra. En la actualidad, la posición de los satélites es

determinada por los radares en la estación terrena. Sin embargo, la implementación de

estos radares es a la vez cara y poco precisa, dando a cada satélite un gran volumen por el

cual se puede localizar la posición del satélite (con aristas de pocos kilómetros), y

reduciendo la densidad de los satélites.

Por esta razón, se implementó un sistema que permita dar una posición precisa logrando la

extensión de los receptores GNSS (Sistema Global de Navegación por Satélite) desde la

Tierra (el conocido GPS) al espacio. En el año 1998, se desarrolló un nuevo enfoque que

permita aprovechar las ventajas de los receptores GNSS (en forma específica GPS) para la

implementación en satélites [2].

Se escogió como primera opción la implementación de un Sistema GNSS sobre un satélite

debido a las múltiples ventajas que posee: autonomía, reducidos costos de operación,

mayor precisión, control más eficiente de la posición en el espacio, menor consumo de

energía, mayor duración de las misiones y más satélites en el mismo volumen [3].

Sin embargo, debido a la alta velocidad de desplazamiento de los satélites de Órbita Baja

Terrestre (LEO) (aproximadamente 50 minutos respecto a las 6 horas de rotación alrededor

de la tierra), el efecto Doppler que afecta la señal recibida es del orden de magnitud más

grande que el efecto Doppler sobre la Tierra [2]. En consecuencia, se necesita un desarrollo

especial para un receptor LEO GNSS.

En la actualidad, existen dos Sistemas GNSS completamente implementados, los cuales

son el Sistema de Posicionamiento Global (GPS) y GLONASS (Sistema de Navegación

Global por Satélite). Además, existen dos sistemas de navegación que están en desarrollo:

2

el Sistema de Navegación Galileo (Unión Europea) [4] y el Sistema Compass o Beidou

(China) [5]. Dentro de las etapas de desarrollo del sistema Galileo y el sistema Compass, el

Sistema Galileo tendrá compatibilidad con el Sistema GPS, por ejemplo el uso de similares

rango de frecuencia entre los dos sistemas, logrando así un mayor número de satélites para

realizar sus cálculos. Por lo tanto, se espera que el Sistema Galileo se utilice a nivel

mundial en dispositivos receptores tales como teléfonos móviles, computadoras personales,

etc.

Desde el año 2000, se han desarrollado varios proyectos de investigación en la comunidad

científica sobre receptores GNSS para microsatélites (cuyo peso es entre 10 a 100 Kg), en

diferentes países como Italia, Australia, China y Francia [6] [7] [8] [9] [10] . Sin embargo,

la mayoría de ellos sólo plantean la implementación de una interfaz a nivel físico,

ocasionando grandes gastos a largo plazo en recursos económicos, personal técnico y

tiempo para la actualización y corrección de fallas del dispositivo. Como consecuencia

directa de esto, los componentes del receptor GNSS del microsatélite serán rápidamente

desactualizados.

Debido a esto, el presente estudio tiene como finalidad la implementación de un sistema de

seguimiento para un receptor GNSS a nivel hardware – software, el cual posee una parte

del algoritmo de seguimiento dentro de un dispositivo (procesador) como software y a

través de la configuración del procesador en VHDL, lo cual servirá para acelerar algunos

procesos que no son eficientes a nivel de software.

1.2 Objetivo general

Estudiar, analizar, simular, optimizar e implementar un algoritmo de seguimiento GNSS

para pequeños satélites.

1.3 Objetivos específicos

La presente tesis tiene como objetivos específicos lo siguiente:

� Implementación y optimización del algoritmo de seguimiento en lenguaje C dentro del

Procesador LEON.

� Configuración y síntesis del Procesador LEON en VHDL.

� Implementar el algoritmo de seguimiento en un FPGA Digilent Spartan 3E-1600

Development Board.

1.4 Justificación

El contar con un sistema hardware-software que permita implementar un sistema de

seguimiento para receptores GNSS, el cual estará orientado a pequeños satélites,

3

beneficiará a la comunidad académica ya que cubrirán tópicos que no han sido

mayormente analizados en detalle y se están pasando por alto en otras investigaciones,

como son la flexibilidad del sistema, permitir la incorporación de otros sistemas GNSS y la

reducción de costos de implementación a largo plazo.

1.5 Alcances y delimitaciones

La presente tesis tiene los siguientes alcances:

� Proporcionar un sistema de seguimiento a nivel de hardware-software (código C dentro

de un Procesador y configuración del Procesador en VHDL).

� Proporcionar flexibilidad de modificación del código C lo cual permita adaptarlo a otros

sistemas GNSS (Galileo, Compass o GLONASS), dejando las implementaciones de estos

sistemas GNSS a futuros trabajos de investigación.

Sin embargo, la presente tesis tiene las siguientes delimitaciones:

� Solamente se analizará la etapa de seguimiento de un receptor GNSS, dejando las otras

etapas a futuros trabajos de investigación.

� Se analizará solamente el efecto Doppler en el receptor GNSS debido a que es el mayor

responsable de la degradación de las señales recibidas.

� Estará orientada a GPS debido a que es el sistema GNSS mayormente usado; sin

embargo, se van a dar ciertas modificaciones que se pueden realizar para realizar la

implementar en el sistema Galileo.

1.6 Recapitulación

En el Capítulo I se plantea la problemática a estudiar, el objetivo general y los específicos

de la tesis, la justificación por la cual se elige este tema y sus alcances y limitaciones. En el

Capítulo II se tratará acerca de los fundamentos de los sistemas GNSS como son los

componentes de un sistema GNSS, posicionamiento del receptor, la señales utilizadas en

los sistemas GPS y Galileo, la estructura de la señal GNSS recibida, componentes de un

receptor GNSS y los fundamentos de las etapas de adquisición y seguimiento. En el

Capítulo III se desarrollará el algoritmo de seguimiento propuesto y además se darán los

lineamientos para la adaptación al sistema Galileo. En el Capítulo IV se tratará acerca de la

arquitectura hardware-software utilizada en la implementación del sistema y como la etapa

de hardware interactúa con el software que está implementado dentro del procesador.

Además, se detallará el escenario de pruebas que se ha utilizado para probar el

funcionamiento del algoritmo. En el Capítulo V se analizarán los resultados obtenidos del

escenario de pruebas del algoritmo. Finalmente, en Conclusiones y Recomendaciones, se

4

dará a conocer las conclusiones del proyecto y se plantearán trabajos futuros en base a la

investigación realizada.

CAPÍTULO II CONCEPTOS DE SISTEMA DE POSICIONAMIENTO GLOBAL

2.1 Introducción

Durante los últimos 15 años han existido y existen muchos tópicos interesantes dentro de

los Sistemas GNSS, como son:

a) La puesta en operación del sistema GPS en 1993, cuando 24 satélites GPS estuvieron

operando en órbitas asignadas y disponibles tanto para uso militar como para uso civil.

b) El nuevo sistema europeo satelital Galileo.

c) La modernización de los sistemas satelitales de los Estados Unidos de Norteamérica,

GPS.

d) La reconstrucción del sistema de satélites rusos GLONASS.

Debido a esto, la definición de sistemas GNSS es la interoperatividad y compatibilidad

técnica entre los diversos sistemas de navegación, como son GPS, Galileo y Glonass, para

ser usados en el campo civil sin tener en cuenta las barreras limítrofes propias de cada país

a fin de promover el bienestar y comodidad de la sociedad [11].

2.2 Componentes de un sistema GNSS

El sistema GNSS consiste de tres segmentos [12]:

a) Segmento de espacio: Consiste de un grupo o constelación de satélites1 en órbita que

circulan la Tierra aproximadamente dos veces al día. A fín de proveer una cobertura

adecuada de las señales en tierra, debe haber entre 20 y 30 satélites dentro de una

constelación y deben estar distribuidos entre tres y seis diferentes planos orbitales.

b) Segmento de control: Consiste de un sistema de estaciones de seguimiento localizadas

alrededor del mundo, las cuales constantemente recepcionan las señales de los satélites.

Estas usan esta información para calcular las órbitas exactas y las correcciones de la deriva

del reloj2 para todos los satélites y transmite la información al satélite respectivo.

1 Algunos autores prefieren llamar a los satélites vehículo espacial (SV) en vez de satélite. 2 Se entiende por deriva de reloj a un conjunto de fenómenos que ocasionan una desincronización de un reloj respecto a los otros. En el espacio suele ocurrir debido a la dilatación del tiempo. Para mayor información consultar [23].

6

c) Segmento de usuario: Consiste de los receptores GNSS y los usuarios. Los receptores

GNSS reciben las señales de los satélites y con esa información obtienen su posición,

velocidad y tiempo estimado.

En la figura 2.1 se observa cada uno de los componentes del sistema GNSS. El segmento

de espacio cuenta con una etapa: la constelación de satélites. El segmento de control cuenta

con tres etapas: red de estaciones de monitoreo, estaciones de control y estaciones de

subida. El segmento de usuario cuenta con cuatro etapas: antena, receptor, procesador de

rango y procesador de navegación.

Figura 2.1 Componentes de un sistema GNSS

La función que cumple el segmento de usuario son las siguientes [13]:

a) La antena convierte las señales de radio a señales eléctricas.

b) El receptor demodula las señales usando un reloj el cual le proporciona un tiempo de

referencia.

c) El procesador de rango utiliza los algoritmos de adquisición y seguimiento para

determinar la distancia entre la antena a cada uno de los satélites de las cuales provienen

las señales recibidas.

d) El procesador de navegación utiliza la medición de distancia para calcular la posición,

velocidad y tiempo del receptor.

2.3 Posicionamiento del sistema

Una posición de un objeto utilizando el sistema GNSS es determinado por el cálculo de la

distancia en tres dimensiones. El tiempo de llegada de la señal ��� es determinado por el

reloj receptor, mientras que el tiempo de transmisión �� de cada señal es determinado

7

utilizando sus ranging code3 y la información del mensaje.

Cuando el receptor y los satélites están sincronizados, el alcance ρ desde el satélite hasta el

receptor se obtiene del producto de la velocidad de la luz y de la diferencia entre el tiempo

de llegada y el tiempo de transmisión de la señal. De esta forma, el alcance ρ es expresado

según la ecuación (2.1).

� = ���,� − ��,��� ( 2.1)

Donde el índice j es utilizado para denominar el número del satélite o el canal receptor. En

este modelo, no son considerados los errores de la fuente de transmisión [13].

Sin embargo, el receptor y el satélite no están realmente sincronizados, por lo cual la

diferencia entre ��� y �� es una función que depende del alcance del satélite al receptor y

del desplazamiento del reloj del receptor, tal como se muestra en la ecuación (2.2).

��� = ���,� − ��,��� + � ∗ � ( 2.2)

Donde b sería el desplazamiento del reloj y ��� es conocido como el pseudo alcance [14].

Finalmente, se debe considerar que la cantidad mínima de satélites para realizar el

posicionamiento del receptor son cuatro [15].

2.4 Fundamentos de espectro ensanchado

Un sistema de espectro ensanchado posee las siguientes características [14]:

a) La información es modulada en la portadora de tal forma que posea un gran ancho de

banda respecto a la tasa de transmisión de la información.

b) El transmisor utiliza una señal determinística para modular la señal de la información y

de esa forma ensanchar el espectro de la señal transmitida. A esta señal determinística se le

conoce como código PRN (ruido pseudo aleatorio).

c) El receptor realiza la correlación de la señal recibida con una copia del código PRN en

el proceso de modulación de la información.

En la figura 2.2 se muestra el proceso de generación de la señal con espectro ensanchado.

Respecto a los códigos PRN, estos son una secuencia finita de bits las cuales deben

cumplir las siguientes condiciones4 [14] [16] [17]:

a) Propiedad de balance: En cada periodo de un código PRN, la diferencia de la cantidad

de símbolos ‘+1’ respecto a la cantidad de símbolos ‘-1’ es 1.

3 Se llama ranging code al identificador que es enviado desde el transmisor y es utilizado para determinar el tiempo de transmisión que una señal demora desde el transmisor hacia el receptor. 4 Estas propiedades se les conocen también como propiedades de Golomb. Sin embargo, existen más propiedades de los códigos PRN, para mayor información consultar [15].

8

b) Ejecución: Se llama ejecución de longitud k a una secuencia de k idénticos dígitos, es

decir sea la secuencia ���, ����, … , ������ en cualquier secuencia de código PRN tal que ���� ≠ �� = ⋯ = ������ ≠ ����.

Figura 2.2 Proceso de generación de la señal con espectro ensanchado

En cualquier código PRN, la mitad de las ejecuciones tienen longitud 1, la cuarta parte de

las ejecuciones tienen longitud 2, la octava parte de las ejecuciones tienen longitud 3, la

dieciseisava parte de las ejecuciones tienen longitud 4 y así sucesivamente hasta que estas

fracciones den un número entero de ejecuciones. También, en cada caso, el número de

ejecuciones de -1’s es igual al número de ejecuciones de +1’s.

c) Autocorrelación: La autocorrelación de la secuencia PRN de longitud N está dado por

la ecuación (2.3).

#�$ = % 1 − |$| (1) + 1* , +,-, |$| ≤ /0− 1) , +,-, /0 ≤ |$| ≤ �) − 1 /0 ( 2.3)

2.5 Señales del Sistema GPS

El Sistema GPS fue creado por el Departamento de Defensa de los Estados Unidos.

Consiste de 24 satélites posicionados en seis planos orbitales de la Tierra con un radio

orbital aproximado de 26600 Km. En la figura 2.3 se muestra una representación de la

constelación del Sistema GPS.

A continuación se presentan las principales señales del Sistema GPS.

2.5.1 GPS L1 C/A

La señal GPS L1 C/A se emite en la frecuencia: fL1=1575.42MHz = 154*10.23MHz,

siendo 10.23 MHz la frecuencia de referencia de los relojes atómicos ubicados en los

satélites a bordo.

La señal GPS L1 C/A se modula con un código de dispersión de 1023 chips a 1.023 MHz y

un pseudo-periodo de 1 ms. El código de dispersión posee una longitud de onda de 293 m

9

Figura 2.3 Constelación del sistema GPS

y es una secuencia pseudo aleatoria con buena auto correlación y propiedades de

ortogonalidad. Este código es una secuencia de Oro (Gold Code) y puede ser reconstituida

localmente por un generador de código. La señal GPS L1 C/A es llamada también BPSK-

R(1). El valor ‘1’ de BPSK-R(1) se toma respecto a un valor de referencia, que en este

caso es la frecuencia de 1.023 MHz.

Su Densidad Espectral de Potencia (DEP) en banda base es mostrado en la figura 2.4 y la

envolvente del PSD es representada según la ecuación (2.4).

12 3⁄ �5 = /2 . �78�9�5/2 ( 2.4)

Figura 2.4 DEP de la señal GPS L1 C/A

10

2.5.2 GPS L5

La señal GPS L5 se emite en la frecuencia: fL5=1176.45MHz = 115*10.23MHz.

La señal GPS L5 es una modulación QPSK compuesta de dos modos:

� Modo en fase, conteniendo el mensaje de navegación.

� Modo en cuadratura, no conteniendo datos.

A señal GPS L5 tiene un periodo de 10 ms y está codificado por un código de corrección

de errores. El periodo de los bits del mensaje de navegación es de 20 ms.

2.5.3 Generación de los códigos C/A para GPS

Para la generación de los códigos C/A para GPS se tiene el esquema mostrado en la figura

2.5 [15].

Figura 2.5 Generador de código C/A

Como se puede apreciar, el generador de código C/A es la suma de dos señales G1 y G2.

Las señales G1 y G2 son obtenidas mediante la operación xor de los valores almacenados

dentro de sus respectivos registros. Finalmente, se debe recalcar que cada código C/A es

diferente para cada satélite GPS.

2.6 Señales del Sistema Galileo

El Sistema Galileo es un sistema de posicionamiento global desarrollado por la Unión

Europea, del cual estará disponible para el año 2014. Este consistirá de 30 satélites (27

operacionales y 3 de repuesto) posicionados en la órbita MEO con un semieje mayor

11

promedio de 29601.297 Km.

A continuación se presentan las principales señales del Sistema Galileo.

2.6.1 Galileo E1 OS

La señal Galileo E1 OS se emite en la frecuencia: fE1=1575.42MHz

Además, la expresión analítica de la señal Galileo E1 OS para el k ésimo satélite está dado

por la ecuacion (2.5).

��� = √; ∙ ��� ∙ =�� ∙ ���� ∙ >� 9?@A�B� ( 2.5)

Donde:

� √;: amplitud de la señal compleja

� =�� : señal de datos

� ��� : código de dispersión

� ���� : subportadora, ���� = �7C8��78 2E5�0� o ���� = �7C8��F� 2E5�0�

� 5�0: frecuencia de la subportadora

� 5G: frecuencia de la portadora

� H: fase de la señal

Este tipo de señal es llamada también BOC(m,n) con n = fKL fMN⁄ y m = fL fMN⁄ , siendo fMN

la frecuencia de referencia del código de dispersión GPS L1 C/A: fMN=1.023 MHz. Por

ejemplo, la señal BOC(1,1) tiene una frecuencia de subportadora fKL=1.023 MHz y código

de dispersión fL=1.023 MHz.

La señal Galileo E1 OS es la combinación de dos modulaciones BOC. Esta señal es

conocida también como CBOC(3,1,1/11) y está en función de las modulaciones BOC(1,1)

y BOC(6,1). Esta señal tiene un código de dispersión de 4092 chips a 1.023 MHZ y un

pseudo periodo de 4 ms.

Finalmente, su densidad espectral de potencia en función de BOC(1,1) y BOC (6,1) se

muestra en la ecuación (2.6).

Φ2QR2�5 = 1011 ΦQR2��,� �5 + 111 ΦQR2�T,� �5 ( 2.6)

2.6.2 Galileo E5a

La señal Galileo E5a se emite en la frecuencia: fE5a=1176.45MHz.

La señal Galileo E5a es una modulación QPSK compuesta de dos modos:

� Modo en fase conteniendo el mensaje de navegación: Galileo Ea5-I

� Modo en cuadratura no conteniendo datos: Galileo Ea5-Q

12

Los códigos de dispersión de la señal Galileo Ea5 tienen una frecuencia de 10.23MHz, una

longitud de 10230 chips y un pseudo-periodo de 1 ms. Cada modo es entonces un BPSK-R

(10).

El mensaje de navegación sobre Galileo Ea5-I se emite en una secuencia binaria a 50 b.s-1.

Además, los dos modos, Galileo Ea5-I y Galileo Ea5-Q, se modulan como códigos

secundarios. En la tabla 2.1 se muestra una ampliación de lo explicado [4].

Tabla 2.1 Tamaño de los códigos para la señal Galileo E5a

Componente Periodo de pseudo

código (ms)

Tamaño del código

primario (chips)

Tamaño del código

secundario (chips)

E5a-I 20 10230 20

E5a-Q 100 10230 100

2.6.3 Densidad Espectral de Potencia

La densidad espectral de potencia de la modulación BOC en banda base está dado por la

ecuación (2.7).

UQR2�5 =VWWWXWWWY 50 Zsin ( E525�0* sin (E550 *

E5 cos ( E525�0* _9

, 8 = 25�050 +,-50 Zsin ( E525�0* sin (E550 *

E5 cos ( E525�0* _9

, 8 = 25�050 7`+,- ( 2.7)

En la figura 2.6 se muestra la densidad espectral de potencia para la modulación BOC(1,1).

Como se puede observar, la densidad espectral de potencia es diferente a la densidad

espectral de potencia de la señal GPS L1 C/A en cuanto a la cantidad de lóbulos

principales (GPS L1 C/A posee un lóbulo principal y BOC(1,1) posee dos lóbulos

principales).

2.7 Desafíos de la implementación en el espacio de un receptor GNSS

La señal GNSS es afectada por múltiples interferencias las cuales van a degradar la calidad

de recepción de la señal. En esta sección del capítulo se revisarán alguna de las principales

interferencias que ocurren en los receptores GNSS a nivel de órbitas LEO.

2.7.1 Efecto Doppler

El efecto Doppler es producido por el movimiento relativo del satélite GNSS respecto al

13

usuario o receptor. La velocidad v se calcula utilizando la información de las efemérides5 y

el modelo de la órbita del receptor. En la figura 2.7 se muestra la curva de la frecuencia

Doppler recibida por un receptor GNSS la cual depende del tiempo. Además, a medida que

el satélite esté más próximo al receptor, la frecuencia Doppler disminuirá; y a medida que

el satélite esté más lejos del receptor, la frecuencia Doppler aumentará [15].

Figura 2.6 Densidad espectral de potencia para BOC(1,1)

Se puede aproximar la frecuencia 5� utilizando la ecuación clásica Doppler, la cual se

muestra en la ecuación (2.8).

5� = 5a b1 − �cd ∙ , � e ( 2.8)

Donde 5a es la frecuencia transmitida por el satélite, cd es la velocidad relativa del satélite

respecto al receptor GNSS, , es el vector unitario que sigue la dirección de la línea de vista

del receptor al satélite y c es la velocidad de la luz.

Para un receptor en órbita LEO, el rango de la frecuencia Doppler es desde -42 KHz hasta

42 KHz, lo cual es bastante respecto al rango de la frecuencia Doppler en tierra que es

desde -4KHz hasta 4 KHz. Sin embargo, la ventaja del receptor en el espacio respecto a un

receptor en tierra es que el movimiento del receptor es muy predecible, lo cual el patrón de

búsqueda puede ser considerablemente reducido utilizando los datos del almanaque6 GNSS

[18].

5 Es una tabla de valores que proporciona la posición de los objetos en el espacio. 6 Los datos del almanaque es la información sobre la posición de los satélites. Cada satélite transmite información de posición sobre todos los satélites. El receptor almacena la información de manera que pueda determinar su propia posición. Los satélites tardan aproximadamente 12,5 minutos en transmitir los datos de posición al receptor.

14

Figura 2.7 Frecuencia Doppler recibida por un receptor GNSS

El efecto Doppler tiene un importante efecto en el sistema de seguimiento por lo cual el

sistema de seguimiento debe ser lo suficientemente robusto y veloz para detectarlo y

seguirlo ante cualquier cambio en la frecuencia Doppler, ya que la tasa de cambio de la

frecuencia Doppler es normalmente ±62 Hz.s-1.

2.7.2 Multitrayecto

El multitrayecto puede suceder si la señal se refleja en la superficie del equipo receptor.

Además, debido a que los satélites tienen formas complejas y el diseñador sólo se ha

preocupado en obtener una buena antena, el efecto multitrayecto podría ser perjudicial por

una mala ubicación de la antena dentro del receptor [19].

También existe otra forma, aunque no es tan común, de conseguir el efecto multitrayecto.

Este caso sucede si la señal a recibir pasa a través de un obstáculo, por ejemplo un satélite,

y este refleje la señal a recibir, siendo este caso el más crítico para el sistema receptor. En

la figura 2.8 se ilustra el caso en el cual se transmiten dos señales, sin embargo una de ellas

es bloqueada por un satélite y la otra es reflejada en múltiples señales debido a la presencia

de un satélite que actúa como obstáculo.

2.7.3 Interferencia

Debido a que los receptores GNSS procesan la información en base a una señal RF, estas

señales son vulnerables a interferencias RF, ya sea en forma involuntaria o intencional7. La

interferencia normalmente se clasifica como interferencia de banda ancha e interferencia

de banda angosta. Esta definición depende del ancho de banda de la señal GNSS, siendo

interferencia de banda ancha cuando el ancho de banda de la interferencia es más grande

que el ancho de banda de la señal GNSS e interferencia de banda angosta cuando el ancho

7 Una interferencia intencional se conoce como jamming.

15

de banda de la interferencia es menor que el ancho de banda de la señal GNSS.

También puede darse el caso que exista interferencia entre señales del mismo tipo, por

ejemplo dos señales GPS interfiriéndose entre sí en la etapa de recepción. A este tipo de

interferencia se conoce como interferencia intrasistema.

Figura 2.8 Señal reflejada y bloqueada por un satélite (obstáculo)

Además de la interferencia intrasistema, puede darse el caso en que una señal de otro

sistema GNSS interfiera con la señal GNSS deseada, por ejemplo una señal del sistema

Galileo interfiera con otra señal del sistema GPS. Este tipo de interferencia se le llama

interferencia entre sistemas.

2.7.4 Centelleo ionosférico

La ionósfera es una capa de la atmósfera de la Tierra que comienza a partir de los 50 km de

altura hasta varios kilómetros de la Tierra. En esta capa, la radiación solar incidente separa

una fracción de componentes neutros en iones cargados positivamente y electrones libres.

Además, la máxima densidad de electrones libres ocurre a 350 km [15].

Sin embargo, las irregularidades en la ionósfera pueden generar, dependiendo de la altitud

del receptor GNSS y la elevación aparente de los satélites GNSS, un rápido

desvanecimiento en el nivel de potencia de la señal recibida, causando un aumento del

error de posicionamiento en varias decenas de metros. Este fenómeno se conoce como

centelleo ionosférico y ocasiona problemas de seguimiento de uno o varios satélites por

cortos periodos de tiempo. Además, el centelleo ionosférico es común y más severo

durante el ciclo solar, el cual dura aproximadamente 11 años.

16

El centelleo ionosférico causa una perturbación tanto en la amplitud como en la fase de la

señal. El modelo de la señal recibida en presencia de centelleo es mostrado en la ecuación

(2.9) [15].

-�� = √2f ∙ gf ∙ ��� cos�h� + i + gi + 8�� ( 2.9)

Donde:

� f es la potencia de la señal recibida.

� h es frecuencia de la portadora (rad/s).

� ��� es la señal normalizada transmitida.

� i es la fase de la señal transmitida.

� 8�� es ruido.

� √gf es un valor escalar que caracteriza el desvanecimiento en la amplitud debido al

centelleo.

� gi es la variación de la fase debido al centelleo (rad). gf se modela generalmente siguiendo la distribución Nakagami-m cuya función de

densidad de probabilidad está dado por la ecuación (2.10) [20].

+�gf = 2`jgfj�k.lΓ�` >�jno, gf ≥ 0 ( 2.10)

Cuya media es 1 y varianza es 1 `⁄ . La intensidad de la amplitud de desvanecimiento

debido al centelleo ionosférico se caracteriza mediante el índice Uq, el cual es la inversa de

la desviación estándar de gf y cuyo valor está dado en la ecuación (2.11).

Sin embargo, debido a la propiedad de la distribución Nakagami-m, el índice Uq debe ser

menor o igual a √2.

Uq = 1√` ( 2.11)

En la figura 2.9 se muestra la distribución Nakagami-m para m = 2.

La variación de la fase debido al centelleo ionosférico se modela normalmente como una

distribución gaussiana, tal como se muestra en la ecuación (2.12).

+�gi = 1√2Ers >�nst9uvt ( 2.12)

Donde rs es la desviación estándar de la variación de la fase.

2.8 Procesamiento de la señal GNSS recibida

Un receptor capta múltiples señales GNSS, las cuales llegan con diferentes frecuencias

17

Doppler, diferentes retardos y diferentes atenuaciones. En la ecuación (2.13) se muestra la

recepción de un receptor GNSS.

Figura 2.9 Distribución Nakagami-m para m=2

��8 = w xyzy�8/� − $y �y�8/� − $y >��9?�@{|�}~ �a���|

y∈��,⋯,@�+ ��8/�

( 2.13)

Donde:

� $y: Retardo de la señal del satélite α debido a la propagación de la señal

� xy: Atenuación de la señal del satélite α

� zy: Secuencia de bits (datos) del satélite α

� �y: Señal PRN del satélite α

� �k: Fase de la portadora

� 5�y: Frecuencia Doppler del satélite α

� ��: Frecuencia intermedia

� /�: Tasa de muestreo de la señal

� �: Ruido aditivo gaussiano

En esta sección del capítulo, se explican los conceptos básicos de las etapas de adquisición

y seguimiento. En el capítulo 3 se explicará con mayor detalle cómo se procesa la señal

GNSS recibida frente al efecto Doppler dentro del sistema de seguimiento.

2.8.1 Principio de adquisición

La etapa de adquisición permite encontrar una buena estimación de la frecuencia Doppler 5�� y del retardo de la señal $̂ para cada satélite.

18

Un ejemplo de búsqueda se muestra en la figura 2.10, en la cual se busca la señal en una

grilla formada por las frecuencias y los retardos de código de la señal [19]. En este método

se realiza la búsqueda manteniendo la frecuencia fija y buscando a través de todos los

posibles retardos hasta encontrar el que tenga mayor valor. A este método se conoce como

búsqueda serial.

Figura 2.10 Proceso de adquisición de la señal

Sin embargo, el método de búsqueda serial es muy lento y puede tomar una cantidad

considerable de minutos para detectar la presencia de la señal.

Por otra parte, existen otros métodos más eficaces los cuales permiten detectar la señal en

un menor tiempo. Por ejemplo se encuentra el método de adquisición utilizando la

transformada rápida de Fourier (FFT) desarrollado por D. Akopian, el cual analiza los

inconvenientes de un receptor GPS basado en FFT y propone un FFT más eficiente,

reduciendo cálculos innecesarios y produciendo una respuesta más rápida. Para este caso

propone dos métodos [21]:

El primer método procesa en forma serial la señal y agrupa la búsqueda para varias

frecuencias alrededor de una sola afín de optimizar el número de cálculos. Además se usa

una matriz de corrección de Doppler. El diagrama del algoritmo se presenta en la figura

2.11.

El segundo método elimina la necesidad del uso de una matriz de corrección Doppler, sin

embargo hace uso de una FFT de tamaño variable. El diagrama del algoritmo se presenta

en la figura 2.12.

2.8.2 Principio de seguimiento

Una vez obtenidos los parámetros estimados de la frecuencia Doppler 5�� y del retardo de la

19

señal $̂ del sistema de adquisición, estos valores entran al sistema de seguimiento como

parámetros iniciales. Esta fase permite demodular el mensaje de navegación satelital y

medir los pseudo alcances.

Figura 2.11 Primer método del algoritmo de adquisición

Figura 2.12 Segundo método del algoritmo de adquisición

El sistema de seguimiento realiza el seguimiento de los cambios del retardo de código, fase

y la frecuencia Doppler para obtener una estimación más precisa de estos parámetros a

través del tiempo. Los cambios de la fase y la frecuencia Doppler estimados sirven para

corregir los errores de la portadora y, de esta forma, decodificar el mensaje. El estimado

del retardo de código sirve para calcular el pseudo alcance y, de esta forma, obtener la

posición del receptor.

Compensación de la frecuencia (frecuencia sin

corregir)

Re-arreglo en una matriz

FFT de

filas

Compensación en frecuencia

epoch

FFT de columnas

FFT de la réplica

Corrección del código Doppler

IFFT de las

columnas

Entrada �� Salida

Ent

rada

�� FFT de tamaño )�)9 para la longitud de la integración coherente

Posibles ámbitos de los bucles: 1. Satélites 2. Compensación de la

frecuencia (frecuencia sin corregir)

Re-arreglo en una matriz

Tratamiento no

coherente

Corrección del código Doppler

IFFT de las

columnas

Réplica de desplazamiento y multiplicación

Salida

20

En la figura 2.13 se muestra un sistema de seguimiento típico. En este sistema se utilizan

filtros de realimentación para obtener los estimados de los parámetros.

Figura 2.13 Sistema de seguimiento típico

Un filtro de realimentación básico tiene tres componentes: unidad de mezcla, unidad de

control y unidad de realimentación. La unidad de mezcla utiliza el valor estimado obtenido

del filtro ,� y la entrada al sistema , para obtener una señal que está en función del error

del parámetro estimado a seguir �. Luego, la señal � se ingresa hacia la unidad de control,

la cual usará un discriminador para obtener una señal de error �G. Finalmente, la señal �G

se ingresa hacia la unidad de realimentación, la cual usa la señal ingresada para actualizar

el valor estimado ,�.

El módulo de correlación permite seguir las variaciones en frecuencia y fase mediante el

seguimiento de picos máximos del proceso de correlación entre la réplica del código,

obtenido del generador de réplica del código PRN, y tres señales que provienen de la señal

recibida y han sido adelantadas o retrasadas en el tiempo: una señal adelantada (Early), una

señal igual a la señal recibida (Prompt) y una señal que ha sido retrasada (Late).

CAPÍTULO III ANALISIS DEL ALGORITMO DE MITIGACION DEL EFECTO DOPPLER

PARA GPS PROPUESTO 3.1 Introducción

Dentro de un sistema receptor GNSS, el receptor GNSS debe generar un código PRN

idéntico al código PRN de la señal recibida para realizar la correlación. Cuando las fases

de la señal GNSS y del código PRN generado coinciden, se produce un valor máximo en la

correlación. Sin embargo, cuando el desfasaje entre ellos es mayor que un chip o un bit

dentro de un código PRN, se produce un valor mínimo en la correlación. Este método es

utilizado para detectar la señal GNSS en el proceso de seguimiento.

Sin embargo, debido al efecto Doppler y al ruido del canal, se produce la distorsión de la

señal recibida y, por consiguiente, el sistema de seguimiento debe realizar el seguimiento

de la frecuencia Doppler y la corrección de la señal recibida. De esta forma se obtiene la

demodulación de la señal GNSS.

3.2 Filtro de entrada

Antes de realizar el procesamiento de la señal GNSS recibida, esta señal debe pasar por un

filtro FIR pasa bajo, el cual se va a encargar de filtrar las señales arriba de la frecuencia de

los lóbulos principales de las señales GPS L1 C/A y Galileo E1 OS. En la ecuación (3.1) se

muestra la función de transferencia del filtro. Este filtro tiene una frecuencia de corte en

2.5 MHz aproximadamente.

��� = 0.0399 � 0.0498��� � 0.1127��9 � 0.0136��� � 0.3093��q

� 0.5277��l � 0.3093��T � 0.0136��� � 0.1127���

� 0.0498��� � 0.0399���k

( 3.1)

3.3 Correlación e integración

Una vez generados los códigos PRN réplicas en el receptor, se realiza la correlación e

integración de las señales recibidas.

La correlación es una operación matemática en la cual se utilizan dos señales para producir

una tercera señal. Para generar la tercera señal, una de las señales se desplaza a lo largo de

la otra señal, la cual permanece fija. La fórmula matemática de la correlación se muestra en

22

la ecuación (3.2).

-��� = w ,�8� ∙ ��8 � �����

� k, � ∈ ���) � 1 , �) � 1 � ( 3.2)

Debido a las propiedades del código PRN, se puede detectar la forma de onda de la señal

incluso en presencia de ruido.

Para lograr tal fin, se utilizan tres códigos PRN las cuales se correlacionan con las señales

de entrada. Estos códigos PRN se conocen como códigos ;Gd¡jG, ;¢�d£¤, ;£�¢ y están

espaciados cada uno en ±1/2 chip. Esto permite saber si la señal está adelantada o retrasada

en el tiempo.

La figura 3.1 ilustra la correlación de estos tres códigos PRN con la señal entrante. Cuando

la señal muestre un valor 1 en la correlación con ;Gd¡jG, la señal recibida estará

sincronizada y no presenta error. Sin embargo, puede suceder que la señal entrante

presente valor 1 en la correlación diferente del código ;Gd¡jG y exista error. También,

puede suceder que se presenten dos valores máximos en la correlación que sean diferentes

de 1. En cualquiera de los dos casos, se está produciendo un mal seguimiento y es debido a

que la señal sufrió una alteración en el canal de transmisión. Por lo tanto la señal GNSS

debe ser corregida y sincronizada con el código PRN ;Gd¡jG [15].

Para disminuir el error de la señal, se implementa el sistema de integración. En este

sistema, existen dos tipos de integraciones: la primera integración, la cual tiene una

duración de 1ms; y la segunda integración, la cual tiene una duración variable.

Figura 3.1 Etapa de correlación

23

La duración de la segunda integración depende del instante de sincronización

�8��,8�U¥8�ℎ-F y del tiempo de integración /��. Sin embargo, la duración de la segunda

integración debe ser entre 1 ms y 5 ms, esto se hace con el fin de que no sea ni tan pequeño

ni tan grande respecto a la duración de una señal GNSS, por ejemplo la señal GPS L1 C/A

tiene un periodo de 20 ms el periodo.

Finalmente, se obtienen seis salidas:

� I¨, I©, Iª, Q¨, Q© y Qª: Son las salidas de la segunda integración.

� I©�¬K y Q©�¬K: Son las salidas de la integración a 1 ms

El diagrama completo del sistema de correlación e integración se muestra en la figura 3.2.

3.4 Lazo de seguimiento en fase y frecuencia

Esta etapa realiza el seguimiento de la señal en banda base a través de un filtro de lazo

cerrado de fase PLL y a través de un filtro de lazo cerrado de frecuencia FLL. El PLL es

más preciso que el FLL y reproduce la fase exacta de la señal; sin embargo el PLL es más

sensitivo a la dinámica de la señal recibida que el FLL. Por otro lado, el FLL solo logra

una aproximación de la frecuencia de la señal.

Como se explicó en el capítulo 2, el sistema de seguimiento tiene una unidad de control, el

cual usa un discriminador. En nuestro caso, debemos utilizar dos discriminadores:

discriminador de fase y discriminador de frecuencia. En la siguiente sección se tratará el

discriminador de código.

Figura 3.2 Correlación e integración de la señal

24

3.4.1 Discriminador de fase

En caso del seguimiento de una señal compuesta, se utiliza un filtro de lazo Costas como

PLL si se desea que el sistema sea inmune a las rotaciones de fase de π rad [15]. En la

figura 3.3 se muestran los discriminadores de fase utilizados en un filtro de lazo Costas

[15] [19].

De la relación de los discriminadores de fase mostrados en la tabla 3.1, se utiliza el último

discriminador debido a su independencia de la amplitud de la señal, posee la salida óptima

para altas y bajas SNR, y no produce errores de división entre cero. A pesar que la carga

computacional del discriminador sea alta respecto a los otros discriminadores, ese factor se

compensa con la capacidad de procesamiento del dispositivo. En la figura 3.3 se muestra la

salida de los cuatro discriminadores.

Figura 3.3 Salida de los diferentes discriminadores del filtro de lazo Costas

Tabla 3.1 Discriminadores de fase para un filtro de lazo Costas

Discriminador

Salida de

error de

fase

Características

­®¯ × ±®¯ sin�2i

� Cercano al valor óptimo para bajo SNR.

� Envolvente proporcional a la amplitud al cuadrado de

la señal.

� Moderada carga computacional.

­®¯× ¯²³´�±®¯ sini

� Cercano al valor óptimo para alto SNR.

� Envolvente proporcional a la amplitud de la señal.

� Mínima carga computacional.

25

­®¯ ±®¯⁄ tani

� No es tan bueno como los anteriores pero funciona

bien para altas y bajas SNR.

� Envolvente no dependiente de la amplitud de la señal.

� Alta carga computacional.

� Error al dividir por cero en ±90o.

·¸¹�º�­®¯ ±®¯⁄ i

� Óptimo a bajas y altas SNR.

� Envolvente no dependiente de la amplitud de la señal.

� Posee la más alta carga computacional.

3.4.2 Discriminador de frecuencia

El discriminador de frecuencia es más robusto a los errores debido a las transiciones de los

bits de datos en la fase de transición. Es decir, el discriminador de frecuencia permite al

sistema de seguimiento seguir la señal hasta el momento de la transición de los bits,

cuando el mensaje es encontrado. En la tabla 3.2 se muestran los diferentes tipos de

discriminadores de frecuencia [15] [19].

De la relación de discriminadores de frecuencia mostrados en la tabla 3.2, se utiliza el

último discriminador debido a su independencia de la amplitud de la señal y posee la salida

óptima para altas y bajas SNR. A pesar que la carga computacional del discriminador sea

alta respecto a los demás, ese factor se compensa con la capacidad de procesamiento del

dispositivo. En la figura 3.4 se muestra la salida de los tres discriminadores para un /�� de

10 ms.

Tabla 3.2 Discriminadores de frecuencia

Discriminador

Salida de

error de

frecuencia

Características

�»�¼¼½²´¾

sin�gi

/��

� Cercano al valor óptimo para bajo SNR.

� Envolvente proporcional a la amplitud al

cuadrado de la señal.

� Mínima carga computacional.

�»�¼¼ × ¯²³´���¾ ½²´¾

sin�2gi /��

� Cercano al valor óptimo para alto SNR.

� Envolvente proporcional a la amplitud de la

señal.

� Moderada carga computacional.

26

·¸¹�º���¾ �»�¼¼⁄ ½²´¾ gi/��

� Óptimo a bajas y altas SNR.

� Envolvente no dependiente de la amplitud de

la señal.

� Posee la más alta carga computacional.

Donde:

� �»�¼¼ = ±®�´ − º� ∗ ­®�´� � ±®�´� ∗ ­®�´ � º� � ��¾ = ±®�´ � º� ∗ ±®�´� � ­®�´ � º� ∗ ­®�´� Y

� ±®�´ � º�, ±® en el instante �´ � º . ½²´¾

� ±®�´�, ±® en el instante ´. ½²´¾ Siendo ½²´¾ el tiempo de integración de la señal.

Figura 3.4 Comparación de la salida de los diferentes discriminadores de frecuencia

3.4.3 Filtro de lazo

El filtro de lazo FPLL reduce el ruido a fin de producir una estimación confiable del error

entre la señal recibida y la réplica del código PRN. En la figura 3.5 se muestra el filtro de

lazo a usar. Las entradas a este filtro son el discriminador de fase ¿--fÀÀ y el

discriminador de frecuencia ¿--�ÀÀ, obteniendo como salida h¢dd¡d [15].

El filtro a utilizar es un filtro de tercer orden y depende de la banda de ruido del filtro Á�G.

La banda de ruido de un sistema lineal, con función de transferencia ��Â2E5 , es el ancho

de banda (en Hertz) de un filtro pasa bajo rectangular ficticio con la misma área que tiene |��Â2E5 |9.

La figura 3.6 muestra un filtro pasa bajo con una función de transferencia ��Â2E5 y el

filtro pasa bajo rectangular ficticio el cual servirá para calcular la banda de ruido del filtro.

27

Figura 3.5 Filtro de lazo para el filtrado de señal y frecuencia

Figura 3.6 Diagrama del cálculo de la banda de ruido

Primeramente se realiza el cálculo del área bajo |��Â2E5 |9. En la ecuación (3.3) se

muestra el cálculo del área bajo |��Â2E5 |9.

,->,à = Ä |��Â2E5 |9=5Å�Å ( 3.3)

Ahora, si se fija el filtro pasa bajo ficticio con altura ��0 y ancho 2Á�G, el área bajo ese

filtro sería lo mostrado en la ecuación (3.4).

,->,@�£d¡ @�0�0�¡ = 2Á�G��0 ( 3.4)

Igualando las ecuaciones (3.3) y (3.4) se obtiene el valor del ancho de banda de ruido, el

cual es mostrado en la ecuación (3.5).

Á�G = 12��0 Ä |��Â2E5 |9=5Å�Å (3.5)

Finalmente, los parámetros del filtro en función de Á�G se calculan de la siguiente forma: hkG = Á�G 0.7845⁄ , hk@ = Á�G 0.53⁄ , ,9 = 1.414, ,� = 1.1 y �� = 2.4. Finalmente, el

diagrama general del discriminador y del filtro de lazo FPLL se muestra en la figura 3.7.

3.4.4 Oscilador controlado digitalmente (NCO)

El oscilador controlado digitalmente NCO provee señales con una frecuencia normalizada.

En este caso se utiliza el NCO debido a que la salida del filtro de lazo es un pulso en

28

�-F�� = �o�8 − 1�Æo�8� − �o�8�Æo�8 − 1� =F� = �o�8 − 1��o�8� − Æo�8 − 1�Æo�8� Figura 3.7 Sistema global de filtro de fase y frecuencia

radianes y este error debe ser normalizado en el tiempo. En el sistema mostrado en la

figura 3.8, la salida del NCO, ΦÇ G, se multiplica con la señal de entrada para obtener la

corrección de fase.

Figura 3.8 NCO de la portadora

Donde:

� �=���: Frecuencia Doppler encontrada en la fase de adquisición.

� h¢dd¡d: Salida del filtro de lazo FPLL.

� �0¡dd: Corrección de frecuencia en caso de colisión sobre una frecuencia equivocada.

� ��� : Señal de entrada.

3.5 Lazo de seguimiento del retardo de código

En esta etapa se realiza, siguiendo lo explicado en la sección 2.10, el desarrollo del filtro

de lazo de seguimiento de retardo de código. Este módulo sigue la fase del código PRN y

29

compensa el cambio del pseudo periodo debido al efecto Doppler.

3.5.1 Discriminador de código

Existen principalmente dos tipos de discriminadores de código: el discriminador de código

coherente y el discriminador de código no coherente. Los discriminadores de código

coherentes son una combinación lineal de una señal y requieren menos carga

computacional, sin embargo son menos precisos en las salidas. Los discriminadores de

código no coherentes no son una combinación lineal de las señales y requieren mayor

carga computacional respecto a los discriminadores coherentes, sin embargo poseen mayor

precisión que los discriminadores coherentes. También existe una combinación de estos

dos tipos los cuales son llamados discriminadores de código cuasi coherentes. En la tabla

3.3 se muestran los diferentes tipos de discriminadores de código [15] [19].

Tabla 3.3 Discriminadores de código

Discriminador Características

ºÈ (±É − ±Ê±®+ ­É − ­Ê­® *

� Potencia cuasi coherente del producto interno.

� Uso los tres correlacionadores (Early, Late y Prompt).

� Baja carga computacional.

� En ausencia de ruido, produce un valor cercano a la salida del

error verdadero si se tiene como entrada un error entre +0.5 y –

0.5 chip.

ºË ÉË − ÊËÉË + ÊË

� Potencia no coherente Early – Late.

� Moderada carga computacional.

� En ausencia de ruido, produce un valor similar al anterior

discriminador si se tiene como entrada un error entre +0.5 y –0.5

chip.

ºË É − ÊÉ + Ê

� Envolvente Early – Late no coherente independiente de la

amplitud de la señal.

� Alta carga computacional.

� En ausencia de ruido, produce el valor de error verdadero si se

tiene como entrada un error entre +0.5 y – 0.5 chip.

� Se vuelve inestable para una entrada de error en ±1.5 chip.

Donde:

30

� Ì = ͱÉË + ­ÉË

� Î = ͱÊË + ­ÊË

De la relación de discriminadores de código mostrados en la tabla 3.3, se utiliza el último

discriminador debido a que es el más preciso para obtener el error de retardo de código.

Sin embargo, a pesar que la carga computacional del discriminador sea alta respecto a los

demás discriminadores de código, ese factor se compensa con la capacidad de

procesamiento del dispositivo. En la figura 3.9 se muestra la salida de los tres

discriminadores.

Figura 3.9 Comparación de la salida de los diferentes discriminadores de código

Finalmente, el valor de salida del discriminador ¿--zÀÀ se multiplica por el factor 4Á�0,

siendo Á�0 el ancho de banda del ruido del filtro (medido en Hz). Además, el valor de Á�0

depende de la salida del detector de bloqueo de fase. Finalmente, la salida es h0¡�¢¢dd¡d.

La figura 3.10 ilustra lo explicado.

Figura 3.10 Salida completa del discriminador de código

3.5.2 Factor de escala

En la figura 3.11 se muestra el diagrama de la generación de Φ�����Ï.

El error generado por el FPLL debe ser corregido por un factor de escala el cual depende

de la frecuencia de modulación de la señal GNSS 5k y la frecuencia del código PRN 50¡�¢.

31

La salida Φ�����Ï se normaliza por TÑ, el cual es el periodo de muestreo. En la ecuación

(3.6) se muestra la función Φ�����Ï.

Figura 3.11 Generación del factor de escala

Φ�����Ï = 50¡�¢2E5k /d�2E�=��� + 2E�0¡dd + h¢dd¡d ( 3.6)

3.5.3 Oscilador controlado digitalmente (NCO)

Finalmente, para obtener los códigos ;Gd¡jG, ;¢�d£¤, ;£�¢ primero se pasan las señales de

entrada Φ�����Ï y h0¡�¢ ¢dd¡d a través de un oscilador controlado digitalmente NCO y,

junto con la frecuencia del código, se obtiene la salida ΦÇ 0¡�¢. En la figura 3.12 se muestra

el proceso explicado anteriormente.

Figura 3.12 Generación de �Ç ���� a través de un oscilador controlado digitalmente (NCO)

3.6 Generador de códigos réplica

Finalmente, ΦÇ 0¡�¢ se almacena en memoria y a través de un shift register, utilizando el

espaciamiento entre cada código (=0¡dd), se obtienen los códigos ;Gd¡jG, ;¢�d£¤, ;£�¢. =0¡dd es la fracción de un chip y debe ser un múltiplo de la frecuencia de muestreo. En la

figura 3.13 se muestra el diagrama del generador de códigos réplica.

3.7 Detectores de bloqueo

En un sistema GNSS, debemos conocer si la señal está siendo seguida o no, a pesar que se

haya incluido el modulo del sistema de seguimiento dentro del receptor. Por lo tanto, los

detectores de bloqueo servirán para cumplir tal función. Si el detector de bloqueo detecta

32

Figura 3.13 Generación de los códigos PRN

alguna salida que esté fuera del rango definido, el detector de bloqueo tratará de corregirlo.

3.7.1 Detector de bloqueo de fase

Para adaptar los parámetros del filtro, necesitamos recolectar dos tipos de información: el

bloqueador de fase optimista y el bloqueador de fase pesimista.

El bloqueador de fase optimista decide rápido y su cambio de decisión es lento, sin

embargo la salida no es tan confiable como el bloqueador de fase pesimista, el cual decide

más lento que el bloqueador de fase optimista pero cambia más rápido que el bloqueador

de fase optimista [15].

El funcionamiento del detector de bloqueo de fase es de la siguiente forma: Cuando se

active el bloqueo de fase, �o �j� será de valor máximo y Æo �j� será de valor mínimo. Esto

se realiza debido que la fase de la envolvente de la señal está más cercano al eje I y cuando

ocurre el jitter en la fase, la fase de la envolvente oscilará alrededor del eje I.

En la figura 3.14 se muestra el diagrama completo del detector de bloqueo de fase. En esta

etapa, las señales �o �j� y Æo �j� pasan por un filtro pasa bajo y la señal �o �j� se

multiplica con un factor de escala �9 dando dos tipos de salidas, las cuales llamaremos A y

B respectivamente.

Luego, las entradas A y B pasan por un comparador y, dependiendo de los valores

obtenidos, se decide si el valor de A es mayor o menor que B. Si el valor de A es mayor

que el valor de B, el bloqueo de fase optimista se activa y si el valor de A es menor o igual

al valor de B, el bloqueo de fase pesimista se desactiva.

Además, se incorporan dos contadores f� y f9 los cuales sirven para activar el bloqueador

de fase optimista y desactivar el bloqueador de fase pesimista en caso se alcance una

cantidad superior a un valor fijo.

Los valores típicos a utilizar son: �� = 0,0247, �9 = 0,666, Ào = 50 y ÀR = 240.

3.7.2 Detector de bloqueo de código

El detector de bloqueo de código es un estimador C/N0, el cual se utilizará en el detector

de bloqueo falso. Una falta de bloqueo del código puede producir una falla en la

33

estimación de la relación C/N0 y producir una inestabilidad del sistema.

Figura 3.14 Detector de bloqueo de fase

Dentro de esta etapa, el sistema compara la potencia recibida de dos fuentes diferentes: una

fuente en banda ancha y la otra en banda estrecha. En la ecuación (3.7) se muestra el

cálculo de la potencia en banda ancha y en la ecuación (3.8) se muestra el cálculo de la

potencia en banda estrecha [22].

ÒÁf� = (w ��9 + Æ�9Ó� � *� ( 3.7)

)Áf� = (w ��9Ó� � *� + (w Æ�9Ó

� � *� ( 3.8)

Donde:

� �: Salida de la etapa de integración a 1 ms (�o �j�).

� Æ: Salida de la etapa de integración a 1 ms (Æo �j�).

� Ô: Periodo de suma.

Para el caso de una señal GPS C/A, el valor de M es 20 debido a que se tienen que sumar

periodos de 1 ms cada uno para obtener el periodo de la señal GPS C/A. Para el caso del

sistema Galileo E1 OS, 20 ms corresponden a 5 periodos del código CBOC (3,1,1/11).

Luego, se toma la relación de las potencias )Áf� y ÒÁf�, y los resultados obtenidos se

suman para obtener el valor del detector de bloqueo. La ecuación (3.9) muestra lo

explicado anteriormente.

Õ̂�o = 1Ö w )Áf�ÒÁf�×� � ( 3.9)

Donde Ö tiene el valor de 50 y de esta forma se obtendría un periodo de 20*50 ms = 1 s.

Para obtener el valor de la tasa C/N0 estimada se sigue la relación dada en la ecuación

(3.10). En la figura 3.15 se muestra el diagrama de bloques del detector de bloqueo de

34

código.

Donde / es igual a 1 ms.

;)kØ = 10 log�k (1/ Õ̂�o − 1Ô − Õ̂�o* ( 3.10)

Figura 3.15 Detector de bloqueo de código

En la figura 3.16 se muestra la relación entre el valor de bloqueo y la tasa C/N0 estimada y

Figura 3.16 Relación entre el valor de bloqueo y la tasa C/N0 estimada.

3.7.3 Detector de bloqueo falso

La implementación del detector de bloqueo falso es necesario en caso que el sistema de

seguimiento esté trabajando con una frecuencia falsa, la cual ronda alrededor de los 100 Hz

respecto a la frecuencia verdadera. Además, otra razón es debido a que el detector de

bloqueo de fase no detecta la falsa frecuencia en el siguiente caso:

� Bloqueo de fase optimista: falso

� Bloqueo de fase pesimista: falso.

Esto se produce debido a que la salida del discriminador de frecuencia es generalmente de

un valor bajo y el filtro no puede procesar el error de frecuencia correctamente, obteniendo

una incorrecta recuperación del mensaje de la señal.

El detector de bloqueo falso consiste en comparar la tasa C/N0 estimada con respecto a un

umbral donde el detector de fase falle en alcanzar la fase de bloqueo o cuando la detección

35

de las transiciones falle. Para obtener la salida de la frecuencia corregida se integra los

valores de h0¡�¢¢dd¡d, tal como se muestra en la ecuación (3.11).

�0¡dd = 5k50¡�¢1Ö w h0¡�¢¢dd¡d�7 ×

� � ( 3.11)

Un valor común para la integración de h0¡�¢¢dd¡d es 1s. Además, como se están trabajando

con muestras con un periodo de 5 ms, entonces el valor de Ö será 200. @Û@ÜÝ{Þ es un factor de escala de la frecuencia de modulación respecto a la frecuencia del

código PRN de la señal GNSS.

3.8 Detección de la transición de los bits de datos

Este módulo es utilizado solamente por la señal GPS L1 C/A debido a que señal Galileo E1

OS tiene los modos piloto y datos.

Si la tasa C/N0 está por debajo de los 35-36 dBHz, el método de búsqueda de tiempo de

transición mediante histogramas falla. Debido a esto, en esta etapa se propone un método

basado en búsqueda de energía de la señal. Este método tiene la ventaja de obtener una

rápida convergencia hacia un valor óptimo y una rápida actualización en tiempo real del

instante de transición de los integradores. Además, este método reduce la duración de la

fase de transición, debido a que la salida de los discriminadores son valores extremos si los

integradores acumulan códigos PRN rápidamente sobre la transición del bit. La rápida

acumulación de códigos PRN es causado por la inversión de polaridad de los códigos PRN.

Por lo tanto, la convergencia en tiempo real del instante de transición permite sincronizar

en tiempo real los integradores y por consiguiente reducir los valores extremos de los

discriminadores.

Ahora, el método de búsqueda energía funciona de la siguiente manera:

Por cada muestra �o �j� y Æo �j� en un instante n, �� y Æ� respectivamente, se tienen las

ecuaciones (3.12) y (3.13).

U~ = w ������� k ( 3.12)

Uß = w Æ������ k ( 3.13)

Estas dos salidas se utilizan para obtener el módulo U� tal como se muestra en la ecuación

(3.14).

U� = ÍU~9 + Uß9 ( 3.14)

36

Si se desea hacer 20 veces este proceso, se obtendrá 20 posibles alternativas ��� en el

instante de transición de los datos. Ya que existen 20 pseudo periodos de código dentro de

cada bit de información, se deben sumar todas esas 20 posibles alternativas tal como se

muestra en la ecuación (3.15).

��� = w U�,�9k� ( 3.15)

De esa forma se obtiene la alternativa que posea mayor nivel de energía. Cuando aquel

nivel se estabilice durante un tiempo lo suficientemente largo (por lo menos 1 segundo), se

obtendrá el instante de transición y por lo tanto se podrá realizar una adecuada

sincronización. La ecuación (3.16) resume lo explicado.

7 = �|Ã��  j�à�à (3.16)

Finalmente, se debe utilizar un filtro pasa bajo con el fin de variar dinámicamente el

instante de transición. Una alternativa es mostrada en la ecuación (3.17).

�8��,8�U¥8�ℎ-F = 14 w 7£�£ k ( 3.17)

3.9 Demodulación de la señal

En esta última etapa, la señal �o �j� se integra por un periodo de 20 ms y finalmente pasa a

un bloque de decisión el cual posee dos salidas:

� Si la entrada es mayor o igual a cero, su salida es ‘0’.

� Si su entrada es menor que cero, su salida es ‘1’.

De esta forma, se obtiene la información deseada.

Finalmente, la figura 3.17 muestra el diagrama de bloques de la demodulación de la señal.

Figura 3.17 Demodulación de la señal

CAPÍTULO IV IMPLEMENTACIÓN DEL ALGORITMO DE MITIGACIÓN DEL EFECTO

DOPPLER PARA GPS EN UN FPGA 4.1 Introducción

El uso de procesadores a nivel de software en sistemas embebidos ha proporcionado una

gran ventaja respecto a los procesadores a nivel de hardware, debido a que permite su

portabilidad a diferentes dispositivos. En la actualidad existen una gran variedad de estos

tipos de procesadores, siendo el Procesador LEON uno de los más utilizados para

aplicaciones espaciales.

Los procesadores a nivel de software permiten incluir programas escritos en lenguaje

C/C++ para poder ser ejecutados gracias a la creación de los compiladores cruzados,

permitiendo de esta forma que el programador se preocupe en cómo opera el algoritmo y

no se preocupe tanto por su implementación en hardware.

En este capítulo se tratará acerca del Procesador LEON, la implementación del algoritmo

de mitigación del efecto Doppler y el escenario de prueba del algoritmo.

4.2 El Procesador LEON

SPARC (Scalable Processor ARChitecture o Arquitectura de Procesador Escalable) es una

arquitectura CPU basado en el conjunto de instrucciones (ISA), derivado del conjunto de

instrucciones reducido para computadoras (RISC). SPARC permite ser implementado en

una amplia gama de chips y sistemas y está orientada a diferentes aplicaciones, desde uso

comercial hasta trabajos de ingeniería.

El procesador del SPARC posee tres componentes:

� Unidad de punto flotante (FPU): Tiene 32 registros de punto flotante de 32 bits. Un

valor de doble precisión ocupa un par de registros correlativos, y un valor de cuádruple

precisión ocupa un grupo alineado de 4 registros.

Las instrucciones de carga/descarga en punto flotante son utilizadas para mover los datos

entre la FPU y la memoria. Las direcciones de memoria son calculadas por la IU.

� Coprocesador (CP): El coprocesador tiene su propio conjunto de registros que son de 32

bits. Este módulo sirve para utilizar funciones que no contiene el procesador y su uso es

38

opcional.

� Unidad entera (IU): Ejecuta instrucciones aritméticas enteras y calcula las direcciones

de memoria para la carga y almacenamiento de información. También, este componente

mantiene el contador de programa y la ejecución de las instrucciones de control para la

Unidad de punto flotante (FPU) y el Coprocesador (CP).

Además, cada componente del SPARC posee sus propios registros. Para mayor

información sobre SPARC, consultar [23].

La especificación Arquitectura Avanzada para Bus de Microcontroladores AMBA define

un estándar de comunicación sobre chips para microcontroladores embebidos de alto

rendimiento.

El estándar define tres tipos de buses:

� Bus Avanzado de Alto Rendimiento (AHB): Este bus es para módulos del sistema que

requieran un alto rendimiento y trabajen a altas frecuencias de reloj.

� El bus AHB actúa como un backbone y soporta de forma eficiente la conexión de

procesadores, memorias internas y externas y periféricos con funciones macroceldas de

baja potencia.

� Bus Avanzado del Sistema (ASB): Este bus es para módulos de sistema de alto

rendimiento y es adecuado cuando no se requiera de un alto rendimiento comparado con el

bus AHB. El bus ASB soporta los mismos periféricos que el bus AHB.

� Bus Avanzado para Periféricos (APB): Este bus es para periféricos de baja potencia. El

bus APB ha sido optimizado para un mínimo consumo de energía y una reducida

complejidad de las interfaces para la conexión con los periféricos. Además, puede ser

usado con el bus AHB o ASB.

Para mayor información sobre la especificación AMBA consultar [24].

El Procesador LEON es un modelo sintetizable VHDL de un procesador de 32 bits el cual

está acorde con la arquitectura SPARC Versión 8. Este procesador está especialmente

diseñado para aplicaciones embebidas con varias características para sistemas sobre chip,

como instrucciones separadas en la caché de datos, multiplicador y divisor en hardware,

dos temporizadores de 24 bit, dos UART, función de baja potencia, watchdog, puertos de

entrada/salida y un controlador de memoria flexible. También el procesador LEON tiene la

opción de agregar múltiples módulos a través del sistema de buses AMBA 2.0 AHB y

soporta la tecnología Plug and Play.

39

4.3 Arquitectura del Procesador LEON

El Procesador LEON puede ser visto como un diagrama de bloques, tal como se observa en

la figura 4.1 para el caso de una tarjeta Spartan3-1500. La arquitectura del Procesador

LEON está constituida por el Procesador LEON y un conjunto de bloques IP (Propiedad

Intelectual) conectados a través de los buses AMBA AHB/APB.

Figura 4.1 Diagrama de bloques del procesador LEON3 para una tarjeta Spartan3 1500

El diseño es alrededor del bus AMBA donde el procesador LEON3 y otros dispositivos de

alto ancho de banda son utilizados. Se accede a la memoria externa a través de un

controlador combinado de memoria PROM/IO/SRAM/SDRAM. El diseño es altamente

configurable y existen varias características que pueden ser eliminadas si se desea.

La mayor parte del diseño es provista como código fuente a través de la licencia GNU

GPL. Sin embargo, la unidad de punto flotante (GRFPU-Lite) y el enlace SpaceWire está

disponible bajo una licencia comercial y o una licencia de evaluación.

4.3.1 El procesador LEON con arquitectura SPARC V8

Existe una plantilla de diseño del procesador LEON la cual está basada en la arquitectura

SPARC V8. El núcleo del procesador puede ser configurado a través de una configuración

con interfaz de usuario gráfica. La unidad de soporte de depurado del LEON3 (DSU3) está

habilitado por defecto, lo cual permite descargar y depurar los programas a través de un

puerto serial o JTAG. [25]

4.3.2 Interfaces de memoria

La memoria externa es conectada a través de una interfaz que utiliza un controlador de

40

memoria PROM/IO/SRAM/SDRAM (MCTRL). En el caso de una tarjeta Spartan3 1500

se tiene 8 Mbyte de memoria PROM flash y 64 Mbyte de memoria SDRAM, y la memoria

SRAM así como las señales de entrada/salida están disponibles sobre las extensiones de los

conectores.

4.3.3 Registro de estado del AHB

El registro de estado del AHB captura las respuestas de error sobre el bus AHB y bloquea

las direcciones de falla y el dispositivo maestro activo. Aquellos valores permiten al

programa recuperarse de eventos fallidos del sistema.

4.3.4 Enlaces SpaceWire

El sistema puede ser configurado hasta con 3 enlaces SpaceWire y cada enlace es

controlado de forma separada a través del bus APB. Este enlace transfiere la información

transmitida y recibida a través de una transferencia DMA sobre AHB. El enlace SpaceWire

puede ser configurado con soporte RMAP en hardware.

4.3.5 Unidad temporizadora

La unidad temporizadora consiste de un escalador común y hasta siete temporizadores

individuales. El temporizador puede trabajar en modo periódico o en modo de un disparo.

El modo periódico el contador del temporizador opera continuamente cada vez que el

contador alcance el valor cero.

El modo de un disparo el contador del temporizador deja de operar cuando el contador

alcance el valor cero y espera que se ingrese un nuevo valor en el contador.

Además, uno de los temporizadores puede ser configurado como watchdog. El watchdog

permite al procesador recuperarse de algún mal funcionamiento.

4.3.6 Control de interrupción

El control de interrupciones manipula hasta quince interrupciones en dos niveles de

prioridad. La interrupción es automáticamente asignada y routeada al controlador a través

del sistema plug and play de GRLIB.

4.3.7 UART

Uno o dos UARTs pueden ser configurados en el diseño. El UART tiene tamaños FIFO

configurables y tiene generadores de la tasa de baudios.

4.3.8 Puerto entrada/salida de propósito general

Un puerto entrada/salida de propósito general (GPIO) es provisto en el diseño. El puerto

puede ser desde 1 hasta 32 bits de ancho, y cada bit puede ser configurado dinámicamente

como entrada o salida. El GPIO también genera interrupciones desde dispositivos externos.

41

4.3.9 Ethernet

Una interfaz Ethernet puede ser habilitado. La interfaz Ethernet soporta una operación en

10/100 Mbit ya sea en half-duplex o full-duplex. Una interfaz de depuración basada en

Ethernet (EDCL) puede ser habilitada.

4.3.10 Controlador de Área de Red (CAN-2.0)

El Controlador de Área de Red CAN es bus de comunicación serial diseñado para la

industria automotriz. Este bus es inmune a la interferencia eléctrica y puede auto

diagnosticarse y reparar el error de la información [26].

Para el procesador LEON, una o dos interfaces CAN-2.0 pueden ser habilitadas. Esta

interfaz está basada en el núcleo CAN desde OpenCores, con mejoras adicionales.

4.3.11 Controlador VGA

Un controlador de video basado en texto puede ser habilitado. El controlador puede

mostrar una pantalla de 80x48 caracteres sobre un monitor de 640x480.

4.3.12 Interfaz de teclado PS/2

Una interfaz de teclado PS/2 puede ser opcionalmente activado. Este proporciona los scan

codes desde un teclado y tiene un FIFO de 16 bytes.

4.3.13 Generador de reloj

El núcleo del generador de reloj portable es utilizado para generar el procesador y el reloj

de la SDRAM. El generador de reloj puede generar una frecuencia arbitraria multiplicando

o dividiendo la frecuencia de 50 MHz de la placa. El factor de escala del reloj puede ser

configurado.

4.4 Características del Procesador LEON

A continuación se detallan las principales características del Procesador LEON.

4.4.1 Tolerancia a fallas

Es decir, tiene un sistema adecuado de protección de la memoria y de los registros, lo cual

lo hace ideal para aplicaciones dentro del campo militar y aeroespacial. Sin embargo, la

licencia para el Procesador LEON con tolerancia a fallas (LEON3-FT) está disponible bajo

una licencia comercial.

4.4.2 Librería GRLIB

Es un conjunto integrado por núcleos IP reusables, diseñados para el desarrollo de

Sistemas sobre Chip (SoC). Los núcleos IP son centralizados alrededor del bus común

(AMBA) y usa el método coherente para simulación y síntesis.

42

4.4.3 Creación de Código C

Un compilador cruzado (cross compiler) es una herramienta de software el cual convierte

el código fuente de la aplicación en código máquina para un procesador determinado cuya

arquitectura y conjunto de instrucciones son diferentes respecto al procesador donde se está

ejecutando la compilación. Para el desarrollo de sistemas embebidos es típico el uso de

este tipo de compiladores [27].

El Procesador LEON soporta código C/C++ a través de BCC (Bare Cross Compiler). El

compilador BCC está basado en las herramientas del compilador GNU y en las librerías C

Newlib. Además, soporta operaciones de punto flotante a nivel de hardware y software así

como las instrucciones de multiplicación y división en la arquitectura SPARC V8 [28].

BCC consiste de los siguientes paquetes:

1. Compilador GNU GCC C/C++ v3.4.4. y v4.4.2.

2. Librería C Newlib v1.13.1.

3. Rutinas de entrada/salida de bajo nivel para el procesador LEON3, incluyendo soporte

de interrupciones.

4. Micro núcleo IP de la Pila TCP/IP.

5. Depurador GDB v.4 con aplicaciones para el usuario para el Depurador de

Visualización de Datos (DDD), el cual muestra los resultados de la depuración con

gráficos en pantalla.

6. Compilador Mkprom para LEON3/4.

7. Soporte para Linux y Windows (a través de Cygwin).

4.5 Entorno de desarrollo

Actualmente se encuentran disponibles programas para desarrolladores provistos por la

empresa Gaisler, creadora del Procesador LEON [29] [30].

4.5.1 Plugin del Procesador LEON para el entorno Eclipse

Este plugin permite el desarrollo y depuración de aplicaciones en lenguaje C elaborados

para el procesador LEON. También incluye la depuración utilizando GRMON, el cual es

usando una conexión con el procesador LEON implementado en el FPGA, o utilizando

TSIM, el cual es la simulación del procesador LEON en una computadora en caso no se

disponga un FPGA para la implementación del procesador LEON. En la figura 4.2 se

muestra el entorno de desarrollo en Eclipse.

4.5.2 GRMON (Gaisler Research Monitor)

GRMON es un monitor de depuración para el Procesador LEON y para los diseños SoC

43

basados en la librería GRLIB IP. GRMON incluye las siguientes funcionalidades: [29]

Figura 4.2 Entorno de desarrollo de una aplicación para el procesador LEON en Eclipse.

� Acceso de lectura/escritura para todos los registros del sistema y memoria.

� Desensamblador incorporado y gestión del buffer de seguimiento.

� Descarga y ejecución de aplicaciones LEON.

� Gestión de los puntos de ruptura (breakpoint) y puntos de observación (watchpoint).

� Conexión remota al depurador GNU (GDB).

� Soporte para enlaces de depuración utilizando USB, JTAG, RS232, PCI, Ethernet y

SpaceWire.

Figura 4.3 Conexión al procesador LEON a través de un puerto serial utilizando GrmonRCP

44

Sin embargo, GRMON es una aplicación que se utiliza en un terminal (Linux o Windows),

por lo cual se ha creado una aplicación de depuración con interfaz gráfica. Esta aplicación

se llama GrmonRCP y está basado en Eclipse. Esta aplicación está disponible como una

aplicación independiente de GRMON.

En la figura 4.3 se muestra la interfaz de GrmonRCP cuando se configura una conexión

con el procesador LEON a través de un puerto serial. Se observa que en la ventana de

nombre “Choose Target configuration” se escoge el tipo de depuración y la interface a

utilizar para la conexión. Además, se debe seleccionar la ruta del dispositivo y la tasa de

transmisión.

4.6 Arquitectura propuesta

En la figura 4.4 se muestra la arquitectura para el receptor GNSS utilizando el Procesador

LEON3. Se observa que el algoritmo de seguimiento está dentro del Procesador LEON3 y

para tal fin se debe programar el algoritmo en código C. Además, se debe realizar la

síntesis del código VHDL del Procesador LEON3 para la tarjeta a utilizar así como

configurar los registros para la recepción de los datos a través del puerto serial.

Figura 4.4 Arquitectura propuesta para el sistema de seguimiento

Como se puede observar, el código del sistema de seguimiento al estar embebido en el

Procesador LEON3 se puede corregir fácilmente si existe alguna falla en la ejecución del

sistema.

45

4.7 Escenario de pruebas

El escenario de pruebas está conformado por los siguientes componentes:

� Computadora de escritorio: Permite transmitir los datos de entrada hacia el FPGA

mediante puerto serial.

� Laptop: Permite cargar el código del algoritmo al FPGA.

� Tarjeta FPGA: Dispositivo que realizará el procesamiento de la señal. El Procesador

LEON3 ya se encuentra incorporado al FPGA y el FPGA que se usó en este escenario fue

el Digilent Spartan 3E-1600 Development Board (ver ANEXO A).

En la figura 4.5 se muestra un esquema del escenario de pruebas. La laptop, mediante una

comunicación JTAG, permite conectarse al procesador LEON implementado en el FPGA y

de esa forma carga el algoritmo de seguimiento (ver ANEXO B). Mediante una

comunicación serial, se envía la señal GPS hacia el FPGA desde la computadora de

escritorio. A medida que el FPGA va procesando la señal GPS, este va enviando el

seguimiento de la frecuencia Doppler, la fase y retardo de código hacia la Computadora

personal.

Figura 4.5 Diagrama del escenario de pruebas del algoritmo de seguimiento

En la figura 4.6 se muestra una fotografía del escenario de pruebas del algoritmo de

seguimiento.

4.7.1 Herramientas utilizadas

� Eclipse Helios Release 2: Entorno de desarrollo para aplicaciones C.

� Codeblocks 10.01: Entorno de desarrollo para aplicaciones C.

� GRMON 2.0.39 versión académica

� GrmonRCP 0.9.20

� LnxCOMM 1.0

� Compilador cruzado BCC para LEON3/4 gcc-3.4.4 y gcc 4.4.2

� Xilinx ISE Webpack 10.1

� Laptop con sistema operativo Windows 7 de 64 bits

Laptop Tarjeta FPGA Computadora de escritorio

Comunicación JTAG

Comunicación Serial

46

� Computadora con sistema operativo ArchLinux 32 bits

Figura 4.6 Escenario de pruebas del algoritmo de seguimiento

4.7.2 Síntesis del Procesador LEON en el FPGA

Antes de realizar la síntesis se deben configurar los archivos VHDL del Procesador LEON.

Para las pruebas del algoritmo de seguimiento se utilizará la versión 3 del Procesador

LEON y el Procesador de Punto Flotante GRFPU-Lite.

Primeramente se debe descargar el GRLIB de la página de la empresa Gaisler y los netlist

del GRFPU-Lite. Todos los archivos de GRFPU-Lite deben estar dentro de la carpeta de

GRLIB.

Luego, se ingresa al directorio “grlib-gpl-1.3.0-b4133/designs/leon3-digilent-xc3s1600e” y

se escribe el comando “make xconfig” en el terminal, lo cual mostrará la ventana de

configuración del procesador LEON. La ventana de configuración del procesador LEON se

muestra en la figura 4.7.

Figura 4.7 Ventana principal de la configuración del Procesador LEON

Se observa que la ventana de configuración tiene múltiples opciones como la configuración

del procesador, de los buses AMBA, del reloj y de los periféricos. Los valores que figuran

en el procesador son valores por defecto, sin embargo la configuración por defecto no

Laptop

FPGA con el Procesador LEON.

Computadora

47

incluye la unidad de punto flotante.

Para agregar la unidad de punto flotante, se selecciona la opción “Processor” y dentro de

esa ventana se selecciona la opción “Floating-point unit”.

En la figura 4.8 se muestra la ventana de configuración de la unidad de punto flotante. Se

activa la opción “Enable FPU”, se selecciona GRFPU-Lite en “FPU core” y finalmente se

activa el uso de VHDL netlist.

Figura 4.8 Ventana de configuración de la unidad de punto flotante.

Ahora, para iniciar la síntesis del procesador LEON se escribe el comando “make ise” en el

Terminal. Este proceso puede tardar hasta una hora y debe acabar sin errores, caso

contrario se debe verificar los valores ingresados en la configuración.

Ahora, para ejecutar la verificación de la síntesis se escribe el comando “make ise-launch”

y debe mostrase la ventana Xilinx ISE. En la figura 4.9 se muestran los archivos .vhd del

Procesador LEON en el Xilinx ISE.

Para poder realizar la síntesis del procesador LEON en la ventana de Xilinx ISE, se

selecciona la opción Run de la opción Synthesize-XST, tal como se muestra en la figura

4.10.

Una vez terminada la síntesis se continúa con las opciones siguientes:

� Implement Design, realiza el diseño del programa para el FPGA. Une los diferentes

proyectos VHDL creados y realiza el mapeo y enrutamiento de los módulos creados.

� Generate Programming File, genera el archivo .bit el cual será utilizado para incrustarlo

en el FPGA.

48

� Configure Target Device, selecciona el tipo de conexión con el FPGA y carga el archivo

.bit al FPGA.

Figura 4.9 Ventana de Xilinx ISE

Figura 4.10 Opción Synthesize-XST en Xilinx ISE

4.7.3 Configuración de la transmisión serial

La transmisión y recepción de datos a través del puerto serial en un FPGA y utilizando el

Procesador LEON3 es gracias al módulo APBUART, el cual es el UART para el Bus

AMBA APB [25].

El UART soporta trama de datos con 8 bits de datos, un bit de paridad (opcional) y un bit

de parada. Para generar la tasa de transmisión, cada UART tiene un divisor de 12 bits, el

49

cual es programable. También soporta un control de flujo a nivel de hardware a través de

las señales handshake RTSN/CTSN. Finalmente, dos FIFOs son usados para la

transferencia de datos entre el bus y el UART.

En la figura 4.11 se muestra el diagrama de bloques del APBUART.

Figura 4.11 Diagrama de bloques del APBUART

a) Registros del APBUART

El módulo es controlado a través de registros, los cuales fueron mapeados en el espacio de

dirección del APB. En la Tabla 4.1 se muestran los registros del módulo APBUART.

Tabla 4.1 Registros del APBUART

Dirección de desplazamiento en el APB Registro

0x0 Registro de datos del APBUART

0x4 Registro de estado del APBUART

0x8 Registro de control del APBUART

0xC Registro de escala del APBUART

En la figura 4.12 se muestra el Registro de datos del APBUART. Este registro posee

solamente un campo:

� Dato de lectura o escritura en el FIFO: Este campo posee una longitud de 8 bits y

almacena los datos recibidos o a ser transmitidos por el APBUART.

Figura 4.12 Registro de datos del APBUART

50

En la figura 4.13 se muestra el Registro de estado del UART. Este registro posee trece

campos:

� Dato listo (DR): Indica que un nuevo dato está disponible en el receptor.

� Registro de desplazamiento vacío (TS): Indica que el registro de desplazamiento del

transmisor está vacío.

� FIFO transmisor vacío (TE): Indica que el FIFO transmisor está vacío.

� Sentencia Break recibida (BR): Indica que la sentencia BREAK ha sido recibida.

� Sobrecarga (OV): Indica que uno o más caracteres se han perdido en la sobrecarga de

información en el FIFO.

� Error de paridad (PE): Indica que fue detectado un error de paridad.

� Error en la trama (FE): Indica que fue detectado un error en la trama.

� FIFO medio lleno en el transmisor (TH): Indica que el FIFO del transmisor tiene

información de un tamaño menor que el tamaño completo.

� FIFO medio lleno en el receptor (RH): Indica que menos de la mitad de los datos en el

FIFO del receptor están en modo de espera.

� FIFO lleno en el transmisor (TF): Indica que el FIFO del transmisor está lleno.

� FIFO lleno en el receptor (RF): Indica que el FIFO del receptor está lleno.

� Contador en el FIFO del transmisor (TCNT): Indica el número de trama de datos en el

FIFO del transmisor.

� Contador en el FIFO del receptor (RCNT): Indica el número de trama de datos en el

FIFO del receptor.

Figura 4.13 Registro de estado del APBUART

En la figura 4.14 se muestra el Registro de Control del UART. Este registro posee once

campos:

� Receptor activo (RE): Si se selecciona en 1, habilita el receptor.

� Transmisor activo (TE): Si se selecciona en 1, habilita el transmisor.

� Interrupción del receptor activado (RI): Si se selecciona en 1, las interrupciones son

activadas cuando una trama es recibida.

� Interrupción del transmisor activado (TI): Si se selecciona en 1, las interrupciones son

activadas cuando una trama es transmitida.

� Paridad seleccionada (PS): Selecciona el tipo de paridad (0=paridad par, 1=paridad

51

impar).

� Paridad activada (PE): Si se selecciona en 1, activa la generación y la verificación de la

paridad.

� Control de flujo (FL): Si se selecciona en 1, activa el control de flujo por CTS/RTS.

� Loop back (LB): Si se selecciona en 1, el modo loop back será habilitado.

� Reloj externo (EC): Si se selecciona en 1, el escalador del UART será temporizado por

un reloj externo (UARTI.EXTCLK) en vez del reloj del sistema. La frecuencia del reloj

externo debe ser menor que la mitad de la frecuencia del reloj del sistema.

� Interrupción del FIFO en el transmisor activado (TF): Cuando se selecciona en 1, el

nivel de interrupción del FIFO del transmisor será activado.

� Interrupción del FIFO en el receptor activado (RF): Cuando se selecciona en 1, el nivel

de interrupción del FIFO del receptor será activado.

Figura 4.14 Registro de control del APBUART

En la figura 4.15 se muestra el Registro escalador del UART. Este registro posee

solamente un campo:

� Valor de recarga del escalador: Cada UART tiene un escalador de 12 bits para generar la

tasa de baudios deseada. El escalador es temporizado por el reloj del sistema y genera un

pulso en el UART cada vez que este subdesborda8. Esto es recargado con el valor del

registro de recarga del escalador del UART después de cada subdesbordamiento. La

frecuencia del tick del UART resultante sería 8 veces la tasa de baudios deseada.

Figura 4.15 Registro escalador del APBUART

b) Transmisión en el puerto serial

El transmisor está habilitado a través del bit TE en el registro de control del UART. Los

datos que serán transmitidos son almacenados en el FIFO mediante la escritura en el

registro de datos. Además, el tamaño del FIFO es configurable. Cuando el puerto serial

está listo para transmitir, los datos son transmitidos desde el FIFO transmisor hacia el

8 El subdesbordamiento sucede cuando la información que llega es a una tasa de transmisión menor de la que el receptor tiene, por lo tanto si el receptor hace una solicitud de lectura de información este estaría leyendo una información nula.

52

registro de desplazamiento del transmisor y convertidos a un flujo serial sobre el pin de

salida serial del transmisor (TXD). Este automáticamente envía un bit de inicio, seguido de

ocho bits de datos, un bit de paridad (opcional) y un bit de parada. El bit menos

significativo es enviado primero. En la figura 4.16 se muestra la trama de datos de un envío

serial con y sin bit de paridad.

(a) Trama de datos sin paridad

(b) Trama de datos con paridad

Figura 4.16 Trama de datos de un envío serial para una tramas de datos sin paridad (a) y con paridad (b)

Seguido del bit de parada, si un nuevo carácter no está disponible en el FIFO transmisor, la

salida de los datos de transmisión serial permanece en valor alto y el bit del registro de

desplazamiento del transmisor vacío (TS) será seleccionado en registro de estado del

UART. La transmisión se reanuda y el TS se vacía cuando un nuevo carácter es cargado en

el FIFO transmisor. Cuando el FIFO está vacío el bit TE es seleccionado en el registro de

estado del UART. Si el transmisor es deshabilitado, este automáticamente detiene

cualquier transmisión activa incluyendo el carácter que esté siendo sacado del registro de

desplazamiento del transmisor.

El bit de estado TF del registro de estado del UART es seleccionado en 1 si el FIFO

transmisor esté lleno y el bit TH es seleccionado en 1 cada vez que el FIFO esté con una

cantidad de datos de menor de la mitad de su capacidad. El bit de control TF del registro de

control del UART habilita las interrupciones del FIFO cuando se selecciona. El registro de

estado también contiene un contador (TCNT) mostrando el número actual de entrada de

datos en el FIFO.

Si el flujo de control está activado, la entrada CTSN debe ser bajo a fin que el carácter sea

transmitido. Si este es denegado a mitad de la transmisión, el carácter en el registro de

desplazamiento es transmitido y la salida serial del transmisor permanecerá inactivo hasta

que CTSN sea aceptado de nuevo. Si el CTSN está conectado a un receptor RTSN, la

sobrecarga puede ser prevenida.

c) Recepción en el puerto serial

El receptor está habilitado para la recepción de datos a través del bit Receptor Activo (RE)

53

en el registro de control del UART. El receptor busca una transición desde un valor alto

hacia un valor bajo de un bit de inicio sobre la entrada de recepción serial. Si una

transición es detectada, el estado de la señal de entrada es muestreado una mitad del reloj

de bit después. Si la entrada serial es muestreada en alto, el bit de inicio es inválido y la

búsqueda para un bit de inicio válido continúa. Si la entrada serial está todavía en bajo, se

asume un bit de inicio y el receptor continúa muestreando la entrada serial en un bit cada

intervalo de tiempo (en el centro teórico del bit) hasta el número de bits de datos apropiado

y el bit de paridad ha sido ensamblado y un bit de parada ha sido detectado. La entrada

serial es desplazada a través de un registro de desplazamiento de 8 bits, donde todos los

bits deben tener el mismo valor antes que el nuevo valor sea tomado en cuenta, formando

un filtro pasa bajo con una frecuencia de corte de un octavo de la frecuencia de reloj del

sistema.

El receptor también tiene un FIFO configurable el cual es idéntico al FIFO del transmisor.

Durante la recepción, el bit menos significativo es recibido primero. Los datos son luego

enviados al FIFO del receptor y el bit de datos listos (DR) es seleccionado en el registro de

estado del UART tan pronto como el FIFO contenga al menos una trama de datos. Los bits

de paridad, tramado y sobrecarga son seleccionados en la frontera del byte receptor, al

mismo tiempo cuando el bit de Receptor Listo (RE) es seleccionado. La trama de datos no

es almacenada en el FIFO si un error es detectado. También, los nuevos bits de estado de

error son ordenados con los viejos valores antes que ellos sean almacenados en el registro

de estado. De esta forma, estos datos no son limpiados hasta que son escritos con ceros

desde el bus AMBA APB. Si el FIFO del receptor y el registro de desplazamiento están

llenos cuando un nuevo bit de inicio es detectado, entonces el carácter mantenido en el

registro de desplazamiento del receptor será perdido y el bit de sobrecarga será

seleccionado en el registro de estado del UART. Si el flujo de control es habilitado,

entonces el RTSN será negado (señal en alto) cuando un bit de inicio válido es detectado y

el FIFO receptor esté lleno.

d) Configuración de la transmisión desde el computador

En el lado del computador se utilizará la aplicación LnxCOMM, el cual posee librerías en

C las cuales permitirán configurar fácilmente el puerto serial a transmitir [31]. Para

configurar una transmisión de un puerto serial en C, se programará tal como se muestra en

la figura 4.17 (ver ANEXO D). Primeramente, se debe crear un manipulador del puerto

serial el cual será el puente entre el puerto serial y el programa desarrollado. Luego, se

54

debe abrir el puerto serial a utilizar en la transmisión y se debe realizar la configuración de

la tasa de transmisión y la paridad. En este caso se utilizará una tasa de transmisión de

38400 baudios y una paridad 8N1 (8 bits de datos, ningún bit de paridad y 1 bit de parada).

Para el modelo de FPGA (Digilent Spartan 3E-1600 Development Board) utilizado en las

simulaciones, este no soporta control de flujo a nivel de hardware, por lo cual se tiene que

mantener un flujo constante de datos al momento de transmisión y recepción. Debido a

esto la configuración del control de flujo se desactivará. Luego, se abrirá un archivo para

guardar la información recibida por el puerto serial.

Figura 4.17 Configuración del puerto serial en el computador

Ahora, antes de iniciar la transmisión, se debe configurar la misma tasa de baudios, la

paridad y control de flujo en el receptor (FPGA).

Finalmente, se procederá con el envío de datos de la información utilizando el comando

write_port. Este comando permite el envío de la información con una longitud de bits

determinada. Como se va a mantener un flujo constante de datos, se opta por enviar una

cantidad de datos repetitivos cuando no se tenga que enviar información. Para mayor

información sobre la transmisión serial consultar [31].

4.7.4 Generación de la señal GPS desde el computador

La señal GPS a simular se genera conforme a lo explicado en la ecuación (2.13). Dentro

del archivo “Parameters.txt” se guardan los parámetros para diferentes señales GPS y la

relación C/N0 del sistema. La estructura del archivo “Parameters.txt” es lo mostrado en la

HANDLE fd; // Manejador del puerto serial

FILE *SignalFile; // Creación de un puntero hacia un archivo

FILE *pFile; // Creación de un puntero hacia un archivo

fd = Open_Port("/dev/ttyUSB0"); // Abrir el puerto serial

// En el caso de un MS Windows fd=Open_Port("COMX");

// donde X puede ser 1,2,3,..

Configure_Port(fd,B38400,"8N1"); // Configurar puerto serial con una paridad

Set_Hands_Haking(fd,2); // Configurar el control de flujo (opcional)

/* Abrir el archivo de la señal */

SignalFile = fopen(NameSignalFile, "rb");

/* Abrir los archivos para guardar los resultados */

pFile = fopen(NameEstimatedDopplerFile, "w");

55

tabla 4.2. Para mayor detalle del código consultar el ANEXO C.

Luego, un programa generará la señal GPS y lo guardará en un archivo .bin, el cual es un

archivo donde la información de cada dato se guarda en 8 bits. Para poder verificar que la

señal se ha generado de forma adecuada, se utilizará un programa que simula un algoritmo

Tabla 4.2 Valores a ingresar en el archivo “Parameters.txt”

Valores

C/N0 C/N0 de inicio C/N0 de fin

Señal 1 Código PRN de

la señal 1

Retardo en el

tiempo de la

señal 1 (s)

Frecuencia

Doppler (Hz)

de la señal 1

Ganancia de la

señal 1

… … …. …. …

Señal n Código PRN de

la señal n

Retardo en el

tiempo de la

señal n (s)

Frecuencia

Doppler (Hz)

de la señal n

Ganancia de la

señal n

de adquisición GPS. Este programa fue proporcionado por la Université de Bretagne Sud, a

través del Dr. Emmanuel Boutillon, y se basa en un algoritmo desarrollado por esta

universidad donde utilizan Transformadas Rápidas de Fourier en la adquisición. Para

mayores detalles sobre el algoritmo de adquisición, consultar [32] y [33].

Por ejemplo, para generar una señal GPS con las características de la tabla 4.3, la figura

4.18 muestra la salida del algoritmo de adquisición utilizando como señal de prueba el

archivo .bin generado por el programa generador de señales GPS, los cuales muestran el

código PRN de cada señal y sus respectivas frecuencias Doppler, desfasaje y número de

integraciones no coherentes. En la figura 4.19, figura 4.20 y figura 4.21 se muestran la

detección del desfasaje y frecuencia Doppler de cada señal GPS con su respectivo código

PRN utilizando como parámetro el valor máximo de la función de autocorrelación de cada

señal (ACF) y los picos máximos de la función de autocorrelación se encuentran marcados

con un círculo rojo.

Esta etapa es una de las más importantes para la prueba del algoritmo de seguimiento,

debido a que una mala adquisición de las señales GNSS no permitirá seguir

adecuadamente la señal. La salida de esta etapa servirá para dar valores iniciales a la

56

frecuencia Doppler, retardo y número de integraciones del código PRN de la señal GNSS.

Tabla 4.3 Señales GPS de prueba

Valores

C/N 40 40

Señal 1 1 0.00015 156 1

Señal 2 2 0.0002 110 0.8

Señal 3 9 0.0004 130 0.8

Señal 4 12 0.0003 120 0.8

Señal 5 7 0.0002 140 0.7

Señal 6 15 0.0001 150 0.9

Señal 7 26 0.0001 120 0.5

Figura 4.18 Salida del programa de adquisición de señales GNSS

>>Lecture Fichier signal

Lecture OK

(01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

28 29 30 31 32)

Bilan de la phase d'acquisition

-----------------------------------------------------------------

| PRN | Doppler (Hz) | Desfasaje (Muestras) | Nbr de int no-coh |

-----------------------------------------------------------------

| 01 | +1.56250e+02 | 6.140e+02 | 2 |

| 02 | +1.56250e+02 | 8.180e+02 | 2 |

| 15 | +1.56250e+02 | 4.090e+02 | 2 |

-----------------------------------------------------------------

57

Figura 4.19 Detección del desfasaje y la frecuencia Doppler para la señal con PRN 1

Figura 4.20 Detección del desfasaje y la frecuencia Doppler para la señal con PRN 2

-5 -4 -3 -2 -1 0 1 2 3 4 5-30

-20

-10

0Satélite PRN : 1

Doppler (kHz)

AC

F (

dB)

0 500 1000 1500 2000 2500 3000 3500 4000 4500-40

-30

-20

-10

0

Desfasaje (muestras)

AC

F (

dB)

-5 -4 -3 -2 -1 0 1 2 3 4 5-30

-20

-10

0Satélite PRN : 2

Doppler (kHz)

AC

F (

dB)

0 500 1000 1500 2000 2500 3000 3500 4000 4500-40

-30

-20

-10

0

Desfasaje (muestras)

AC

F (

dB)

58

Figura 4.21 Detección del desfasaje y la frecuencia Doppler para la señal con PRN 15

-5 -4 -3 -2 -1 0 1 2 3 4 5-30

-20

-10

0Satélite PRN : 15

Doppler (kHz)

AC

F (

dB)

0 500 1000 1500 2000 2500 3000 3500 4000 4500-40

-30

-20

-10

0

Desfasaje (muestras)

AC

F (

dB)

CAPÍTULO V ANÁLISIS DE RESULTADOS

5.1 Síntesis del Procesador LEON en la Tarjeta Digilent Spartan 3E-1600

Development Board

Los resultados de la síntesis son mostrados en la tabla 5.1. Se observa que el porcentaje de

los componentes utilizados en el FPGA no sobrepasan el 40%, por lo cual habría recursos

físicos disponibles para poder realizar una implementación de algún componente en el

FPGA.

Tabla 5.1 Resultados de la síntesis del Procesador LEON

Utilización lógica Usado Disponible Utilización

(%)

Número de Slices 125 14752 1

Número de LUTs (Look-Up Tables)

de 4 entradas 219 29504 1

Número de bonded IOBs 98 250 39

5.2 Implementación del algoritmo de seguimiento en el Procesador LEON

Se realizaron diversas pruebas del funcionamiento del algoritmo de seguimiento utilizando

diferentes relaciones C/N0, retardos y frecuencias Doppler diferentes.

Para la prueba del algoritmo se utilizaron los parámetros mostrados en la tabla 5.2. La tabla

5.2 muestra la tasa C/N0 utilizada así como el retardo que insertó en las pruebas y la

frecuencia Doppler que se utilizó. El canal de transmisión es un canal gaussiano y las

pruebas fueron para una transmisión de 30 segundos.

En la tabla 5.3 se muestran los resultados obtenidos como son las desviaciones estándar de

la salida del seguimiento de la frecuencia Doppler y del retardo para cada tasa C/N0.

Además, se muestran la media y mediana del retardo y de la estimación de la tasa C/N0

para cada tasa C/N0.

60

La duración de cada prueba fue de 15 minutos como mínimo. Como se puede observar la

duración de la prueba del algoritmo es alta.

Se observa que la mayoría de las desviaciones estándar de la frecuencia Doppler son

menores a 0.88 Hz y la mayoría de las desviaciones estándar del retardo son menores a 40

us. El estimador C/N0 obtuvo los resultados que en su mayoría son diferentes a los

ingresados por la señal y esto es debido a la interferencia de las demás señales, el retardo y

el efecto Doppler.

En la figura 5.1 se observa que durante las primeras fracciones de segundo, la estimación

de la frecuencia Doppler estaba alrededor de 162 Hz, sin embargo, el sistema logro seguir

a la frecuencia Doppler de entrada, el cual era de 156 Hz.

Tabla 5.2 Parámetros de la prueba

Parámetro Valor

C/N0 (dB-Hz) 40-42 con un paso de 0.5

PRN 1

Retardo (us) 150

Frecuencia Doppler (Hz) 156

Canal Canal gaussiano.

Tiempo de prueba (s) 30

Tabla 5.3 Resultados de la implementación del algoritmo de seguimiento en el Procesador LEON

C/N0

(dB-

Hz)

Desviación

estándar

Doppler

(us)

Media

retardo

(us)

Mediana

Retardo

(us)

Desviación

estándar

del retardo

(us)

Media

C/N0

(dB-

Hz)

Mediana

C/N0

(dB-Hz)

Desviación

estándar

C/N0 (dB-

Hz)

40 0,43 142,08 150,49 31,51 39,56 39,51 1,27

40 0,75 145,52 151,83 43,37 36,50 36,87 0,98

40 0,65 145,10 151,45 36,10 34,54 34,47 1,15

40 0,45 148,67 153,36 27,97 36,63 36,68 0,89

40,5 0,52 143,01 151,51 25,56 41,03 40,81 1,08

40,5 0,62 141,56 150,36 26,60 40,78 40,70 0,80

61

40,5 0,37 149,20 153,72 27,21 37,45 37,42 0,80

40,5 0,41 149,43 153,33 26,71 36,88 36,89 0,95

41 0,63 134,29 142,79 30,21 41,09 41,24 1,30

41 0,31 146,61 151,86 30,10 38,18 38,33 1,14

41 0,32 145,25 150,54 28,54 39,10 39,22 1,42

41 0,37 140,07 149,92 29,22 41,34 41,27 1,48

41,5 0,34 145,31 152,81 23,92 41,88 41,70 0,85

41,5 0,27 150,00 153,84 23,70 39,12 39,25 1,15

41,5 0,32 146,66 153,08 25,38 41,35 41,35 1,17

41,5 1,26 148,98 153,95 34,07 33,70 33,94 1,16

42 0,31 145,35 152,89 25,03 42,30 42,27 1,65

42 0,26 150,51 153,75 29,29 39,16 39,26 1,03

42 0,24 150,11 153,68 26,74 39,80 39,78 0,69

42 0,25 147,87 153,23 21,45 41,45 41,42 0,87

Figura 5.1 Seguimiento de la frecuencia

Las figuras 5.2 y 5.3 muestran los resultados obtenidos de las pruebas de desempeño del

algoritmo deducibles de la tabla 5.3. En la figura 5.2 se muestra la gráfica de la mediana de

C/N0 vs la desviación estándar de la frecuencia Doppler. Se observa que a medida que va

aumentando la relación C/N0 va disminuyendo la desviación estándar de la frecuencia

Doppler.

De igual manera, en la figura 5.3 se muestra la gráfica de la mediana de C/N0 vs la

desviación estándar del retardo. Se observa que a medida que va aumentando la relación

C/N0 va disminuyendo la desviación estándar del retardo.

De estas dos últimas gráficas se comprueba el buen desempeño que ofrece el algoritmo de

0 1 2 3 4 5 6 7 8 9 10153

154

155

156

157

158

159

160

161

162

163

Time (s)

Est

imat

ed D

oppl

er (

Hz)

62

seguimiento en las pruebas. Por lo cual las mejoras a realizarse serían para reducir el

tiempo de procesamiento del algoritmo de seguimiento.

Figura 5.2 Gráfica desviación estándar de la frecuencia Doppler (Hz) vs el valor C/N0 estimado (dB-Hz)

Figura 5.3 Gráfica desviación estándar del retardo (us) vs el valor C/N0 estimado (dB-Hz)

0,00

0,20

0,40

0,60

0,80

1,00

1,20

1,40

33,00 35,00 37,00 39,00 41,00 43,00

Sig

ma

Dop

pler

(H

z)

C/N0 estimado (dB-Hz)

0,005,00

10,0015,0020,0025,0030,0035,0040,0045,0050,00

33,00 35,00 37,00 39,00 41,00 43,00

Sig

ma

Ret

ardo

(us)

C/N0 estimado (dB-Hz)

CONCLUSIONES Y RECOMENDACIONES Conclusiones

1. Teniendo como resultado la disminución de la desviación estándar de la frecuencia

Doppler y del retardo a medida que aumenta la relación C/N0, se concluye que el

algoritmo de seguimiento desarrollado en la tesis cumple los requerimientos básicos de

un algoritmo de seguimiento GNSS en el espacio.

2. Además, teniendo en cuenta que el procesador LEON funciona adecuadamente e

incluso ocupa menos del 50% de los recursos del FPGA, se concluye que el procesador

no consume recursos importantes y se podría implementar en dispositivos de menos

recursos.

3. Teniendo como resultado un alto tiempo de procesamiento del algoritmo, se concluye

que aún el tiempo de procesamiento del algoritmo es aún insuficiente y es necesario

disminuirlo.

Recomendaciones

1. Se recomienda realizar la implementación en VHDL de las etapas del algoritmo de

seguimiento como continuación del tema de tesis, debido a que algunos módulos del

algoritmo de seguimiento requieren mucho tiempo de procesamiento de las señales

GNSS. La implementación sería principalmente en el módulo de correlación e

integración, los cuales requieren mayores recursos de hardware.

2. Se recomienda realizar la implementación de las demás etapas del receptor GNSS para

futuros temas de tesis, como son el algoritmo de adquisición y el algoritmo para el

cálculo de la actitud. De esta forma se obtendría el diseño completo de un receptor

GNSS.

3. Debido a que el algoritmo de seguimiento para GPS desarrollado es escalable. Se

sugiere adaptar este algoritmo a otros sistemas como GLONASS o Beidou. De esa

forma se obtendría una mayor precisión en el cálculo de la posición del receptor debido

al aumento del número de satélites porporcionado por cada sistema GNSS.

ANEXO A Hoja de datos de la Digilent Spartan 3E-1600 Dev. Board

65

Digilent Spartan 3E-1600 Development Board

IC: XC3S1600E Spartan 3E FPGA Analog Devices ADM3232EARNZ RS-232 Line Driver/Receiver

Connector(s):

100-pin Hirose FX2 connector Three 6-pin Pmod connectors DB15HD VGA Two DB9 RS-232 connectors RJ-45 Ethernet 16-pin header for optional LCD modules SMA connector for high-speed clock input

Programming:

JTAG programming via on-board USB2 port, external parallel or USB cables. The FPGA supports numerous configuration options including on-board platform flash, SPI flash, and parallel flash.

• Xilinx XC3S1600E FPGA • Xilinx XCF04 Platform Flash for

storing FPGA configurations • ST Microelectronics M25P16

16Mbit Serial Flash • Intel TE28F128 (or JS28F128)

128Mbit StartaFlash • Linear Technologies Power

Supplies • Texas Instruments TPS75003

Triple-Supply Power Management IC

• SMSC LAN83C185 Ethernet PHY • Micron 256Mbit DDR SDRAM

The Spartan 3E-1600 Development Board provides a powerful and highly advanced self-contained development platform for designs targeting the Spartan 3E FPGA from Xilinx. It features a 1600K gate Spartan 3E capable of implementing large complex digital systems including the 32-bit MicroBlaze RISC soft processor with DDR interfaces. The board features JTAG programming via on-board USB2 port, external parallel or USB cables. The FPGA supports configuration via the on-board Xilinx platform flash, Intel StrataFlash, ST Microelectonics Serial Flash and numerous additional options. It is fully compatible with all versions of the Xilinx ISE tools including the free WebPack. The board ships with a power supply and USB cable for programming so designs can be implemented immediately with no hidden costs. The Spartan 3E-1600 Development Board is also compatible with the Xilinx Embedded Development Kit (EDK) featuring the 32-bit MicroBlaze RISC processor. The PicoBlaze soft processor core is also supported via ISE.

ANEXO B Código Bare C del algoritmo de seguimiento GNSS

67

“main.c”

1. #include <asm-leon/irq.h>

2. #include <stdio.h>

3. #include <stdlib.h>

4. #include <string.h>

5. #include <math.h>

6. #include "address.h"

7. /* Functions */

8. #include "Constants.h"

9. #include "structures_recepteur.h"

10. #include "code_gene_GPS.h"

11. #include "initRecepteur.h"

12. #include "falseLockDetector.h"

13. #include "localCodeGenerator.h"

14. #include "dopplerEstime.h"

15. #include "fpll.h"

16. #include "code_discriminator.h"

17. #include "integrator.h"

18. #include "dataDemodulation.h"

19. #include "bitSynchro.h"

20. #include "codeLockDetector.h"

21. #include "correlateurComplet.h"

22. #include "localCarrierGenerator.h"

23. #include "filter.h"

24. #include "codeNCO.h"

25. #include "canal_Bruit.h"

26. /**************************************/

27. /* Recepteur GNSS */

28. /**************************************/

29. int main(){

30. int reg;

31. int *UART;

32. UART = (int*) 0x80000100;

68

33. UART[0] = UART[0] & 0xFFFFFF00;

34. reg = UART[0];

35. reg = reg & 0xFFFFFF00;

36. reg = UART[1];

37. reg = UART[2];

38. reg = reg | 0x00000043;

39. reg = reg & 0xFFFFFF43;

40. UART[2] = reg;

41. double data_base=0.0;

42. double data_exp=0.0;

43. double data1=0.0;

44. precepteurS = &recepteurS;

45. scanf("%12lf",&data_base);

46. data1=data_base;

47. printf("%+12.9lf\n",data_base);

48. scanf("%12lf",&data_exp);

49. printf("%+12.8lf\n",data_exp);

50. data1 = data1*pow(10,data_exp);

51. precepteurS->Sreceive_data._DopplerEstime = data1;

52. scanf("%12lf",&data_base);

53. data1=data_base;

54. printf("%+12.9lf\n",data_base);

55. scanf("%12lf",&data_exp);

56. printf("%+12.8lf\n",data_exp);

57. data1 = data1*pow(10,data_exp);

58. precepteurS->Sreceive_data._DephasageEstime = data1;

59. //scanf("%s",data);

60. scanf("%12lf",&data_base);

61. data1=data_base;

62. printf("%+12.9lf\n",data_base);

63. scanf("%12lf",&data_exp);

64. printf("%+12.8lf\n",data_exp);

65. data1 = data1*pow(10,data_exp);

69

66. precepteurS->Sreceive_data._NbIntegration = data1;

67. scanf("%12lf",&data_base);

68. data1=data_base;

69. printf("%+12.9lf\n",data_base);

70. scanf("%12lf",&data_exp);

71. printf("%+12.8lf\n",data_exp);

72. data1 = data1*pow(10,data_exp);

73. precepteurS->Sreceive_data._PRN = (int)data1;

74. scanf("%12lf",&data_base);

75. data1=data_base;

76. printf("%+12.9lf\n",data_base);

77. scanf("%12lf",&data_exp);

78. printf("%+12.8lf\n",data_exp);

79. data1 = data1*pow(10,data_exp);

80. precepteurS->Sreceive_data._Time_NS = data1;

81. /** --------------------- Functions ------------------- **/

82. precepteurS = initFilter(precepteurS);

83. precepteurS = acquisition_parameters(precepteurS);

84. precepteurS = initGene(precepteurS);

85. precepteurS = initCorrelateur(precepteurS);

86. precepteurS = initCodeLockDetector(precepteurS);

87. precepteurS = initPhaseLockDetector(precepteurS);

88. precepteurS = initIntegrator(precepteurS);

89. precepteurS = initBitSynchro(precepteurS);

90. precepteurS = initDiscri(precepteurS);

91. precepteurS = initFiltreFPLL(precepteurS);

92. precepteurS = initCodeDiscriminator(precepteurS);

93. precepteurS = initFalseLockDetector(precepteurS);

94. precepteurS = initCodeNCO(precepteurS);

95. precepteurS = initLocalCodeGenerator(precepteurS);

96. precepteurS = initDataDemodulation(precepteurS);

97. precepteurS = initDoppleEstime(precepteurS);

98. FCanalBruit(precepteurS);

70

99. return 0;

100. }

“address.h”

1. #ifndef __address_h__

2. #define __address_h__

3. #ifndef LEON3

4. #define LEON3

5. #endif

6. #ifdef LEON3

7. #define ICLEAR 0x20c

8. #define IMASK 0x240

9. #define IFORCE 0x208

10. #else

11. #define ICLEAR 0x9c

12. #define IMASK 0x90

13. #define IFORCE 0x98

14. #endif

15. #endif

“bitSynchro.h”

1. #ifndef BITSYNCHRO_H_

2. #define BITSYNCHRO_H_

3. struct recepteur *FbitSynchro(struct recepteur *precepteurS){

4. int i;

5. /* Mémorisation du module de la voie prompt */

6. precepteurS->Sbitsynchro._IndexData = (int)precepteurS-

>Scorrelateur_prompt.SynchroBit_Rxx[0];

7. precepteurS->Sbitsynchro._CodeLock = precepteurS-

>Scodelock_detector.CodeLock;

8. precepteurS->Sbitsynchro.DataBufferRe[precepteurS->Sbitsynchro._IndexData]

= precepteurS->Scorrelateur_prompt.SynchroBit_Rxx[1];

9. precepteurS->Sbitsynchro.DataBufferIm[precepteurS->Sbitsynchro._IndexData]

= precepteurS->Scorrelateur_prompt.SynchroBit_Rxx[2];

10. if (precepteurS->Sbitsynchro.Synchro == 0){

71

11. /* Intégration du buffer tournant */

12. precepteurS->Sbitsynchro.IntegrationRe = 0;

13. precepteurS->Sbitsynchro.IntegrationIm = 0;

14. for (i = 0 ;i<20;i++){

15. precepteurS->Sbitsynchro.IntegrationRe += precepteurS-

>Sbitsynchro.DataBufferRe[i];

16. precepteurS->Sbitsynchro.IntegrationIm += precepteurS-

>Sbitsynchro.DataBufferIm[i];

17. }

18. /* Calcul du module résultant */

19. precepteurS->Sbitsynchro.Module = sqrt(pow(precepteurS-

>Sbitsynchro.IntegrationRe,2.0)+pow(precepteurS-

>Sbitsynchro.IntegrationIm,2.0));

20. // Gestion de l'index du buffer circulaire

21. if (precepteurS->Sbitsynchro._IndexData == 19){

22. precepteurS->Sbitsynchro.LockRecherche = 1;

23. precepteurS->Sbitsynchro.IndexBuffer = 0;

24. /* Recherche du maximum d'energie */

25. // 1re condition de recherche de l'instant de synchronisation

26. for (i = 0 ;i<20;i++){

27. if (precepteurS->Sbitsynchro.AccBuffer[i] > precepteurS-

>Sbitsynchro.AccBuffer[precepteurS->Sbitsynchro.IndiceMax]){

28. precepteurS->Sbitsynchro.IndiceMax = i;

29. precepteurS->Sbitsynchro.NbHits = 0;

30. }

31. }

32. precepteurS->Sbitsynchro.NbHits += 1;

33. precepteurS->Sbitsynchro.TabMoyenne[precepteurS-

>Sbitsynchro.IndiceMoyenne] = precepteurS->Sbitsynchro.IndiceMax;

34. if (precepteurS->Sbitsynchro.IndiceMoyenne == Const_TailleFiltre - 1)

35. precepteurS->Sbitsynchro.IndiceMoyenne = 0;

36. else

37. precepteurS->Sbitsynchro.IndiceMoyenne += 1;

72

38. // Filtrage

39. precepteurS->Sbitsynchro.AccMoyenne = 0;

40. for (i=0;i<Const_TailleFiltre;i++)

41. precepteurS->Sbitsynchro.AccMoyenne += precepteurS-

>Sbitsynchro.TabMoyenne[i];

42. precepteurS->Sbitsynchro._InstantSynchro = (int)((double)precepteurS-

>Sbitsynchro.AccMoyenne/(double)Const_TailleFiltre);

43. #ifdef OUTPUTFILE

44. //fprintf(thread_data_recepteur->bitsynchro_struct->pFile1,"IndiceMax :

%d : InstantSynchro : %d\n",thread_data_recepteur->bitsynchro_struct-

>IndiceMax,thread_data_recepteur->bitsynchro_struct->_InstantSynchro);

45. send_data_int(precepteurS->Sbitsynchro.IndiceMax);

46. send_data_int(precepteurS->Sbitsynchro._InstantSynchro);

47. #endif

48. precepteurS->Sbitsynchro.InstantSynchro = precepteurS-

>Sbitsynchro._InstantSynchro;

49. precepteurS->Sbitsynchro.DataDemodulation_InstantSynchro =

precepteurS->Sbitsynchro._InstantSynchro;

50. precepteurS->Sbitsynchro.CodeLock_InstantSynchro = precepteurS-

>Sbitsynchro._InstantSynchro;

51. }

52. else

53. precepteurS->Sbitsynchro.IndexBuffer += 1;

54. // Accumulation de l'intégration avec les précédents résultats

55. if (precepteurS->Sbitsynchro.LockRecherche){

56. precepteurS->Sbitsynchro.AccBuffer[precepteurS-

>Sbitsynchro.IndexBuffer] += precepteurS->Sbitsynchro.Module;

57. }

58. }

59. else

60. if (precepteurS->Sbitsynchro._CodeLock == 0){

61. //initBitSynchro();

62. for (i=0;i<20;i++)

73

63. precepteurS->Sbitsynchro.AccBuffer[i] = 0;

64. precepteurS->Sbitsynchro.LockRecherche = 0;

65. precepteurS->Sbitsynchro.IndiceMax = 0;

66. precepteurS->Sbitsynchro._IndexData = 0;

67. precepteurS->Sbitsynchro.NbHits = 0;

68. precepteurS->Sbitsynchro.Synchro = 0;

69. precepteurS->Sbitsynchro.IndexBuffer = 0;

70. precepteurS->Sbitsynchro.IndiceMoyenne = 0;

71. for (i=0;i<Const_TailleFiltre;i++)

72. precepteurS->Sbitsynchro.TabMoyenne[i] = 0;

73. precepteurS->Sbitsynchro.FalseLockDetector_SynchroLock[0] =

precepteurS->Sbitsynchro.Synchro;

74. precepteurS->Sbitsynchro.FalseLockDetector_SynchroLock[1] = 0;

75. }

76. if (precepteurS->Sbitsynchro.NbHits >=50){

77. if (precepteurS->Sbitsynchro._CodeLock == 1){

78. if (precepteurS->Sbitsynchro.Synchro == 0){

79. precepteurS->Sbitsynchro.Synchro = 1;

80. precepteurS->Sbitsynchro.FalseLockDetector_SynchroLock[0] =

precepteurS->Sbitsynchro.Synchro;

81. precepteurS->Sbitsynchro.FalseLockDetector_SynchroLock[1] = 0;

82. }

83. }

84. else{

85. precepteurS->Sbitsynchro.NbHits = 0;

86. precepteurS->Sbitsynchro.Synchro = 0;

87. precepteurS->Sbitsynchro.FalseLockDetector_SynchroLock[0] =

precepteurS->Sbitsynchro.Synchro;

88. precepteurS->Sbitsynchro.FalseLockDetector_SynchroLock[1] = 1;

89. }

90. }

91. FdataDemodulation(precepteurS);

92. return precepteurS;

74

93. }

94. #endif /* BITSYNCHRO_H_ */

“canal_Bruit.h”

1. #ifndef CANAL_BRUIT_H_

2. #define CANAL_BRUIT_H_

3. void FCanalBruit(struct recepteur *precepteurS){//, int *UART){

4. int i;

5. int samples;

6. double _I,_Q;

7. double data_base;

8. double data_exp;

9. double data1;

10. double data;

11. samples = (int)(precepteurS->Sreceive_data._Time_NS/122.05);

12. precepteurS->clockGNSS = (int)1000000000/122.05;

13. for(i=0;i<samples;i++){

14. scanf("%12lf",&data_base);

15. data1=data_base;

16. printf("%+12.9lf\n",data_base);

17. scanf("%12lf",&data_exp);

18. printf("%+12.8lf\n",data_exp);

19. data1 = data1*pow(10,data_exp);

20. _I = data1;

21. scanf("%12lf",&data_base);

22. data1=data_base;

23. printf("%+12.9lf\n",data_base);

24. scanf("%12lf",&data_exp);

25. printf("%+12.8lf\n",data_exp);

26. data1 = data1*pow(10,data_exp);

27. _Q = data1;

28. precepteurS->Scanal.I_out = _I;

29. precepteurS->Scanal.Q_out = _Q;

30. if(i%precepteurS->clockGNSS == 0)

75

31. falseLock5(precepteurS);

32. FcodeNCO(precepteurS);

33. Ffilter(precepteurS);

34. for(i=0;i<2;i++){

35. scanf("%12lf",&data);

36. if(precepteurS->estado[i] == 1){

37. printf("%+12.9lf\n",precepteurS->data_base[i]);

38. scanf("%12lf",&data);

39. printf("%+12.8lf\n",precepteurS->data_exp[i]);

40. }

41. else{

42. printf("%+12.9lf\n",data);

43. scanf("%12lf",&data);

44. printf("%+12.8lf\n",data);

45. }

46. precepteurS->estado[i] = 0.0;

47. }

48. }

49. }

50. #endif /* CANAL_BRUIT_H_ */

“code_Discriminator.h”

1. #ifndef CODE_DISCRIMINATOR_H_

2. #define CODE_DISCRIMINATOR_H_

3. /** StateMacBandwidth **/

4. struct recepteur *StateMacBandwidth(struct recepteur *precepteurS){

5. // Section 4.9 Expert Report (Bnc)

6. //Machine d'état

7. precepteurS->Scode_discriminateur._OptimisticPhaseLock = precepteurS-

>Scodelock_detector.CodeDiscriLock[0];

8. precepteurS->Scode_discriminateur._PessimisticPhaseLock = precepteurS-

>Scodelock_detector.CodeDiscriLock[1];

9. if (precepteurS->Scode_discriminateur._OptimisticPhaseLock == 1){

10. if (precepteurS->Scode_discriminateur._PessimisticPhaseLock == 1){

76

11. if (precepteurS->Scode_discriminateur.Bdll>0.1)

12. precepteurS->Scode_discriminateur.Bdll-=0.001;

13. }

14. else

15. precepteurS->Scode_discriminateur.Bdll=1.0;

16. }

17. else

18. precepteurS->Scode_discriminateur.Bdll=2.0;

19. return precepteurS;

20. }

21. /** Discriminator **/

22. struct recepteur *Discriminator(struct recepteur *precepteurS){

23. precepteurS->Scode_discriminateur._PromptReRxxInt = precepteurS-

>Sintegrator.PromptRxxInt[0];

24. precepteurS->Scode_discriminateur._PromptImRxxInt = precepteurS-

>Sintegrator.PromptRxxInt[1];

25. precepteurS->Scode_discriminateur._EarlyReRxxInt = precepteurS-

>Sintegrator.EarlyRxxInt[0];

26. precepteurS->Scode_discriminateur._EarlyImRxxInt = precepteurS-

>Sintegrator.EarlyRxxInt[1];

27. precepteurS->Scode_discriminateur._LateReRxxInt = precepteurS-

>Sintegrator.LateRxxInt[0];

28. precepteurS->Scode_discriminateur._LateImRxxInt = precepteurS-

>Sintegrator.LateRxxInt[1];

29. #ifdef OUTPUTFILE

30. send_data_double(precepteurS->Scode_discriminateur._PromptReRxxInt);

31. send_data_double(precepteurS->Scode_discriminateur._EarlyReRxxInt);

32. send_data_double(precepteurS->Scode_discriminateur._LateReRxxInt);

33. #endif

34. // Test d'un autre discriminateur page 174 Kaplan : Noncoherent early minus late

35. // Section 4.4.1 Expert Report

36. precepteurS->Scode_discriminateur.E = sqrt(pow(precepteurS-

>Scode_discriminateur._EarlyReRxxInt, 2.0) + pow(precepteurS-

77

>Scode_discriminateur._EarlyImRxxInt, 2.0));

37. precepteurS->Scode_discriminateur.L = sqrt(pow(precepteurS-

>Scode_discriminateur._LateReRxxInt, 2.0) + pow(precepteurS-

>Scode_discriminateur._LateImRxxInt, 2.0));

38. precepteurS->Scode_discriminateur.EplusL = precepteurS-

>Scode_discriminateur.E + precepteurS->Scode_discriminateur.L;

39. if (precepteurS->Scode_discriminateur.EplusL != 0)

40. precepteurS->Scode_discriminateur.Discri = 0.5*(precepteurS-

>Scode_discriminateur.E - precepteurS-

>Scode_discriminateur.L)/precepteurS->Scode_discriminateur.EplusL;

41. else

42. precepteurS->Scode_discriminateur.Discri = 0;

43. // Filtre

44. // Section 4.4.2 Expert Report

45. precepteurS->Scode_discriminateur.DiscriFiltre = 4*precepteurS-

>Scode_discriminateur.Bdll/Const_Fe_re*precepteurS-

>Scode_discriminateur.Discri;

46. #ifdef OUTPUTFILE

47. //fprintf(my_data->code_discriminateur_struct->pFile1,"%g\n",my_data-

>code_discriminateur_struct->Discri);

48. //VDLLFile<<Discri<<std::endl;

49. send_data_double(precepteurS->Scode_discriminateur.Discri);

50. //fprintf(my_data->code_discriminateur_struct->pFile2,"%g\n",my_data-

>code_discriminateur_struct->Bdll);//BDLLFile<<Bdll<<std::endl;

51. send_data_double(precepteurS->Scode_discriminateur.Bdll);

52. #endif

53. /* Sortie du discriminateur de code */

54. precepteurS->Scode_discriminateur.NCO_VeDLL = precepteurS-

>Scode_discriminateur.DiscriFiltre;

55. precepteurS->Scode_discriminateur.DopplerEstimator_VeDLL = precepteurS-

>Scode_discriminateur.DiscriFiltre;

56. precepteurS->Scode_discriminateur.FalseLockDetector_VeDLL = precepteurS-

>Scode_discriminateur.DiscriFiltre;

78

57. // Le discri du Kaplan a l'air plus performant que celui de M3S

58. return precepteurS;

59. }

60. /** ----------------- Init Code Discriminator ----------------- **/

61. struct recepteur *Fcode_discriminator(struct recepteur *precepteurS){

62. if(precepteurS->Sintegrator.DumpEnable == 1){

63. /* StateMacBandwidth */

64. StateMacBandwidth(precepteurS);

65. /* Discriminator */

66. Discriminator(precepteurS);

67. Ffpll(precepteurS);

68. FfalseLock(precepteurS);

69. }

70. return precepteurS;

71. }

72. #endif /* CODE_DISCRIMINATOR_H_ */

“code_gene_GPS.h”

1. #include <stdio.h>

2. #include <stdlib.h>

3. void ones(int *t,int n){

4. int i;

5. for(i=0;i<n;i++)

6. *(t+i)=1;

7. }

8. int xor(int a,int b){

9. if(a==b)

10. return 0.0;

11. else

12. return 1.0;

13. }

14. void code_gene_GPS(struct recepteur *precepteurS)

15. {

16. int CoupleSV[32][2]={{2,6},{3,7},{4,8},{5,9},{1,9},{2,10},{1,8},{2,9},{3,10},

79

{2,3},{3,4},{5,6},{6,7},{7,8},{8,9},{9,10},{1,4},{2,5},{3,6},{4,7},

{5,8},{6,9},{1,3},{4,6},{5,7},{6,8},{7,9},{8,10},{1,6},{2,7},{3,8},{4,9}};

17. int vecteur[10];

18. int *t = &vecteur[0];

19. int codeG1[1023];

20. int *t1 = &codeG1[0];

21. int codeG2[1023];

22. int *t2 = &codeG2[0];

23. int dec;

24. int i,j;

25. int temp,temp1;

26. int SV = precepteurS->Sacquisition.PRN;

27. /* Generation of code G1*/

28. ones(t,10);

29. for(i=0;i<1023;i++){

30. *(t1+i)=*(t+9);

31. for(j=0;j<10;j++){

32. if(j==0){

33. temp = *t;

34. *t=xor(*(t+2),*(t+9));

35. }

36. else{

37. temp1 = *(t+j);

38. *(t+j) = temp;

39. temp = temp1;

40. }

41. }

42. }

43. /* Generation of code G2 */

44. ones(t,10);

45. for(i=0;i<1023;i++){

46. *(t2+i)=xor(*(t+(int)CoupleSV[SV-1][0]-1),*(t+(int)CoupleSV[SV-1][1]-1));

47. dec = xor(xor(xor(*(t+1),*(t+2)), xor(*(t+5),*(t+7))), xor(*(t+8),*(t+9)));

80

48. for(j=0;j<10;j++){

49. if(j==0){

50. temp = *t;

51. *t=dec;

52. }

53. else{

54. temp1 = *(t+j);

55. *(t+j) = temp;

56. temp = temp1;

57. }

58. }

59. }

60. /* Generation of code GPS */

61. for(i=0;i<1023;i++){

62. precepteurS->Slocal_code_generator.TabCode[i]=2*xor(*(t1+i),*(t2+i))-1;

63. }

64. }

“codeLockDetector.h”

1. #ifndef CODELOCKDETECTOR_H_

2. #define CODELOCKDETECTOR_H_

3. /** CodeLock detector **/

4. struct recepteur *Fcodelock_detector(struct recepteur *precepteurS){

5. int j;

6. if(precepteurS->Sintegrator.RazIntP ==1){

7. /* C/N0 estimator */

8. // Spilker Vol.1 page 390

9. // Section 4.6.2 Expert Report

10. precepteurS->Scodelock_detector._IndexData = (int)precepteurS-

>Scorrelateur_prompt.CodeLock_Rxx[0];

11. precepteurS->Scodelock_detector._PromptReRxxInt = precepteurS-

>Scorrelateur_prompt.CodeLock_Rxx[1];

12. precepteurS->Scodelock_detector._PromptImRxxInt = precepteurS-

>Scorrelateur_prompt.CodeLock_Rxx[2];

81

13. precepteurS->Scodelock_detector._InstantSynchro = precepteurS-

>Sbitsynchro.CodeLock_InstantSynchro;

14. if (precepteurS->Scodelock_detector._IndexData == precepteurS-

>Scodelock_detector._InstantSynchro){

15. precepteurS->Scodelock_detector.AccWBP = 0.0;

16. precepteurS->Scodelock_detector.AccNBPI = 0.0;

17. precepteurS->Scodelock_detector.AccNBPQ = 0.0;

18. for (j=0;j<20;j++){

19. precepteurS->Scodelock_detector.AccWBP += pow(precepteurS-

>Scodelock_detector.TabI[j],2.0)+pow(precepteurS-

>Scodelock_detector.TabQ[j],2.0);

20. precepteurS->Scodelock_detector.AccNBPI += precepteurS-

>Scodelock_detector.TabI[j];

21. precepteurS->Scodelock_detector.AccNBPQ += precepteurS-

>Scodelock_detector.TabQ[j];

22. }

23. precepteurS->Scodelock_detector.WBP[precepteurS-

>Scodelock_detector.k] = precepteurS->Scodelock_detector.AccWBP;

24. precepteurS->Scodelock_detector.NBP[precepteurS-

>Scodelock_detector.k] = pow(precepteurS-

>Scodelock_detector.AccNBPI,2.0) + pow(precepteurS-

>Scodelock_detector.AccNBPQ,2.0);

25. if (precepteurS->Scodelock_detector.WBP[precepteurS-

>Scodelock_detector.k] != 0){

26. precepteurS->Scodelock_detector.NP[precepteurS-

>Scodelock_detector.k] = precepteurS-

>Scodelock_detector.NBP[precepteurS-

>Scodelock_detector.k]/precepteurS-

>Scodelock_detector.WBP[precepteurS->Scodelock_detector.k];

27. if (precepteurS->Scodelock_detector.NMoy<50)

28. precepteurS->Scodelock_detector.NMoy += 1;

29. if (precepteurS->Scodelock_detector.k>=49)

30. precepteurS->Scodelock_detector.k =0;

82

31. else

32. (precepteurS->Scodelock_detector.k)++;

33. precepteurS->Scodelock_detector.AccNP = 0.0;

34. for (j=0;j<50;j++){

35. precepteurS->Scodelock_detector.AccNP += precepteurS-

>Scodelock_detector.NP[j];

36. }

37. precepteurS->Scodelock_detector.Fraction = (precepteurS-

>Scodelock_detector.AccNP/precepteurS->Scodelock_detector.NMoy-

1.0)/(20.0-precepteurS->Scodelock_detector.AccNP/precepteurS-

>Scodelock_detector.NMoy);//u_NP = AccNP/NMoy

38. if (precepteurS->Scodelock_detector.Fraction < 0)

39. precepteurS->Scodelock_detector._C_N_estimated = -100.0;

40. else

41. precepteurS->Scodelock_detector._C_N_estimated =

10*log10(1.0/(1.0/1000.0)*precepteurS-

>Scodelock_detector.Fraction);//T = 1/1000

42. #ifdef OUTPUTFILE

43. send_data_double(precepteurS->Scodelock_detector._C_N_estimated);

44. #endif

45. }

46. }

47. precepteurS->Scodelock_detector.TabI[precepteurS-

>Scodelock_detector._IndexData] = precepteurS-

>Scodelock_detector._PromptReRxxInt;

48. precepteurS->Scodelock_detector.TabQ[precepteurS-

>Scodelock_detector._IndexData] = precepteurS-

>Scodelock_detector._PromptImRxxInt;

49. /* Phase Lock Estimator */

50. // Kaplan page 233-234

51. //Echantillonnage tout les 20 ms

52. // Section 4.6.1 Expert Report

53. if (precepteurS->Scodelock_detector._IndexData == precepteurS-

83

>Scodelock_detector._InstantSynchro){

54. precepteurS->Scodelock_detector.AbsPromptReRxxInt =

abs(precepteurS->Scodelock_detector._PromptReRxxInt);

55. precepteurS->Scodelock_detector.AbsPromptImRxxInt =

abs(precepteurS->Scodelock_detector._PromptImRxxInt);

56. // Low Pass Filter

57. // Real (Iprompt)

58. precepteurS->Scodelock_detector.LPFResultRe_previous = precepteurS-

>Scodelock_detector.LPFResultRe;

59. precepteurS->Scodelock_detector.LPFinterRe = Const_K1*(precepteurS-

>Scodelock_detector.AbsPromptReRxxInt - precepteurS-

>Scodelock_detector.LPFResultRe_previous);

60. precepteurS->Scodelock_detector.LPFResultRe = (precepteurS-

>Scodelock_detector.LPFinterRe + precepteurS-

>Scodelock_detector.LPFResultRe_previous);

61. precepteurS->Scodelock_detector.A = precepteurS-

>Scodelock_detector.LPFResultRe/Const_K2;

62. // Imaginary (Qprompt)

63. precepteurS->Scodelock_detector.LPFResultIm_previous = precepteurS-

>Scodelock_detector.LPFResultIm;

64. precepteurS->Scodelock_detector.LPFinterIm = Const_K1*(precepteurS-

>Scodelock_detector.AbsPromptImRxxInt - precepteurS-

>Scodelock_detector.LPFResultIm_previous);

65. precepteurS->Scodelock_detector.LPFResultIm = precepteurS-

>Scodelock_detector.LPFinterIm + precepteurS-

>Scodelock_detector.LPFResultIm_previous;

66. precepteurS->Scodelock_detector.B = precepteurS-

>Scodelock_detector.LPFResultIm;

67. if(precepteurS->Scodelock_detector.A > precepteurS-

>Scodelock_detector.B){

68. // YES Branch

69. precepteurS->Scodelock_detector._OptimisticPhaseLock = 1;

70. precepteurS->Scodelock_detector.Pcount[2] = 0;

84

71. if(precepteurS->Scodelock_detector.Pcount[1] > Const_Lp)

72. precepteurS->Scodelock_detector._PessimisticPhaseLock = 1;

73. else

74. precepteurS->Scodelock_detector.Pcount[1] += 1;

75. }

76. else{

77. // No Branch

78. precepteurS->Scodelock_detector._PessimisticPhaseLock = 0;

79. precepteurS->Scodelock_detector.Pcount[1] = 0;

80. if(precepteurS->Scodelock_detector.Pcount[2] > Const_Lo)

81. precepteurS->Scodelock_detector._OptimisticPhaseLock = 0;

82. else

83. precepteurS->Scodelock_detector.Pcount[2] += 1;

84. }

85. }

86. precepteurS->Scodelock_detector.C_N_estimated = precepteurS-

>Scodelock_detector._C_N_estimated;

87. precepteurS->Scodelock_detector.CodeLock = precepteurS-

>Scodelock_detector._OptimisticPhaseLock;

88. precepteurS->Scodelock_detector.CodeDiscriLock[0] = precepteurS-

>Scodelock_detector._OptimisticPhaseLock;

89. precepteurS->Scodelock_detector.CodeDiscriLock[1] = precepteurS-

>Scodelock_detector._PessimisticPhaseLock;

90. precepteurS->Scodelock_detector.PhaseLock[0] = precepteurS-

>Scodelock_detector._OptimisticPhaseLock;

91. precepteurS->Scodelock_detector.PhaseLock[1] = precepteurS-

>Scodelock_detector._PessimisticPhaseLock;

92. precepteurS->Scodelock_detector.FalseLockDetector_PhaseLock[0] =

precepteurS->Scodelock_detector._OptimisticPhaseLock;

93. precepteurS->Scodelock_detector.FalseLockDetector_PhaseLock[1] =

precepteurS->Scodelock_detector._PessimisticPhaseLock;

94. precepteurS->Scodelock_detector.FalseLockDetector_EstimatedCN0 =

precepteurS->Scodelock_detector._C_N_estimated;

85

95. FbitSynchro(precepteurS);

96. }

97. return precepteurS;

98. }

99. #endif /* CODELOCKDETECTOR_H_ */

“codeNCO.h”

1. #ifndef CODENCO_H_

2. #define CODENCO_H_

3. struct recepteur *FcodeNCO(struct recepteur *precepteurS){

4. // Aide de la FPLL

5. precepteurS->ScodeNCO.CodeFPLL =

(double)Const_Rca/(2*M_PI*Const_f0)*(precepteurS->ScodeNCO.DopplerIni

+ precepteurS->ScodeNCO._VeFPLL);

6. precepteurS->ScodeNCO.CodeNCO = precepteurS->ScodeNCO._VeDLL +

precepteurS->ScodeNCO.CodeFPLL;

7. precepteurS->ScodeNCO.CodeIndexPrompt = precepteurS-

>ScodeNCO.CodeNCO + Const_Rc_re + precepteurS-

>ScodeNCO.CodeIndexPrompt;

8. #ifdef OUTPUTFILE

9. if(precepteurS->ScodeNCO.CodeFPLL != precepteurS-

>ScodeNCO.CodeFPLL_previous){

10. precepteurS->ScodeNCO.CodeFPLL_previous = precepteurS-

>ScodeNCO.CodeFPLL;

11. //fprintf(precepteurS->ScodeNCO.pFile1,"%g\n",precepteurS-

>ScodeNCO.CodeFPLL);//CodeNCOFile<<CodeFPLL<<std::endl;

12. printf("%g",precepteurS->ScodeNCO.CodeFPLL);

13. }

14. #endif

15. if(precepteurS->ScodeNCO.CodeIndexPrompt>=Const_LongueurCode)

16. precepteurS->ScodeNCO.CodeIndexPrompt -= Const_LongueurCode;

17. precepteurS->ScodeNCO.CodeIndexEarly = precepteurS-

>ScodeNCO.CodeIndexPrompt + Const_DistanceCorrelateur*Const_Rc_re;

18. if(precepteurS->ScodeNCO.CodeIndexEarly>=Const_LongueurCode)

86

19. precepteurS->ScodeNCO.CodeIndexEarly -= Const_LongueurCode;

20. precepteurS->ScodeNCO.CodeIndexLate = precepteurS-

>ScodeNCO.CodeIndexPrompt - Const_DistanceCorrelateur*Const_Rc_re;

21. if(precepteurS->ScodeNCO.CodeIndexLate < 0)

22. precepteurS->ScodeNCO.CodeIndexLate += Const_LongueurCode;

23. precepteurS->ScodeNCO.LocalCodeGenerator_CodeIndexEarly = precepteurS-

>ScodeNCO.CodeIndexEarly;

24. precepteurS->ScodeNCO.LocalCodeGenerator_CodeIndexPrompt =

25. precepteurS->ScodeNCO.CodeIndexPrompt;

26. precepteurS->ScodeNCO.LocalCodeGenerator_CodeIndexLate = precepteurS-

>ScodeNCO.CodeIndexLate;

27. precepteurS->ScodeNCO._VeFPLL = precepteurS-

>SfiltreFPLL.NCO_VeFPLL;

28. precepteurS->ScodeNCO._VeDLL = precepteurS-

>Scode_discriminateur.NCO_VeDLL;

29. FlocalCode(precepteurS);

30. return precepteurS;

31. }

32. #endif /* CODENCO_H_ */

“Constants.h”

1. #ifndef CONSTANTS_H_

2. #define CONSTANTS_H_

3. /******************************************************************/

4. /** Global Variables **/

5. /******************************************************************/

6. /*********************************************/

7. /** Constants **/

8. /*********************************************/

9. /** --------------- Files ----------------- **/

10. // Sortie des resultats vers fichiers texte

11. //#define OUTPUTFILE

12. // Enregistrement des sortie des correlateurs vers les fichiers "ReRxx.dat" et

13. "ImRxx.dat"

87

14. //#define RXXOUTPUTFILE

15. // Enregistrement des sortie des intégrateurs vers les fichiers "ReRxxInt.dat" et

16. "ImRxxInt.dat"

17. //#define RXXINTOUTPUTFILE

18. //#define DATAOUTPUTFILE

19. /** --------- Numerical Values ------------ **/

20. // Frequence de la sous-porteuse

21. // Fsc = Rca*n

22. static const int Const_n = 1;

23. // Frequence du code

24. // Fc = Const_Rca*m

25. static const int Const_m = 1;

26. #ifdef BPSK

27. #define Const_MultPorteuse Const_m

28. #else

29. #define Const_MultPorteuse Const_n

30. #endif

31. #define Const_Fe_re (4*2048000.0*Const_MultPorteuse)

32. #define Const_Periode_re (1.0/Const_Fe_re)

33. static const int Const_NbIntegrationMax = 20;

34. // Phase Lock Detector

35. static const double Const_K1 = 0.0247;

36. static const double Const_K2 = 1.5;

37. static const int Const_Lp = 50;

38. static const int Const_Lo = 240;

39. // BitSynchro (Spilker Vol1 page 395)

40. //static const int Const_NBS1 = 25;

41. //static const int Const_NBS2 = 10;

42. static const int Const_TailleFiltre = 4;

43. // Fréquence de la modulation

44. #define Const_f0 (1.5754*pow(10.0,9.0))

45. // Rythme de référence du code C/A (en chip par seconde)

46. static const double Const_Rca = 1023000.00;

88

47. // Taille des FFT de l'algo d'quisition

48. static const double TailleFFT = 4096.0;

49. // Filtres de boucles

50. //-------------------

51. // Bande de boucle:

52. // 21/07/2008 :

53. // La bande de boucle (1.0) a été adaptée pour le cas particulier oú on a également

54. enlevé

55. // la Doppler afin de travailler en bande de base. L'effet du Doppler se ressent

56. toujours

57. // sur le code mais plus sur la porteuse. La bande doit donc être 'relachée afin de

58. pouvoir

59. // suivre les variation sur le code sans l'aide de la porteuse.

60. // La valeur normale est 0.1

61. static const double Const_Bdll=1.0; // Bande de la DLL (en Hz)

62. static const double Const_a2 = 1.414;

63. static const double Const_a3 = 1.1;

64. static const double Const_b3 = 2.4;

65. // Constantes du récepteur

66. // Longueur du code

67. static const int Const_LongueurCode = 1023;

68. // Période en pico-secondes

69. #define Const_Periode_re_ps ((int)Const_Periode_re*pow(10.0,12.0))

70. #define Const_Periode_re_fs ((int)Const_Periode_re*pow(10.0,15.0))

71. // Générateur local du code

72. #define Const_Rc_em ((double)Const_m*Const_Rca/(Const_Fe_em))

73. #define Const_Rc_re ((double)Const_m*Const_Rca/(Const_Fe_re))

74. // Distance entre les correlateurs

75. //--------------------------------

76. // Exprimées en nombre de chip à la fréquence d'échantillonnage du recepteur

77. static const int Const_DistanceCorrelateur = 3;

78. #endif /* CONSTANTS_H_ */

89

“correlateurComplet.h”

1. #ifndef CORRELATEURCOMPLET_H_

2. #define CORRELATEURCOMPLET_H_

3. /** Correlateur Prompt **/

4. struct recepteur *FcorrelateurPrompt(struct recepteur *precepteurS){

5. precepteurS->Scorrelateur_prompt._I = precepteurS-

>Slocal_carrier_generator.Iout;

6. precepteurS->Scorrelateur_prompt._Q = precepteurS-

>Slocal_carrier_generator.Qout;

7. precepteurS->Scorrelateur_prompt.NCO_Calcul = 1;

8. // Lecture de l'indice des chips

9. precepteurS->Scorrelateur_prompt._CodeIndex_previous = precepteurS-

>Scorrelateur_prompt._CodeIndex;

10. precepteurS->Scorrelateur_prompt._CodeIndex = precepteurS-

>Scorrelateur_prompt.PromptI[0];

11. precepteurS->Scorrelateur_prompt._CodeLocalI = precepteurS-

>Scorrelateur_prompt.PromptI[1];

12. // Determination de la condition de reset des intégrateurs

13. if(precepteurS->Scorrelateur_prompt._CodeIndex == 0 && precepteurS-

>Scorrelateur_prompt._CodeIndex_previous !=0)

14. precepteurS->Scorrelateur_prompt.RazInt = 1;

15. else

16. precepteurS->Scorrelateur_prompt.RazInt = 0;

17. // Correlation

18. precepteurS->Scorrelateur_prompt.MultI = precepteurS-

>Scorrelateur_prompt._I*(double)(precepteurS-

>Scorrelateur_prompt._CodeLocalI);

19. precepteurS->Scorrelateur_prompt.MultQ = precepteurS-

>Scorrelateur_prompt._Q*(double)(precepteurS-

>Scorrelateur_prompt._CodeLocalI);

20. precepteurS->Sintegrator.RazIntP = precepteurS->Scorrelateur_prompt.RazInt;

21. if(precepteurS->Scorrelateur_prompt.RazInt == 1){

22. // Ecriture des correlateurs et reset de l'integrateur

90

23. precepteurS->Scorrelateur_prompt.PromptRxx[0] = (int)precepteurS-

>Scorrelateur_prompt.IndexData;

24. precepteurS->Scorrelateur_prompt.PromptRxx[1] = precepteurS-

>Scorrelateur_prompt.CumulReRxx;

25. precepteurS->Scorrelateur_prompt.CodeLock_Rxx[0] = (int)precepteurS-

>Scorrelateur_prompt.IndexData;

26. precepteurS->Scorrelateur_prompt.CodeLock_Rxx[1] = precepteurS-

>Scorrelateur_prompt.CumulReRxx;

27. precepteurS->Scorrelateur_prompt.SynchroBit_Rxx[0] = (int)precepteurS-

>Scorrelateur_prompt.IndexData;

28. precepteurS->Scorrelateur_prompt.SynchroBit_Rxx[1] = precepteurS-

>Scorrelateur_prompt.CumulReRxx;

29. precepteurS->Scorrelateur_prompt.DataDemodulation_Rxx[0] =

(int)precepteurS->Scorrelateur_prompt.IndexData;

30. precepteurS->Scorrelateur_prompt.DataDemodulation_Rxx[1] = precepteurS-

>Scorrelateur_prompt.CumulReRxx;

31. precepteurS->Scorrelateur_prompt.DataDemodulation_Rxx[2] = precepteurS-

>Scorrelateur_prompt.CumulImRxx;

32. precepteurS->Scorrelateur_prompt.CumulReRxx = precepteurS-

>Scorrelateur_prompt.MultI;

33. precepteurS->Scorrelateur_prompt.PromptRxx[2] = precepteurS-

>Scorrelateur_prompt.CumulImRxx;

34. precepteurS->Scorrelateur_prompt.CodeLock_Rxx[2] = precepteurS-

>Scorrelateur_prompt.CumulImRxx;

35. precepteurS->Scorrelateur_prompt.SynchroBit_Rxx[2] = precepteurS-

>Scorrelateur_prompt.CumulImRxx;

36. precepteurS->Scorrelateur_prompt.CumulImRxx = precepteurS-

>Scorrelateur_prompt.MultQ;

37. if(precepteurS->Scorrelateur_prompt.IndexData>=Const_NbIntegrationMax-1)

38. precepteurS->Scorrelateur_prompt.IndexData = 0;

39. else

40. precepteurS->Scorrelateur_prompt.IndexData += 1;

41. }

91

42. else{

43. // Integrate

44. precepteurS->Scorrelateur_prompt.CumulReRxx += precepteurS-

>Scorrelateur_prompt.MultI;

45. precepteurS->Scorrelateur_prompt.CumulImRxx += precepteurS-

>Scorrelateur_prompt.MultQ;

46. }

47. return precepteurS;

48. }

49. /** Correlateur Early **/

50. struct recepteur *FcorrelateurEarly(struct recepteur *precepteurS){

51. precepteurS->Scorrelateur_early._I = precepteurS-

>Slocal_carrier_generator.Iout;

52. precepteurS->Scorrelateur_early._Q = precepteurS-

>Slocal_carrier_generator.Qout;

53. precepteurS->Scorrelateur_early._CodeIndex_previous = precepteurS-

>Scorrelateur_early._CodeIndex;

54. precepteurS->Scorrelateur_early._CodeIndex = precepteurS-

>Scorrelateur_early.EarlyI[0];

55. precepteurS->Scorrelateur_early._CodeLocalI = precepteurS-

>Scorrelateur_early.EarlyI[1];

56. // Détermination de la condition de reset des intégrateurs

57. if(precepteurS->Scorrelateur_early._CodeIndex == 0 && precepteurS-

>Scorrelateur_early._CodeIndex_previous != 0)

58. precepteurS->Scorrelateur_early.RazInt = 1;

59. else

60. precepteurS->Scorrelateur_early.RazInt = 0;

61. // Correlation

62. precepteurS->Scorrelateur_early.MultI = precepteurS-

>Scorrelateur_early._I*precepteurS->Scorrelateur_early._CodeLocalI;

63. precepteurS->Scorrelateur_early.MultQ = precepteurS-

>Scorrelateur_early._Q*precepteurS->Scorrelateur_early._CodeLocalI;

64. if(precepteurS->Scorrelateur_early.RazInt == 1){

92

65. // Ecriture des correlateurs et reset de l'integrateur

66. precepteurS->Scorrelateur_early.EarlyRxx[0] = precepteurS-

>Scorrelateur_early.CumulReRxx;

67. precepteurS->Scorrelateur_early.CumulReRxx = precepteurS-

>Scorrelateur_early.MultI;

68. precepteurS->Scorrelateur_early.EarlyRxx[1] = precepteurS-

>Scorrelateur_early.CumulImRxx;

69. precepteurS->Scorrelateur_early.CumulImRxx = precepteurS-

>Scorrelateur_early.MultQ;

70. }

71. else{

72. // Integrate

73. precepteurS->Scorrelateur_early.CumulReRxx += precepteurS-

>Scorrelateur_early.MultI;

74. precepteurS->Scorrelateur_early.CumulImRxx += precepteurS-

>Scorrelateur_early.MultQ;

75. }

76. return precepteurS;

77. }

78. /** Correlateur Late **/

79. struct recepteur *FcorrelateurLate(struct recepteur *precepteurS){

80. precepteurS->Scorrelateur_late._I = precepteurS->Slocal_carrier_generator.Iout;

81. precepteurS->Scorrelateur_late._Q = precepteurS-

>Slocal_carrier_generator.Qout;

82. // Lecture de l'indice des chips

83. precepteurS->Scorrelateur_late._CodeIndex_previous = precepteurS-

>Scorrelateur_late._CodeIndex;

84. precepteurS->Scorrelateur_late._CodeIndex = precepteurS-

>Scorrelateur_late.LateI[0];

85. precepteurS->Scorrelateur_late._CodeLocalI = precepteurS-

>Scorrelateur_late.LateI[1];

86. // Détermination de la condition de reset des intégrateurs

87. if(precepteurS->Scorrelateur_late._CodeIndex == 0 && precepteurS-

93

>Scorrelateur_late._CodeIndex_previous != 0)

88. precepteurS->Scorrelateur_late.RazInt = 1;

89. else

90. precepteurS->Scorrelateur_late.RazInt = 0;

91. // Correlation

92. precepteurS->Scorrelateur_late.MultI = precepteurS-

>Scorrelateur_late._I*precepteurS->Scorrelateur_late._CodeLocalI;

93. precepteurS->Scorrelateur_late.MultQ = precepteurS-

>Scorrelateur_late._Q*precepteurS->Scorrelateur_late._CodeLocalI;

94. if(precepteurS->Scorrelateur_late.RazInt == 1){

95. // Ecriture des correlateurs et reset de l'integrateur

96. precepteurS->Scorrelateur_late.LateRxx[0] = precepteurS-

>Scorrelateur_late.CumulReRxx;

97. precepteurS->Scorrelateur_late.CumulReRxx = precepteurS-

>Scorrelateur_late.MultI;

98. precepteurS->Scorrelateur_late.LateRxx[1] = precepteurS-

>Scorrelateur_late.CumulImRxx;

99. precepteurS->Scorrelateur_late.CumulImRxx = precepteurS-

>Scorrelateur_late.MultQ;

100. }

101. else{

102. // Integrate

103. precepteurS->Scorrelateur_late.CumulReRxx += precepteurS-

>Scorrelateur_late.MultI;

104. precepteurS->Scorrelateur_late.CumulImRxx += precepteurS-

>Scorrelateur_late.MultQ;

105. }

106. return precepteurS;

107. }

108. /** --------------- Correlateur Complet ---------------- **/

109. struct recepteur *FcorrelateurComplet(struct recepteur *precepteurS){

110. /* Correlateur Prompt */

111. FcorrelateurPrompt(precepteurS);

94

112. /* Correlateur Early */

113. FcorrelateurEarly(precepteurS);

114. /* Correlateur Late */

115. FcorrelateurLate(precepteurS);

116. Fintegrator(precepteurS);

117. Fcodelock_detector(precepteurS);

118. return precepteurS;

119. }

120. #endif /* CORRELATEURCOMPLET_H_ */

“dataDemodulation.h”

1. #ifndef DATADEMODULATION_H_

2. #define DATADEMODULATION_H_

3. struct recepteur *FdataDemodulation(struct recepteur *precepteurS){

4. int i;

5. // Section 4.8 Expert Report

6. precepteurS->Sdata_demodulation._IndexData = (int)precepteurS-

>Scorrelateur_prompt.DataDemodulation_Rxx[0];

7. precepteurS->Sdata_demodulation._PromptReRxx = precepteurS-

>Scorrelateur_prompt.DataDemodulation_Rxx[1];

8. precepteurS->Sdata_demodulation._PromptImRxx = precepteurS-

>Scorrelateur_prompt.DataDemodulation_Rxx[2];

9. precepteurS->Sdata_demodulation._InstantSynchro = precepteurS-

>Sbitsynchro.DataDemodulation_InstantSynchro;

10. if (precepteurS->Sdata_demodulation._IndexData == precepteurS-

>Sdata_demodulation._InstantSynchro){

11. precepteurS->Sdata_demodulation.AccPromptRe = 0.0;

12. precepteurS->Sdata_demodulation.AccPromptIm = 0.0;

13. for (i=0; i<Const_NbIntegrationMax;i++){

14. precepteurS->Sdata_demodulation.AccPromptRe += precepteurS-

>Sdata_demodulation.TablePromptRe[i];

15. precepteurS->Sdata_demodulation.AccPromptIm += precepteurS-

>Sdata_demodulation.TablePromptIm[i];

16. }

95

17. if (precepteurS->Sdata_demodulation.AccPromptRe >= 0)

18. precepteurS->Sdata_demodulation._DataBit = 1;

19. else

20. precepteurS->Sdata_demodulation._DataBit = 0;

21. //_DataBit = -1;

22. #ifdef DATAOUTPUTFILE

23. send_data_int(precepteurS->Sdata_demodulation._DataBit);

24. send_data_double(precepteurS->Sdata_demodulation.AccPromptRe);

25. send_data_double(precepteurS->Sdata_demodulation.AccPromptIm);

26. #endif

27. #ifdef GENERATEUR_SYSTEMC

28. thread_data_recepteur->data_demodulation_struct->DataBit =

29. thread_data_recepteur->data_demodulation_struct-

>_DataBit;//DataBit.write(_DataBit);

30. #endif

31. }

32. precepteurS->Sdata_demodulation.TablePromptRe[precepteurS-

>Sdata_demodulation._IndexData] = precepteurS-

>Sdata_demodulation._PromptReRxx;

33. precepteurS->Sdata_demodulation.TablePromptIm[precepteurS-

>Sdata_demodulation._IndexData] = precepteurS-

>Sdata_demodulation._PromptImRxx;

34. return precepteurS;

35. }

36. #endif /* DATADEMODULATION_H_ */

“dopplerEstime.h”

1. #ifndef DOPPLERESTIME_H_

2. #define DOPPLERESTIME_H_

3. struct recepteur *FdopplerEstime(struct recepteur *precepteurS){

4. int i;

5. // Sections 4.4.3 and 4.4.4 Expert Report

6. precepteurS->Sdoppler_estime._VeFPLL = precepteurS-

>SfiltreFPLL.DopplerEstimator_VeFPLL;

96

7. precepteurS->Sdoppler_estime._VeDLL = precepteurS-

>Scode_discriminateur.DopplerEstimator_VeDLL;

8. // Estimation du Doppler par la phase

9. precepteurS->Sdoppler_estime.PhaseCorr = precepteurS-

>Sdoppler_estime.DopplerIni + precepteurS->Sdoppler_estime._VeFPLL;

10. precepteurS->Sdoppler_estime.DopplerPhase = precepteurS-

>Sdoppler_estime.PhaseCorr*Const_Fe_re/(2.0*M_PI);

11. #ifdef OUTPUTFILE

12. //fprintf(thread_data_recepteur->doppler_estime_struct-

>pFile1,"%g\n",thread_data_recepteur->doppler_estime_struct->DopplerPhase);

13. send_data_double(precepteurS->Sdoppler_estime.DopplerPhase);

14. #endif

15. precepteurS->estado[0] = 1.0;

16. if(precepteurS->Sdoppler_estime.DopplerPhase == 0.0){

17. precepteurS->data_exp[0] = 0.0;

18. precepteurS->data_base[0] = 0.0;

19. }

20. else{

21. precepteurS->data_exp[0] = floor(log10(fabs(precepteurS-

>Sdoppler_estime.DopplerPhase)));

22. precepteurS->data_base[0] = precepteurS-

>Sdoppler_estime.DopplerPhase/pow(10,precepteurS->data_exp[0]);

23. }

24. // Estimation du Doppler par le code

25. precepteurS->Sdoppler_estime.CodeFPLL =

Const_Rc_re/(2*M_PI*Const_f0)*(precepteurS->Sdoppler_estime.DopplerIni +

precepteurS->Sdoppler_estime._VeFPLL);

26. precepteurS->Sdoppler_estime.CodeNCO = precepteurS-

>Sdoppler_estime._VeDLL + precepteurS->Sdoppler_estime.CodeFPLL;

27. precepteurS->Sdoppler_estime.NChip_par_periode = precepteurS-

>Sdoppler_estime.CodeNCO + Const_Rc_re;

28. precepteurS->Sdoppler_estime.Fcode = precepteurS-

>Sdoppler_estime.NChip_par_periode * Const_Fe_re;

97

29. precepteurS->Sdoppler_estime.EstDopplerCode = Const_f0*(precepteurS-

>Sdoppler_estime.Fcode - Const_n*Const_Rca)/(Const_n*Const_Rca);

30. precepteurS->Sdoppler_estime.TabDoppler[precepteurS-

>Sdoppler_estime.IndexDoppler] = precepteurS-

>Sdoppler_estime.EstDopplerCode;

31. if (precepteurS->Sdoppler_estime.IndexDoppler>=99)

32. precepteurS->Sdoppler_estime.IndexDoppler = 0;

33. else

34. precepteurS->Sdoppler_estime.IndexDoppler += 1;

35. precepteurS->Sdoppler_estime.AccDoppler = 0.0;

36. for (i = 0; i <100; i++)

37. precepteurS->Sdoppler_estime.AccDoppler += precepteurS-

>Sdoppler_estime.TabDoppler[i];

38. precepteurS->Sdoppler_estime.DopplerCode = precepteurS-

>Sdoppler_estime.AccDoppler / 100.0;

39. #ifdef OUTPUTFILE

40. //fprintf(thread_data_recepteur->doppler_estime_struct-

>pFile2,"%g\n",thread_data_recepteur->doppler_estime_struct->DopplerCode);

41. send_data_double(precepteurS->Sdoppler_estime.DopplerCode);

42. #endif

43. precepteurS->estado[1] = 1.0;

44. if(precepteurS->Sdoppler_estime.DopplerCode == 0.0){

45. precepteurS->data_exp[1] = 0.0;

46. precepteurS->data_base[1] = 0.0;

47. }

48. else{

49. precepteurS->data_exp[1] = floor(log10(fabs(precepteurS-

>Sdoppler_estime.DopplerCode)));

50. precepteurS->data_base[1] = precepteurS-

>Sdoppler_estime.DopplerCode/pow(10,precepteurS->data_exp[1]);

51. }

52. return precepteurS;

53. }

98

54. #endif /* DOPPLERESTIME_H_ */

“falseLockDetector.h”

1. #ifndef FALSELOCKDETECTOR_H_

2. #define FALSELOCKDETECTOR_H_

3. /** FalseLock Detector 2 **/

4. struct recepteur *falseLock2(struct recepteur *precepteurS){

5. precepteurS->Sfalselock_detector._OptimisticPhaseLock = precepteurS-

>Scodelock_detector.FalseLockDetector_PhaseLock[0];

6. precepteurS->Sfalselock_detector._PessimisticPhaseLock = precepteurS-

>Scodelock_detector.FalseLockDetector_PhaseLock[1];

7. return precepteurS;

8. }

9. /** FalseLock Detector 3 **/

10. struct recepteur *falseLock3(struct recepteur *precepteurS){

11. precepteurS->Sfalselock_detector._EstimatedCN0 = precepteurS-

>Scodelock_detector.FalseLockDetector_EstimatedCN0;

12. return precepteurS;

13. }

14. /** FalseLock Detector 4 **/

15. struct recepteur *falseLock4(struct recepteur *precepteurS){

16. precepteurS->Sfalselock_detector._SynchroLock = precepteurS-

>Sbitsynchro.FalseLockDetector_SynchroLock[0];

17. precepteurS->Sfalselock_detector._FalseLock = precepteurS-

>Sbitsynchro.FalseLockDetector_SynchroLock[1];

18. return precepteurS;

19. }

20. /** FalseLock Detector 5 **/

21. struct recepteur *falseLock5(struct recepteur *precepteurS){

22. int i;

23. (precepteurS->Sfalselock_detector.Contador)++;

24. if ((precepteurS->Sfalselock_detector._SynchroLock == 1) || (precepteurS-

>Sfalselock_detector._FalseLock == 1) || (precepteurS-

>Sfalselock_detector._PessimisticPhaseLock == 1)){

99

25. if (precepteurS->Sfalselock_detector._EstimatedCN0<25.0){

26. // False Lock

27. precepteurS->Sfalselock_detector.AccVeDLL = 0.0;

28. for(i=0; i<200;i++)

29. precepteurS->Sfalselock_detector.AccVeDLL += precepteurS-

>Sfalselock_detector.TableVeDLL[i];

30. precepteurS->Sfalselock_detector.MoyVeDll = precepteurS-

>Sfalselock_detector.AccVeDLL/precepteurS-

>Sfalselock_detector.NbDataStock;

31. precepteurS->Sfalselock_detector.Ferr = precepteurS-

>Sfalselock_detector.MoyVeDll*Const_f0*Const_Fe_re/Const_Rca;

32. precepteurS->Sfalselock_detector.FreqCorr = precepteurS-

>Sfalselock_detector.Ferr;

33. }

34. }

35. return precepteurS;

36. }

37. /** FalseLock Detector 1 **/

38. struct recepteur *falseLock1(struct recepteur *precepteurS){

39. precepteurS->Sfalselock_detector._VeDLL = precepteurS-

>Scode_discriminateur.FalseLockDetector_VeDLL;

40. precepteurS->Sfalselock_detector.TableVeDLL[precepteurS-

>Sfalselock_detector.IndexTableVdll] = precepteurS-

>Sfalselock_detector._VeDLL;

41. if (precepteurS->Sfalselock_detector.IndexTableVdll<199){

42. (precepteurS->Sfalselock_detector.IndexTableVdll)++;

43. }

44. else

45. precepteurS->Sfalselock_detector.IndexTableVdll = 0;

46. if (precepteurS->Sfalselock_detector.NbDataStock < 200)

47. precepteurS->Sfalselock_detector.NbDataStock = precepteurS-

>Sfalselock_detector.NbDataStock + 1;

48. return precepteurS;

100

49. }

50. /** ----------------- Init False Lock Detector ----------------- **/

51. struct recepteur *FfalseLock(struct recepteur *precepteurS){

52. if(precepteurS->Sintegrator.DumpEnable == 1){

53. falseLock1(precepteurS);

54. falseLock2(precepteurS);

55. falseLock3(precepteurS);

56. falseLock4(precepteurS);

57. }

58. return precepteurS;

59. }

60. #endif /* FALSELOCKDETECTOR_H_ */

“filter.h”

1. #ifndef FILTER_H_

2. #define FILTER_H_

3. struct recepteur *Ffilter(struct recepteur *precepteurS){

4. int i;

5. precepteurS->Sreceiver_filter._I = precepteurS->Scanal.I_out;

6. precepteurS->Sreceiver_filter._Q = precepteurS->Scanal.Q_out;

7. for(i=9;i>=0;i--){

8. precepteurS->Sreceiver_filter.TabFilterRe[i+1] = precepteurS-

>Sreceiver_filter.TabFilterRe[i];

9. precepteurS->Sreceiver_filter.TabFilterIm[i+1] = precepteurS-

>Sreceiver_filter.TabFilterIm[i];

10. }

11. precepteurS->Sreceiver_filter.TabFilterRe[0] = precepteurS->Sreceiver_filter._I;

12. precepteurS->Sreceiver_filter.TabFilterIm[0] = precepteurS-

>Sreceiver_filter._Q;

13. precepteurS->Sreceiver_filter.AccFilterRe = 0.0;

14. precepteurS->Sreceiver_filter.AccFilterIm = 0.0;

15. for(i=0;i<11;i++){

16. precepteurS->Sreceiver_filter.AccFilterRe += precepteurS-

>Sreceiver_filter.TabFilterRe[i]*precepteurS->Sreceiver_filter.TabCoeff[i];

101

17. precepteurS->Sreceiver_filter.AccFilterIm += precepteurS-

>Sreceiver_filter.TabFilterIm[i]*precepteurS->Sreceiver_filter.TabCoeff[i];

18. }

19. precepteurS->Sreceiver_filter.I_out = precepteurS-

>Sreceiver_filter.AccFilterRe;

20. precepteurS->Sreceiver_filter.Q_out = precepteurS-

>Sreceiver_filter.AccFilterIm;

21. FlocalCarrierGenerator(precepteurS);

22. return precepteurS;

23. }

24. #endif /* FILTER_H_ */

“fpll.h”

1. #ifndef FPLL_H_

2. #define FPLL_H_

3. /** Carrier Discriminator **/

4. struct recepteur *FfreqDiscri(struct recepteur *precepteurS){

5. precepteurS->Scarrier_discriminator.PromptReRxx_Previous = precepteurS-

>Scarrier_discriminator.PromptReRxx_Now;

6. precepteurS->Scarrier_discriminator.PromptReRxx_Now = precepteurS-

>Sintegrator.FreqDiscri_PromptRxx[0];

7. precepteurS->Scarrier_discriminator.PromptImRxx_Previous = precepteurS-

>Scarrier_discriminator.PromptImRxx_Now;

8. precepteurS->Scarrier_discriminator.PromptImRxx_Now = precepteurS-

>Sintegrator.FreqDiscri_PromptRxx[1];

9. precepteurS->Scarrier_discriminator.Dot = precepteurS-

>Scarrier_discriminator.PromptReRxx_Previous*precepteurS-

>Scarrier_discriminator.PromptReRxx_Now + precepteurS-

>Scarrier_discriminator.PromptImRxx_Previous*precepteurS-

>Scarrier_discriminator.PromptImRxx_Now;

10. precepteurS->Scarrier_discriminator.Cross = precepteurS-

>Scarrier_discriminator.PromptReRxx_Previous*precepteurS-

>Scarrier_discriminator.PromptImRxx_Now - precepteurS-

>Scarrier_discriminator.PromptImRxx_Previous*precepteurS-

102

>Scarrier_discriminator.PromptReRxx_Now;

11. if (precepteurS->Scarrier_discriminator.Dot == 0.0)

12. precepteurS->Scarrier_discriminator._VeFLL = 0.0;

13. else

14. // Correction le 19/10/2007

15. precepteurS->Scarrier_discriminator._VeFLL = (atan(precepteurS-

>Scarrier_discriminator.Cross/precepteurS-

>Scarrier_discriminator.Dot))/((double)precepteurS->_NbIntegration/1000.0);

16. precepteurS->Scarrier_discriminator.ErreurFrequenceFLL = precepteurS-

>Scarrier_discriminator._VeFLL/(2.0*M_PI);

17. #ifdef OUTPUTFILE

18. //fprintf(thread_data_recepteur->carrier_discriminator_struct-

>pFile1,"%g\n",thread_data_recepteur->carrier_discriminator_struct-

>ErreurFrequenceFLL);//ErreurFrequence<<ErreurFrequenceFLL<<std::endl;

19. send_data_double(precepteurS->Scarrier_discriminator.ErreurFrequenceFLL);

20. #endif

21. precepteurS->Scarrier_discriminator.VeFLL = precepteurS-

>Scarrier_discriminator._VeFLL;

22. return precepteurS;

23. }

24. struct recepteur *FphaseDiscri(struct recepteur *precepteurS){

25. precepteurS->Scarrier_discriminator._PromptReRxx = precepteurS-

>Sintegrator.PhaseDiscri_PromptRxx[0];

26. precepteurS->Scarrier_discriminator._PromptImRxx = precepteurS-

>Sintegrator.PhaseDiscri_PromptRxx[1];

27. if (precepteurS->Scarrier_discriminator._PromptReRxx == 0.0)

28. precepteurS->Scarrier_discriminator._VePLL = 0.0;

29. else

30. // Test d'un discri trouvé dans GNSS_SDR 20/07/2008

31. // Code precdent

32. precepteurS->Scarrier_discriminator._VePLL = atan(precepteurS-

>Scarrier_discriminator._PromptImRxx/precepteurS-

>Scarrier_discriminator._PromptReRxx);

103

33. precepteurS->Scarrier_discriminator.VePLL = precepteurS-

>Scarrier_discriminator._VePLL;

34. #ifdef OUTPUTFILE

35. //fprintf(thread_data_recepteur->carrier_discriminator_struct-

>pFile2,"%g\n",thread_data_recepteur->carrier_discriminator_struct-

>_VePLL);//ErreurPhase<<_VePLL<<std::endl;

36. send_data_double(precepteurS->Scarrier_discriminator._VePLL);

37. #endif

38. return precepteurS;

39. }

40. /** Filtre FPLL **/

41. struct recepteur *FstateMacBandWidth(struct recepteur *precepteurS){

42. // Machine à état

43. precepteurS->SfiltreFPLL._OptimisticPhaseLock = precepteurS-

>Scodelock_detector.PhaseLock[0];

44. precepteurS->SfiltreFPLL._PessimisticPhaseLock = precepteurS-

>Scodelock_detector.PhaseLock[1];

45. if (precepteurS->SfiltreFPLL._OptimisticPhaseLock){

46. if (precepteurS->SfiltreFPLL._PessimisticPhaseLock){

47. if (precepteurS->SfiltreFPLL.Bfll>5.0){

48. //Bpll-=0.01;

49. precepteurS->SfiltreFPLL.Bfll-=0.01;

50. }

51. }

52. else{

53. precepteurS->SfiltreFPLL.Bpll=10.0;

54. precepteurS->SfiltreFPLL.Bfll=10.0;

55. }

56. }

57. else{

58. precepteurS->SfiltreFPLL.Bpll=18.0;

59. precepteurS->SfiltreFPLL.Bfll=18.0;

60. }

104

61. precepteurS->SfiltreFPLL.w0f = precepteurS->SfiltreFPLL.Bfll/0.53;//Section

4.3.3 Expert Report

62. precepteurS->SfiltreFPLL.GainFreqAcc = pow(precepteurS-

>SfiltreFPLL.w0f,2.0);

63. precepteurS->SfiltreFPLL.GainFreqVel = Const_a2*precepteurS-

>SfiltreFPLL.w0f;

64. precepteurS->SfiltreFPLL.w0p=precepteurS->SfiltreFPLL.Bpll/0.7845;

65. precepteurS->SfiltreFPLL.GainPhJit = pow(precepteurS->SfiltreFPLL.w0p,3.0);

66. precepteurS->SfiltreFPLL.GainPhAcc = Const_a3*pow(precepteurS-

>SfiltreFPLL.w0p,2.0);

67. precepteurS->SfiltreFPLL.GainPhVel = Const_b3*precepteurS-

>SfiltreFPLL.w0p;

68. precepteurS->SfiltreFPLL.GainAcc = 0.5;

69. precepteurS->SfiltreFPLL.GainVel = 0.5;

70. precepteurS->SfiltreFPLL.GainTint = precepteurS-

>_NbIntegration*Const_LongueurCode/(double)(Const_n*Const_Rca);

71. return precepteurS;

72. }

73. struct recepteur *FfiltreFPLL(struct recepteur *precepteurS){

74. precepteurS->SfiltreFPLL._VeFLL = precepteurS-

>Scarrier_discriminator.VeFLL;//Figure 4-11 Expert Report

75. precepteurS->SfiltreFPLL.f1 = precepteurS-

>SfiltreFPLL.GainFreqVel*precepteurS->SfiltreFPLL._VeFLL*precepteurS-

>SfiltreFPLL.FLL;

76. precepteurS->SfiltreFPLL.f2 = precepteurS-

>SfiltreFPLL.GainFreqAcc*precepteurS->SfiltreFPLL._VeFLL*precepteurS-

>SfiltreFPLL.FLL*precepteurS->SfiltreFPLL.GainTint;

77. //PLL

78. precepteurS->SfiltreFPLL._VePLL = precepteurS-

>Scarrier_discriminator.VePLL;

79. precepteurS->SfiltreFPLL.p1 = precepteurS-

>SfiltreFPLL.GainPhJit*precepteurS->SfiltreFPLL._VePLL*precepteurS-

>SfiltreFPLL.GainTint;

105

80. precepteurS->SfiltreFPLL.p2 = precepteurS-

>SfiltreFPLL.GainPhAcc*precepteurS->SfiltreFPLL._VePLL;

81. precepteurS->SfiltreFPLL.p3 = precepteurS-

>SfiltreFPLL.GainPhVel*precepteurS->SfiltreFPLL._VePLL;

82. precepteurS->SfiltreFPLL.fil1_previous = precepteurS->SfiltreFPLL.fil1;

83. precepteurS->SfiltreFPLL.fil1 = precepteurS->SfiltreFPLL.f2 + precepteurS-

>SfiltreFPLL.p1 + precepteurS->SfiltreFPLL.fil1_previous;

84. precepteurS->SfiltreFPLL.fil2 = precepteurS-

>SfiltreFPLL.GainAcc*(precepteurS->SfiltreFPLL.fil1 + precepteurS-

>SfiltreFPLL.fil1_previous);

85. precepteurS->SfiltreFPLL.fil3 = precepteurS-

>SfiltreFPLL.GainTint*(precepteurS->SfiltreFPLL.p2 + precepteurS-

>SfiltreFPLL.fil2 + precepteurS->SfiltreFPLL.f1);

86. precepteurS->SfiltreFPLL.fil4_previous = precepteurS->SfiltreFPLL.fil4;

87. precepteurS->SfiltreFPLL.fil4 = precepteurS->SfiltreFPLL.fil3 + precepteurS-

>SfiltreFPLL.fil4_previous;

88. precepteurS->SfiltreFPLL.fil5 = precepteurS-

>SfiltreFPLL.GainVel*(precepteurS->SfiltreFPLL.fil4 + precepteurS-

>SfiltreFPLL.fil4_previous);

89. precepteurS->SfiltreFPLL._VeFPLL = Const_Periode_re*(precepteurS-

>SfiltreFPLL.fil5 + precepteurS->SfiltreFPLL.p3);

90. precepteurS->SfiltreFPLL._FreqCorr = precepteurS-

>Sfalselock_detector.FreqCorr;

91. precepteurS->SfiltreFPLL.CorrVeFPLL =

92. 2.0*M_PI*Const_Periode_re*precepteurS->SfiltreFPLL._FreqCorr;

93. precepteurS->SfiltreFPLL._VeFPLL += precepteurS-

>SfiltreFPLL.CorrVeFPLL;

94. precepteurS->SfiltreFPLL.NCO_VeFPLL = precepteurS-

>SfiltreFPLL._VeFPLL;

95. precepteurS->SfiltreFPLL.LocalCarrierGenerator_VeFPLL = precepteurS-

>SfiltreFPLL._VeFPLL;

96. precepteurS->SfiltreFPLL.DopplerEstimator_VeFPLL = precepteurS-

>SfiltreFPLL._VeFPLL;

106

97. #ifdef OUTPUTFILE

98. //fprintf(thread_data_recepteur->filtreFPLL_struct-

>pFile1,"%g\n",thread_data_recepteur->filtreFPLL_struct-

>Bfll);//BfllFile<<Bfll<<std::endl;

99. send_data_double(precepteurS->SfiltreFPLL.Bfll);

100. //fprintf(thread_data_recepteur->filtreFPLL_struct-

>pFile2,"%g\n",thread_data_recepteur->filtreFPLL_struct->_VeFPLL);

101. send_data_double(precepteurS->SfiltreFPLL._VeFPLL);

102. #endif

103. return precepteurS;

104. }

105. /** Thread main **/

106. struct recepteur *Ffpll(struct recepteur *precepteurS){

107. FfreqDiscri(precepteurS);

108. FphaseDiscri(precepteurS);

109. FstateMacBandWidth(precepteurS);

110. FfiltreFPLL(precepteurS);

111. FdopplerEstime(precepteurS);

112. return precepteurS;

113. }

114. #endif /* FPLL_H_ */

“initRecepteur.h”

1. #ifndef INITRECEPTEUR_H_

2. #define INITRECEPTEUR_H_

3. /** ---------- Acquiring the parameters -------- **/

4. struct recepteur *acquisition_parameters(struct recepteur *precepteurS){

5. precepteurS->Sacquisition.NCO_DopplerEstime = precepteurS-

>Sreceive_data._DopplerEstime;

6. precepteurS->Sacquisition.LocalCarrierGenerator_DopplerEstime =

7. precepteurS->Sreceive_data._DopplerEstime;

8. precepteurS->Sacquisition.DopplerEstimator_DopplerEstime = precepteurS-

>Sreceive_data._DopplerEstime;

9. precepteurS->Sacquisition.DephasageEstime = precepteurS-

107

>Sreceive_data._DephasageEstime;

10. precepteurS->Sacquisition.PRN = precepteurS->Sreceive_data._PRN;

11. return precepteurS;

12. }

13. /** ------------ Creating the filter ------------ **/

14. struct recepteur *initFilter(struct recepteur *precepteurS){

15. float Coeff[]={0.0399,0.0498,-0.1127,-0.0136,0.3093,0.5277,0.3093,-0.0136,-

16. 0.1127,0.0498,0.0399};

17. int i;

18. // Lecture d'un ficher

19. for(i=0;i<11;i++)

20. precepteurS->Sreceiver_filter.TabCoeff[i] = Coeff[i];

21. for(i=0;i<11;i++){

22. precepteurS->Sreceiver_filter.TabFilterRe[i] = 0.0;

23. precepteurS->Sreceiver_filter.TabFilterIm[i] = 0.0;

24. }

25. precepteurS->Sreceiver_filter.Iprev = 0;

26. precepteurS->Sreceiver_filter.Qprev = 0;

27. return precepteurS;

28. }

29. /** ------- Init the Local Carrier Generator ------- **/

30. struct recepteur *initGene(struct recepteur *precepteurS){

31. precepteurS->Slocal_carrier_generator.AccPhaseCarrier = 0;

32. precepteurS->Slocal_carrier_generator._CarrierNCOCorr = 0;

33. precepteurS->Slocal_carrier_generator._VeFPLL = 0;

34. precepteurS->Slocal_carrier_generator.Iprev = 0.0;

35. precepteurS->Slocal_carrier_generator.Qprev = 0.0;

36. precepteurS->_NbIntegration = precepteurS->Sreceive_data._NbIntegration;

37. precepteurS->_CarrierPhiIni = 0.0;

38. precepteurS->Slocal_carrier_generator.DopplerIni =

2.0*M_PI*Const_Periode_re*precepteurS-

>Sacquisition.LocalCarrierGenerator_DopplerEstime;

39. return precepteurS;

108

40. }

41. /** ------------- Correlateur Complet ------------- **/

42. /** initialization of variables **/

43. struct recepteur *initCorrelateur(struct recepteur *precepteurS){

44. /* Correlateur Prompt */

45. precepteurS->Scorrelateur_prompt._CodeIndex_previous = 0;

46. precepteurS->Scorrelateur_prompt._CodeIndex = 0;

47. precepteurS->Scorrelateur_prompt.PromptI[0] = 0;

48. precepteurS->Scorrelateur_prompt.PromptI[1] = 0;

49. precepteurS->Scorrelateur_prompt.IndexData = 0;

50. precepteurS->Scorrelateur_prompt._CodeLocalI = 0;

51. precepteurS->Scorrelateur_prompt.CumulReRxx = 0;

52. precepteurS->Scorrelateur_prompt.CumulImRxx = 0;

53. precepteurS->Scorrelateur_prompt.RazInt = 0;

54. /* Correlateur Early */

55. precepteurS->Scorrelateur_early._CodeIndex_previous = 0;

56. precepteurS->Scorrelateur_early._CodeIndex = 0;

57. precepteurS->Scorrelateur_early.EarlyI[0] = 0;

58. precepteurS->Scorrelateur_early.EarlyI[1] = 0;

59. precepteurS->Scorrelateur_early._CodeLocalI = 0;

60. precepteurS->Scorrelateur_early.CumulReRxx = 0;

61. precepteurS->Scorrelateur_early.CumulImRxx = 0;

62. precepteurS->Scorrelateur_early.RazInt = 0;

63. /* Correlateur Late */

64. precepteurS->Scorrelateur_late._CodeIndex_previous = 0;

65. precepteurS->Scorrelateur_late._CodeIndex = 0;

66. precepteurS->Scorrelateur_late.LateI[0] = 0;

67. precepteurS->Scorrelateur_late.LateI[1] = 0;

68. precepteurS->Scorrelateur_late._CodeLocalI = 0;

69. precepteurS->Scorrelateur_late.CumulReRxx = 0;

70. precepteurS->Scorrelateur_late.CumulImRxx = 0;

71. precepteurS->Scorrelateur_late.RazInt = 0;

72. return precepteurS;

109

73. }

74. /** ----------- Init CodeLock Detector ---------- **/

75. struct recepteur *initCodeLockDetector(struct recepteur *precepteurS){

76. int j;

77. precepteurS->Scodelock_detector._InstantSynchro = 0;

78. for (j=0;j<20;j++)

79. {

80. precepteurS->Scodelock_detector.TabI[j] =0.0;

81. precepteurS->Scodelock_detector.TabQ[j] =0.0;

82. }

83. for (precepteurS->Scodelock_detector.k=0;precepteurS-

84. >Scodelock_detector.k<50;(precepteurS->Scodelock_detector.k)++)

85. {

86. precepteurS->Scodelock_detector.WBP[precepteurS->Scodelock_detector.k]

87. = 0.0;

88. precepteurS->Scodelock_detector.NBP[precepteurS->Scodelock_detector.k] =

89. 0.0;

90. //NBD[k] = 0.0;

91. precepteurS->Scodelock_detector.NP[precepteurS->Scodelock_detector.k] =

92. 0.0;

93. }

94. precepteurS->Scodelock_detector.AccWBP = 0.0;

95. precepteurS->Scodelock_detector.AccNBPI = 0.0;

96. precepteurS->Scodelock_detector.AccNBPQ = 0.0;

97. precepteurS->Scodelock_detector.AccNP = 0.0;

98. precepteurS->Scodelock_detector.NMoy = 0.0;

99. precepteurS->Scodelock_detector.k=0;

100. precepteurS->Scodelock_detector._OptimisticPhaseLock = 0;

101. precepteurS->Scodelock_detector._PessimisticPhaseLock = 0;

102. return precepteurS;

103. }

104. /** ------------ Init PhaseLock Detector ----------- **/

105. struct recepteur *initPhaseLockDetector(struct recepteur *precepteurS){

110

106. // Phase Lock detector

107. precepteurS->Scodelock_detector.LPFResultRe = 0.0;

108. precepteurS->Scodelock_detector.LPFResultIm = 0.0;

109. precepteurS->Scodelock_detector.Pcount[0] = 0;

110. precepteurS->Scodelock_detector.Pcount[1] = 0;

111. precepteurS->Scodelock_detector.Pcount[2] = 0;

112. precepteurS->Scodelock_detector._OptimisticPhaseLock = 0;

113. precepteurS->Scodelock_detector._PessimisticPhaseLock = 0;

114. return precepteurS;

115. }

116. /** ------------- Init Integrator ------------- **/

117. struct recepteur *initIntegrator(struct recepteur *precepteurS){

118. int i;

119. precepteurS->Sintegrator.CompteInt = 0;

120. precepteurS->Sintegrator.DumpEnable = 0;

121. precepteurS->Sintegrator._InstantSynchro = 0;

122. for (i=0; i<Const_NbIntegrationMax;i++)

123. {

124. precepteurS->Sintegrator.TablePromptRe[i] = 0.0;

125. precepteurS->Sintegrator.TablePromptIm[i] = 0.0;

126. precepteurS->Sintegrator.TableEarlyRe[i] = 0.0;

127. precepteurS->Sintegrator.TableEarlyIm[i] = 0.0;

128. precepteurS->Sintegrator.TableLateRe[i] = 0.0;

129. precepteurS->Sintegrator.TableLateIm[i] = 0.0;

130. }

131. precepteurS->Sintegrator.Integration = 1;

132. precepteurS->Sintegrator.InInter = 0;

133. precepteurS->Sintegrator.DebutIntegration = 0;

134. precepteurS->Sintegrator.FinIntegration = 4;

135. return precepteurS;

136. }

137. /** -------------- Init BitSynchro --------------- **/

138. struct recepteur *initBitSynchro(struct recepteur *precepteurS){

111

139. int i;

140. for(i=0;i<20;i++)

141. precepteurS->Sbitsynchro.AccBuffer[i] = 0;

142. precepteurS->Sbitsynchro.LockRecherche = 0;

143. precepteurS->Sbitsynchro.IndiceMax = 0;

144. precepteurS->Sbitsynchro._IndexData = 0;

145. precepteurS->Sbitsynchro.NbHits = 0;

146. precepteurS->Sbitsynchro.Synchro = 0;

147. precepteurS->Sbitsynchro.IndexBuffer = 0;

148. precepteurS->Sbitsynchro.IndiceMoyenne = 0;

149. precepteurS->Sbitsynchro.CodeLock_InstantSynchro = 0.0;

150. for(i=0;i<Const_TailleFiltre;i++)

151. precepteurS->Sbitsynchro.TabMoyenne[i] = 0;

152. for(i=0;i<20;i++){

153. precepteurS->Sbitsynchro.DataBufferRe[i] = 0.0;

154. precepteurS->Sbitsynchro.DataBufferIm[i] = 0.0;

155. }

156. return precepteurS;

157. }

158. /** --------- Init Code Discriminator --------- **/

159. struct recepteur *initCodeDiscriminator(struct recepteur *precepteurS){

160. precepteurS->Scode_discriminateur.Bdll = 1.0;

161. return precepteurS;

162. }

163. /** ------------- Init CarrierDiscriminator ------------- **/

164. struct recepteur *initDiscri(struct recepteur *precepteurS){

165. precepteurS->Scarrier_discriminator.PromptReRxx_Now = 0.0;

166. precepteurS->Scarrier_discriminator.PromptImRxx_Now = 0.0;

167. precepteurS->Scarrier_discriminator.Enable = 0;

168. return precepteurS;

169. }

170. /** ------------- Init False Lock Detector --------------- **/

171. struct recepteur *initFalseLockDetector(struct recepteur *precepteurS){

112

172. precepteurS->Sfalselock_detector.Ferr = 0.0;

173. for(precepteurS->Sfalselock_detector.IndexTableVdll=0; precepteurS-

>Sfalselock_detector.IndexTableVdll<200;(precepteurS-

>Sfalselock_detector.IndexTableVdll)++)

174. precepteurS->Sfalselock_detector.TableVeDLL[precepteurS-

>Sfalselock_detector.IndexTableVdll] = 0.0;

175. precepteurS->Sfalselock_detector.IndexTableVdll = 0;

176. precepteurS->Sfalselock_detector.Contador = 0;

177. return precepteurS;

178. }

179. /** ------------------ Init FiltreFPLL ------------------- **/

180. struct recepteur *initFiltreFPLL(struct recepteur *precepteurS){

181. /* Init Carrier Discriminator */

182. precepteurS->Scarrier_discriminator.PromptReRxx_Now = 0.0;

183. precepteurS->Scarrier_discriminator.PromptImRxx_Now = 0.0;

184. precepteurS->Scarrier_discriminator.Enable = 1;

185. /* Init filtre FPLL */

186. precepteurS->SfiltreFPLL._OptimisticPhaseLock = 0;

187. precepteurS->SfiltreFPLL._PessimisticPhaseLock = 0;

188. // FLL = 0.0 pour un filtre de PLL seul

189. // FLL = 1.0 pour un filtre FPLL

190. precepteurS->SfiltreFPLL.FLL = 1.0;

191. // Init des variables intermédiaires du filtre

192. precepteurS->SfiltreFPLL.f1 = 0;

193. precepteurS->SfiltreFPLL.f2 = 0;

194. precepteurS->SfiltreFPLL.p1 = 0;

195. precepteurS->SfiltreFPLL.p2 = 0;

196. precepteurS->SfiltreFPLL.p3 = 0;

197. precepteurS->SfiltreFPLL.fil1 = 0;

198. precepteurS->SfiltreFPLL.fil1_previous = 0;

199. precepteurS->SfiltreFPLL.fil2 = 0;

200. precepteurS->SfiltreFPLL.fil3 = 0;

201. precepteurS->SfiltreFPLL.fil4 = 0;

113

202. precepteurS->SfiltreFPLL.fil4_previous = 0;

203. precepteurS->SfiltreFPLL.fil5 = 0;

204. //Init des caractéristiques du filtre

205. precepteurS->SfiltreFPLL.Bpll=18.0;

206. precepteurS->SfiltreFPLL.Bfll=18.0;

207. precepteurS->SfiltreFPLL.w0f = precepteurS->SfiltreFPLL.Bfll/0.53;

208. precepteurS->SfiltreFPLL.GainFreqAcc = pow(precepteurS-

>SfiltreFPLL.w0f,2.0);

209. precepteurS->SfiltreFPLL.GainFreqVel = Const_a2*precepteurS-

>SfiltreFPLL.w0f;

210. precepteurS->SfiltreFPLL.w0p=precepteurS->SfiltreFPLL.Bpll/0.7845;

211. precepteurS->SfiltreFPLL.GainPhJit = pow(precepteurS->SfiltreFPLL.w0p,3.0);

212. precepteurS->SfiltreFPLL.GainPhAcc = Const_a3*pow(precepteurS-

>SfiltreFPLL.w0p,2.0);

213. precepteurS->SfiltreFPLL.GainPhVel = Const_b3*precepteurS-

>SfiltreFPLL.w0p;

214. precepteurS->SfiltreFPLL.GainAcc = 0.5;

215. precepteurS->SfiltreFPLL.GainVel = 0.5;

216. precepteurS->SfiltreFPLL._FreqCorr = 0.0;

217. return precepteurS;

218. }

219. /** ------------- Init Code NCO ------------- **/

220. struct recepteur *initCodeNCO(struct recepteur *precepteurS){

221. precepteurS->ScodeNCO._DopplerEstime = precepteurS-

>Sacquisition.NCO_DopplerEstime;

222. precepteurS->ScodeNCO._DephasageEstime = precepteurS-

>Sacquisition.DephasageEstime;

223. precepteurS->ScodeNCO._VeDLL = 0;

224. precepteurS->ScodeNCO._VeFPLL = 0;

225. precepteurS->ScodeNCO.DopplerIni =

2.0*M_PI*Const_Periode_re*precepteurS->ScodeNCO._DopplerEstime;

226. //CodeIndexPrompt = (2048.0-DephasageEstime)/2.0-5.0*Const_Rc_re;

227. precepteurS->ScodeNCO.CodeIndexPrompt = 2.0*Const_LongueurCode –

114

precepteurS->ScodeNCO._DephasageEstime*1023.0/TailleFFT-

5.0*Const_Rc_re;

228. //CodeIndexPrompt = (2048.0-750.0)/2.0-5.0*Const_Rc_re;

229. precepteurS->ScodeNCO._VeFPLL = 0;

230. precepteurS->ScodeNCO._VeDLL = 0;

231. precepteurS->SfiltreFPLL.NCO_VeFPLL = 0.0;

232. precepteurS->Scode_discriminateur.NCO_VeDLL = 0.0;

233. return precepteurS;

234. }

235. /** -------------- Init Local Code Generator -------------- **/

236. struct recepteur *initLocalCodeGenerator(struct recepteur *precepteurS){

237. code_gene_GPS(precepteurS);

238. precepteurS->Slocal_code_generator.ChipEarly = precepteurS-

>Slocal_code_generator.TabCode[0];

239. precepteurS->Slocal_code_generator._CodeIndexPrompt = 0;

240. precepteurS->Slocal_code_generator._CodeIndexEarly = 0;

241. precepteurS->Slocal_code_generator._CodeIndexLate = 0;

242. return precepteurS;

243. }

244. /** ---------------- Init Data Demodulation ---------------- **/

245. struct recepteur *initDataDemodulation(struct recepteur *precepteurS){

246. int i;

247. precepteurS->Sdata_demodulation._InstantSynchro = 0;

248. for (i=0; i<Const_NbIntegrationMax;i++){

249. precepteurS->Sdata_demodulation.TablePromptRe[i] = 0.0;

250. precepteurS->Sdata_demodulation.TablePromptIm[i] = 0.0;

251. }

252. return precepteurS;

253. }

254. /** ----------------- Init Doppler Estime ------------------- **/

255. struct recepteur *initDoppleEstime(struct recepteur *precepteurS){

256. int i;

257. for (i=0; i<100;i++)

115

258. precepteurS->Sdoppler_estime.TabDoppler[i] = 0.0;

259. precepteurS->Sdoppler_estime.IndexDoppler = 0;

260. precepteurS->Sdoppler_estime._VeFPLL = 0.0;

261. precepteurS->Sdoppler_estime._VeDLL = 0.0;

262. precepteurS->Sdoppler_estime._DopplerEstime = precepteurS-

>Sacquisition.DopplerEstimator_DopplerEstime;

263. precepteurS->Sdoppler_estime.DopplerIni =

2.0*M_PI*Const_Periode_re*precepteurS->Sdoppler_estime._DopplerEstime;

264. for(i=0; i<2; i++){

265. precepteurS->estado[i] = 0.0;

266. precepteurS->data_base[i] = 0.0;

267. precepteurS->data_exp[i] = 0.0;

268. }

269. return precepteurS;

270. }

271. #endif /* INITRECEPTEUR_H_ */

“integrator.h”

1. #ifndef INTEGRATOR_H_

2. #define INTEGRATOR_H_

3. struct recepteur *Fintegrator(struct recepteur *precepteurS){

4. int i;

5. //my_data->bitsynchro_struct->InstantSynchro = 0.0;

6. if(precepteurS->Sintegrator.RazIntP ==1){

7. precepteurS->Sintegrator._IndexData = (int)precepteurS-

>Scorrelateur_prompt.PromptRxx[0];

8. precepteurS->Sintegrator._PromptReRxx = precepteurS-

>Scorrelateur_prompt.PromptRxx[1];

9. precepteurS->Sintegrator._PromptImRxx = precepteurS-

>Scorrelateur_prompt.PromptRxx[2];

10. precepteurS->Sintegrator._EarlyReRxx = precepteurS-

>Scorrelateur_early.EarlyRxx[0];

11. precepteurS->Sintegrator._EarlyImRxx = precepteurS-

>Scorrelateur_early.EarlyRxx[1];

116

12. precepteurS->Sintegrator._LateReRxx = precepteurS-

>Scorrelateur_late.LateRxx[0];

13. precepteurS->Sintegrator._LateImRxx = precepteurS-

>Scorrelateur_late.LateRxx[1];

14. precepteurS->Sintegrator._NbIntegration = precepteurS->_NbIntegration;

15. precepteurS->Sintegrator._InstantSynchro = precepteurS-

>Sbitsynchro.InstantSynchro;

16. if(precepteurS->Sintegrator.Integration == 1){

17. if (precepteurS->Sintegrator.DebutIntegration == precepteurS-

>Sintegrator._IndexData){

18. precepteurS->Sintegrator.CompteInt = 0;

19. precepteurS->Sintegrator.DumpEnable = 1;

20. }

21. else{

22. precepteurS->Sintegrator.CompteInt += 1;

23. precepteurS->Sintegrator.DumpEnable = 0;

24. }

25. }

26. else{

27. precepteurS->Sintegrator.CompteInt = 0;

28. precepteurS->Sintegrator.DumpEnable = 0;

29. }

30. if (precepteurS->Sintegrator.DebutIntegration == precepteurS-

>Sintegrator._IndexData){

31. // Calcul de l'intervalle d'intégration

32. precepteurS->Sintegrator.NbSample = precepteurS-

>Sintegrator.DebutIntegration;

33. for (i=1; i<(precepteurS->Sintegrator._NbIntegration);i++){

34. precepteurS->Sintegrator.NbSample += 1;

35. if (precepteurS->Sintegrator.NbSample >= Const_NbIntegrationMax)

36. precepteurS->Sintegrator.NbSample -= Const_NbIntegrationMax;

37. precepteurS->Sintegrator.Intervalle[i] = precepteurS-

>Sintegrator.NbSample;

117

38. }

39. precepteurS->Sintegrator.FinIntegration = precepteurS-

>Sintegrator.Intervalle[precepteurS->Sintegrator._NbIntegration-1];

40. // Test de l'intervalle

41. for (i=1; i<(precepteurS->Sintegrator._NbIntegration);i++){

42. precepteurS->Sintegrator.InInter = 0;

43. if(precepteurS->Sintegrator.Intervalle[i] == precepteurS-

>Sintegrator._InstantSynchro){

44. precepteurS->Sintegrator.InInter = 1;

45. break;

46. }

47. }

48. if (precepteurS->Sintegrator.InInter == 1){

49. precepteurS->Sintegrator.Integration = 0;

50. precepteurS->Sintegrator.DebutIntegration = precepteurS-

>Sintegrator._InstantSynchro;

51. }

52. else{

53. precepteurS->Sintegrator.Integration = 1;

54. precepteurS->Sintegrator.DebutIntegration += precepteurS-

>Sintegrator._NbIntegration;

55. if(precepteurS-

>Sintegrator.DebutIntegration>=Const_NbIntegrationMax)

56. precepteurS->Sintegrator.DebutIntegration -= Const_NbIntegrationMax;

57. }

58. }

59. if (precepteurS->Sintegrator.DumpEnable == 1){

60. precepteurS->Sintegrator.AccPromptRe = 0.0;

61. precepteurS->Sintegrator.AccPromptIm = 0.0;

62. precepteurS->Sintegrator.AccEarlyRe = 0.0;

63. precepteurS->Sintegrator.AccEarlyIm = 0.0;

64. precepteurS->Sintegrator.AccLateRe = 0.0;

65. precepteurS->Sintegrator.AccLateIm = 0.0;

118

66. for (i=0; i<Const_NbIntegrationMax;i++){

67. precepteurS->Sintegrator.AccPromptRe += precepteurS-

>Sintegrator.TablePromptRe[i];

68. precepteurS->Sintegrator.AccPromptIm += precepteurS-

>Sintegrator.TablePromptIm[i];

69. precepteurS->Sintegrator.AccEarlyRe += precepteurS-

>Sintegrator.TableEarlyRe[i];

70. precepteurS->Sintegrator.AccEarlyIm += precepteurS-

>Sintegrator.TableEarlyIm[i];

71. precepteurS->Sintegrator.AccLateRe += precepteurS-

>Sintegrator.TableLateRe[i];

72. precepteurS->Sintegrator.AccLateIm += precepteurS-

>Sintegrator.TableLateIm[i];

73. }

74. precepteurS->Sintegrator.PromptRxxInt[0] = precepteurS-

>Sintegrator.AccPromptRe/precepteurS->Sintegrator._NbIntegration;

75. precepteurS->Sintegrator.PromptRxxInt[1] = precepteurS-

>Sintegrator.AccPromptIm/precepteurS->Sintegrator._NbIntegration;

76. precepteurS->Sintegrator.EarlyRxxInt[0] = precepteurS-

>Sintegrator.AccEarlyRe/precepteurS->Sintegrator._NbIntegration;

77. precepteurS->Sintegrator.EarlyRxxInt[1] = precepteurS-

>Sintegrator.AccEarlyIm/precepteurS->Sintegrator._NbIntegration;

78. precepteurS->Sintegrator.LateRxxInt[0] = precepteurS-

>Sintegrator.AccLateRe/precepteurS->Sintegrator._NbIntegration;

79. precepteurS->Sintegrator.LateRxxInt[1] = precepteurS-

>Sintegrator.AccLateIm/precepteurS->Sintegrator._NbIntegration;

80. precepteurS->Sintegrator.FreqDiscri_PromptRxx[0] = precepteurS-

>Sintegrator.AccPromptRe/precepteurS->Sintegrator._NbIntegration;

81. precepteurS->Sintegrator.FreqDiscri_PromptRxx[1] = precepteurS-

>Sintegrator.AccPromptIm/precepteurS->Sintegrator._NbIntegration;

82. precepteurS->Sintegrator.PhaseDiscri_PromptRxx[0] = precepteurS-

>Sintegrator.AccPromptRe/precepteurS->Sintegrator._NbIntegration;

83. precepteurS->Sintegrator.PhaseDiscri_PromptRxx[1] = precepteurS-

119

>Sintegrator.AccPromptIm/precepteurS->Sintegrator._NbIntegration;

84. #ifdef RXXINTOUTPUTFILE

85. //fprintf(thread_data_recepteur->integrator_struct-

>pFile3,"%g\n",thread_data_recepteur->integrator_struct-

>PromptRxxInt[0]);//ReRxxIntFile<<(AccPromptRe/NbIntegration)<<endl;

86. send_data_int(precepteurS->Sintegrator.PromptRxxInt[0]);

87. //fprintf(thread_data_recepteur->integrator_struct-

>pFile4,"%g\n",thread_data_recepteur->integrator_struct-

>PromptRxxInt[1]);//ImRxxIntFile<<(AccPromptIm/NbIntegration)<<endl;

88. send_data_int(precepteurS->Sintegrator.PromptRxxInt[1]);

89. #endif

90. }

91. #ifdef RXXOUTPUTFILE

92. //fprintf(thread_data_recepteur->integrator_struct-

>pFile1,"%g\n",thread_data_recepteur->integrator_struct-

>_PromptReRxx);//ReRxxFile<<_PromptReRxx<<std::endl;

93. send_data_double(precepteurS->Sintegrator._PromptReRxx);

94. //fprintf(thread_data_recepteur->integrator_struct-

>pFile2,"%g\n",thread_data_recepteur->integrator_struct-

>_PromptImRxx);//ImRxxFile<<_PromptImRxx<<std::endl;

95. send_data_double(precepteurS->Sintegrator._PromptImRxx);

96. #endif

97. precepteurS->Sintegrator.TablePromptRe[precepteurS-

>Sintegrator.CompteInt] = precepteurS->Sintegrator._PromptReRxx;

98. precepteurS->Sintegrator.TablePromptIm[precepteurS-

>Sintegrator.CompteInt] = precepteurS->Sintegrator._PromptImRxx;

99. precepteurS->Sintegrator.TableEarlyRe[precepteurS->Sintegrator.CompteInt]

= precepteurS->Sintegrator._EarlyReRxx;

100. precepteurS->Sintegrator.TableEarlyIm[precepteurS->Sintegrator.CompteInt]

= precepteurS->Sintegrator._EarlyImRxx;

101. precepteurS->Sintegrator.TableLateRe[precepteurS->Sintegrator.CompteInt]

= precepteurS->Sintegrator._LateReRxx;

102. precepteurS->Sintegrator.TableLateIm[precepteurS->Sintegrator.CompteInt]

120

= precepteurS->Sintegrator._LateImRxx;

103. Fcode_discriminator(precepteurS);

104. }

105. return precepteurS;

106. }

107. #endif /* INTEGRATOR_H_ */

“localCarrierGenerator.h”

1. #ifndef LOCALCARRIERGENERATOR_H_

2. #define LOCALCARRIERGENERATOR_H_

3. struct recepteur *FlocalCarrierGenerator(struct recepteur *precepteurS){

4. double I, Q;

5. I = precepteurS->Sreceiver_filter.I_out;

6. Q = precepteurS->Sreceiver_filter.Q_out;

7.

8. if(precepteurS->SfiltreFPLL._VeFPLL != 0)

9. precepteurS->Slocal_carrier_generator._VeFPLL = precepteurS-

>SfiltreFPLL._VeFPLL;

10. precepteurS->Slocal_carrier_generator._CarrierNCOCorr = precepteurS-

>Slocal_carrier_generator.DopplerIni + precepteurS-

>Slocal_carrier_generator._VeFPLL;

11. precepteurS->Slocal_carrier_generator.AccPhaseCarrier += precepteurS-

>Slocal_carrier_generator._CarrierNCOCorr;

12. precepteurS->Slocal_carrier_generator.CorrectionPhase = precepteurS-

>Slocal_carrier_generator.AccPhaseCarrier + precepteurS->_CarrierPhiIni;

13. precepteurS->Slocal_carrier_generator.CarrierCos = cos(precepteurS-

>Slocal_carrier_generator.CorrectionPhase);

14. precepteurS->Slocal_carrier_generator.CarrierSin = sin(precepteurS-

>Slocal_carrier_generator.CorrectionPhase);

15. precepteurS->Slocal_carrier_generator._Iout = I*(precepteurS-

>Slocal_carrier_generator.CarrierCos) +Q*(precepteurS-

>Slocal_carrier_generator.CarrierSin);

16. precepteurS->Slocal_carrier_generator._Qout = -I*(precepteurS-

>Slocal_carrier_generator.CarrierSin) + Q*(precepteurS-

121

>Slocal_carrier_generator.CarrierCos);

17. precepteurS->Slocal_carrier_generator.Iout = precepteurS-

>Slocal_carrier_generator._Iout;

18. precepteurS->Slocal_carrier_generator.Qout = precepteurS-

>Slocal_carrier_generator._Qout;

19. FcorrelateurComplet(precepteurS);

20. return precepteurS;

21. }

22. #endif /* LOCALCARRIERGENERATOR_H_ */

“localCodeGenerator.h”

1. #ifndef LOCALCODEGENERATOR_H_

2. #define LOCALCODEGENERATOR_H_

3. struct recepteur *FlocalCode(struct recepteur *precepteurS){

4. precepteurS->Slocal_code_generator._CodeIndexEarly = precepteurS-

>ScodeNCO.LocalCodeGenerator_CodeIndexEarly;

5. precepteurS->Slocal_code_generator._CodeIndexPrompt = precepteurS-

>ScodeNCO.LocalCodeGenerator_CodeIndexPrompt;

6. precepteurS->Slocal_code_generator._CodeIndexLate = precepteurS-

>ScodeNCO.LocalCodeGenerator_CodeIndexLate;

7. precepteurS->Scorrelateur_early.EarlyI[0] = precepteurS-

>Slocal_code_generator._CodeIndexPrompt;

8. precepteurS->Scorrelateur_early.EarlyI[1] = precepteurS-

>Slocal_code_generator.TabCode[precepteurS-

>Slocal_code_generator._CodeIndexEarly];

9. precepteurS->Slocal_code_generator.ChipEarly = precepteurS-

>Slocal_code_generator.TabCode[precepteurS-

>Slocal_code_generator._CodeIndexEarly];

10. precepteurS->Scorrelateur_prompt.PromptI[0] = precepteurS-

>Slocal_code_generator._CodeIndexPrompt;

11. precepteurS->Scorrelateur_prompt.PromptI[1] = precepteurS-

>Slocal_code_generator.TabCode[precepteurS-

>Slocal_code_generator._CodeIndexPrompt];

12. precepteurS->Slocal_code_generator.ChipPrompt = precepteurS-

122

>Slocal_code_generator.TabCode[precepteurS-

>Slocal_code_generator._CodeIndexPrompt];

13. precepteurS->Scorrelateur_late.LateI[0] = precepteurS-

>Slocal_code_generator._CodeIndexPrompt;

14. precepteurS->Scorrelateur_late.LateI[1] = precepteurS-

>Slocal_code_generator.TabCode[precepteurS-

>Slocal_code_generator._CodeIndexLate];

15. precepteurS->Slocal_code_generator.ChipLate = precepteurS-

>Slocal_code_generator.TabCode[precepteurS-

>Slocal_code_generator._CodeIndexLate];

16. return precepteurS;

17. }

18. #endif /* LOCALCODEGENERATOR_H_ */

“structures_recepteur.h”

1. #ifndef STRUCTURES_RECEPTEUR_H_

2. #define STRUCTURES_RECEPTEUR_H_

3. #include "Constants.h"

4. /** ------------------------------------------------- **/

5. /** ---------------- Receive data ---------------- **/

6. struct receive_data{

7. double _DopplerEstime, _DephasageEstime, _NbIntegration;

8. int _PRN;

9. double _Time_NS;

10. };

11. /** ---------------- Canal struct ---------------- **/

12. struct canal{

13. double I_out;

14. double Q_out;

15. };

16. /** ---------- Receiver filter struct ------------ **/

17. struct receiver_filter{

18. double I;

19. double Q;

123

20. double I_out;

21. double Q_out;

22. /* Variables internas */

23. double _I,_Q;

24. double AccFilterRe, AccFilterIm;

25. double Iprev, Qprev;

26. double TabCoeff[11], TabFilterRe[11], TabFilterIm[11];

27. };

28. /** ------------- Acquisition struct ------------- **/

29. struct acquisition{

30. double NCO_DopplerEstime;

31. double LocalCarrierGenerator_DopplerEstime;

32. double DopplerEstimator_DopplerEstime;

33. double DephasageEstime;

34. int PRN;

35. };

36. /** ------------Local Carrier Generator ---------- **/

37. struct local_carrier_generator{

38. double Iin, Qin;

39. double CarrierPhiIni;

40. double VeFPLL;

41. double Iout, Qout;

42. /* Variables internas */

43. double _VeFPLL;

44. double AccPhaseCarrier, CorrectionPhase;

45. double CarrierCos, CarrierSin;

46. double _Iout, _Qout;

47. double _CarrierNCOCorr;

48. double DopplerIni;

49. double _DopplerEstime;

50. double Iprev,Qprev;

51. double Iprev2,Qprev2;

52. };

124

53. /** ------------ Correlateur Complet ------------- **/

54. /** Correlateur Prompt **/

55. struct correlateur_prompt{

56. double I,Q;

57. int PromptI[2];//PromptI[0] = front

58. // Demande de calcul au NCO

59. int NCO_Calcul;//bool

60. // Canal vers l'integrateur

61. double PromptRxx[3];//PromptRxx[0] = front

62. // Canal vers le détecteur de Code Lock

63. double CodeLock_Rxx[3];//CodeLock_Rxx[0] = front

64. // Canal vers la synchro bit

65. double SynchroBit_Rxx[3];//SynchroBit_Rxx[0] = front

66. // Canal vers la démodulation des bits

67. double DataDemodulation_Rxx[3];//DataDemodulation_Rxx[0] = front

68. /* Variables internas */

69. int _CodeIndex, _CodeIndex_previous;

70. int IndexData;

71. double MultI, MultQ;

72. double _I, _Q;

73. double _CodeLocalI;

74. double CumulReRxx;

75. double CumulImRxx;

76. int RazInt;

77. };

78. /** Correlateur Early **/

79. struct correlateur_early{

80. double I,Q;

81. int EarlyI[2];// EarlyI[0] = front

82. double EarlyRxx[2];// EarlyRxx[0] = front

83. /* Variables internas */

84. int _CodeIndex, _CodeIndex_previous;

85. double MultI, MultQ;

125

86. double _I, _Q;

87. double _CodeLocalI;

88. double CumulReRxx;

89. double CumulImRxx;

90. int RazInt;

91. };

92. /** Correlateur Late **/

93. struct correlateur_late{

94. double I,Q;

95. int LateI[2];// LateI[0] = front

96. double LateRxx[2];// LateRxx[0] = front

97. /* Variables internas */

98. int _CodeIndex, _CodeIndex_previous;

99. double MultI, MultQ;

100. double _I, _Q;

101. double _CodeLocalI;

102. double CumulReRxx;

103. double CumulImRxx;

104. int RazInt;

105.

106. };

107. /** ------------- CodeLock Detector -------------- **/

108. struct codelock_detector{

109. double PromptRxxInt;

110. int InstantSynchro;

111. double C_N_estimated;

112. int CodeLock;// bool

113. int CodeDiscriLock[2];// bool

114. int PhaseLock[2];// bool

115. int FalseLockDetector_PhaseLock[2];// bool

116. double FalseLockDetector_EstimatedCN0;

117. /* Variables internas */

118. double WBP[50], NBP[50], NP[50];

126

119. double TabI[20], TabQ[20];//Const_NbIntegrationMax = 20

120. int InitInt;//bool

121. int _InstantSynchro;

122. double AccWBP, AccNBPI, AccNBPQ, AccNP;

123. double Fraction;

124. int j, k;

125. double NMoy;

126. // Phase Lock detector

127. double LPFResultRe;

128. double LPFResultIm;

129. int Pcount[3];

130. /* Más variables internas */

131. enum {Idle, WaitPhaseLock, WaitLockLoss} StateLock;

132. int _IndexData;

133. double _PromptReRxxInt, _PromptImRxxInt;

134. double AbsPromptReRxxInt,AbsPromptImRxxInt;

135. double LPFResultRe_previous, LPFinterRe, A;

136. double LPFResultIm_previous, LPFinterIm, B;

137. int _OptimisticPhaseLock, _PessimisticPhaseLock;//bool

138. double _C_N_estimated;

139. /* Más variables internas */

140. double _PromptReRxx, _PromptImRxx;

141. double _EarlyReRxx, _EarlyImRxx;

142. double _LateReRxx, _LateImRxx;

143. double AccPromptRe, AccPromptIm;

144. double AccEarlyRe, AccEarlyIm;

145. double AccLateRe, AccLateIm;

146. int _NbIntegration;

147. int NbSample;

148. };

149. /** ---------------- Integrator ------------------ **/

150. struct integrator{

151. double PromptRxx;

127

152. double EarlyRxx;

153. double LateRxx;

154. int NbIntegration;

155. int InstantSynchro;

156. double PromptRxxInt[2];

157. double EarlyRxxInt[2];

158. double LateRxxInt[2];

159. // Canal vs FPLL

160. double FreqDiscri_PromptRxx[2];

161. double PhaseDiscri_PromptRxx[2];

162. /* Variables internas */

163. double TablePromptRe[20], TablePromptIm[20];//Const_NbIntegrationMax = 20

164. double TableEarlyRe[20], TableEarlyIm[20];//Const_NbIntegrationMax = 20

165. double TableLateRe[20], TableLateIm[20];//Const_NbIntegrationMax = 20

166. int _IndexData;

167. int CompteInt, i;

168. int DumpEnable;// bool

169. int _InstantSynchro;

170. int Integration, InInter;// bool

171. int DebutIntegration, FinIntegration;

172. int Intervalle[20];//Const_NbIntegrationMax = 20

173. int RazIntP, RazIntE, RazIntL;

174. /* Más variables internas */

175. double _PromptReRxx, _PromptImRxx;

176. double _EarlyReRxx, _EarlyImRxx;

177. double _LateReRxx, _LateImRxx;

178. double AccPromptRe, AccPromptIm;

179. double AccEarlyRe, AccEarlyIm;

180. double AccLateRe, AccLateIm;

181. int _NbIntegration;

182. int NbSample;

183. };

184. /** ----------------- Bitsynchro ------------------**/

128

185. struct bitsynchro{

186. double PromptRxx;

187. int CodeLock;//bool

188. int InstantSynchro;

189. int DataDemodulation_InstantSynchro;

190. int CodeLock_InstantSynchro;

191. int FalseLockDetector_SynchroLock[2];//bool

192. /* Variables internas */

193. int _CodeLock;//bool

194. int Synchro, LockRecherche;//bool

195. int _InstantSynchro;

196. double Module;

197. double DataBufferRe[20];

198. double DataBufferIm[20];

199. int _IndexData;

200. double AccBuffer[20];

201. int IndiceMax, IndexBuffer;

202. int NbHits;

203. double IntegrationRe, IntegrationIm;

204. double IntegrationRe_previous, IntegrationIm_previous;

205. int TabMoyenne[4], IndiceMoyenne, AccMoyenne;

206. };

207. /** ------------- Code Discriminateur ------------- **/

208. struct code_discriminateur{

209. double PromptRxx;

210. double EarlyRxx;

211. double LateRxx;

212. int CodeDiscriLock;//bool

213. double NCO_VeDLL;

214. double DopplerEstimator_VeDLL;

215. double FalseLockDetector_VeDLL;

216. /* Variables internas */

217. double Bdll;

129

218. int _OptimisticPhaseLock, _PessimisticPhaseLock;//bool

219. double _PromptReRxxInt, _PromptImRxxInt;

220. double _EarlyReRxxInt, _EarlyImRxxInt;

221. double _LateReRxxInt, _LateImRxxInt;

222. #ifdef TEST2DISCRI

223. double Re_EmL, Im_EmL;

224. double ConjPromptImRxx;

225. double ReVeDLL, ImVeDLL;

226. double Power, Norm;

227. double ErrorPowerNormalized;

228. double CodeDoppler;

229. #endif

230. double E, L, EplusL, Discri, DiscriFiltre;

231. #ifdef TEST2DISCRI

232. FILE * pFile6;//std::ofstream VDLLFile2;

233. #endif

234. };

235. /** ------------- FalseLock Detector -------------- **/

236. struct falselock_detector{

237. int PhaseLock;//bool

238. int SynchroLock;//bool

239. double VeDLL;

240. double EstimatedCN0;

241. double FreqCorr;

242. /* Variables internas */

243. double TableVeDLL[200];

244. int NbDataStock;

245. double _EstimatedCN0;

246. int _SynchroLock, _FalseLock;//bool

247. int _OptimisticPhaseLock, _PessimisticPhaseLock;//bool

248. double _VeDLL;

249. int IndexTableVdll;

250. double AccVeDLL, MoyVeDll;

130

251. double Ferr;

252. int Contador;

253. };

254. /** ------------ Carrier Discriminator ------------ **/

255. struct carrier_discriminator{

256. double FreqDiscri_PromptRxx;

257. double PhaseDiscri_PromptRxx;

258. double VeFLL;

259. double VePLL;

260. /* Variables internas */

261. double _VeFLL;

262. double _VePLL;

263. double PromptReRxx_Previous, PromptReRxx_Now;

264. double PromptImRxx_Previous, PromptImRxx_Now;

265. double _PromptReRxx, _PromptImRxx;

266. double Dot, Cross;

267. double ErreurFrequenceFLL;

268. int Enable;// bool

269. };

270. /** ----------------- Filtre FPLL ----------------- **/

271. struct filtreFPLL{

272. int CodeLock;// bool

273. int PhaseLock;// bool

274. double FreqCorr;// bool

275. double NCO_VeFPLL;

276. double LocalCarrierGenerator_VeFPLL;

277. double DopplerEstimator_VeFPLL;

278. /* Variables internas */

279. int _OptimisticPhaseLock, _PessimisticPhaseLock;//bool

280. double f1, f2, p1, p2, p3;

281. double fil1, fil1_previous, fil2, fil3;

282. double fil4, fil4_previous, fil5;

283. double _VeFLL, _VePLL, _VeFPLL;

131

284. // Bande de boucle:

285. //double Bdll; // Bande de la DLL (en Hz)

286. double Bpll; // Bande de la PLL (en Hz)

287. double Bfll; // Bande de la FLL (en Hz)

288. // Calcul des paramètres de la FLL

289. // Filtre du 2ème ordre

290. double w0f;

291. double GainFreqAcc, GainFreqVel;

292. // Calcul des paramètres de la PLL

293. // Filtre du 3ème ordre

294. double w0p;

295. double GainPhJit, GainPhAcc, GainPhVel;

296. double GainAcc, GainVel;

297. double GainTint;

298. double FLL;

299. double _FreqCorr, CorrVeFPLL;

300. };

301. /** ------------------ Code NCO ------------------- **/

302. struct codeNCO{

303. int NCO_Calcul;//bool

304. double VeDLL;

305. double VeFPLL;

306. int LocalCodeGenerator_CodeIndexEarly;

307. int LocalCodeGenerator_CodeIndexPrompt;

308. int LocalCodeGenerator_CodeIndexLate;

309. double DopplerEstime;

310. double DephasageEstime;

311. /* Variables internas */

312. double _VeDLL, _VeFPLL;

313. double CodeIndexEarly, CodeIndexPrompt, CodeIndexLate;

314. double _DopplerEstime, _DephasageEstime;

315. double CodeFPLL, CodeNCO;

316. double DopplerIni;

132

317. double CodeFPLL_previous;

318. #ifdef MTI_SYSTEMC

319. double _Rc_re;

320. #endif

321. };

322. /** ------------ Local Code Generator --------------**/

323. struct local_code_generator{

324. /* Variables internas */

325. int ChipEarly, ChipPrompt, ChipLate;

326. int _CodeIndexPrompt, _CodeIndexEarly, _CodeIndexLate;

327. //int _PRN;

328. //char buffer[5];

329. //int i;

330. //char str[200];

331. int TabCode[1023];

332. //int Coeff;

333. };

334. /** ------------- Data Demodulation --------------- **/

335. struct data_demodulation{

336. int InstantSynchro;

337. double DataDemodulation_Rxx[3];

338.

339. #ifdef GENERATEUR

340. int DataBit;

341. #endif

342. /* Variables internas */

343. int _IndexData;

344. int _InstantSynchro;

345. double TablePromptRe[20],TablePromptIm[20] ;

346. double AccPromptRe, AccPromptIm;

347. int _DataBit;

348. double _PromptReRxx, _PromptImRxx;

349. };

133

350. /** --------------- Doppler Estime ---------------- **/

351. struct doppler_estime{

352. double VeFPLL;

353. double VeDLL;

354. double DopplerEstime;

355. double DopplerPhase, DopplerCode;

356. /* Variables internas */

357. double _VeDLL, _VeFPLL;

358. double TabDoppler[100];

359. int IndexDoppler;

360. double PhaseCorr;

361. double CodeFPLL, CodeNCO, NChip_par_periode, Fcode, EstDopplerCode;

362. double AccDoppler;

363. double DopplerIni;

364. double _DopplerEstime;

365. };

366. /****************************************************/

367. /** ---------------Recepteur Struct -------------- **/

368. /****************************************************/

369. struct recepteur{

370. //struct serial_conf Sserial_conf;

371. struct receive_data Sreceive_data;

372. struct canal Scanal;

373. struct receiver_filter Sreceiver_filter;

374. struct acquisition Sacquisition;

375. struct local_carrier_generator Slocal_carrier_generator;

376. struct correlateur_prompt Scorrelateur_prompt;

377. struct correlateur_early Scorrelateur_early;

378. struct correlateur_late Scorrelateur_late;

379. struct codelock_detector Scodelock_detector;

380. struct bitsynchro Sbitsynchro;

381. struct integrator Sintegrator;

382. struct data_demodulation Sdata_demodulation;

134

383. struct code_discriminateur Scode_discriminateur;

384. struct falselock_detector Sfalselock_detector;

385. struct carrier_discriminator Scarrier_discriminator;

386. struct filtreFPLL SfiltreFPLL;

387. struct codeNCO ScodeNCO;

388. struct local_code_generator Slocal_code_generator;

389. struct doppler_estime Sdoppler_estime;

390. int _NbIntegration;

391. double _CarrierPhiIni;

392. int clockGNSS;

393. double data_base[2];

394. double data_exp[2];

395. double estado[2];

396. };

397. struct recepteur recepteurS, *precepteurS;

398. #endif /* STRUCTURES_RECEPTEUR_H_ */

ANEXO C Código C del generador de señales GPS

136

“main.c”

1. #include "gnss.h"

2. int main(int argc, char *argv[])

3. {

4. int i,j;

5. int n;

6. int index1,index2;

7. int xi;

8. int8_t a[2];

9. double yi_I,yi_Q;// in-phase and in-quadrature output

10. double interval;

11. // Noise addition

12. double time_ac;//actual time (seconds)

13. #ifdef NOISEADDITION

14. double time_si;

15. double C_N0dB;

16. double Pth;

17. double C;

18. double N0;

19. double rand1, rand2, randn;

20. #endif

21. printf("-------------------------------------------------------------------------------\n");

22. printf("| GPS L1 C/A Signal Generator |\n");

23. printf("-------------------------------------------------------------------------------\n");

24. /** -------------------- Pointers -------------------- **/

25. struct transmitter *ptransmitterS = &transmitterS;

26. ptransmitterS->pFile1 = fopen(NameParameters,"r");

27. #ifdef OUTPUTFILE

28. ptransmitterS->pFile2 = fopen(NameSignalFile,"wb");

29. ptransmitterS->pFile3 = fopen(NameSignalData,"w");

30. #endif

31. FreadFile(ptransmitterS);

32. for(i=0;i<n_satellites;i++){

137

33. codeGeneGPS(ptransmitterS,i);

34. }

35. /** Creation of the seed **/

36. srand(time(NULL));//variable seed

37. //srand(1);//fixed seed

38. /** Data generation **/

39. for(j=0;j<n_satellites;j++){

40. for(i=0;i<n_bits;i++){

41. ptransmitterS->Data[i][j] = 2*(rand()%2) - 1;

42. fprintf(ptransmitterS->pFile3,"%i ",ptransmitterS->Data[i][j]);

43. }

44. fprintf(ptransmitterS->pFile3,"\n");

45. }

46. n = n_bits*fs1*timeperbit;//number of samples

47. interval = fcode/fs1;//interval between samples

48. yi_I = 0;

49. yi_Q = 0;

50. #ifdef NOISEADDITION

51. time_si = timeperbit*n_bits;

52. #endif

53. for(j=0;j<n_satellites;j++)

54. ptransmitterS->Delay_samples[j] = (int)(ptransmitterS->Delay[j]*fs1);//

Convertion time to samples per time

55. /** Signal generation **/

56. for(i=0;i<n;i++){

57. for(j=0;j<n_satellites;j++)

58. if(i>=ptransmitterS->Delay_samples[j])

59. if(i<n-ptransmitterS->Delay_samples[j]){

60. xi = (int)floor((i-ptransmitterS->Delay_samples[j])*interval);

61. index1 = xi%n_code;

62. index2 = (int)floor((double)xi/(n_chipsperbit*n_code));

63. time_ac = i/fs1;

64. yi_I = yi_I + (double)(ptransmitterS->Gain[j]*ptransmitterS-

138

>Data[index2][j]*ptransmitterS-

>TabCode[index1][j]*cos(2*M_PI*(fi+ptransmitterS-

>Doppler[j])*time_ac));

65. yi_Q = yi_Q + (double)(ptransmitterS->Gain[j]*ptransmitterS-

>Data[index2][j]*ptransmitterS-

>TabCode[index1][j]*sin(2*M_PI*(fi+ptransmitterS-

>Doppler[j])*time_ac));

66. }

67. #ifdef NOISEADDITION

68. /** Noise addition **/

69. C_N0dB = ptransmitterS->CN_Start - (ptransmitterS->CN_Start-

ptransmitterS->CN_End)*i/(time_si*fs1);

70. C = 0.5;

71. N0 = C*pow(10.0,-C_N0dB/10.0);

72. Pth = sqrt(fs1*N0);

73. /** For in-phase signal **/

74. rand1 = (double)rand()/(double)RAND_MAX;

75. if(rand1 == 0.0)

76. rand1 = 0.000001;

77. rand2 = (double)rand()/(double)RAND_MAX;

78. if(rand2 == 0.0)

79. rand2 = 0.000001;

80. /* Normal Distribution */

81. randn = sqrt(-2*log(rand1))*cos(2*M_PI*rand2);

82. yi_I = yi_I + (double)Pth*randn;

83. /** For in-quadrature signal **/

84. rand1 = (double)rand()/(double)RAND_MAX;

85. if(rand1 == 0.0)

86. rand1 = 0.000001;

87. rand2 = (double)rand()/(double)RAND_MAX;

88. if(rand2 == 0.0)

89. rand2 = 0.000001;

90. /* Normal Distribution */

139

91. randn = sqrt(-2*log(rand1))*cos(2*M_PI*rand2);

92. yi_Q = yi_Q + (double)Pth*randn;

93. #endif

94. /** Save the signal into a Bin file as int8 **/

95. #ifdef OUTPUTFILE

96. a[0] = (int8_t)(quantization*yi_I);

97. a[1] = (int8_t)(quantization*yi_Q);

98. fwrite(a,1,sizeof(a),ptransmitterS->pFile2);

99. #endif

100. yi_I = 0;

101. yi_Q = 0;

102. }

103. return 0;

104. }

“codeGeneGPS.c”

1. #include "codeGeneGPS.h"

2. void ones(int *t,int n){

3. int i;

4. for(i=0;i<n;i++)

5. *(t+i)=1;

6. }

7. int xor(int a,int b){

8. if(a==b)

9. return 0;

10. else

11. return 1;

12. }

13. void codeGeneGPS(struct transmitter *ptransmitterS, int num){

14. int CoupleSV[32][2]={{2,6},{3,7},{4,8},{5,9},{1,9},{2,10},{1,8},{2,9},{3,10},

{2,3},{3,4},{5,6},{6,7},{7,8},{8,9},{9,10},{1,4},{2,5},{3,6},{4,7},{5,8},{6,9},

{1,3},{4,6},{5,7},{6,8},{7,9},{8,10},{1,6},{2,7},{3,8},{4,9}};

15. int vecteur[10];

16. int *t = &vecteur[0];

140

17. int codeG1[1023];

18. int *t1 = &codeG1[0];

19. int codeG2[1023];

20. int *t2 = &codeG2[0];

21. int dec;

22. int i,j;

23. int temp,temp1;

24. int SV = ptransmitterS->PRN[num];

25. /* Generation of code G1*/

26. ones(t,10);

27. for(i=0;i<1023;i++){

28. *(t1+i)=*(t+9);

29. for(j=0;j<10;j++){

30. if(j==0){

31. temp = *t;

32. *t=xor(*(t+2),*(t+9));

33. }

34. else{

35. temp1 = *(t+j);

36. *(t+j) = temp;

37. temp = temp1;

38. }

39. }

40. }

41. /* Generation of code G2 */

42. ones(t,10);

43. for(i=0;i<1023;i++){

44. *(t2+i)=xor(*(t+(int)CoupleSV[SV-1][0]-1),*(t+(int)CoupleSV[SV-1][1]-1));

45. dec = xor(xor(xor(*(t+1),*(t+2)), xor(*(t+5),*(t+7))), xor(*(t+8),*(t+9)));

46. for(j=0;j<10;j++){

47. if(j==0){

48. temp = *t;

49. *t=dec;

141

50. }

51. else{

52. temp1 = *(t+j);

53. *(t+j) = temp;

54. temp = temp1;

55. }

56. }

57. }

58. /* Generation of code GPS */

59. for(i=0;i<1023;i++){

60. ptransmitterS->TabCode[i][num]=2*xor(*(t1+i),*(t2+i))-1;

61. }

62. }

“codeGeneGPS.h”

1. /** codeGeneGPS.c

2. * Author: Jean León

3. * Date: Nov 8, 2012

4. * Description:

5. * This function generates the PRN code for GPS.

6. * This function was extracted from Kaplan p.129.

7. **/

8. #include "gnss.h"

9. void codeGeneGPS(struct transmitter *ptransmitterS, int num);

“constants.h”

1. #include <math.h>

2. #define OUTPUTFILE

3. #define NOISEADDITION

4. #ifdef OUTPUTFILE

5. static const char *NameParameters = "Parameters.txt";

6. static const char *NameSignalFile = "Result/Result.bin";//SignalGNSS_SDR.bin";

7. static const char *NameSignalData = "Result/DataGenerated.txt";

8. #endif

9. /** --------- Numerical Values ------------ **/

142

10. #define fcode ((double)1.023*pow(10,6))// F_CAcode = 1.023 MHz

11. #define fs ((double)1540*10.23*pow(10,6))// fs = 10*(154*10.23MHz)

12. #define fs1 ((double)20*pow(10,6))// Fs = 20 MHz

13. #define fi ((double)5.02*pow(10,6))// IF = 5.02 MHz

14. #define timeperbit ((double)20*pow(10,-3))// time per bit = 20 ms

15. #define n_chipsperbit 20 // chips per bit = 20

16. //static const int n_code = 1023;// size of PRN code = 1023

17. #define n_samplespercode 15400// samples per code

18. #define n_bits 10

19. #define n_satellites 7

20. #define n_code 1023

21. #define quantization ((double)(127/32))

“gnss.h”

1. /** gnss.h

2. * GPS L1 C/A generator v1.0

3. * Author: Jean León

4. * Date: Nov 28, 2012

5. * Description:

6. * This file contains all the basic libraries and headers to be used in this program.

7. **/

8. #include <time.h>

9. #include <stdio.h>

10. #include <stdlib.h>

11. #include <math.h>

12. #include <string.h>

13. #include <sys/stat.h>

14. #include <stdint.h>

15. #include "constants.h"

16. #include "structures.h"

“readFile.c”

1. /** readFile.c

2. * GPS L1 C/A generator v1.0

3. * Author: Jean León

143

4. * Date: Nov 28, 2012

5. * Description:

6. * This function reads a Txt file (Parameters.txt) which contains all the parameters

to generate the signal.

7. **/

8. #include "readFile.h"

9. void FreadFile(struct transmitter *ptransmitterS){

10. int i;

11. fscanf(ptransmitterS->pFile1,"%lf",&(ptransmitterS->CN_Start));

12. fscanf(ptransmitterS->pFile1,"%lf",&(ptransmitterS->CN_End));

13. printf("CN_start: %lf CN_end: %lf\n",ptransmitterS->CN_Start,ptransmitterS-

>CN_End);

14. for(i=0;i<n_satellites;i++){

15. fscanf(ptransmitterS->pFile1,"%i",&(ptransmitterS->PRN[i]));

16. fscanf(ptransmitterS->pFile1,"%lf",&(ptransmitterS->Delay[i]));

17. fscanf(ptransmitterS->pFile1,"%lf",&(ptransmitterS->Doppler[i]));

18. fscanf(ptransmitterS->pFile1,"%lf",&(ptransmitterS->Gain[i]));

19. printf("PRN: %i Delay: %lf Doppler: %lf Gain: %lf\n",ptransmitterS-

>PRN[i],ptransmitterS->Delay[i],ptransmitterS->Doppler[i],ptransmitterS-

>Gain[i]);

20. }

21. }

“readFile.h”

1. /** readFile.h

2. * GPS L1 C/A generator v1.0

3. * Author: Jean León

4. * Date: Nov 28, 2012

5. * Description:

6. * This function reads a Txt file (Parameters.txt) which contains all the parameters

to generate the signal.

7. **/

8. #include "gnss.h"

9. void FreadFile(struct transmitter *ptransmitterS);

144

“structures.h”

1. struct transmitter{

2. /* Input variables */

3. //int n_bits;

4. int PRN[n_satellites];

5. double Doppler[n_satellites];

6. double Delay[n_satellites];

7. double Gain[n_satellites];

8. double CN_Start;

9. double CN_End;

10. int TabCode[n_code][n_satellites];

11. int Time_NS;

12. int Data[n_bits][n_satellites];

13. int Delay_samples[n_satellites];

14. FILE *pFile1;

15. FILE *pFile2;

16. FILE *pFile3;

17. };

18. struct transmitter transmitterS;

ANEXO D Código C de la transmisión serial

146

“main.c”

1. /*

2. * File: main.c

3. * Author: Jean León

4. * Description: This program sends the signal file to the LEON Processor by serial

port.

5. */

6. #define __LINUX_COM__ // If you are using a Linux distribution

7. // #define __WINDOWS_COM__ // In case of you are using a Windows

distribution

8. #include "com/serial.h"

9. #include <stdlib.h>

10. #include <string.h>

11. #include <math.h>

12. #include "send_data.h"

13. static const char *NameSignalFile = "Result.bin";// Path of the signal file

14. static const char *NameEstimatedDopplerFile = "Results/EstimatedDoppler.dat";//

15. Output file of the results

16. static const char *NameEstimatedDopplerCodeFile =

17. "Results/EstimatedDopplerCode.dat";// Output file of the results

18. int main(){

19. HANDLE fd;

20. FILE *SignalFile;

21. char _TabSigChar[10000];

22. int IncChar;

23. FILE *pFile[2];

24. /* Values obtained in the acquisition phase */

25. double dopplerEstime;

26. double dephasageEstime;

27. double nbIntegration;

28. double prn;

29. double timeNS; // Simulation time (ns)

30. double temp;

147

31. double data_received;

32. int i;

33. int j;

34. int samples;

35. IncChar = 0;

36. fd=Open_Port("/dev/ttyUSB0");// Open the serial port

37. // In case of Windows: fd=Open_Port("COMX");

38. // where X could be 1,2,3,..

39. Configure_Port(fd,B38400,"8N1"); // Setting the serial port.

40. Set_Hands_Haking(fd,2); // Setting the control flow (optional)

41. /* Open the signal file */

42. SignalFile =fopen(NameSignalFile, "rb");

43. /* Open Doppler Estime file*/

44. pFile[0] = fopen(NameEstimatedDopplerFile, "w");

45. /* Open Doppler code file*/

46. pFile[1] = fopen(NameEstimatedDopplerCodeFile,"w");

47. if(SignalFile == NULL){

48. printf("Canal.c : Ficher Signal %s not found\n",NameSignalFile);

49. exit(0);

50. }

51. else

52. printf("Canal.c : Ficher Signal %s opened\n",NameSignalFile);

53. /** Starting sending the initial values **/

54. /** Doppler Estime **/

55. dopplerEstime = 156.25;

56. dato_recibido = Fsend_data(fd,dopplerEstime,0);

57. printf("Doppler Estime: %lf\n",dato_recibido);

58. /** Dephasage Estime **/

59. dephasageEstime = 1205;

60. dato_recibido = Fsend_data(fd,dephasageEstime,1);

61. printf("Dephasage Estime: %lf\n",dato_recibido);

62. /** Nb Integration **/

63. nbIntegration = 1.0;

148

64. dato_recibido = Fsend_data(fd,nbIntegration,1);

65. printf("Nb Integration: %lf\n",dato_recibido);

66. /** PRN **/

67. prn = 9.0;

68. dato_recibido = Fsend_data(fd,prn,1);

69. printf("PRN: %lf\n",dato_recibido);

70. /** Time ns **/

71. timeNS = 10000000.0;

72. dato_recibido = Fsend_data(fd,timeNS,1);

73. printf("Time(ns): %lf\n",dato_recibido);

74. samples = (int)timeNS/122.05;

75. printf("\n");

76. printf("************** Starting transmission ****************\n");

77. printf("\n");

78. for(j=0;j<samples;j++){

79. if(IncChar == 0){

80. fread(_TabSigChar,10000,1,SignalFile);

81. }

82. temp=(double)_TabSigChar[IncChar++];

83. data_received = Fsend_data(fd,temp,1); // Sends the I component of the signal

84. //printf("I: %lf ",data_received);

85. temp=(double)_TabSigChar[IncChar++]; // Sends the Q component of the

signal

86. data_received = Fsend_data(fd,temp,1);

87. //printf("Q: %lf\n",data_received);

88. printf(" <-Samples \r %d",j+1);

89. for(i=0;i<2;i++){

90. temp = 1.111;

91. dato_recibido = Fsend_data(fd,temp,1);

92. if(dato_recibido == temp)

93. dato_recibido = 0.0;

94. else

95. fprintf(pFile[i],"%g\n",data_received);// Save the data in the indicated file

149

96. }

97. if(IncChar >= 10000)

98. IncChar = 0;

99. }

100. Close_Port(fd); // Close the serial port

101. return 0;

102. }

“send_data.h”

1. /*

2. * File: send_data.h

3. * Author: Jean León

4. * Description: This program reads and write data to the serial port.

5. * For only test the program, the data is sent using scientifc notation, but

could be send in other way.

6. * For the first value to be sent, Gets_Port is only used once, but Gets_Port

must be used twice for the next transmissions.

7. */

8. double Fsend_data(HANDLE fd, double num, int indice){

9. double exp;

10. double base;

11. char data_base[12];

12. char data_exp[12];

13. char cad2_base[13];

14. char cad2_exp[13];

15. if(num == 0.0){

16. exp = 0.0;

17. base = 0.0;

18. }

19. else{

20. exp = floor(log10(fabs(num)));

21. base = num/pow(10,exp);;

22. }

23. sprintf(data_base,"%+12.9lf\r",base);// send the base of the data

150

24. Write_Port(fd,data_base,13);// Escritura en el puerto serie.

25. if(indice == 1){

26. while(Kbhit_Port(fd)<13);

27. Gets_Port(fd,cad2_base,13);// Reads the serial port

28. }

29. while(Kbhit_Port(fd)<13);

30. Gets_Port(fd,cad2_base,13);//

31. sprintf(data_exp,"%+12.8lf\r",exp);// Send the exponent of the data

32. Write_Port(fd,data_exp,13);

33. while(Kbhit_Port(fd)<13);

34. Gets_Port(fd,cad2_exp,13);// Reads the serial port

35. while(Kbhit_Port(fd)<13);

36. Gets_Port(fd,cad2_exp,13);// Reads the serial port

37. //printf("Data received: %f*10^(%f)\n",atof(cad2_base),atof(cad2_exp));

38. return atof(cad2_base)*pow(10,atof(cad2_exp));

39. }

BIBLIOGRAFÍA

[1] C. Wang y G. Lachapelle, «GPS Attitude Determination Reliability Performance

Improvement Using Low cost Receivers,» Journal of Global Positioning Systems, pp.

85-95, 2002.

[2] F. Bauer, K. Hartman y E. G. Lightsey, «Spaceborne GPS Current Status and Future

Visions,» de 1998 IEEE Aerospace Conference, Snowmass, 1998.

[3] E. G. Lightsey, «Development and Flight Demonstration of a GPS Receiver for

Space,» UMI, Ann Arbor, 1997.

[4] E. Comission, «European GNSS (Galileo) Open Service: Signal in Space: Interface

Control Document,» Office of the European Union, 2010.

[5] S. Hongwei, L. Zhigang y P. Feng, «Development of Satellite Navigation in China,»

de IEEE International Frequency Control Symposium, 2007 Joint with the 21st

European Frequency and Time Forum, Geneva, 2007.

[6] P. Tortora, «A GPS based attitude determination algorithm for the spin-stabilized

microsatellite UNISAT,» Acta Astronautica, vol. 47, nº 2-9, pp. 139-146, 2000.

[7] A. S. &. T. (AST), «Andrews Technical Services,» Andrews Space & Technology

(AST), 2001. [En línea]. Available: http://www.spaceandtech.com. [Último acceso: 3

Mayo 2013].

[8] B. Fraser, C. Russell, J. Means, F. Menk y C. Waters, «FedSat - An Australian

research microsatellite,» Advances in Space Research, vol. 25, nº 7-8, pp. 1325-1336,

2000.

[9] H. Zhang y M. Unwin, «The Use of GPS Receiver on Tsinghua-1 Microsatellite,» de

Proceedings of the International Symposium on Digital Earth, Beijing, 1999.

[10] M. Grondin, M. Belasic, L. Ries, J.-L. Issler, P. Bataille, L. Jobey y G. Richard, «A

New Operational Low cost GNSS Software Receiver for Microsatellites,» de 2010 5th

ESA Workshop on Satellite Navigation Technologies and European Workshop on

152

GNSS Signals and Signal Processing (NAVITEC), Noordwijk, 2010.

[11] Y. Feng, «Combined Galileo and GPS: A Technical Perspective,» Journal of Global

Positioning Systems, vol. 2, nº 1, pp. 67-72, 2003.

[12] D. Devly y S. Cobb, GNSS for Vehicle Control, Norwood: Artech House, 2010.

[13] P. Groves, Principles of GNSS, Inertial, and Multisensor Integrated Navigation

Systems, Artech House, 2008.

[14] M. Braasch y A. Van Dierendock, «GPS Receiver Architectures and Measurements,»

Proceedings of the IEEE, vol. 87, nº 1, pp. 48-64, 1999.

[15] E. Kaplan y C. Hergarty, Understanding GPS: Principles and Applications, Norwood:

Artech House, 2006.

[16] A. Mitra, «On the Properties of Pseudo Noise Sequences with a Simple Proposal of

Randomness Test,» International Journal of Electrical and Computer Engineering,

vol. 3, nº 3, pp. 164-169, 2008.

[17] U. N. O. f. O. S. A. «Education Curriculum: Global Navigation Satellite Systems,»

United Nations, New York, 2012.

[18] A. Dion, V. Calmettes y E. Boutillon, «Reconfigurable GPS-Galileo receiver for

satellite based applications,» de 2008 National Technical Meeting of The Institute of

Navigation, San Diego, 2008.

[19] S. Gleason y D. Gebre-Egzihaber, GNSS Applications and Methods, Norwood:

Artech House, 2009.

[20] R. Conker, B. El-Arini, C. Hegarty y T.-Y. Hsiao, «Modeling the Effects of

Ionospheric Scintillation on GPS/SBAS Availability,» MITRE, McLean, 2000.

[21] D. Akopian, «Fast FFT based GPS satellite acquisition methods,» IEE Proceedings -

Radar, Sonar and Navigation, vol. 152, nº 4, pp. 277-286, 2005.

[22] B. Parkinson y J. Spilker, Global Positioning System: Theory and Applications, AIAA

Inc., 1996.

[23] SPARC International Inc., «The SPARC Architecture Manual - Version 8,» SPARC

International Inc., Menlo Park, 1992.

[24] ARM Limited, «AMBA Specification (Rev 2.0),» ARM Limited, Cambridge, 1999.

[25] J. Gaisler y M. Isomäki, «LEON3 GR-XC3S-1500 Template Design,» Gaisler

153

Research, Goteborg, 2006.

[26] S. Corrigan, «Introduction to Controller Area Network (CAN),» Texas Instruments,

Dallas, 2005.

[27] K. V. Shibu, Introduction to Embedded Systems, Delhi: Tata McGraw Hill, 2009.

[28] J. Gaisler y K. Eisele, «BCC - Bare-C Cross-Compiler User's Manual,» Aeroflex

Gaisler AB, Goteborg, 2013.

[29] Aeroflex Gaisler AB, «GRMON User's Manual,» Aeroflex Gaisler AB, Goteborg,

2013.

[30] Aeroflex Gaisler, «Eclipse C/C++ IDE plugin for LEON software development,»

Aeroflex Gaisler AB, [En línea]. Available:

http://www.gaisler.com/index.php/products/operating-

systems/bcc?option=com_content&task=view&id=292&Itemid=31. [Último acceso:

11 Agosto 2013].

[31] F. Pujaico Rivera, «LnxCOMM,» TrucomanX, 3 Junio 2008. [En línea]. Available:

http://lnxcomm.sourceforge.net/. [Último acceso: 16 Julio 2013].

[32] V. Calmettes, A. Dion, E. Boutillon y E. Liegeon, «Fast Acquisition Unit for

GPS/Galileo Receivers in Space Enviroment,» de Proceedings of the 2008 National

Technical Meeting of The Institute of Navigation, San Diego, 2008.

[33] A. Dion, E. Boutillon, V. Calmettes y E. Liegon, «A Flexible Implementation of a

Global Navigation Satellite System (GNSS) Receiver for On-Board Satellite

Navigation,» de 2010 Conference on Design and Architectures for Signal and Image

Processing (DASIP), Edinburgh, 2010.

[34] J. Awange, Environmental Monitoring Using GNSS, Verlag: Springer, 2012.

154