FUNDAMENTOS DE NAVEGACIÓN AÉREA Práctica 1: Cartografía y Rutas. NOMBRE DEL ALUMNO: En esta práctica se pretende repasar los conceptos estudiados de cartografía y rutas. Evaluación: Se pide resolver el problema indicado al final con los datos especificados para cada alumno que se pueden encontrar en enseñanza virtual. 1. Cartografía Arrancar los ordenadores del centro de cálculo con Matlab. Vamos a añadir funcionalidades de cartografía incluyendo el paquete gratuito m_map, que se puede encontrar en: http://www.eos.ubc.ca/~rich/private/mapug.html La propia página indicada es una guía que vamos a seguir parcialmente, adaptada a nuestras necesidades. Se descarga el archivo zip enlazado al principio. Se añade el directorio donde se haya instalado al path de Matlab. Este paquete nos permite dibujar mapas del mundo usando distintas proyecciones. El primer ejemplo podría ser escribir en Matlab: m_proj('oblique mercator'); m_coast; m_grid; Observamos un mapa poco reconocible; se trata de la región noroeste de Estados Unidos y Canadá, de donde son los autores del paquete, en una proyección que no hemos visto en clase (Mercator oblicua). Si quisiéramos dibujar un mapa más reconocible para nosotros, cerramos la anterior figura y escribimos: m_proj('Equidistant Cylindrical','longitudes',[-10 5],'latitudes',[35 45]) m_coast; m_grid; Para ver la lista de proyecciones disponibles, escribimos: m_proj set; Obtenemos la siguiente lista: Available projections are: Stereographic Orthographic Azimuthal Equal-area Azimuthal Equidistant Gnomonic Satellite Albers Equal-Area Conic Lambert Conformal Conic Mercator Miller Cylindrical Equidistant Cylindrical Oblique Mercator Transverse Mercator Sinusoidal Gall-Peters Hammer-Aitoff Mollweide Robinson UTM De estas, algunas se han visto en clase y otras no. Para informarse rápidamente de las propiedades de estas proyecciones, se puede consultar la lista de Wikipedia donde están casi todas: http://en.wikipedia.org/wiki/List_of_map_projectionsl La guía también explica bastante bien todas las proyecciones disponibles. Una vez seleccionada una proyección, podemos ver sus propiedades con la orden m_proj get Para ver las propiedades de una proyección distinta a la que tenemos podemos usar: m_proj('set','stereographic'); Para ver un mapa global del mundo podemos usar varias proyecciones. Escribimos varios ejemplos, hay que cerrar la anterior figura para cada uno de ellos: m_proj('Equidistant Cylindrical'); m_coast; m_grid; Probar la Mercator, la Lambert Conformal Conic y la Miller. Si por ejemplo si queremos ver la zona de los polos, es más recomendable usar una proyección estereográfica. m_proj('stereographic','lat',90,'long',0,'radius',90); m_coast; m_grid; Los otros dos comandos tienen la siguiente función: m_coast dibuja la línea costera con una precisión de ¼ de grado. Se puede conseguir mayor resolución (ver la guía de m_map). También se pueden usar otras opciones. Por ejemplo: m_coast('linewidth',2,'color','r'); usa una línea más gruesa y roja. Para rellenar las zonas de Tierra: m_coast('patch',[.7 .7 .7],'edgecolor','none'); m_grid dibuja las líneas de longitud y latitud. m_grid get da las opciones disponibles. Por ejemplo, dibujando de nuevo la cilíndrica equidistante: m_proj('Equidistant Cylindrical'); m_coast; m_grid('box','fancy'); El paquete tiene muchas otras posibilidades, descritas en la guía. Básicamente lo usaremos para dibujar rutas. 2. Rutas Explicaremos el cálculo y representación de rutas con un ejemplo. Fijar la proyección cilíndrica equidistante de momento. Vamos a calcular la ruta ortodrómica y loxodrómica entre Bogotá (4º35’56” N 74º04’51” O) y Sidney (33º51’36”S 151º12’40”E). Empezamos definiendo las coordenadas: phiA=4+35/60+56/3600; lambdaA=-(74+04/60+51/3600); phiB=-(33+51/60+36/3600); lambdaB=151+12/60+40/3600; Pasamos los datos a radianes para más adelante: phiA_rad=phiA*pi/180; lambdaA_rad=lambdaA*pi/180; phiB_rad=phiB*pi/180; lambdaB_rad=lambdaB*pi/180; Ahora representamos las ciudades en el mapa usando la orden m_plot: hold on; m_plot(lambdaA, phiA,'b*'); m_plot(lambdaB,phiB,'r*'); Se ve claro que la ruta debe ir hacia el Oeste. Por si acaso podemos comprobar abs(lambdaA-lambdaB) Calculamos la distancia (en nmi) y rumbo ortodrómicos alpha=acos(sin(phiA_rad)*sin(phiB_rad)+cos(phiA_rad)*cos(phiB_rad)*cos(lambdaB_r ad-lambdaA_rad)); orth_distance=alpha*180/pi*60 chi=acos((cos(phiA_rad)*sin(phiB_rad)sin(phiA_rad)*cos(phiB_rad)*cos(lambdaB_rad-lambdaA_rad))/sin(alpha)); De modo que ya tenemos la distancia, pero el curso no es correcto. Lo corregimos por ir hacia el Oeste y lo escribimos por pantalla en grados: chi=2*pi-chi; orth_initial_course=chi*180/pi Repetimos con la loxodrómica, teniendo en cuenta que cruzamos el meridiano 180º y que B está al Este y al Sur de A, escribiéndolo por pantalla en grados: chi_lox=atan((lambdaB_rad-2*pi-lambdaA_rad)/log((tan(pi/4-phiA_rad/2)/tan(pi/4phiB_rad/2)))); chi_lox=chi_lox+pi; loxo_course=chi_lox*180/pi Finalmente calculamos la distancia loxodrómica en nmi: loxo_angle_distance=(phiB_rad-phiA_rad)/cos(chi_lox); loxo_distance=loxo_angle_distance*180/pi*60 Es importante comparar la ortodrómica y la loxodrómica y ver si los resultados tienen sentido. Ahora vamos a usar la cartografía para dibujar las rutas. Elegimos cien puntos para cada una de ellas y empezamos por la ortodrómica. N=100; %Predefine the vectors which we will compute phi_ort=zeros(N,1); lambda_ort=zeros(N,1); Ahora calculamos los puntos que conforman la ortodrómica, recordando que está va hacia el Oeste. for i=1:N distance=alpha/N*i; phi_ort(i)=asin(cos(chi)*sin(distance)*cos(phiA_rad)+cos(distance)* ... sin(phiA_rad)); lambda_ort(i)=lambdaA_rad+2*pi-acos((cos(distance)-... sin(phiA_rad)*sin(phi_ort(i)))/(cos(phiA_rad)*cos(phi_ort(i)))); if lambda_ort(i)>pi lambda_ort(i)=lambda_ort(i)-2*pi; end if lambda_ort(i)<-pi lambda_ort(i)=lambda_ort(i)+2*pi; end phi_ort(i)=phi_ort(i)*180/pi; lambda_ort(i)=lambda_ort(i)*180/pi; end Para representar, es importante tener en cuenta que el cruce por 180º estropea la representación. Para ello metemos un NaN (que Matlab no representa) justo en el cruce: for i=1:N-1 if abs(lambda_ort(i)-lambda_ort(i+1))>180 lambda_ort=[lambda_ort(1:i);NaN;lambda_ort(i+1:end)]; phi_ort=[phi_ort(1:i);NaN;phi_ort(i+1:end)]; end end m_plot(lambda_ort,phi_ort); Repetimos el proceso con la loxodrómica: phi_lox=zeros(N,1); lambda_lox=zeros(N,1); for i=1:N distance=loxo_angle_distance/N*i; phi_lox(i)=distance*cos(chi_lox)+phiA_rad; lambda_lox(i)=lambdaA_rad+tan(chi_lox)*log((tan(pi/4-phiA_rad/2)/tan(pi/4phi_lox(i)/2))); if lambda_lox(i)>pi lambda_lox(i)=lambda_lox(i)-2*pi; end if lambda_lox(i)<-pi lambda_lox(i)=lambda_lox(i)+2*pi; end phi_lox(i)=phi_lox(i)*180/pi; lambda_lox(i)=lambda_lox(i)*180/pi; end for i=1:N-1 if abs(lambda_lox(i)-lambda_lox(i+1))>180 lambda_lox=[lambda_lox(1:i);NaN;lambda_lox(i+1:end)]; phi_lox=[phi_lox(1:i);NaN;phi_lox(i+1:end)]; end end m_plot(lambda_lox,phi_lox); Vamos a estudiar ahora como aproximar la ortodrómica por varios segmentos loxodrómicos, por ejemplo 3. Para ello tenemos que calcular dos puntos intermedios, a alpha/3 y 2*alpha/3 de distancia del punto A. phi1=asin(cos(chi)*sin(alpha/3)*cos(phiA_rad)+cos(alpha/3)*sin(phiA_rad)); lambda1=lambdaA_rad+2*pi-acos((cos(alpha/3)sin(phiA_rad)*sin(phi1))/(cos(phiA_rad)*cos(phi1))); if lambda1>pi lambda1=lambda1-2*pi; end if lambda1<-pi lambda1=lambda1+2*pi; end phi2=asin(cos(chi)*sin(2*alpha/3)*cos(phiA_rad)+cos(2*alpha/3)*sin(phiA_rad)); lambda2=lambdaA_rad+2*pi-acos((cos(2*alpha/3)sin(phiA_rad)*sin(phi2))/(cos(phiA_rad)*cos(phi2))); if lambda2>pi lambda2=lambda2-2*pi; end if lambda2<-pi lambda2=lambda2+2*pi; end m_plot(lambda1*180/pi, phi1*180/pi,'k*'); m_plot(lambda2*180/pi,phi2*180/pi,'k*'); Viendo los puntos en el mapa, tenemos que calcular ahora tres loxodrómicas. De A a 1, de 1 a 2, y de 2 a B. Observamos que 1 está al sur de A, 2 está al sur de 1, pero B está al norte de 2! También, el único cruce por 180º sucede de 2 a B. Calculamos primero las loxodrómicas: chi_loxA1=atan((lambda1-lambdaA_rad)/log((tan(pi/4-phiA_rad/2)/tan(pi/4phi1/2)))); chi_loxA1=chi_loxA1+pi; loxo_courseA1=chi_loxA1*180/pi loxo_angle_distanceA1=(phi1-phiA_rad)/cos(chi_loxA1); loxo_distanceA1=loxo_angle_distanceA1*180/pi*60 chi_lox12=atan((lambda2-lambda1)/log((tan(pi/4-phi1/2)/tan(pi/4-phi2/2)))); chi_lox12=chi_lox12+pi; loxo_course12=chi_lox12*180/pi loxo_angle_distance12=(phi2-phi1)/cos(chi_lox12); loxo_distance12=loxo_angle_distance12*180/pi*60 chi_lox2B=atan((lambdaB_rad-2*pi-lambda2)/log((tan(pi/4-phi2/2)/tan(pi/4phiB_rad/2)))); loxo_course2B=chi_lox2B*180/pi loxo_angle_distance2B=(phiB_rad-phi2)/cos(chi_lox2B); loxo_distance2B=loxo_angle_distance2B*180/pi*60 total_approx_loxo_distance=loxo_distanceA1+loxo_distance12+loxo_distance2B Comparar la distancia suma de los tres segmentos con la loxodrómica y ortodrómica directa. Finalmente representamos la ruta aproximada calculando los puntos de las tres loxodrómicas y uniéndolos: phi_loxA1=zeros(N,1); lambda_loxA1=zeros(N,1); for i=1:N distance=loxo_angle_distanceA1/N*i; phi_loxA1(i)=distance*cos(chi_loxA1)+phiA_rad; lambda_loxA1(i)=lambdaA_rad+tan(chi_loxA1)*log((tan(pi/4phiA_rad/2)/tan(pi/4-phi_loxA1(i)/2))); phi_loxA1(i)=phi_loxA1(i)*180/pi; lambda_loxA1(i)=lambda_loxA1(i)*180/pi; end phi_lox12=zeros(N,1); lambda_lox12=zeros(N,1); for i=1:N distance=loxo_angle_distance12/N*i; phi_lox12(i)=distance*cos(chi_lox12)+phi1; lambda_lox12(i)=lambda1+tan(chi_lox12)*log((tan(pi/4-phi1/2)/tan(pi/4phi_lox12(i)/2))); phi_lox12(i)=phi_lox12(i)*180/pi; lambda_lox12(i)=lambda_lox12(i)*180/pi; end phi_lox2B=zeros(N,1); lambda_lox2B=zeros(N,1); for i=1:N distance=loxo_angle_distance2B/N*i; phi_lox2B(i)=distance*cos(chi_lox2B)+phi2; lambda_lox2B(i)=lambda2+tan(chi_lox2B)*log((tan(pi/4-phi2/2)/tan(pi/4phi_lox2B(i)/2))); if lambda_lox2B(i)>pi lambda_lox2B(i)=lambda_lox2B(i)-2*pi; end if lambda_lox2B(i)<-pi lambda_lox2B(i)=lambda_lox2B(i)+2*pi; end phi_lox2B(i)=phi_lox2B(i)*180/pi; lambda_lox2B(i)=lambda_lox2B(i)*180/pi; end phi_lox_approximate=[phi_loxA1;phi_lox12;phi_lox2B]; lambda_lox_approximate=[lambda_loxA1;lambda_lox12;lambda_lox2B]; for i=1:3*N-1 if abs(lambda_lox_approximate(i)-lambda_lox_approximate(i+1))>180 lambda_lox_approximate=[lambda_lox_approximate(1:i);NaN;lambda_lox_approximate(i +1:end)]; phi_lox_approximate=[phi_lox_approximate(1:i);NaN;phi_lox_approximate(i+1:end)]; end end m_plot(lambda_lox_approximate,phi_lox_approximate); Ejercicio en clase: Repetir este procedimiento con la ruta Ciudad de México-Islamabad. Ejercicio fuera de clase (a entregar): será asignado próximamente.