jord-2.0.0.0: Geographical Position Calculations
Copyright(c) 2020 Cedric Liegeois
LicenseBSD3
MaintainerCedric Liegeois <ofmooseandmen@yahoo.fr>
Stabilityexperimental
Portabilityportable
Safe HaskellSafe-Inferred
LanguageHaskell2010

Data.Geo.Jord.Kinematics

Description

Types and functions for working with kinematics calculations assuming a spherical celestial body.

In order to use this module you should start with the following imports:

import qualified Data.Geo.Jord.Geodetic as Geodetic
import qualified Data.Geo.Jord.Kinematics as Kinematics

All functions are implemented using the vector-based approached described in Gade, K. (2010). A Non-singular Horizontal Position Representation and in Shudde, Rex H. (1986). Some tactical algorithms for spherical geometry

Synopsis

The Track type.

data Track a Source #

Track represents the state of a vehicle by its current horizontal position, bearing and speed.

Constructors

Track 

Fields

Instances

Instances details
Model a => Eq (Track a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

(==) :: Track a -> Track a -> Bool #

(/=) :: Track a -> Track a -> Bool #

Model a => Show (Track a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

showsPrec :: Int -> Track a -> ShowS #

show :: Track a -> String #

showList :: [Track a] -> ShowS #

The Course type.

data Course Source #

Course represents the cardinal direction in which the vehicle is to be steered.

Instances

Instances details
Eq Course Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

(==) :: Course -> Course -> Bool #

(/=) :: Course -> Course -> Bool #

Show Course Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

The Cpa type.

data Cpa a Source #

Time to, and distance at, closest point of approach (CPA) as well as position of both tracks at CPA.

Instances

Instances details
Model a => Eq (Cpa a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

(==) :: Cpa a -> Cpa a -> Bool #

(/=) :: Cpa a -> Cpa a -> Bool #

Model a => Show (Cpa a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

showsPrec :: Int -> Cpa a -> ShowS #

show :: Cpa a -> String #

showList :: [Cpa a] -> ShowS #

timeToCpa :: Cpa a -> Duration Source #

time to CPA.

distanceAtCpa :: Cpa a -> Length Source #

distance at CPA.

cpaOwnshipPosition :: Cpa a -> HorizontalPosition a Source #

horizontal position of ownship CPA.

cpaIntruderPosition :: Cpa a -> HorizontalPosition a Source #

horizontal position of intruder at CPA.

The Intercept type.

data Intercept a Source #

Time, distance and position of intercept as well as speed and initial bearing of interceptor.

Instances

Instances details
Model a => Eq (Intercept a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

Methods

(==) :: Intercept a -> Intercept a -> Bool #

(/=) :: Intercept a -> Intercept a -> Bool #

Model a => Show (Intercept a) Source # 
Instance details

Defined in Data.Geo.Jord.Kinematics

timeToIntercept :: Intercept a -> Duration Source #

time to intercept.

distanceToIntercept :: Intercept a -> Length Source #

distance travelled to intercept.

interceptPosition :: Intercept a -> HorizontalPosition a Source #

horizontal position of intercept.

interceptorBearing :: Intercept a -> Angle Source #

initial bearing of interceptor.

interceptorSpeed :: Intercept a -> Speed Source #

speed of interceptor.

Calculations

course :: Spherical a => HorizontalPosition a -> Angle -> Course Source #

course p b computes the course of a vehicle currently at position p and following bearing b.

positionAfter :: Spherical a => HorizontalPosition a -> Angle -> Speed -> Duration -> HorizontalPosition a Source #

positionAfter p b s d computes the horizontal position of a vehicle currently at position p following bearing b and travelling at speed s after duration d has elapsed. For example:

>>> let p = Geodetic.s84Pos 53.321 (-1.729)
>>> let b = Angle.decimalDegrees 96.0217
>>> let s = Speed.kilometresPerHour 124.8
>>> Kinematics.positionAfter p b s (Duration.hours 1)
53°11'19.367"N,0°8'2.456"E (S84)

This is equivalent to:

Kinematics.positionAfter' p (Kinematics.course p b) s d

positionAfter' :: Spherical a => HorizontalPosition a -> Course -> Speed -> Duration -> HorizontalPosition a Source #

positionAfter' p c s d computes the horizontal position of a vehicle currently at position p on course c and travelling at speed s after duration d has elapsed. Note: course must have been calculated from position p.

trackPositionAfter :: Spherical a => Track a -> Duration -> HorizontalPosition a Source #

trackPositionAfter t d computes the horizontal position of a track t after duration d has elapsed. For example:

>>> let p = Geodetic.s84Pos 53.321 (-1.729)
>>> let b = Angle.decimalDegrees 96.0217
>>> let s = Speed.kilometresPerHour 124.8
>>> Kinematics.trackPositionAfter (Kinematics.Track p b s) (Duration.hours 1)
53°11'19.367"N,0°8'2.456"E (S84)

cpa :: Spherical a => Track a -> Track a -> Maybe (Cpa a) Source #

cpa ownship intruder computes the closest point of approach between tracks ownship and intruder. The closest point of approach is calculated assuming both ships maintain a constant course and speed.

>>> let ownship = Kinematics.Track (Geodetic.s84Pos 20 (-60)) (Angle.decimalDegrees 10) (Speed.knots 15)
>>> let intruder = Kinematics.Track (Geodetic.s84Pos 34 (-50)) (Angle.decimalDegrees 220) (Speed.knots 300)
>>> let cpa = Kinematics.cpa ownship intruder
Just (Cpa { timeToCpa = 3H9M56.155S
          , distanceAtCpa = 124.231730834km
          , cpaOwnshipPosition = 20°46'43.641"N,59°51'11.225"W (S84)
          , cpaIntruderPosition = 21°24'8.523"N,60°50'48.159"W (S84)})

intercept :: Spherical a => Track a -> HorizontalPosition a -> Maybe (Intercept a) Source #

intercept t p computes the minimum speed of interceptor at position p needed for an intercept with target track t to take place. Intercept time, position, distance and interceptor bearing are derived from this minimum speed. For example:

>>> let t = Kinematics.Track (Geodetic.s84Pos 34 (-50)) (Angle.decimalDegrees 220) (Speed.knots 600)
>>> let ip = Geodetic.s84Pos 20 (-60)
>>> Kinematics.intercept t ip
Just (Intercept { timeToIntercept = 1H39M53.831S
                , distanceToIntercept = 162.294627463km
                , interceptPosition = 20°43'42.305"N,61°20'56.848"W (S84)
                , interceptorBearing = 300°10'18.053"
                , interceptorSpeed = 97.476999km/h})

Returns Nothing if intercept cannot be achieved e.g.:

  • interceptor and target are at the same position
  • interceptor is "behind" the target

interceptBySpeed :: Spherical a => Track a -> HorizontalPosition a -> Speed -> Maybe (Intercept a) Source #

interceptBySpeed t p s computes the time needed by interceptor at position p and travelling at speed s to intercept target track t.

Returns Nothing if intercept cannot be achieved e.g.:

  • interceptor and target are at the same position
  • interceptor speed is below minimum speed returned by intercept

interceptByTime :: Spherical a => Track a -> HorizontalPosition a -> Duration -> Maybe (Intercept a) Source #

interceptByTime t p d computes the speed of interceptor at position p needed for an intercept with target track t to take place after duration d.For example:

>>> let t = Kinematics.Track (Geodetic.s84Pos 34 (-50)) (Angle.decimalDegrees 220) (Speed.knots 600)
>>> let ip = Geodetic.s84Pos 20 (-60)
>>> let d = Duration.seconds 2700
>>> interceptByTime t ip d
Just (Intercept { timeToIntercept = 0H45M0.000S
                , distanceToIntercept = 1015.302358852km
                , interceptPosition = 28°8'12.046"N,55°27'21.411"W (S84)
                , interceptorBearing = 26°7'11.649"
                , interceptorSpeed = 1353.736478km/h})

Returns Nothing if given duration is <= 0 or interceptor and target are at the same position. Contrary to intercept and interceptBySpeed this function handles cases where the interceptor has to catch up the target.

re-exported for convenience

data Duration Source #

A duration with a resolution of 1 millisecond.

Instances

Instances details
Eq Duration Source # 
Instance details

Defined in Data.Geo.Jord.Duration

Ord Duration Source # 
Instance details

Defined in Data.Geo.Jord.Duration

Read Duration Source #

See duration.

Instance details

Defined in Data.Geo.Jord.Duration

Show Duration Source #

Show Duration as (-)nHnMn.nS.

Instance details

Defined in Data.Geo.Jord.Duration

data Speed Source #

A speed with a resolution of 1 millimetre per hour.

Instances

Instances details
Eq Speed Source # 
Instance details

Defined in Data.Geo.Jord.Speed

Methods

(==) :: Speed -> Speed -> Bool #

(/=) :: Speed -> Speed -> Bool #

Ord Speed Source # 
Instance details

Defined in Data.Geo.Jord.Speed

Methods

compare :: Speed -> Speed -> Ordering #

(<) :: Speed -> Speed -> Bool #

(<=) :: Speed -> Speed -> Bool #

(>) :: Speed -> Speed -> Bool #

(>=) :: Speed -> Speed -> Bool #

max :: Speed -> Speed -> Speed #

min :: Speed -> Speed -> Speed #

Read Speed Source #

See speed.

Instance details

Defined in Data.Geo.Jord.Speed

Show Speed Source #

Speed is shown in kilometres per hour.

Instance details

Defined in Data.Geo.Jord.Speed

Methods

showsPrec :: Int -> Speed -> ShowS #

show :: Speed -> String #

showList :: [Speed] -> ShowS #