-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Types and functions for Kepler orbits. -- -- Types and functions for Kepler orbits. @package orbits @version 0.4.0.1 module Data.Constants.Mechanics.Extra -- | One complete revolution in radians turn :: Floating a => PlaneAngle a -- | π radians halfTurn :: Floating a => PlaneAngle a -- | Multiply by 1 radian addRad :: Qu b 'DefaultLCSU a -> Qu (Normalize ('[ 'F PlaneAngle One] @+ b)) 'DefaultLCSU a -- | Divide by 1 radian delRad :: Qu u 'DefaultLCSU a -> Qu (Normalize (u @- '[ 'F PlaneAngle One])) 'DefaultLCSU a module Physics.Orbit.Metrology data PlaneAngleHyperbolic PlaneAngleHyperbolic :: PlaneAngleHyperbolic data RadianHyperbolic RadianHyperbolic :: RadianHyperbolic type Quantity u = MkQu_ULN u 'DefaultLCSU -- | A measure in seconds. type Time = Quantity (Second) -- | A measure in meters. type Distance = Quantity (Meter) -- | A measure in meters per second. type Speed = Quantity ((:*) Meter ((:^) Second (Pred 'Zero))) -- | A measure in kilograms. type Mass = Quantity ((:@) Kilo Gram) -- | A measure in radians. type Angle = Quantity (Radian) -- | A measure in radians (hyperbolic) type AngleH = Quantity RadianHyperbolic -- | A unitless measure. type Unitless = Quantity (Number) instance Data.Metrology.Units.Unit Physics.Orbit.Metrology.RadianHyperbolic instance GHC.Show.Show Physics.Orbit.Metrology.RadianHyperbolic instance Data.Metrology.Dimensions.Dimension Physics.Orbit.Metrology.PlaneAngleHyperbolic -- | Types and functions for dealing with Kepler orbits. module Physics.Orbit -- | Data type defining an orbit parameterized by the type used to -- represent values data Orbit a Orbit :: !Unitless a -> !Distance a -> !InclinationSpecifier a -> !PeriapsisSpecifier a -> !Quantity (:*) ((:^) Meter (Succ (Succ (Succ 'Zero)))) ((:^) Second (Pred (Pred 'Zero))) a -> Orbit a -- | The orbit's eccentricity, e. -- -- eccentricity must be non-negative. -- -- An eccentricity of 0 describes a circular orbit. -- -- An eccentricity of less than 1 describes an elliptic orbit. -- -- An eccentricity equal to 1 describes a parabolic orbit. -- -- An eccentricity greater than 1 describes a hyperbolic orbit. [eccentricity] :: Orbit a -> !Unitless a -- | The orbit's periapsis, q. -- -- periapsis must be positive. -- -- The periapsis is the distance between the bodies at their closest -- approach. [periapsis] :: Orbit a -> !Distance a -- | The inclinationSpecifier describes the angle between the -- obtital plane and the reference plane. [inclinationSpecifier] :: Orbit a -> !InclinationSpecifier a -- | periapsisSpecifier is Circular iff eccentricity -- is 0 -- -- The periapsis specifier describes any rotation of the orbit relative -- to the reference direction in the orbital plane. [periapsisSpecifier] :: Orbit a -> !PeriapsisSpecifier a -- | The gravitational parameter of the system's primary, μ. -- -- μ is equal to the mass of the primary times -- <https://en.wikipedia.org/wiki/Gravitational_constant G>. -- -- primaryGravitationalParameter must be positive. [primaryGravitationalParameter] :: Orbit a -> !Quantity (:*) ((:^) Meter (Succ (Succ (Succ 'Zero)))) ((:^) Second (Pred (Pred 'Zero))) a -- | Along with PeriapsisSpecifier the InclinationSpecifier -- describes orbital elements extra to its geometry. data InclinationSpecifier a -- | The orbit does not lie exactly in the reference plane Inclined :: !Angle a -> !Angle a -> InclinationSpecifier a -- | The longitude of the ascending node, Ω. -- -- The angle between the reference direction and the point where the -- orbiting body crosses the reference plane in the positive z direction. [longitudeOfAscendingNode] :: InclinationSpecifier a -> !Angle a -- | The orbit's inclination, i. -- -- The angle between the reference plane and the orbital plane [inclination] :: InclinationSpecifier a -> !Angle a -- | The orbit lies in the reference plane NonInclined :: InclinationSpecifier a -- | Along with InclinationSpecifier the PeriapsisSpecifier -- describes orbital elements extra to its geometry. data PeriapsisSpecifier a -- | The orbit is not circular Eccentric :: !Angle a -> PeriapsisSpecifier a -- | The argument of periapsis, ω. -- -- The argumentOfPeriapsis is the angle of the periapsis relative -- to the reference direction in the orbital plane. [argumentOfPeriapsis] :: PeriapsisSpecifier a -> !Angle a -- | The orbit has an eccentricity of 0 so the argumentOfPeriapsis -- is indeterminate. Circular :: PeriapsisSpecifier a -- | What form the orbit's geometry takes. This is dependant only on the -- eccentricity, e >= 0, of the orbit. data Classification -- | 0 <= e < 1 -- -- This includes circular orbits. Elliptic :: Classification -- | e == 1 Parabolic :: Classification -- | e > 1 Hyperbolic :: Classification -- | Determines if the orbital elements are valid (e >= 0 -- etc...). The behavior of all the other functions in this module is -- undefined when given an invalid orbit. isValid :: (Ord a, Num a) => Orbit a -> Bool -- | What shape is the orbit classify :: (Num a, Ord a) => Orbit a -> Classification -- | Return an equivalent orbit such that -- -- normalizeOrbit :: (Floating a, Real a) => Orbit a -> Orbit a -- | Calculate the distance between the bodies when they are at their most -- distant. apoapsis returns Nothing when given a parabolic -- or hyperbolic orbit. apoapsis :: (Fractional a, Ord a) => Orbit a -> Maybe (Distance a) -- | Calculate the mean motion, n, of an orbit -- -- This is the rate of change of the mean anomaly with respect to time. meanMotion :: (Floating a, Ord a) => Orbit a -> Quantity (:/) Radian Second a -- | Calculate the orbital period, p, of an elliptic orbit. -- -- period returns Nothing if given a parabolic or hyperbolic -- orbit. period :: (Floating a, Ord a) => Orbit a -> Maybe (Time a) -- | Calculate the areal velocity, A, of the orbit. -- -- The areal velocity is the area swept out by the line between -- the orbiting body and the primary per second. arealVelocity :: (Ord a, Floating a) => Orbit a -> Quantity (:/) ((:^) Meter (Succ (Succ 'Zero))) Second a -- | Calculate the semi-major axis, a, of the Orbit. Returns -- Nothing when given a parabolic orbit for which there is no -- semi-major axis. Note that the semi-major axis of a hyperbolic orbit -- is negative. semiMajorAxis :: (Fractional a, Ord a) => Orbit a -> Maybe (Distance a) -- | Calculate the semi-minor axis, b, of the Orbit. Like -- semiMajorAxis 'semiMinorAxis' o is negative when -- o is a hyperbolic orbit. In the case of a parabolic orbit -- semiMinorAxis returns 0m. semiMinorAxis :: (Floating a, Ord a) => Orbit a -> Distance a -- | Calculate the semiLatusRectum, l, of the Orbit semiLatusRectum :: Num a => Orbit a -> Distance a -- | Calculate the angle at which a body leaves the system when on a -- hyperbolic trajectory relative to the argument of periapsis. This is -- the limit of the true anomaly as time tends towards -infinity minus -- the argument of periapsis. The approach angle is in the closed range -- (-π..π/2). -- -- This is the negation of the departure angle. -- -- hyperbolicApproachAngle returns Nothing when given a -- non-hyperbolic orbit and -π when given a parabolic orbit. hyperbolicApproachAngle :: (Floating a, Ord a) => Orbit a -> Maybe (Angle a) -- | Calculate the angle at which a body leaves the system when on an -- escape trajectory relative to the argument of periapsis. This is the -- limit of the true anomaly as time tends towards infinity minus the -- argument of periapsis. The departure angle is in the closed range -- (π/2..π). -- -- This is the negation of the approach angle. -- -- hyperbolicDepartureAngle returns Nothing when given an elliptic -- orbit and π when given a parabolic orbit. hyperbolicDepartureAngle :: (Floating a, Ord a) => Orbit a -> Maybe (Angle a) -- | Calculate the time since periapse, t, when the body has the given -- mean anomaly, M. M may be negative, indicating that the -- orbiting body has yet to reach periapse. -- -- The sign of the time at mean anomaly M is the same as the sign of M. -- -- The returned time is unbounded. timeAtMeanAnomaly :: (Floating a, Ord a) => Orbit a -> Angle a -> Time a -- | Calculate the time since periapse, t, of an elliptic orbit when at -- eccentric anomaly E. -- -- timeAtEccentricAnomaly returns Nothing if given a parabolic or -- hyperbolic orbit. timeAtEccentricAnomaly :: (Floating a, Ord a) => Orbit a -> Angle a -> Maybe (Time a) -- | Calculate the time since periapse, t, of a hyperbolic orbit when at -- hyperbolic anomaly H. -- -- Returns Nothing if given an elliptic or parabolic orbit. timeAtHyperbolicAnomaly :: (Floating a, Ord a) => Orbit a -> AngleH a -> Maybe (Time a) -- | Calculate the time since periapse given the true anomaly, ν, of an -- orbiting body. -- -- Returns Nothing if the body never passed through the specified -- true anomaly. timeAtTrueAnomaly :: (Real a, Floating a) => Orbit a -> Angle a -> Maybe (Time a) -- | Calculate the mean anomaly, M, at the given time since -- periapse, t. t may be negative, indicating that the orbiting body has -- yet to reach periapse. -- -- The sign of the mean anomaly at time t is the same as the sign of t. -- -- The returned mean anomaly is unbounded. meanAnomalyAtTime :: (Floating a, Ord a) => Orbit a -> Time a -> Angle a -- | Calculate the mean anomaly, M, of an elliptic orbit when at eccentric -- anomaly E -- -- meanAnomalyAtEccentricAnomaly returns Nothing if given a -- parabolic or hyperbolic orbit. -- -- The number of orbits represented by the anomalies is preserved; i.e. M -- div 2π = E div 2π meanAnomalyAtEccentricAnomaly :: (Floating a, Ord a) => Orbit a -> Angle a -> Maybe (Angle a) -- | Calculate the mean anomaly, M, of a hyperbolic orbit when at -- hyperbolic anomaly H meanAnomalyAtHyperbolicAnomaly :: (Floating a, Ord a) => Orbit a -> AngleH a -> Maybe (Angle a) -- | Calculate the mean anomaly, M, of an orbiting body when at the given -- true anomaly, ν. -- -- The number of orbits represented by the anomalies is preserved; i.e. M -- div 2π = ν div 2π -- -- Returns Nothing for parabolic orbits. -- -- Returns Nothing when the trajectory is not defined for the -- given true anomaly. meanAnomalyAtTrueAnomaly :: (Real a, Floating a) => Orbit a -> Angle a -> Maybe (Angle a) -- | Calculate the eccentric anomaly, E, of an elliptic orbit at time t. -- -- eccentricAnomalyAtTime returns Nothing when given a parabolic -- or hyperbolic orbit. -- -- The number of orbits represented by the time is preserved; i.e. t -- div p = E div 2π eccentricAnomalyAtTime :: (Converge [a], Floating a, Real a) => Orbit a -> Time a -> Maybe (Angle a) -- | Calculate the eccentric anomaly, E, of an elliptic orbit when at mean -- anomaly M. This function is considerably slower than most other -- conversion functions as it uses an iterative method as no closed form -- solution exists. -- -- The number of orbits represented by the anomalies is preserved; i.e. M -- div 2π = E div 2π -- -- eccentricAnomalyAtMeanAnomaly returns Nothing when given a -- parabolic or hyperbolic orbit. eccentricAnomalyAtMeanAnomaly :: forall a. (Converge [a], Floating a, Real a) => Orbit a -> Angle a -> Maybe (Angle a) -- | eccentricAnomalyAtMeanAnomaly specialized to Float. -- -- This function is used to calculate the initial guess for -- eccentricAnomalyAtMeanAnomaly. eccentricAnomalyAtMeanAnomalyFloat :: Orbit Float -> Angle Float -> Maybe (Angle Float) -- | Calculate the eccentric anomaly, E, of an orbiting body when it has -- true anomaly, ν. -- -- The number of orbits represented by the anomalies is preserved; i.e. ν -- div 2π = E div 2π -- -- Returns Nothing if given a parabolic or hyperbolic orbit. eccentricAnomalyAtTrueAnomaly :: (Floating a, Real a) => Orbit a -> Angle a -> Maybe (Angle a) hyperbolicAnomalyAtTime :: forall a. (Converge [a], RealFloat a) => Orbit a -> Time a -> Maybe (AngleH a) hyperbolicAnomalyAtMeanAnomaly :: forall a. (Converge [a], RealFloat a) => Orbit a -> Angle a -> Maybe (AngleH a) -- | Calculate the hyperbolic anomaly, H, at a given mean anomaly. Unline -- eccentricAnomalyAtMeanAnomalyFloat this uses double precision -- floats to help avoid overflowing. hyperbolicAnomalyAtMeanAnomalyDouble :: Orbit Double -> Angle Double -> Maybe (AngleH Double) -- | Returns the hyperbolic anomaly, H, for an orbit at true anomaly ν. -- -- Returns Nothing when given an Elliptic or -- Parabolic orbit, or a true anomaly out of the range of the -- hyperbolic orbit. hyperbolicAnomalyAtTrueAnomaly :: (Floating a, Ord a) => Orbit a -> Angle a -> Maybe (AngleH a) -- | Calculate the true anomaly, ν, of a body at time since periapse, t. trueAnomalyAtTime :: forall a. (Converge [a], RealFloat a) => Orbit a -> Time a -> Angle a -- | Calculate the true anomaly, ν, of an orbiting body when it has the -- given mean anomaly, _M. trueAnomalyAtMeanAnomaly :: (Converge [a], RealFloat a) => Orbit a -> Angle a -> Angle a -- | Calculate the true anomaly, ν, of an orbiting body when it has the -- given eccentric anomaly, _E. -- -- The number of orbits represented by the anomalies is preserved; i.e. ν -- div 2π = E div 2π trueAnomalyAtEccentricAnomaly :: RealFloat a => Orbit a -> Angle a -> Maybe (Angle a) trueAnomalyAtHyperbolicAnomaly :: (Ord a, Floating a) => Orbit a -> AngleH a -> Maybe (Angle a) -- | Specific angular momentum, h, is the angular momentum per unit mass specificAngularMomentum :: Floating a => Orbit a -> Quantity (:*) ((:^) Meter (Succ (Succ 'Zero))) ((:^) Second (Pred 'Zero)) a -- | Specific orbital energy, ε, is the orbital energy per unit mass specificOrbitalEnergy :: (Ord a, Floating a) => Orbit a -> Quantity (:/) Joule ((:@) Kilo Gram) a -- | Specific potential energy, εp, is the potential energy per unit mass -- at a particular true anomaly specificPotentialEnergyAtTrueAnomaly :: (Ord a, Floating a) => Orbit a -> Angle a -> Quantity (:/) Joule ((:@) Kilo Gram) a -- | Specific kinetic energy, εk, is the kinetic energy per unit mass at a -- particular true anomaly specificKineticEnergyAtTrueAnomaly :: (Ord a, Floating a) => Orbit a -> Angle a -> Quantity (:/) Joule ((:@) Kilo Gram) a -- | What is the speed, v, of a body at a particular true anomaly speedAtTrueAnomaly :: (Ord a, Floating a) => Orbit a -> Angle a -> Speed a -- | The distance, r, from the primary body to the orbiting body at a -- particular true anomaly. radiusAtTrueAnomaly :: (Ord a, Floating a) => Orbit a -> Angle a -> Distance a -- | The escape velocity for a primary with specified gravitational -- parameter at a particular distance. escapeVelocityAtDistance :: Floating a => Quantity (:*) ((:^) Meter (Succ (Succ (Succ 'Zero)))) ((:^) Second (Pred (Pred 'Zero))) a -> Distance a -> Speed a type Quantity u = MkQu_ULN u 'DefaultLCSU -- | A measure in seconds. type Time = Quantity (Second) -- | A measure in meters. type Distance = Quantity (Meter) -- | A measure in meters per second. type Speed = Quantity ((:*) Meter ((:^) Second (Pred 'Zero))) -- | A measure in kilograms. type Mass = Quantity ((:@) Kilo Gram) -- | A measure in radians. type Angle = Quantity (Radian) -- | A measure in radians (hyperbolic) type AngleH = Quantity RadianHyperbolic data RadianHyperbolic RadianHyperbolic :: RadianHyperbolic data PlaneAngleHyperbolic PlaneAngleHyperbolic :: PlaneAngleHyperbolic -- | A unitless measure. type Unitless = Quantity (Number) -- | If a type is an instance of Converge then it represents a stream of -- values which are increasingly accurate approximations of a desired -- value class Converge a instance GHC.Classes.Eq a => GHC.Classes.Eq (Physics.Orbit.InclinationSpecifier a) instance GHC.Show.Show a => GHC.Show.Show (Physics.Orbit.InclinationSpecifier a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Physics.Orbit.PeriapsisSpecifier a) instance GHC.Show.Show a => GHC.Show.Show (Physics.Orbit.PeriapsisSpecifier a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Physics.Orbit.Orbit a) instance GHC.Show.Show a => GHC.Show.Show (Physics.Orbit.Orbit a) instance GHC.Classes.Eq Physics.Orbit.Classification instance GHC.Read.Read Physics.Orbit.Classification instance GHC.Show.Show Physics.Orbit.Classification module Physics.Orbit.Sol solMass :: Fractional a => Mass a solGraviationalParameter :: Fractional a => Quantity (:*) ((:^) Meter (Succ (Succ (Succ 'Zero)))) ((:^) Second (Pred (Pred 'Zero))) a venusOrbit :: Fractional a => Orbit a earthOrbit :: Fractional a => Orbit a marsOrbit :: Fractional a => Orbit a halleyOrbit :: Fractional a => Orbit a -- | The fastest comet in the west. Nice for testing as it's on a -- hyperbolic trajectory. See -- https://en.wikipedia.org/wiki/C/1980_E1 -- -- Orbital data from: -- http://ssd.jpl.nasa.gov/horizons.cgi?CGISESSID=6c2730c1201457522760d3f26b7d1f00#results c1980E1Orbit :: Fractional a => Orbit a module Physics.Orbit.StateVectors data StateVectors a StateVectors :: Position a -> Velocity a -> StateVectors a [position] :: StateVectors a -> Position a [velocity] :: StateVectors a -> Velocity a type Position a = V3 (Distance a) type Velocity a = V3 (Speed a) stateVectorsAtTrueAnomaly :: (Conjugate a, RealFloat a) => Orbit a -> Angle a -> StateVectors a -- | Get the position in space of a body after rotating it according to the -- inclination and periapsis specifier. positionAtTrueAnomaly :: (Conjugate a, RealFloat a) => Orbit a -> Angle a -> Position a -- | Get the position of a body relative to the orbital plane positionInPlaneAtTrueAnomaly :: (Ord a, Floating a) => Orbit a -> Angle a -> Position a -- | Get the velocity in space of a body after rotating it according to the -- inclination and periapsis specifier. velocityAtTrueAnomaly :: (Conjugate a, RealFloat a) => Orbit a -> Angle a -> Velocity a -- | The in-plane velocity of a body velocityInPlaneAtTrueAnomaly :: (Ord a, Floating a) => Orbit a -> Angle a -> Velocity a elementsFromStateVectors :: (Ord a, Floating a, Conjugate a, RealFloat a, Show a) => Quantity (:*) ((:^) Meter (Succ (Succ (Succ 'Zero)))) ((:^) Second (Pred (Pred 'Zero))) a -> StateVectors a -> (Orbit a, Angle a) -- | Calculate the eccentricity vector, e, given state vectors eccentricityVector :: Floating a => Quantity (:*) ((:^) Meter (Succ (Succ (Succ 'Zero)))) ((:^) Second (Pred (Pred 'Zero))) a -> StateVectors a -> V3 (Unitless a) -- | Calculate the true anomaly, ν, of a body at position, r, given its -- orbital elements. trueAnomalyAtPosition :: (Conjugate a, RealFloat a) => Orbit a -> Position a -> Angle a -- | A quaternion representing the rotation of the orbital plane orbitalPlaneQuaternion :: RealFloat a => Orbit a -> Quaternion a -- | Rotate a position such that is is relative to the orbital plane -- according to the inclination specifier and periapsis specifier. -- -- The orbital plane is perpendicular to the z axis rotateToPlane :: (Conjugate a, RealFloat a) => Orbit a -> V3 (Qu u l a) -> V3 (Qu u l a) -- | Rotate a position relative to the orbital plane according to the -- inclination specifier and periapsis specifier. -- -- The orbital plane is perpendicular to the z axis rotateFromPlane :: (Conjugate a, RealFloat a) => Orbit a -> V3 (Qu u l a) -> V3 (Qu u l a) -- | Get the flight path angle, φ, of a body a a specific true anomaly. -- This is the angle of the body's motion relative to a vector -- perpendicular to the radius. flightPathAngleAtTrueAnomaly :: (Real a, Floating a) => Orbit a -> Angle a -> Angle a -- | Calculate the momentum vector, h, given state vectors specificAngularMomentumVector :: Num a => StateVectors a -> V3 (Quantity (:/) ((:^) Meter (Succ (Succ 'Zero))) Second a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Physics.Orbit.StateVectors.StateVectors a) instance GHC.Show.Show a => GHC.Show.Show (Physics.Orbit.StateVectors.StateVectors a)