**Goal**

Draw the contour of the iso-doppler and iso-delay lines for a transceiver reflection on a specular plane.

**Implementation**

This Doppler shift can be expressed as follows:

$$ f_ {D, 0} ( vec {r}, t_0) = [vec{V_t} cdot vec{m}(vec{r},t_0) – vec{V_r} cdot vec{n}(vec{r},t_0)]/ lambda $$

where for a given time $ t_0 $, $ vec {m} $ is the unit vector reflected, $ vec {n} $ is the unit vector of incident, $ vec {V_t} $ is the speed of the transmitter, $ vec {V_r} $ is the speed of the receiver, and $ lambda $ is the wave length of the transmitted electromagnetic wave.

The timing of the electromagnetic wave is simply the path traveled divided by the speed of light, assuming that the vacuum propagates.

```
#! / usr / bin / env python
import scipy.integrate as integrated
import numpy as np
import matplotlib.pyplot as a plt
import matplotlib.ticker as ticker
h_t = 20000e3 # meters
h_r = 500e3 # meters
altitude = 60 * np.pi / 180 # rad
# Coordinate frame as defined in Figure 2
# J. F. Marchan-Hernandez, A. Camps, N. Rodriguez-Alvarez, E. Valencia, X.
# Bosch-Lluis and I. Ramos-Perez, "An effective algorithm for the simulation of
# Delay - Doppler Maps of Reflected Signals from the Global Navigation Satellite System »
# IEEE Geoscience and Remote Sensing Transactions, Vol. 47, no. 8, pp.
No. 2733-2740, August 2009.
r_t = np.array ([0,h_t/np.tan(elevation),h_t])
r_r = np.array ([0,-h_r/np.tan(elevation),h_r])
# Speed
v_t = np.array ([2121, 2121, 5]) # Mrs
v_r = np.array ([2210, 7299, 199]) # Mrs
light_speed = 299792458 # m / s
# The GPS center frequency L1 is defined relative to a reference frequency
# f_0 = 10.23e6, so that f_carrier = 154 * f_0 = 1575.42e6 # Hz
# Explained in the "GPS SIGNAL DESCRIPTION" section EMIS & # 39; in Zarotny
# and Voronovich 2000
f_0 = 10.23e6 # Hz
f_carrier = 154 * f_0;
def doppler_shift (r):
& # 39; & # 39; & # 39;
Doppler shift as a contribution of the relative motion of the transmitter and
receiver as well as the point of reflection.
Implements the equation 14
V. U. Zavorotny and A. G. Voronovich, "Dispersion of GPS signals from
the ocean with the application of remote sensing of wind, "says IEEE
Geoscience and Remote Sensing, Vol. 38, no. 2, pages 951 to 964, March 2000.
& # 39; & # 39; & # 39;
wavelength = speed of light / f_carrier
f_D_0 = (1 / wavelength) * (
np.inner (v_t, incident_vector (r))
-np.inner (v_r, reflection_vector (r))
)
#f_surface = scattering_vector (r) * v_surface (r) / 2 * pi
f_surface = 0
returns f_D_0 + f_surface
def doppler_increment (r):
returns doppler_shift (r) - doppler_shift (np.array ([0,0,0]))
def reflexion_vector (r):
reflection_vector = (r_r - r)
reflection_vector_norm = np.linalg.norm (r_r - r)
reflection vector[0] / = reflexion_vector_norm
reflection vector[1] / = reflexion_vector_norm
reflection vector[2] / = reflexion_vector_norm
returns vector_flection
def incident_vector (r):
incident_vector = (r - r_t)
incident_vector_norm = np.linalg.norm (r - r_t)
incident_vector[0] / = incident_vector_norm
incident_vector[1] / = incident_vector_norm
incident_vector[2] / = incident_vector_norm
returns incident_vector
def time_delay (r):
path_r = np.linalg.norm (r-r_t) + np.linalg.norm (r_r-r)
path_specular = np.linalg.norm (r_t) + np.linalg.norm (r_r)
return (1 / light_speed) * (path_r - path_specular)
Tracing area
x_0 = -100e3 # meters
x_1 = 100e3 # meters
n_x = 500
y_0 = -100e3 # meters
y_1 = 100e3 # meters
n_y = 500
x_grid, y_grid = np.meshgrid (
np.linspace (x_0, x_1, n_x),
np.linspace (y_0, y_1, n_y)
)
r = [x_grid, y_grid, 0]
z_grid_delay = time_delay (r) / delay_chip
z_grid_doppler = doppler_increment (r)
delay_start = 0 # chips C / A
delay_increment = 0.5 # chips C / A
delay_end = 15 # chips C / A
iso_delay_values = list (np.arange (delay_start, delay_end, delay_increment))
doppler_start = -3000 # Hz
doppler_increment = 500 # Hz
doppler_end = 3000 # Hz
iso_doppler_values = list (np.arange (doppler_start, doppler_end, doppler_increment))
fig_lines, ax_lines = plt.subplots (1, figsize = (10, 4))
contour_delay = ax_lines.contour (x_grid, y_grid, z_grid_delay, iso_delay_values, cmap => winter & # 39;)
fig_lines.colorbar (outline_delay, label = C / A chips,)
contour_doppler = ax_lines.contour (x_grid, y_grid, z_grid_doppler, iso_doppler_values, cmap => winter)
fig_lines.colorbar (outline_doppler, label = "Hz")
ticks_y = ticker.FuncFormatter (lambda y, pos: # {0: g}. format (y / 1000))
ticks_x = ticker.FuncFormatter (lambda x, pos: {0: g}. format (x / 1000))
ax_lines.xaxis.set_major_formatter (ticks_x)
ax_lines.yaxis.set_major_formatter (ticks_y)
plt.xlabel (& # 39;[km]& # 39;)
plt.ylabel (& # 39;[km]& # 39;)
plt.show ()
```

What produces this output supposedly right:

Do not hesitate to provide recommendations on implementation and style.

**Questions**

In order to calculate the incident vector from a point $ r_t $ I have implemented the following code:

```
def incident_vector (r):
incident_vector = (r - r_t)
incident_vector_norm = np.linalg.norm (r - r_t)
incident_vector[0] / = incident_vector_norm
incident_vector[1] / = incident_vector_norm
incident_vector[2] / = incident_vector_norm
returns incident_vector
```

It works perfectly fine, but I think there must be a cleaner way of writing that. I would like to write something like this:

```
def incident_vector (r):
return (r - r_t) /np.linalg.norm (r - r_t)
```

But unfortunately, it does not work with the grid mesh, because she does not know how to multiply the scalar grid with the grid vector:

```
ValueError: Operands Can not Be Broadcast with Shapes (3,) (500,500)
```