In [12]:
%pylab inline
from sympy import *
from IPython.display import Image
init_printing(use_latex="mathjax")


Populating the interactive namespace from numpy and matplotlib
WARNING: pylab import has clobbered these variables: ['prod', 'Circle', 'power', 'diag', 'sinh', 'trunc', 'binomial', 'plot', 'eye', 'det', 'tan', 'product', 'roots', 'vectorize', 'sin', 'plotting', 'zeros', 'cosh', 'conjugate', 'take', 'solve', 'trace', 'beta', 'ones', 'transpose', 'cos', 'interactive', 'diff', 'invert', 'tanh', 'Polygon', 'reshape', 'sqrt', 'floor', 'source', 'add', 'multinomial', 'test', 'poly', 'mod', 'sign', 'gamma', 'log', 'var', 'seterr', 'flatten', 'nan', 'pi', 'exp']
`%matplotlib` prevents importing * from pylab and numpy

Rotazione del subreflettore intorno al fuoco


In [74]:
Image("files/rot_sub.png")


Out[74]:

Sia dato il sistema descritto il figura in cui:

  • O rappresenta il centro del subriflettore in posizione 0
  • F rappresenta il fulcro del parboloide
  • D è la distanza tra il subriflettore e il fuoco nella posizione 0
  • $ \theta = \widehat{OFP}$ , angolo di rotazione del subriflettore necessario ad inquadrare un feed in vertex
  • $|FO| = |FP| = \textbf{D}$

Vogliamo trovare le compensazioni Z e X da applicare al movimento del subriflettore per mantenerlo centrato sull'asse di fuoco senza introdurre errori di puntamento.


Essendo il triangolo $OFP$ isoscele abbiamo che: $$ \alpha = \frac{\pi - \theta}{2} = \frac{\pi}{2} - \frac{\theta}{2} $$

da cui possiamo ricavare l'ampiezza dell'angolo $\beta$: $$ \beta = \frac{\pi}{2} - \alpha = \frac{\pi}{2} - \frac{\pi}{2} + \frac{\theta}{2} = \frac{\theta}{2} $$

Possiamo quindi calcolare X e Z sapendo che: $$ |PO| = 2 * (D * \sin{\frac{\theta}{2}}) $$ E sfruttando il fatto che $PBO$ è rettangolo in $B$: $$ X = |PO| * \cos{\beta} = 2 * D * \sin{\frac{\theta}{2}} * \cos{\frac{\theta}{2}} = D* \sin{\theta} $$ $$ Z = |PO| * \sin{\beta} = 2 * D * \sin{\frac{\theta}{2}} * \sin{\frac{\theta}{2}} = 2 * D * (\sin{\frac{\theta}{2}})^2$$


In [75]:
d, t, z, x = symbols("D theta z x")
z = 2 * d * (sin(t/2)**2)
x = d * sin(t)

Sapendo che $ D = 310.7mm $ calcolato geometricamente per il subreflettore possiamo calcolare il variare di X e Z al variare dell'angolo in vertex


In [76]:
xaxis = linspace(0, radians(8), 1000)
xaxis_labels = linspace(0, 8, 1000)
#z_at_fixed_d = 2 * 310.7 * np.sin(xaxis/2)**2
#x_at_fixed_d = 310.7 * np.sin(xaxis)
z_at_fixed_d = array([N(z.subs(d, 310.7).subs(t, _theta)) for _theta in xaxis])
x_at_fixed_d = array([N(x.subs(d, 310.7).subs(t, _theta)) for _theta in xaxis])

Dai plot seguenti vediamo come nella posizione 0 del sureflettore una rotazione di un angolo $\theta$ attorno al fuoco rappresenti una piccola correzione in Z e una più consistente correzione in X


In [77]:
pylab.title("Z correction at D = 310.7")
pylab.xlabel("Theta deg.")
pylab.ylabel("Z mm")
pylab.grid(True)
pylab.plot(xaxis_labels, z_at_fixed_d, 'b-', 
           xaxis_labels[500], z_at_fixed_d[500], 'bo', 
           markersize = 12)


Out[77]:
[<matplotlib.lines.Line2D at 0x6af3090>,
 <matplotlib.lines.Line2D at 0x6af3310>]

In [78]:
pylab.title("X correction at D = 310.7")
pylab.xlabel("Theta deg.")
pylab.ylabel("X mm")
pylab.grid(True)
pylab.plot(xaxis_labels, x_at_fixed_d, 'g-', 
           xaxis_labels[500], x_at_fixed_d[500], 'go', 
           markersize = 12)


