## Flight Planning

### January 19, 2010

We begin with some simple definitions from trigonometry. `Rnd` provides both rounding and a type conversion from inexact (real) arithmetic to exact (integer). `Xmodulo` is like the `modulo` function, but simpler. We also use the `square` function from the Standard Prelude:

```(define pi 3.141592653589793) (define (radian->degree r) (/ r pi 2/360)) (define (degree->radian d) (* d 2/360 pi)) (define (rnd x) (round (inexact->exact x))) (define (xmodulo x y) (cond   ((<= 0 x y) x)   ((< x 0) (xmodulo (+ x y) y))   ((>= x y) (xmodulo (- x y) y))))```

For the first method, `navigate1` follows the definition exactly through a sequence of temporary variables:

```(define (navigate1 d gt wn ws as)  (let*   ((b (- gt wn -180))    (b-radians (degree->radian b))    (sin-b (sin b-radians))    (a (radian->degree (asin (/ (* sin-b ws) as))))    (th (xmodulo (+ gt a) 360))    (gs (+ (* as (cos (degree->radian (- th gt))))           (* ws (cos b-radians))))    (th (+ gt a))    (ft (/ d gs)))   (list    (rnd gs)    (rnd a)    (xmodulo (rnd th) 360)    (rnd (* 60 ft)))))```

For the second method, `det` uses the cosine rule in the calculation of the ground speed, and `a` uses the inverse of the cosine rule to calculate the angle of correction between the ground track and the true heading:

```(define (navigate2 d gt wn ws as)  (let*   ((b (xmodulo (- gt wn -180) 360))    (cos-b (cos (degree->radian b)))    (wsqr (square ws))    (asqr (square as))    (det (+ (square (* ws cos-b)) (- wsqr) asqr))    (gs (+ (* ws cos-b) (sqrt det)))    (a (radian->degree (acos (/ (+ asqr (square gs) (- wsqr)) (* 2 gs as)))))    (a ((if (< b 180) + -) a))    (th (+ gt a))    (ft (/ d gs)))   (if (or (< det 0) (< gs 0)) ('error 'navigate "STRANGE" det gs))   (list    (rnd gs)    (rnd a)    (xmodulo (rnd th) 360)    (rnd (* 60 ft)))))```

An example is given below:

```> (navigate1 180 90 90 20 90) (70 0 90 154) > (navigate2 180 90 90 20 90) (70 0 90 154)```

You can run the program at http://programmingpraxis.codepad.org/yE35J5Pw.

Pages: 1 2

### 2 Responses to “Flight Planning”

1. […] Praxis – Flight Planning By Remco Niemeijer In today’s Programming Praxis exercise we have to implement two algorithms for flight […]

2. Remco Niemeijer said

My Haskell solution (see http://bonsaicode.wordpress.com/2010/01/19/programming-praxis-flight-planning/ for a version with comments):

```import Data.Fixed

toDeg, toRad :: Floating a => a -> a
toDeg d = d * 180 / pi
toRad d = d * pi / 180

navigate1 :: Float -> Float -> Float -> Float -> Float -> [Int]
navigate1 d gt wn ws as = map round [gs, a, th, ft] where
b  = toRad \$ gt - wn + 180
a  = toDeg \$ asin (ws * sin b / as)
th = mod' (gt + a) 360
gs = (cos . toRad \$ th - gt) * as + ws * cos b
ft = d / gs * 60

navigate2 :: Float -> Float -> Float -> Float -> Float -> [Int]
navigate2 d gt wn ws as = if det < 0 || gs < 0 then error "strange"
else map round [gs, a, th, ft] where
b   = mod' (gt - wn + 180) 360
x   = ws * cos (toRad b)
det = x^2 - ws^2 + as^2
gs  = x + sqrt det
a   = (if b < 180 then id else negate) . toDeg . acos \$
(as^2 + gs^2 - ws^2) / (2 * gs * as)
th  = gt + a
ft  = d / gs * 60
```