Radio Amateur Routines for the HP48 QRA to Latitude/Longitude CONVERSION, GREAT CIRCLE DISTANCES and HORIZONS James Gentles jdg@sqf.hp.com February 1992 February 1999 1. Introduction 2. Pseudo Code for Main Routines 3. HP48 Routines: Descriptions 4. HP48 Routines: Programs (ASCII DIR Object) 1. Introduction This file contains a collection of HP48 programs for translating between the QRA or Maidenhead locator system used by Radio Amateurs and Lat/Long, calculating Great Circle Distances and bearings, and calculating Radio Horizons. Also of interest may be a companion set of HP48 routines for performing Transverse Mercator Projection. This will allow additional translation between this common mapping projection and Latitude/Longitude. For example, this is especially useful in the UK, where Amateurs also quote their "WAB" (Worked All Britain) square, which is based on the "National Grid" which is a Transverse Mercator Projection. For those interested in coding these routines in other machines I have included psudo-code descriptions of the main routines. However the main code that follows is written for the HP48. It was originally written for a HP28, but has been improved in the process of translation to the HP48. The code is smaller, faster, and also takes advantage of the HP48's improved language, e.g. TAGing. The code was revised in February 1999 to allow operation on HP48GX as well as HP48SX machines. The calculator's have minor differences in the way they handle tagged objects. "QRA->" was changed and is now compatable with both models. 2. Pseudo Code for Main Routines This pseudo-code is based on the following HP48 routines. The pseudo-code uses mostly two letter variable names, this does not aid readability, however these are the calculator local variables. Leaving the variables like this means that no errors have been introduced in the translation to pseudo-code from HP48 code. Latitude / Longitude to QRA Conversion Note: All calculations in degrees lo = longitude + 180 offset origin to -180degrees longitude, La = latitude + 90 -90degrees latitude. C1 = ASCII CHAR ('IP(lo/20)+65') C2 = ASCII CHAR ('IP(la/10)+65') C3 = ASCII CHAR ('IP(FP(lo/20)*10)+48') C4 = ASCII CHAR ('IP(FP(la/10)*10)+48') C5 = ASCII CHAR ('IP(FP(lo/2)*24)+65') C6 = ASCII CHAR ('IP(FP(la)*24)+65') QRA Locator = String C1+C2+C3+C4+C5+C6 QRA to Latitude / Longitude Conversion First break QRA string into 6 numbers, representing the ASCII number equivilent to each of the 6 characters making up the QRA. Call them a b c d e & f. Latitude = 'b*10+(d+17)+f/24+1/48-90' Longitude = 'a*20+(c+17)*2+e/12+1/24-180' Great Circle Calculations. dif = longitute home - longitute away (this should be within -180 to +180 degrees) (Hint: This number should be non-zero, programs should check for this and make dif=0.0001 as a minimum) lah = latitude of home laa = latitude of away ERAD= Radius of the earth (e.g. 6378.388 Km) dis = 'ACOS(SIN(lah)*SIN(laa)+COS(lah)*COS(laa)*COS(dif))' distance = dis /180 *pi *ERAD angle = 'ACOS((SIN(laa)-SIN(lah)*COS(dis))/(COS(lah)*SIN(dis)))' Line of Sight and Radio Horizon Routines ERAD = 6378.388Km (Radius of the Earth in Km) Radio Horizon (Km) = SQRT('height*ERAD*8/3') ERAD = 6378.388Km (Radius of the Earth in Km) Sight Horizon (Km) = SQRT('height*ERAD*2') 3. HP48 Routines: Descriptions QRA Locator Square Translator: The following procedures translate between the worldwide QRA (or ANB or Maidenhead, whatever its called) locator system used by Radio Amateurs and latitude / longitude. ->QRA Takes Latitude from stack level 2, and Longitude from level 1 and returns a string with the Locator. South and West are negative. The input should be in DD.MMSS format. For example, take QTH ->QRA gives "IO85HX" for my locator. QRA-> Takes a string from the stack level 1 and returns the Latitude in level 2 and Longitude in level 1 of the square center. This is the inverse of ->QRA. The output is in DD.MMSS. Great Circle Distance & Bearings: Calculates the distance between your station and the remote station, also gives beam heading required. GCIR Takes the output of QRA-> (Lat and Long) and uses the Lat and Long in QTH to compute the great circle distance and bearing from QTH to the stack Lat and Long. The distance is returned in Level 2, in the current units of ERAD. The bearing, in DD.MMSS from north (+E,-W) is returned in Level 1. This program assumes the earth is a perfect sphere ( we all know this is an approximation as the earth is actually flat :-). This program uses the PRESERVE routine given in the HP48 Manual II, page 555 to ensure flags are preserved after degrees mode is used. QTH Must contain the two numbers << Lat Long >> representing your stations position, in degrees, minutes and seconds. ERAD Must contain the equatorial radius of the earth. I use: 3963.34655611_mi which is in miles. Thus the answer to GCIR, HORIZ and LOFS will be in miles, You can use the HP48's units management to change this constant if you wish. Radio Horizon: Calculates the flat-band line of sight communication distance at VHF. HORIZ Returns the distance between a point on the earth and the VHF radio 'horizon' given the height above sea level. The height is taken from level 1, and the distance returned in level 1. The height can be in any desired unit, e.g. 3000_ft, note however that the answer will always be in the current unit associated with ERAD. This allows appropriate units to be used for heights and distances. If the height entered is in the base unit of metre's then it does not need the _m suffix. This calculation is NOT the same as the line of sight horizon, as it includes a correction of SQRT(4/3) to allow for tropospheric bending. LOFS Line of Sight. Same as HORIZ but does not take into account any bending, can be used for frequencies above VHF or light. External programs used (included in the listing for completeness): PRESERVE Returns flags to initial state on program exit. Used in GCIR routine. See HP48SX Manual II page 555. 4. HP48 Routines: Programs (ASCII DIR Object) ----------------------- cut here ---------------------------------------- %%HP: T(3)A(D)F(.); DIR \->QRA @ Lat & Long to QRA translation \<< HMS\-> 180 + SWAP HMS\-> 90 + @ offset lat/long to "bottom left corner" \-> lo la \<< lo 20 / IP 65 + CHR la 10 / IP 65 + CHR lo 20 / FP 10 * IP 48 + CHR la 10 / FP 10 * IP 48 + CHR lo 2 / FP 24 * IP 65 + CHR la FP 24 * IP 65 + CHR \>> + + + + + "QRA" \->TAG \>> QRA\-> @ QRA to Lat & Long translation \<< DTAG 1 6 FOR i @ DTAG added for 48GX compatability. i PICK i DUP SUB NUM 65 - NEXT \-> a b c d e f @ break string into numerical elements \<< DROP b 10 * d 17 + f 24 / 48 INV + + + 90 - \->HMS "Lat\^o" \->TAG a 20 * c 17 + 2 * e 12 / 24 INV + + + 180 - \->HMS "Long\^o" \->TAG \>> \>> GCIR \<< \<< DEG HMS\-> SWAP HMS\-> QTH HMS\-> SWAP HMS\-> 4 ROLLD ROT - DUP IF 180 > THEN 360 - END DUP IF -180 < THEN 360 + END IF DUP 0 == THEN .0001 + END @ ensure divisor is non zero \-> lh la d \<< 'ACOS(SIN(lh)*SIN(la)+COS(lh)* COS(la)*COS(d))' \->NUM DUP 180 / \pi * ERAD * \->NUM SWAP \-> ds \<< 'ACOS((SIN(la)-SIN(lh)*COS(ds)) /(COS(lh)*SIN(ds)))' \->NUM \>> IF d 0 > THEN NEG END @ correction for E or W of N \->HMS "\177\^oN" \->TAG \>> \>> PRESERVE \>> HORIZ \<< IF DEPTH THEN ERAD * 8 * 3 / UBASE \v/ ERAD CONVERT ELSE "HORIZ hgt_ \-> dist_" DOERR END \>> LOFS \<< IF DEPTH THEN ERAD * 2 * UBASE \v/ ERAD CONVERT ELSE "LOFS hgt_ \-> dist_" DOERR END \>> ERAD @ Radius of the earth in any '3963.34655611_mi' @ appropriate unit. QTH @ location of station for WZP @ great circle calculations. WZP \<< :Lat\^o: 55.591 @ data is in D.MMSSsss form. :Long\^o: -3.244 \>> @ PRESERVE @ See HP48SX Manual II page 555. \<< RCLF \-> f @ May be more suitably located in HOME \<< EVAL f STOF \>> \>> END