Out[78]:
[<matplotlib.lines.Line2D at 0x6e6e650>,
 <matplotlib.lines.Line2D at 0x6e6e8d0>]

Presupponiamo ora di inquadrare un ricevitore con un angolo di $\theta = 4^{\circ}$ e di voler effettuare un focheggiamento muovendo il subreflettore verso il ricevitore di una quantità che facciamo variare tra 0 e 18cm, calcolati come $ 3\lambda @ 5 GHz$ . Anche in questo caso possiamo controllare il variare delle correzioni applicate in Z e X al variare della distanza del subreflettore dal fuoco.


In [79]:
xaxis = linspace(0, 180, 1000)
z_at_fixed_t = array([N(z.subs(t, radians(4)).subs(d, _d)) for _d in xaxis])
x_at_fixed_t = array([N(x.subs(t, radians(4)).subs(d, _d)) for _d in xaxis])

In [80]:
pylab.title("Z correction at theta = 4 deg.")
pylab.xlabel("D mm")
pylab.ylabel("Z mm")
pylab.grid(True)
pylab.plot(xaxis, z_at_fixed_t, 'b-')


Out[80]:
[<matplotlib.lines.Line2D at 0x7094d90>]

In [81]:
pylab.title("X correction at theta = 4 deg.")
pylab.xlabel("D mm")
pylab.ylabel("X mm")
pylab.grid(True)
pylab.plot(xaxis, x_at_fixed_t, 'g-')


Out[81]:
[<matplotlib.lines.Line2D at 0x721b7d0>]

Tilt del subreflettore


In [82]:
Image("files/tilt_sub2.png")


Out[82]:

Sia dato il sistema in figura in cui:

  • $AB$ è metà di un lato del triangolo subreflettore (vista B in Fig. 3.1.2 pag. 90 "Matematica di sistema" 4 di 4)
  • $|AB| = 2068mm / 2 $
  • $\varphi$ è l'angolo di cui vgliamo ruotare attorno ad un asse il subreflettore
  • $BC$ rappresenta il posizionamento del subreflettore una volta compiuta la rotazione

NOTA: Per semplicità consideriamo il caso di rotazione sull'asse X applicando un angolo $\theta_y$ che si riflette sul solo movimento di due attuatori. In questo caso sto solo cercando di quantificare un possibile errore.

Ragionando sui triangoli e sfruttando il fatto che $|AB| = |BC|$ possiamo desumere che:

  • $\omega = \Omega$ perchè alterni-interni $$ \Omega = \omega = \frac{\pi - \varphi}{2} = \frac{\pi}{2} - \frac{\varphi}{2} $$ $$ \sin{\Omega} = \sin{\omega} = \cos{\frac{\varphi}{2}} $$ $$ \cos{\Omega} = \cos{\omega} = \sin{\frac{\varphi}{2}} $$

Ragionando a questo punto sui lati otteniamo che:

$$ |AC| = 2*|AB|*\sin(\frac{\varphi}{2}) $$$$ |AE| = |AC| * \sin{\omega} = 2*|AB|*\sin{\frac{\varphi}{2}} * \cos{\frac{\varphi}{2}} = 2*|AB|*\frac{\sin{\varphi}}{2} = |AB|*\sin{\varphi}$$$$ |EC| = |AC| * \cos{\omega} = 2*|AB|*\sin{\frac{\varphi}{2}} * \sin{\frac{\varphi}{2}} = 2*|AB|*(\sin{\frac{\varphi}{2}})^2 = |AB|*(1 - \cos{\varphi}) $$$$ |ED| = |EC| * \tan{\varphi} = |AB|* \tan{\varphi} - |AB|*\cos{\varphi}*\frac{\sin{\varphi}}{\cos{\varphi}} = |AB| * (\tan{\varphi} - \sin{\varphi})$$$$ |AD| = |AB| * \tan{\varphi} $$

Que e ci interessa è che quindi quando noi vogliamo comandare un tilt di $\varphi$ e diamo come posizione comandata $|AD|$ in realtà dovremmo dare un valore di $|AC|$ , per cui: $$ |AD| - |AC| = |AB| * \tan{\varphi} - 2*|AB|*\sin{\frac{\varphi}{2}} = |AB|*(\tan{\varphi} - 2*\sin{\frac{\varphi}{2}}) $$

Fissanso quindi come da ipotesi $|AB| = 2098/2mm$ calcoliamo l'errore al variare di $\varphi$:


