Navegando con las EstrellasProgramas FORTRAN.
Pedro de Andres
18 de septiembre de 2014
2
Copyright c©2014 Pedro de Andres.
Capıtulo 1
Programas (? ? ?).
A continuacion se presenta codigo FORTRAN-90 como una ayuda pa-ra realizar los calculos de los ejemplos. Para convertir este codigo en unprograma ejecutable se puede usar cualquier compilador de FORTRAN. Enparticular, en cualquier sistema bajo UNIX, LINUX o OSX (Mac) se puedepuede descargar e instalar un compilador libre y gratuito desde la pagina deel proyecto GNU
www.gnu.org/software/gcc/fortran/
Para usuarios de windows (Microsoft) existen otras alternativas docu-mentadas en la red (p.ej., buscar how to install a fortran compiler).
Los programas constituyen una receta precisa de como realizar los calcu-los (algoritmo) y tambien puede ser util seguirlos linea a linea, interpretandoel significado de las variables, como una ayuda para realizar los calculos. No-tese que los programas se distribuyen con el texto, y las aclaraciones quese han discutido en el texto, y pueden ser usados libremente bajo la res-ponsabilidad exclusiva del lector. El codigo se proporciona bajo demanda([email protected])
No se ofrece ninguna garantia de que estos programas estenlibres de errores; las comprobacines a que han sido sometidos nojustifican su uso sin realizar suficientes comprobaciones de maneraindependiente. No se acepta ninguna responsabilidad por posibleserrores en el codigo.
1.1. Dias entres dos Fechas.
program fechas2dias
3
4 CAPITULO 1. PROGRAMAS (? ? ?).
! P. de Andres, Madrid (2014).
! Calcula el numero de dias entre dos fechas.
! Dia 0 es el 31 de Diciembre de 1999 (12:00 UT).
implicit none
integer,dimension(1:2) :: dd, mm, yy, dias2CeroEnero2000
integer :: jm, jy
integer :: idum
integer :: dias
integer, parameter :: stdout = 6
write (stdout,"(’Introduzca la primera fecha: dia mes anyo’)")
read (*,*) dd(1), mm(1), yy(1)
write (stdout,"(’Introduzca la segunda fecha: dia mes anyo’)")
read (*,*) dd(2), mm(2), yy(2)
do idum = 1, 2
if ( mm (idum) .le. 2 ) then ! enero o febrero
jy = yy (idum) - 1 ! anyo anterior
jm = mm (idum) + 13 ! mes del anyo anterior
else ! los demas
jy = yy (idum) ! anyo correcto
jm = mm (idum) + 1 ! un mes mas
endif
dias2CeroEnero2000 (idum) = Int ( 365.25 * jy ) + &
Int ( 30.6001 * jm ) - &
Int (jy/100.) + &
Int (jy/400.) + &
dd(idum) - 730547
enddo ! idum
dias = dias2CeroEnero2000(2)-dias2CeroEnero2000(1)
write (stdout,"(’Entre las fechas ’)")
1.2. CREPUSCULO O MERIDIANA DEL SOL. 5
write (stdout,"(i2,’-’,i2,’-’,i4,/’ ... y ... ’/,i2,’-’,i2,’-’,i4)") &
dd(1), mm(1), yy(1), dd(2), mm(2), yy(2)
write (stdout,"(’han trascurrido ’, i12, ’ dias’)") dias
stop
end
Por ejemplo, entre el 4 de Enero de 1957 y el 19 de Agosto de 1957, elprograma calcula que han transcurrido 227 dias:
Entre las fechas
4- 1-1957
... y ...
19- 8-1957
han trascurrido 227 dias
1.2. Crepusculo o Meridiana del Sol.
Programa para determinar la hora UT de los crepusculos y de la meri-diana del Sol. El ejemplo calcula estos fenomenos para el dia 19 de Agostode 2014, en Trepuco, Menorca. El resultado es correcto hasta los minutos.
Programa.
Resultados.
Lt = 39.8739013671875
Ln = 4.26674985885620
Crepusculo Nautico
AMANECER. HORA (UT)(h,m) = 3 55
ATARDECER. HORA (UT)(h,m) =19 36
MERIDIANA. HORA (UT)(h,m) =11 46
1.3. Rectas de Altura.
En el Capitulo 8 se propone el calculo de rectas de altura asumiendo quese conoce una posicion de estima, y la hora. Se miden las alturas y acimutesde tres estrellas.
6 CAPITULO 1. PROGRAMAS (? ? ?).
Datos de entrada.
En la primera iteracion, se usan los siguientes datos de entrada:
WVigo ! Lugar.
N 42. 41. ! Latitud (grados, minutos).
W 009. 37. ! Longitud (grados, minutos).
3. ! Altura del observador en m sobre el horizonte.
VEGA ! Astro.
4. 7. 0. 0. ! dia del anyo, hora (horas, minutos, segundos).
60. ! Acimut (grados).
31. 39.6 ! Altura Sextante (grados, minutos).
N 38. 48. ! Declinacion (grados, minutos).
180.238 ! Horario en Greenwich inicial 2014, HG(t=0, d=0) (grados).
SPICA ! Astro.
4. 7. 0. 0. ! dia del anyo, hora (horas, minutos).
181. ! Acimut (grados).
36. 27.5 ! Altura Sextante (grados, minutos).
S 11. 14. ! Declinacion (grados, minutos).
258.101 ! Horario en Greenwich inicial 2014, HG(t=0, d=0) (grados).
POLLUX ! Astro.
4. 7. 0. 0. ! dia del anyo, hora (horas, minutos).
280. ! Acimut (grados).
23. 23.5 ! Altura Sextante (grados, minutos).
N 27. 59.3 ! Declinacion (grados, minutos).
343.034 ! Horario en Greenwich inicial 2014, HG(t=0, d=0) (grados).
En la segunda iteracion, se actualiza la posicion de estima y se sustituyenlos acimutes medidos por los calculados.
WVigo ! Lugar.
N 42. 20. ! Latitud (grados, minutos).
W 009. 19. ! Longitud (grados, minutos).
3. ! Altura del observador en m sobre el horizonte.
VEGA ! Astro.
4. 7. 0. 0. ! dia del anyo, hora (horas, minutos, segundos).
60. ! Acimut (grados).
31. 39.6 ! Altura Sextante (grados, minutos).
N 38. 48. ! Declinacion (grados, minutos).
180.238 ! Horario en Greenwich inicial 2014, HG(t=0, d=0) (grados).
SPICA ! Astro.
1.3. RECTAS DE ALTURA. 7
4. 7. 0. 0. ! dia del anyo, hora (horas, minutos).
181. ! Acimut (grados).
36. 27.5 ! Altura Sextante (grados, minutos).
S 11. 14. ! Declinacion (grados, minutos).
258.101 ! Horario en Greenwich inicial 2014, HG(t=0, d=0) (grados).
POLLUX ! Astro.
4. 7. 0. 0. ! dia del anyo, hora (horas, minutos).
280. ! Acimut (grados).
23. 23.5 ! Altura Sextante (grados, minutos).
N 27. 59.3 ! Declinacion (grados, minutos).
343.034 ! Horario en Greenwich inicial 2014, HG(t=0, d=0) (grados).
Codigo.
program PBPA2h0AcYeta
implicit none
! P. de Andres, Madrid 2014.
! Dado PB y PA,
! Obtener h0, Ac, y eta.
! Doble precision.
integer, parameter :: dp=selected_real_kind(15)
real (kind=dp), parameter :: Pi = 3.14159265358979_dp
character(len=80) :: Lugar, Astro
character(len=1 ) :: PtoCardinal
real (kind=dp) :: lttG, lttM, ltt, lngG, lngM, lng
real (kind=dp) :: zObs
real (kind=dp) :: dia, hrH, hrM, hrS, hrUT
real (kind=dp) :: altG, altM, altHrzSex, altHrz0M, altHrz0C
real (kind=dp) :: acimutM, dclG, dclM, dcl
real (kind=dp) :: HG0, HG, HL
real (kind=dp) :: ta, tb, hz, acimutC
real (kind=dp) :: ETA
integer :: istr
open ( unit=1, file=’sumner1.dat’, status=’old’, readonly )
! Lee datos
read (1,*) Lugar ! Etiqueta del lugar.
write (6,*) trim(Lugar)
8 CAPITULO 1. PROGRAMAS (? ? ?).
read (1,*) PtoCardinal, lttG, lttM ! latitud
If ( PtoCardinal == ’N’ ) then
ltt = +( lttG + lttM / 60. )
else
ltt = -( lttG + lttM / 60. )
endif
write (6,*) PtoCardinal, lttG, lttM, ltt
read (1,*) PtoCardinal, lngG, lngM ! longitud
If ( PtoCardinal == ’E’ ) then
lng = +( lngG + lngM / 60. )
else
lng = -( lngG + lngM / 60. )
endif
lng = 360. - lng ! lng es el angulo ecuatorial, entre 0 y 360.
lng = mod ( lng, 360. )
write (6,*) PtoCardinal, lngG, lngM, lng
read (1,*) zObs ! altura del observador sobre el horizonte geografico.
write (6,*) zObs
istr = 0
do ! itera mientras encuentra Astros para leer
read (1,*,end=991) Astro ! nombre de la estrella.
write (6,*) trim(Astro)
read (1,*) dia, hrH, hrM, hrS ! dia del anyo (1 a 365 o 366), hora UT
hrUT = hrH + hrM/60. + hrS/3600.
read (1,*) acimutM ! acimut medido
read (1,*) altG, altM ! altura sobre el horizonte del sextante
altHrzSex = altG + altM/60.
! altura sobre el horizonte corregida por
! depresion aparente del horizonte
! refraccion
altHrz0M = altHrzSex - 0.0293*Sqrt(zObs) + 0.0162/Tan(altHrzSex*Pi/180.)
write (6,*) acimutM, altHrzSex, altHrz0M
read (1,*) PtoCardinal, dclG, dclM
If ( PtoCardinal == ’N’ ) then
dcl = +( dclG + dclM / 60. )
else
dcl = -( dclG + dclM / 60. )
endif
1.3. RECTAS DE ALTURA. 9
write (6,*) PtoCardinal, dclG, dclM, dcl
read (1,*) HG0
write (6,*) HG0
istr = istr + 1
! Horario en Greenwich para dia del anyo y hrUT.
HG = HG0 + (360./24.)*hrUT + (360./365.25)*(dia+hrUT/24.)
! Horario Local para dia del anyo, hrUT, y lng (angulo ecuatorial).
HL = HG - lng
write (6,*) HG, HL
! Angulos polares.
ta = 90. - dcl
tb = 90. - ltt
! Altura zenital. Ley de los cosenos apoyada en HL.
hz = (180./Pi)*Acos ( &
Cos(ta*Pi/180.)*Cos(tb*Pi/180.) + &
Sin(ta*Pi/180.)*Sin(tb*Pi/180.)*Cos(HL*Pi/180.) &
)
altHrz0C = 90. - hz
write (6,*) hz, altHrz0C
! Acimut calculado. Ley de los cosenos apoyada en acimutC
acimutC = (180./Pi)*Acos ( &
( Cos(ta*Pi/180.) - Cos(hz*Pi/180.)*Cos(tb*Pi/180.) ) / &
( Sin(hz*Pi/180.)*Sin(tb*Pi/180.) ) &
)
write (6,"(’Acimut C =’,f6.1,1x,f6.2’ Acimut M =’,f6.1)") &
acimutC, (360.-acimutC), acimutM
ETA = 60. * (altHrz0M - altHrz0C)
write (6,"(’ETA (mn) =’,f6.2)") ETA
enddo
991 continue
write (6,*) ’ He leido’, istr,’ astros’
stop
end
Datos de salida.
Los datos de salida importantes son la variable ETA (η) y los acimutescalculados en la variable acimutC. En la primera iteracion se obtiene lasiguiente salida (la salida de la segunda iteracion es similar, corresponde alos datos en las tablas del texto, y no se ha incluido para ahorrar espacio).
10 CAPITULO 1. PROGRAMAS (? ? ?).
WVigo
N 42.0000000000000 41.0000000000000 42.6833333333333
W 9.00000000000000 37.0000000000000 9.61666666666667
3.00000000000000
VEGA
60.0000000000000 31.6600000000000 31.6355219522295
N 38.0000000000000 48.0000000000000 38.8000000000000
180.238000000000
289.467979452987 279.851312786321
58.4782545275469 31.5217454724531
Acimut C = 64.3 295.74 Acimut M = 60.0
ETA (mn) = 6.83
SPICA
181.000000000000 36.4583333333333 36.4295106176631
S 11.0000000000000 14.0000000000000 -11.2333333333333
258.101000000000
367.330979452987 357.714312786321
53.9573264974848 36.0426735025152
Acimut C = 177.2 182.77 Acimut M = 181.0
ETA (mn) = 23.21
POLLUX
280.000000000000 23.3916666666667 23.3783685127808
N 27.0000000000000 59.3000000000000 27.9883333333333
343.034000000000
452.263979452987 442.647312786321
66.3449929116452 23.6550070883548
Acimut C = 73.0 287.04 Acimut M = 280.0
ETA (mn) =-16.60
He leido 3 astros
1.4. Minimos Cuadrados.
En la Seccion 8.3 se propone el calculo de la posicion corregida sin ne-cesidad de dibujar las rectas de altura, utilizando directamente un procedi-miento de minimos cuadrados descrito por[Yallop and Hohenkerk(1985)]. Elsiguiente programa resuelve este problema.
Datos de Entrada.
! DATOS DEL OBSERVADOR
1.4. MINIMOS CUADRADOS. 11
NavPac2011-2015-Ej-pgs-18-19 ! Nombre (ia=0)
6.0 0.0 ! altObs (m), indSex
2011 07 14 ! tt; anyo, mes, dia
12 00 00 ! tt; hora, minuto, segundo
W 15 30 N 32 45 ! LNG, LTD (estima inicial)
12. 315. ! V(nds), RMB
! DATOS DE LOS ASTROS (N<10).
!
Luna ! Astro (ia)
2011 07 14 ! tt; anyo, mes, dia
05 54 57 ! tt; dia, hora, minuto, segundo
12. 315. ! V(nds), RMB
30.4433 ! Alt Sex
072. 52.128 N 8 46.602 54.06 L ! GHA, Dec, HP, limbo
!
Estrella ! Astro (ia)
2011 07 14 ! tt; anyo, mes, dia
06 05 21 ! tt; dia, hora, minuto, segundo
12. 315. ! V(nds), RMB
Sirius
32.7150 ! Alt
342 47.904 S 16 43.818 ! GHA, Dec
!
Planeta ! Astro (ia)
2011 07 14 ! tt; anyo, mes, dia
06 15 23 ! tt; dia, hora, minuto, segundo
12. 315. ! V(nds), RMB
Marte
47.1733 ! Alt
327. 28.098 N 21 36.81 0.072 ! GHA, Dec, HP
!
Sol ! Astro (ia=1)
2011 07 14 ! tt; anyo, mes, dia
09 53 45 ! tt; dia, hora, minuto, segundo
12. 315. ! V(nds), RMB
38.2017 ! Alt
329 30.72 N 3. 28.17 15.906 L ! GHA, Dec, SD, limbo
12 CAPITULO 1. PROGRAMAS (? ? ?).
Codigo.
program mejoraPB
implicit none
! Autor: P. de Andres (Madrid 2014).
! Ref: B.D. Yallop and C.Y. Hohenkerk, HM Nautical Almanac Office, London (1985).
! Dada una posicion estimada, PB_1, la fecha y la hora (es decir, PA),
! y medidas de alturas y acimutes para N astros:
! Mejora la posicion estimada del buque (PB_2) y determina la incertidumbre
! en PB_2 basandose en las rectas de altura de los N astros.
! Datos:
! PB_1: posicion geografica estimada de un observador.
!
! Fecha y Hora. Es decir, PA: posicion geografica de varios astros (N).
! PA es la declinacion y el Horario en Greenwich del astro.
!
! Altura medida respecto del horizonte para cada astro.
! Proporciona:
! PB_2 : posicion geografica ***mejorada*** del observadorr,
! y una estimacion de la ***incertidumbre*** en PB_2.
!
! Observese:
! El fichero de entrada consiste de un bloque de datos para el buque,
! y N bloques de datos para N astros.
! Es necesario que N sea mayor o igual que 3.
! Los datos para cada astro se pueden introducir en cualquier orden,
! y se pueden quitar o poner como se desee.
integer, parameter :: dp=selected_real_kind(15)
real (kind=dp), parameter :: pi=3.14159265358979324_dp
real (kind=dp), parameter :: deg2rad = 0.0174532925199432958_dp
real (kind=dp), parameter :: rad2deg = 57.2957795130823209_dp
integer :: ia, iaStr
1.4. MINIMOS CUADRADOS. 13
real (kind=dp), dimension(1:9) :: az, pp
real (kind=dp) :: aa, bb, cc, dd, ee, ff, gg
real (kind=dp) :: gdec, mnd
integer :: deg, mnt, sec
character(len=72) :: buque
real (kind=dp) :: Vnds, RMB
real (kind=dp) :: altSexm, indSex, dipH
real (kind=dp) :: rfrc, PA, Obl, semiDD
real (kind=dp), dimension(0:9) :: rfrcIA, PAIA, OblIA, semiDDIA
integer, dimension(0:9) :: anyo, dia, mes, hora, minuto, segundo
! longitud y latidud en Grados y Minutos
integer, dimension(0:9) :: lngG, lngM, ltdG, ltdM
! longitud y latitud en Nombre
character(len=1), dimension(0:9):: lngH, ltdH
character(len=1) :: dclNM
! longitud y latitud en grados decimates a la hora tUT
real (kind=dp), dimension(0:10) :: tUT, lngtt, ltdtt
character(len=72),dimension(1:9):: astro, nombreEstrella
character(len=1), dimension(1:9):: limb
real (kind=dp), dimension(1:9) :: Dec, AltMedSex, GHA, LHA
real (kind=dp), dimension(1:9) :: AsinAlt, ZtanZ
real (kind=dp), dimension(1:9) :: AltMedCorrIA, AltMedCorrIA1, ETAIA, ETAIAmn
real (kind=dp) :: sinAlt, xx, yy
real (kind=dp) :: AltMedCorr, AltMedCorr1
real (kind=dp), dimension(1:9) :: HP, semiD
real (kind=dp), dimension(1:9) :: intercept
real (kind=dp) :: lngIncr, ltdIncr, lngSigma, ltdSigma
real (kind=dp) :: ltdtt0
real (kind=dp) :: theta, ejeA, ejeB, sigma, IncrPosmn
real (kind=dp) :: grds1, mnts1, grds2, mnts2
! interno, sin significado.
character(len=1) :: dummyC1
! Entrada/Salida
character(len=80) :: datos
14 CAPITULO 1. PROGRAMAS (? ? ?).
character(len=80) :: dummy
integer :: str_pos
integer :: num_atoms_UC
integer, parameter :: stdout=6
integer :: dat_unit
character(len=40) :: dat_file
integer :: tbl_unit
character(len=40) :: tbl_file
integer :: mnc_unit
character(len=40) :: mnc_file
! C-like External functions
integer :: num_args
integer :: iargc
external iargc,getarg
! para ifort: lee directamente de la linea de comandos.
! num_args = iargc()
! if (num_args/=1) then
! write (stdout,*) ’Uso: ./mejoraPB datos ’
! stop
! end if
! call getarg(1,dummy)
! read (dummy,*) datos
datos=’mejoraPB’
dat_unit = 101
dat_file = trim(datos)//".dat"
mnc_unit = 108
mnc_file = trim(datos)//".mnc"
tbl_unit = 109
tbl_file = trim(datos)//".tbl"
open (unit=dat_unit,file=dat_file,status=’old’)
open (unit=mnc_unit,file=mnc_file,status=’unknown’)
open (unit=tbl_unit,file=tbl_file,status=’unknown’)
write (stdout,300) dat_file
300 format(/’ Leyendo fichero de datos ... ’,a40)
1.4. MINIMOS CUADRADOS. 15
! comienza iteraciones en astros (0 es el sitio donde se busca la posicion).
ia = 0
! NOMBRE
read (dat_unit,*) dummyC1
read (dat_unit,*) buque
! altura del sextante (en metros), indice del sextante
read (dat_unit,*) altSexm, indSex
! ANYO MES DIA HORA MINUTO SEGUNDO
! La posicion se obtiene para esta hora y fecha.
read (dat_unit,*) anyo(0), mes(0), dia(0)
read (dat_unit,*) hora(0), minuto(0), segundo(0)
! Calcula hora decimal
tUT(0) = float(hora(0)) + float(minuto(0))/60. + float(segundo(0))/3600.
! posicion de estima (DR), ia=0
read (dat_unit,*) lngH(0), lngG(0), lngM(0), ltdH(0), ltdG(0), ltdM(0)
! E positivo, W negativo.
lngtt(0) = lngG(0) + lngM(0)/60.
if ( lngH(0) == "E" ) then
lngtt(0) = +lngtt(0)
else
lngtt(0) = -lngtt(0)
endif
! N positivo, S negativo.
ltdtt(0) = ltdG(0) + ltdM(0)/60.
if ( ltdH(0) == "N" ) then
ltdtt(0) = +ltdtt(0)
else
ltdtt(0) = -ltdtt(0)
endif
16 CAPITULO 1. PROGRAMAS (? ? ?).
! velocidad (nudos) y rumbo (respecto del norte, grados sexagesimales).
read (dat_unit,*) Vnds, RMB
write (stdout,32) ia, tUT(ia)
32 format ("ia= ",i1," tUT= ", f8.4)
gdec = lngtt(ia)
call dec2deg (gdec, deg, mnt, sec, mnd )
write (stdout,31) gdec, lngH(ia), deg, mnt, sec, deg, mnd
31 format (f9.4,’ g.d ’,a1,1x,i3,’ g ’,i2,’ m ’, i2,’ s ’, i3,’ g ’, f4.1,’ m.d’)
gdec = ltdtt(ia)
call dec2deg (gdec, deg, mnt, sec, mnd )
write (stdout,31) gdec, ltdH(ia), deg, mnt, sec, deg, mnd
iaStr = 0
read (dat_unit,*) dummyC1
do ia= 1, 9 ! comienza a iterar astros
read (dat_unit,*,end=991) dummyC1 ! termina al llegar al final (991)
read (dat_unit,*) astro(ia)
read (dat_unit,*) anyo(ia), mes(ia), dia(ia)
read (dat_unit,*) hora(ia), minuto(ia), segundo(ia)
read (dat_unit,*) Vnds, RMB
iaStr = iaStr + 1
tUT(ia) = &
float(hora(ia)) + float(minuto(ia))/60. + float(segundo(ia))/3600.
write (stdout,"(a72)") trim(astro(ia))
if ( trim(astro(ia)) == "Rumbo" ) then
! esta parte no esta terminada
endif
if ( trim(astro(ia)) == "Sol" ) then
read (dat_unit,*) AltMedSex(ia)
read (dat_unit,*) grds1, mnts1, dclNM, grds2, mnts2, semiD(ia), limb(ia)
HP(ia) = 0.0_dp
GHA(ia) = grds1 + mnts1/60.
1.4. MINIMOS CUADRADOS. 17
Dec(ia) = grds2 + mnts2/60.
semiD(ia) = semiD(ia)/60.
if ( dclNM == "N" ) then
Dec(ia) = + Dec(ia)
else
Dec(ia) = - Dec(ia)
endif
endif
if ( trim(astro(ia)) == "Luna" ) then
read (dat_unit,*) AltMedSex(ia)
read (dat_unit,*) grds1, mnts1, dclNM, grds2, mnts2, HP(ia), limb(ia)
GHA(ia) = grds1 + mnts1/60.
Dec(ia) = grds2 + mnts2/60.
HP(ia) = HP(ia)/60.
semiD(ia) = 0.0_dp
if ( dclNM == "N" ) then
Dec(ia) = + Dec(ia)
else
Dec(ia) = - Dec(ia)
endif
endif
if ( trim(astro(ia)) == "Planeta" ) then
read (dat_unit,*) nombreEstrella (ia)
if ( (trim(nombreEstrella(ia)) == "Venus") &
.OR. (trim(nombreEstrella(ia)) == "Marte") ) then
read (dat_unit,*) AltMedSex(ia)
read (dat_unit,*) grds1, mnts1, dclNM, grds2, mnts2, HP(ia)
GHA(ia) = grds1 + mnts1/60.
Dec(ia) = grds2 + mnts2/60.
HP(ia) = HP(ia)/60.
if ( dclNM == "N" ) then
Dec(ia) = + Dec(ia)
else
Dec(ia) = - Dec(ia)
endif
else
read (dat_unit,*) AltMedSex(ia)
read (dat_unit,*) grds1, mnts1, dclNM, grds2, mnts2
18 CAPITULO 1. PROGRAMAS (? ? ?).
GHA(ia) = grds1 + mnts1/60.
Dec(ia) = grds2 + mnts2/60.
if ( dclNM == "N" ) then
Dec(ia) = + Dec(ia)
else
Dec(ia) = - Dec(ia)
endif
endif
endif
if ( trim(astro(ia)) == "Estrella" ) then
read (dat_unit,*) nombreEstrella (ia)
read (dat_unit,*) AltMedSex(ia)
read (dat_unit,*) grds1, mnts1, dclNM, grds2, mnts2
HP(ia) = 0.0_dp
semiD(ia) = 0.0_dp
GHA(ia) = grds1 + mnts1/60.
Dec(ia) = grds2 + mnts2/60.
if ( dclNM == "N" ) then
Dec(ia) = + Dec(ia)
else
Dec(ia) = - Dec(ia)
endif
endif
lngtt (ia) = lngtt(0) + &
(tUT(ia)-tUT(0)) * (Vnds/60.) * Sin(RMB*deg2rad) / Cos(ltdtt(0)*deg2rad)
ltdtt (ia) = ltdtt(0) + &
(tUT(ia)-tUT(0)) * (Vnds/60.) * Cos(RMB*deg2rad)
enddo ! ia
991 continue
close(unit=1)
write (stdout,*) ’Numero de Astros leidos =’, iaStr
if ( iaStr .gt. 9 ) then
write (stdout,*) ’ 9 astros es el limite, no admite mas. Parando ...’
stop
endif
1.4. MINIMOS CUADRADOS. 19
! Comprueba Tabla de DATOS
write (tbl_unit,"(a60,’ ... identificador’)") trim(buque)
write (tbl_unit,"(’ zObservador(m)=’,f4.1,’ IndiceSextante=’,f4.1)") altSexm, indSex
write (tbl_unit,504) tUT(0), lngtt(0), ltdtt(0)
write (tbl_unit,*) "---"
write (tbl_unit,501) (trim(astro(ia)), ia= 1, iaStr)
501 format (6(a10,2x))
write (tbl_unit,502) (int(anyo(ia)),int(mes(ia)),int(dia(ia)), ia= 1, iaStr)
502 format (6(i4,"-",i2,"-",i2,2x))
write (tbl_unit,503) (int(hora(ia)),int(minuto(ia)),int(segundo(ia)), ia= 1, iaStr)
503 format (6(2x,i2,":",i2,":",i2,2x))
write (tbl_unit,*) "---"
write (tbl_unit,504) (tUT(ia)-tUT(0), ia=1, iaStr)
write (tbl_unit,504) (lngtt(ia), ia=1, iaStr)
write (tbl_unit,504) (ltdtt(ia), ia=1, iaStr)
504 format (6(f10.4,2x))
write (tbl_unit,*) "---"
write (tbl_unit,504) (GHA(ia), ia=1, iaStr)
write (tbl_unit,504) (Dec(ia), ia=1, iaStr)
write (tbl_unit,504) (semiD(ia), ia=1, iaStr)
write (tbl_unit,504) (HP(ia), ia=1, iaStr)
321 format ("ia= ",i1," tUT= ", f8.4, " LNG(tUT)= ",f8.4, " LTD(tUT)= ", f8.4)
341 format(4(i2,1x),f7.4,4(1x,f8.4),a1)
342 format(4(i2,1x),4(1x,f8.4))
343 format(4(i2,1x),f7.4,4(1x,f8.4))
35 format(3(f12.6,1x))
36 format("STR= ",i1," tUT= ",f12.6, " LNGtt= ", f12.6," LTDtt= ", f12.6)
write (stdout,*) " =================="
do ia= 1, iaStr
if ( trim(astro(ia)) == "Rumbo" ) then
! solo acumula astros, no cambios de rumbo.
else
LHA(ia) = GHA(ia) + lngtt(ia)
20 CAPITULO 1. PROGRAMAS (? ? ?).
sinAlt = &
Sin(Dec(ia)*deg2rad)*Sin(ltdtt(ia)*deg2rad) + &
Cos(Dec(ia)*deg2rad)*Cos(ltdtt(ia)*deg2rad)*Cos(LHA(ia)*deg2rad)
AsinAlt(ia) = ASin(sinAlt)
xx = &
Sin(Dec(ia)*deg2rad)*Cos(ltdtt(ia)*deg2rad) - &
Cos(Dec(ia)*deg2rad)*Sin(ltdtt(ia)*deg2rad)*Cos(LHA(ia)*deg2rad)
yy = &
-Cos(Dec(ia)*deg2rad)*Sin(LHA(ia)*deg2rad)
ZtanZ(ia) = ATan(yy/xx)
If( xx .lt. 0.0 ) then
ZtanZ(ia) = ZtanZ(ia) + Pi
else
If(yy .lt. 0.0 ) then
ZtanZ(ia) = ZtanZ(ia) + 2*Pi
endif
endif
write (stdout,37) ia, ZtanZ(ia)*rad2deg
AltMedCorr = AltMedSex(ia)
call altsex2altmedcorr &
( astro(ia), nombreEstrella(ia), limb(ia), &
AltMedSex(ia), semiD(ia), &
HP(ia), ltdtt(ia), ZtanZ(ia), &
AltMedCorr1, AltMedCorr, &
altSexm, indSex, dipH, rfrc, PA, Obl, semiDD )
rfrcIA(ia) = rfrc
PAIA(ia) = PA
OBlIA(ia) = Obl
semiDDIA(ia) = semiDD
AltMedCorrIA1(ia) = AltMedCorr1
AltMedCorrIA(ia) = AltMedCorr
intercept(ia) = AltMedCorr - AsinAlt(ia) * rad2deg
1.4. MINIMOS CUADRADOS. 21
az (ia) = ZtanZ (ia)
pp (ia) = intercept (ia)
ETAIA (ia) = intercept (ia)
ETAIAmn (ia) = intercept (ia)*60.
write (stdout,*) "Altura Medida Sextante = ", AltMedSex(ia)
write (stdout,*) "Altura Medida Corregida = ", AltMedCorr
write (stdout,*) "Altura Calculada = ", AsinAlt(ia) * rad2deg
write (stdout,*) "ETA=AltMed - AltCal (mn)= ", ETAIAmn(ia)
endif
enddo ! ia = 1, N=iaStr
write (stdout,*) " =================="
write (tbl_unit,*) "---"
write (tbl_unit,504) (LHA(ia), ia=1, iaStr)
write (tbl_unit,504) (ZtanZ(ia)*rad2deg, ia=1, iaStr)
write (tbl_unit,504) (AsinAlt(ia)*rad2deg, ia=1, iaStr)
write (tbl_unit,*) "---"
write (tbl_unit,504) (AltMedSex(ia), ia=1, iaStr)
write (tbl_unit,504) indSex
write (tbl_unit,504) dipH
write (tbl_unit,505) (AltMedCorrIA1(ia), ia=1, iaStr)
write (tbl_unit,504) (rfrcIA(ia), ia=1, iaStr)
write (tbl_unit,504) (PAIA(ia), ia=1, iaStr)
write (tbl_unit,504) (OblIA(ia), ia=1, iaStr)
write (tbl_unit,504) (HP(ia), ia=1, iaStr)
write (tbl_unit,504) (semiDDIA(ia), ia=1, iaStr)
write (tbl_unit,506) (AltMedCorrIA(ia), ia=1, iaStr)
write (tbl_unit,*) "---"
write (tbl_unit,507) (ETAIA(ia), ia=1, iaStr)
write (tbl_unit,508) (ETAIAmn(ia), ia=1, iaStr)
write (tbl_unit,*) "---"
505 format (4(f10.4,2x),’ H’)
506 format (4(f10.4,2x),’ H0’)
507 format (4(f10.4,2x),’ ETA (grd)’)
508 format (4(f10.1,2x),’ ETA (mn)’)
22 CAPITULO 1. PROGRAMAS (? ? ?).
37 format("ASTRO= ",i1,1x,"ACIMUT= ",f12.0)
38 format(" intercept (grd)= ", f12.6," intercept (nm)=", f8.4)
ltdtt0 = ltdtt0
call mincuad (iaStr, ltdtt0, az, pp, lngIncr, ltdIncr, &
lngSigma, ltdSigma, sigma, theta, ejeA, ejeB, mnc_unit)
write (stdout,390) lngtt(0), ltdtt(0)
390 format ( ’inicial : ’,’longitud = ’, f10.4, ’ latitud = ’, f10.4 )
write (tbl_unit,509) lngtt(0), ltdtt(0)
write (tbl_unit,510) 60.*lngIncr, 60.*ltdIncr
510 format (2(f10.4,2x),20x,’ Incr lng, Incr ltd (millas nauticas)’)
write (tbl_unit,5100) lngIncr / Cos ( ltdtt(0) * deg2rad ), ltdIncr
5100 format (2(f10.4,2x),20x,’ Incr lng, Incr ltd (grados)’)
write (tbl_unit,5101) 60.*lngIncr / Cos ( ltdtt(0) * deg2rad ), 60.*ltdIncr
5101 format (2(f10.4,2x),20x,’ Incr lng, Incr ltd (minutos de grados)’)
lngtt(10) = lngtt(0) + lngIncr / Cos ( ltdtt(0) * deg2rad )
ltdtt(10) = ltdtt(0) + ltdIncr
IncrPosmn = 60.*Sqrt( (lngIncr / Cos ( ltdtt(0) * deg2rad ))**2 + (ltdIncr)**2 )
write (tbl_unit,511) lngtt(10), ltdtt(10)
write (tbl_unit,*) "---"
509 format (2(f10.4,2x),20x,’ lng(0) , ltd(0) ... pos. estimada’)
511 format (2(f10.4,2x),20x,’ lng , ltd ... pos. mejorada’)
write (tbl_unit,512) IncrPosmn, 2*lngSigma, 2*ltdSigma
512 format (4x,f6.1,2x,f5.1,2x,f5.1,2x,’ Dif P_1 a P2, Err-lng, Err-ltd (mn) 2*sigma’)
write (tbl_unit,*) "---"
write (tbl_unit,514) theta, ejeA, ejeB
514 format (6x,f4.0,2x,f5.1,2x,f5.1,2x,’ theta (grd vs N), semiEjeA, semiEjeB (mn)’)
write (tbl_unit,*) "---"
write (stdout,391) lngtt(10), ltdtt(10)
391 format ( ’final : ’,’longitud = ’, f10.4, ’ latitud = ’, f10.4 )
write (stdout,392) IncrPosmn
392 format ( ’diferencia entre P_I y P_F (mn) = ’, f6.2 )
1.4. MINIMOS CUADRADOS. 23
write (stdout,393) 2*sigma, 2*lngSigma, 2*ltdSigma
393 format ( ’INCERTIDUMBRE. 2 * sigma (nm) : ’,f6.1, ’ longitud = ’, f4.1, ’ latitud = ’, f4.1 )
write (stdout,394) theta, ejeA, ejeB
394 format ( ’acimut elipse confianza (nm) : ’,f6.0,’ ejeA = ’, f4.1, ’ ejeB = ’, f4.1 )
close(unit=tbl_unit)
stop
end program mejoraPB
subroutine altsex2altmedcorr &
( astro, nombreEstrella, limb, &
AltMedSex, semiD, &
HP, ltdtt, azimutRad, &
AltMedCorr1, AltMedCorr, &
altSexm, indSex, dipH, rfrc, PA, Obl, semiDD )
implicit none
integer, parameter :: dp=selected_real_kind(15)
character(len=72) :: astro, nombreEstrella
character(len=1) :: limb
real (kind=dp), parameter :: pi=3.14159265358979324_dp
real (kind=dp), parameter :: deg2rad = 0.0174532925199432958_dp
real (kind=dp), parameter :: rad2deg = 57.2957795130823209_dp
integer :: ia
real (kind=dp) :: altSexm
real (kind=dp) :: AltMedSex
real (kind=dp) :: indSex, dipH, rfrc, semiD, semiDD
real (kind=dp) :: AltMedCorr1, AltMedCorr2
real (kind=dp) :: AltMedCorr3, AltMedCorr4
real (kind=dp) :: fPT, Pmbr, TCls
real (kind=dp) :: ltdtt, azimutRad, AltMedCorr
real (kind=dp) :: UTH, HP, H, H0, Obl, HS, S, PA, R
Pmbr = 1020 ! millibars
TCls = 12.6 ! grados C
fPT = 0.28_dp * Pmbr / ( TCls + 273.0_dp )
fPT = 1.02536_dp
24 CAPITULO 1. PROGRAMAS (? ? ?).
AltMedCorr = 0.0_dp
AltMedCorr1 = 0.0_dp ! H
AltMedCorr2 = 0.0_dp
AltMedCorr3 = 0.0_dp
AltMedCorr4 = 0.0_dp
semiDD = semiD
! Indice Sextante: indSex
! Depresion Horizonte.
dipH = - 0.0293_dp*Sqrt(altSexm)
AltMedCorr1 = AltMedSex + indSex + dipH ! H
! Refraccion (formula de Bennet, J. Inst. Nav. vol 35, p 255 1982)
! Notese que la refraccion se resta normalmente al final, no aqui.
if ( AltMedCorr1 .ge. 15 ) then
rfrc = - 0.0162_dp * fPT/ Tan(AltMedCorr1*deg2rad)
AltMedCorr2 = AltMedCorr1 + rfrc
else
rfrc = - 0.0167_dp * fPT/ Tan( deg2rad * ( AltMedCorr1 + 7.32_dp/(AltMedCorr1+4.32_dp) ) )
AltMedCorr2 = AltMedCorr1 + rfrc
endif
! Una estrella
if ( trim(astro) == "Estrella" ) then
PA = 0.0
semiD = 0.0
semiDD = 0.0
Obl = 0.0
AltMedCorr = AltMedCorr2 ! H0
return
endif
! Un planeta
if ( (trim(astro) == "Planeta") ) then
! Venus o Marte
if ( (trim(nombreEstrella) == "Venus") .OR. &
(trim(nombreEstrella) == "Marte") ) then
PA = HP * Cos (AltMedCorr1*deg2rad )
AltMedCorr = AltMedCorr2 + PA
else ! Jupiter o Saturno
1.4. MINIMOS CUADRADOS. 25
AltMedCorr = AltMedCorr2 ! H0
endif
semiD = 0.0
semiDD = 0.0
Obl = 0.0
return
endif
! Para el Sol, la Luna, Venus y Marte
! calcula el paralaje en altitud (PA) usando el paralaje horizontal (PH)
if ( trim(astro) == "Sol" ) then
Obl = 0.0
HP = 0.0024
PA = HP * Cos (AltMedCorr1*deg2rad )
If(Limb == "L") then
AltMedCorr = +semiD + AltMedCorr2 + PA
else
AltMedCorr = -semiD + AltMedCorr2 + PA
endif
return
endif
if ( trim(astro) == "Luna" ) then
H = AltMedCorr1
PA = HP * Cos(H*deg2rad)
semiD = 0.2724 * HP
semiDD = semiD
Obl = 0.0032 * &
( - Sin(ltdtt*deg2rad) * Sin(ltdtt*deg2rad) * Cos(H*deg2rad) &
+ Sin(2.*ltdtt*deg2rad) * Cos(azimutRad)*Sin(H*deg2rad))
If(Limb == "L" ) then
AltMedCorr = semiD + AltMedCorr2 + PA + Obl
else
AltMedCorr = -semiD + AltMedCorr2 + PA + Obl
endif
return
endif
write (*,*) " Error en altsex2altmedcorr ... parando.", astro
26 CAPITULO 1. PROGRAMAS (? ? ?).
stop
end subroutine altsex2altmedcorr
subroutine mincuad ( iaStr, ltdtt0, az, pp, lngIncr, ltdIncr, &
lngSigma, ltdSigma, sigma, theta, ejeA, ejeB, mnc_unit )
implicit none
integer, parameter :: dp=selected_real_kind(15)
integer :: ia, iaStr, mnc_unit
real (kind=dp), parameter :: pi=3.14159265358979_dp
real (kind=dp), dimension(1:4) :: az, pp
real (kind=dp) :: aa, bb, cc, dd, ee, ff, gg, deg2rad
real (kind=dp) :: ss, sigma
real (kind=dp) :: lngIncr, ltdIncr, lngSigma, ltdSigma
real (kind=dp) :: ltdtt0
real (kind=dp) :: theta, Prb, kP, ejeA, ejeB
if ( iaStr .le. 2 ) then
write (*,*) ’ Al menos tiene que haber tres astros. Parando ...’
stop
endif
deg2rad = pi/180.0_dp
aa = 0.0_dp
bb = 0.0_dp
cc = 0.0_dp
dd = 0.0_dp
ee = 0.0_dp
ff = 0.0_dp
gg = 0.0_dp
do ia= 1, iaStr
aa = aa + Cos (az(ia)) * Cos (az(ia))
bb = bb + Cos (az(ia)) * Sin (az(ia))
cc = cc + Sin (az(ia)) * Sin (az(ia))
dd = dd + pp(ia) * Cos (az(ia))
ee = ee + pp(ia) * Sin (az(ia))
ff = ff + ( pp(ia) )**2
enddo
1.4. MINIMOS CUADRADOS. 27
gg = aa*cc - bb*bb
lngIncr = ( aa * ee - bb * dd ) / gg
ltdIncr = ( dd * cc - ee * bb ) / gg
write (mnc_unit,"(f12.6, ’ A’)") aa
write (mnc_unit,"(f12.6, ’ B’)") bb
write (mnc_unit,"(f12.6, ’ C’)") cc
write (mnc_unit,"(f12.6, ’ D’)") dd
write (mnc_unit,"(f12.6, ’ E’)") ee
write (mnc_unit,"(f12.6, ’ F’)") ff
write (mnc_unit,"(f12.6, ’ G’)") gg
! Incertidumbre en la posicion corregida.
ss = ff - dd * ltdIncr - ee * lngIncr * Cos(ltdtt0*deg2rad)
! Desviacion estandard en mn
sigma = 60. * Sqrt ( ss / float(iaStr-2) )
! Desviacion estandard en longitud (mn)
lngSigma = sigma * Sqrt ( aa/gg )
! Desviacion estandard en latitud (mn)
ltdSigma = sigma * Sqrt ( cc/gg )
! Elipse de confianza que determina que la posicion
! real resida dentro de la elipse con una probabilidad P (=0.95).
! confianza 95/100
Prb = 0.95_dp
kP = Sqrt (-2.0_dp*Log(1.0_dp-Prb) )
write (mnc_unit,"(f12.6,1x,f5.2 ’ kp, Prb’)") kp, Prb
write (mnc_unit,"(f12.6, ’ sigma’)") sigma
! elipse de confianza
! acimut (respecto del N) del eje A
theta = (180./Pi) * ( atan ( 2*bb/(aa-cc) ) / 2. )
! ejes A y B de la elipse
ejeA = sigma * kP / Sqrt ( float(iaStr)/2. + bb / Sin (2.*theta*Pi/180) )
ejeB = sigma * kP / Sqrt ( float(iaStr)/2. - bb / Sin (2.*theta*Pi/180) )
28 CAPITULO 1. PROGRAMAS (? ? ?).
return
end subroutine mincuad
subroutine dec2deg ( gdec, deg, mnt, sec, mnd )
implicit none
integer, parameter :: dp=selected_real_kind(15)
real (kind=dp) :: gdec, mnd
integer :: deg, mnt, sec
! gdec: grados sexagesimales en formato decimal
! deg : grados sexagesimales
! mnt : minutos
! sec : segundos
! mnd : minutos en formato decimal
deg = abs ( int (gdec) )
mnd = (abs(gdec) - abs(int(gdec))) * 60.0_dp
mnt = nint (mnd)
sec = nint ( (mnd - int(mnd) ) * 60.0_dp )
return
end subroutine dec2deg
Resultados.
Leyendo fichero de datos ... NavPac20112015Ejpg18.dat
ia= 0 tUT= 12.0000
-15.5000 g.d W 15 g 30 m 0 s 15 g 30.0 m.d
32.7500 g.d N 32 g 45 m 0 s 32 g 45.0 m.d
Luna
Estrella
Planeta
Sol
Numero de Astros leidos = 4
1.4. MINIMOS CUADRADOS. 29
==================
ASTRO= 1 ACIMUT= 260.
Altura Medida Sextante = 30.4433000000000
Altura Medida Corregida = 31.3649534704583
Altura Calculada = 31.3590359858635
ETA=AltMed - AltCal (mn)= 0.355049075688001
ASTRO= 2 ACIMUT= 143.
Altura Medida Sextante = 32.7150000000000
Altura Medida Corregida = 32.6172994418631
Altura Calculada = 32.6425352193959
ETA=AltMed - AltCal (mn)= -1.51414665196924
ASTRO= 3 ACIMUT= 92.
Altura Medida Sextante = 47.1733000000000
Altura Medida Corregida = 47.0869118810196
Altura Calculada = 47.0758378588209
ETA=AltMed - AltCal (mn)= 0.664441331920216
ASTRO= 4 ACIMUT= 114.
Altura Medida Sextante = 38.2017000000000
Altura Medida Corregida = 38.3757560168468
Altura Calculada = 38.4209461935852
ETA=AltMed - AltCal (mn)= -2.71141060430580
==================
inicial : longitud = -15.5000 latitud = 32.7500
final : longitud = -15.5088 latitud = 32.7882
diferencia entre P_I y P_F (mn) = 2.35
INCERTIDUMBRE. 2 * sigma (nm) : 2.7 longitud = 1.7 latitud = 3.3
acimut elipse confianza (nm) : 16. ejeA = 4.2 ejeB = 1.8
NavPac2011-2015-Ej-pgs-18-19 ... identificador
z Observador(m)= 6.0 IndiceSextante= 0.0
12.0000 -15.5000 32.7500
---
Luna Estrella Planeta Sol
2011- 7-14 2011- 7-14 2011- 7-14 2011- 7-14
5:54:57 6: 5:21 6:15:23 9:53:45
---
-6.0842 -5.9108 -5.7436 -2.1042
-14.4769 -14.5061 -14.5342 -15.1462
31.8896 31.9141 31.9377 32.4524
30 CAPITULO 1. PROGRAMAS (? ? ?).
---
72.8688 342.7984 327.4683 329.5120
8.7767 -16.7303 21.6135 3.4695
0.0000 0.0000 0.0000 0.2651
0.9010 0.0000 0.0012 0.0000
---
58.3919 328.2923 312.9341 314.3658
260.2861 143.2910 91.8857 114.3841
31.3590 32.6425 47.0758 38.4209
---
30.4433 32.7150 47.1733 38.2017
0.0000
-0.0718
30.3715 32.6432 47.1015 38.1299 H
-0.0283 -0.0259 -0.0154 -0.0212
0.7774 0.0000 0.0008 0.0019
-0.0010 0.0000 0.0000 0.0000
0.9010 0.0000 0.0012 0.0024
0.2454 0.0000 0.0000 0.2651
31.3650 32.6173 47.0869 38.3758 H0
---
0.0059 -0.0252 0.0111 -0.0452 ETA (grd)
0.4 -1.5 0.7 -2.7 ETA (mn)
---
-15.5000 32.7500 lng(0) , ltd(0) ... pos. estimada
-0.4458 2.2899 Incr lng, Incr ltd (millas nauticas)
-0.0088 0.0382 Incr lng, Incr ltd (grados)
-0.5301 2.2899 Incr lng, Incr ltd (minutos de grados)
-15.5088 32.7882 lng , ltd ... pos. mejorada
---
2.4 1.7 3.3 Dif P_1 a P2, Err-lng, Err-ltd (mn) 2*sigma
---
16. 4.2 1.8 theta (grd vs N), semiEjeA, semiEjeB (mn)
---
Bibliografıa
[Yallop and Hohenkerk(1985)] B.D. Yallop and C.Y. Hohenkerk. CompactData for Navigation and Astronomy, 1986–1990. HM Nautical AlmanacOffice, Royal Greenwich Observatory (London, UK), 1985.
31