In [83]:
xaxis = linspace(0, radians(8), 1000)
xaxis_labels = linspace(0, 8, 1000)
error = (2098/2) * (np.tan(xaxis) - 2*np.sin(xaxis/2))

In [84]:
pylab.title("Correzione attuatore vs. angolo di tilt")
pylab.xlabel("Phi deg.")
pylab.ylabel("Error mm")
pylab.grid(True)
pylab.plot(xaxis_labels, error, 'b-', 
           xaxis_labels[500], error[500], 'bo', 
           markersize = 12)


Out[84]:
[<matplotlib.lines.Line2D at 0x749d050>,
 <matplotlib.lines.Line2D at 0x749d2d0>]

Ragionando sulle equazioni degli azionamenti

Da "matematica di sistema" 4 di 4 pag. 99 prendiamo le equazioni che tengono conto anche della compensazione relativa alla distanza tra il fuoco e il subreflettore:

$$ X = -D * \tan{\theta_y} $$$$ Y = D * \frac{\tan{\theta_x}}{\cos{8^{\circ}}}$$$$ Z_1 = y * \tan{8^{\circ}} + z + (r-f)*\theta_x $$$$ Z_2 = y * \tan{8^{\circ}} + z -f*\theta_x + \frac{1}{2} * \theta_y $$$$ Z_3 = y * \tan{8^{\circ}} + z -f*\theta_x - \frac{1}{2} * \theta_y $$

Ragioniamo sul caso semplice di voler effettuare unicamente una rotazione di $4.2^\circ$ attorno all'asse X per cui poniamo: $$ D = 310.7 $$ $$ \theta_x = 4.2^\circ $$ $$ \theta_y = 0^\circ $$ $$ y = 0 $$

Dalle simulazioni fatte al CAD dovrebbe risultare: $$ X = 0 $$ $$ Y = 24.358 $$ $$ Z_1 = -88.214 $$ $$ Z_2 = 42.881 $$ $$ Z_3 = Z_2 = 42.881 $$

Mentre applicando le equazioni otteniamo:


In [85]:
azx, azy, z1, z2, z3 = symbols("X Y Z_1 Z_2 Z_3")
d, theta_x, theta_y, x, y, z, r, f = symbols("D theta_x theta_y x y z r f")
azx = - d * tan(theta_y)
azy = d * tan(theta_x) / cos(radians(8))
z1 = y * tan(radians(8)) + z + (r - f) * theta_x
z2 = y * tan(radians(8)) + z - f * theta_x + 0.5 * theta_y 
z3 = y * tan(radians(8)) + z - f * theta_x - 0.5 * theta_y

In [86]:
N(azx.subs(d, 310.7).subs(theta_y,radians(0)))


Out[86]:
$$0$$

In [87]:
N(azy.subs(d, 310.7).subs(theta_x,radians(4.2)))


Out[87]:
$$23.0406114067913$$

In [88]:
N(z1.subs(d, 310.7).subs(r, 1791).subs(f, 597).subs(theta_x, radians(4.2)).subs(y,0).subs(z,0))


Out[88]:
$$87.5247713290116$$

In [89]:
N(z2.subs(d, 310.7).subs(r, 1791).subs(f, 597).subs(theta_x, radians(4.2)).subs(y,0).subs(z,0).subs(theta_y,0))


Out[89]:
$$-43.7623856645058$$

In [90]:
N(z3.subs(d, 310.7).subs(r, 1791).subs(f, 597).subs(theta_x, radians(4.2)).subs(y,0).subs(z,0).subs(theta_y,0))


Out[90]:
$$-43.7623856645058$$

A cosa sono dovute queste differenze? Proviamo ad aplicare le correzioni in Z e per la rotazione della cerniera precedentemente calcolate.

Per quanto riguarda la correzione in Z avremo che il nuovcentro del subreflettore sarà ad una quota Z più alta dello 0, la possiamo ottenere come: $$ Z = 2 * D * (\sin{\frac{\theta}{2}})^2$$


In [91]:
zn = 2 * 310.7 * (np.sin(np.radians(4.2/2))**2)
print zn


0.834391926361

In [92]:
N(z1.subs(d, 310.7).subs(r, 1791).subs(f, 597).subs(theta_x, radians(4.2)).subs(y,0).subs(z,zn))


Out[92]:
$$88.3591632553725$$

In [93]:
N(z2.subs(d, 310.7).subs(r, 1791).subs(f, 597).subs(theta_x, radians(4.2)).subs(y,0).subs(z,zn).subs(theta_y,0))


Out[93]:
$$-42.927993738145$$

Già così possiamo vedere come ci stiamo avvicinando al risultato atteso.