KSP (empty) → 0.1
raw patch · 15 files changed
+1225/−0 lines, 15 filesdep +basesetup-changed
Dependencies added: base
Files
- KSP.cabal +43/−0
- LICENSE +121/−0
- README.md +7/−0
- Setup.hs +2/−0
- src/System/KSP/Auxiliary.hs +35/−0
- src/System/KSP/DataConstructors.hs +34/−0
- src/System/KSP/DataDestructors.hs +156/−0
- src/System/KSP/Datatype/Body.hs +126/−0
- src/System/KSP/Datatype/Object.hs +27/−0
- src/System/KSP/Datatype/Orbit.hs +75/−0
- src/System/KSP/Datatype/System.hs +37/−0
- src/System/KSP/Datatypes.hs +34/−0
- src/System/KSP/KSP.hs +131/−0
- src/System/KSP/OrbitalMechanics.hs +123/−0
- src/System/KSP/Universe.hs +274/−0
+ KSP.cabal view
@@ -0,0 +1,43 @@+name: KSP+version: 0.1+synopsis: A library with the kerbal space program universe and demo code+description: This library is intended to help the haskell affine ksp player to+ calculations within the ksp universe.+homepage: https://github.com/frosch03/kerbal+license: PublicDomain+license-file: LICENSE+author: Matthias Brettschneider+maintainer: frosch03@frosch03.de+category: Testing+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10++library+ -- Modules exported by the library.+ exposed-modules: System.KSP.DataConstructors,+ System.KSP.DataDestructors,+ System.KSP.Datatypes,+ System.KSP.Universe,+ System.KSP.OrbitalMechanics,+ System.KSP.Auxiliary,+ System.KSP.KSP++ other-modules: System.KSP.Datatype.Object,+ System.KSP.Datatype.Body,+ System.KSP.Datatype.Orbit,+ System.KSP.Datatype.System+ + -- other-extensions: GADT+ -- , FlexibleInstances+ + build-depends: base >=4.6 && <= 4.8+ + -- Directories containing source files.+ hs-source-dirs: src+ + default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/frosch03/kerbal.git
+ LICENSE view
@@ -0,0 +1,121 @@+Creative Commons Legal Code++CC0 1.0 Universal++ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED+ HEREUNDER.++Statement of Purpose++The laws of most jurisdictions throughout the world automatically confer+exclusive Copyright and Related Rights (defined below) upon the creator+and subsequent owner(s) (each and all, an "owner") of an original work of+authorship and/or a database (each, a "Work").++Certain owners wish to permanently relinquish those rights to a Work for+the purpose of contributing to a commons of creative, cultural and+scientific works ("Commons") that the public can reliably and without fear+of later claims of infringement build upon, modify, incorporate in other+works, reuse and redistribute as freely as possible in any form whatsoever+and for any purposes, including without limitation commercial purposes.+These owners may contribute to the Commons to promote the ideal of a free+culture and the further production of creative, cultural and scientific+works, or to gain reputation or greater distribution for their Work in+part through the use and efforts of others.++For these and/or other purposes and motivations, and without any+expectation of additional consideration or compensation, the person+associating CC0 with a Work (the "Affirmer"), to the extent that he or she+is an owner of Copyright and Related Rights in the Work, voluntarily+elects to apply CC0 to the Work and publicly distribute the Work under its+terms, with knowledge of his or her Copyright and Related Rights in the+Work and the meaning and intended legal effect of CC0 on those rights.++1. Copyright and Related Rights. A Work made available under CC0 may be+protected by copyright and related or neighboring rights ("Copyright and+Related Rights"). Copyright and Related Rights include, but are not+limited to, the following:++ i. the right to reproduce, adapt, distribute, perform, display,+ communicate, and translate a Work;+ ii. moral rights retained by the original author(s) and/or performer(s);+iii. publicity and privacy rights pertaining to a person's image or+ likeness depicted in a Work;+ iv. rights protecting against unfair competition in regards to a Work,+ subject to the limitations in paragraph 4(a), below;+ v. rights protecting the extraction, dissemination, use and reuse of data+ in a Work;+ vi. database rights (such as those arising under Directive 96/9/EC of the+ European Parliament and of the Council of 11 March 1996 on the legal+ protection of databases, and under any national implementation+ thereof, including any amended or successor version of such+ directive); and+vii. other similar, equivalent or corresponding rights throughout the+ world based on applicable law or treaty, and any national+ implementations thereof.++2. Waiver. To the greatest extent permitted by, but not in contravention+of, applicable law, Affirmer hereby overtly, fully, permanently,+irrevocably and unconditionally waives, abandons, and surrenders all of+Affirmer's Copyright and Related Rights and associated claims and causes+of action, whether now known or unknown (including existing as well as+future claims and causes of action), in the Work (i) in all territories+worldwide, (ii) for the maximum duration provided by applicable law or+treaty (including future time extensions), (iii) in any current or future+medium and for any number of copies, and (iv) for any purpose whatsoever,+including without limitation commercial, advertising or promotional+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each+member of the public at large and to the detriment of Affirmer's heirs and+successors, fully intending that such Waiver shall not be subject to+revocation, rescission, cancellation, termination, or any other legal or+equitable action to disrupt the quiet enjoyment of the Work by the public+as contemplated by Affirmer's express Statement of Purpose.++3. Public License Fallback. Should any part of the Waiver for any reason+be judged legally invalid or ineffective under applicable law, then the+Waiver shall be preserved to the maximum extent permitted taking into+account Affirmer's express Statement of Purpose. In addition, to the+extent the Waiver is so judged Affirmer hereby grants to each affected+person a royalty-free, non transferable, non sublicensable, non exclusive,+irrevocable and unconditional license to exercise Affirmer's Copyright and+Related Rights in the Work (i) in all territories worldwide, (ii) for the+maximum duration provided by applicable law or treaty (including future+time extensions), (iii) in any current or future medium and for any number+of copies, and (iv) for any purpose whatsoever, including without+limitation commercial, advertising or promotional purposes (the+"License"). The License shall be deemed effective as of the date CC0 was+applied by Affirmer to the Work. Should any part of the License for any+reason be judged legally invalid or ineffective under applicable law, such+partial invalidity or ineffectiveness shall not invalidate the remainder+of the License, and in such case Affirmer hereby affirms that he or she+will not (i) exercise any of his or her remaining Copyright and Related+Rights in the Work or (ii) assert any associated claims and causes of+action with respect to the Work, in either case contrary to Affirmer's+express Statement of Purpose.++4. Limitations and Disclaimers.++ a. No trademark or patent rights held by Affirmer are waived, abandoned,+ surrendered, licensed or otherwise affected by this document.+ b. Affirmer offers the Work as-is and makes no representations or+ warranties of any kind concerning the Work, express, implied,+ statutory or otherwise, including without limitation warranties of+ title, merchantability, fitness for a particular purpose, non+ infringement, or the absence of latent or other defects, accuracy, or+ the present or absence of errors, whether or not discoverable, all to+ the greatest extent permissible under applicable law.+ c. Affirmer disclaims responsibility for clearing rights of other persons+ that may apply to the Work or any use thereof, including without+ limitation any person's Copyright and Related Rights in the Work.+ Further, Affirmer disclaims responsibility for obtaining any necessary+ consents, permissions or other rights required for any use of the+ Work.+ d. Affirmer understands and acknowledges that Creative Commons is not a+ party to this document and has no duty or obligation with respect to+ this CC0 or use of the Work.
+ README.md view
@@ -0,0 +1,7 @@++# README++## What is this++KSP is intended to be an library, that enables the haskell affine+kerbel space program nerd to do calculations.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/System/KSP/Auxiliary.hs view
@@ -0,0 +1,35 @@+{-|+Module : Auxiliary+Description : This module contains some auxiliary functions.+License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.Auxiliary+ ( takeUntil+ , firstJust+ )+where++import Data.Maybe (fromJust, catMaybes)+import Data.List (find)+++ +-- | The function 'takeUntil' takes a test function and a list of+-- values. It returns all elements that do not pass the test function+-- until it reaches the first one that passes the test function,+-- otherwise it returns the empty list.+takeUntil :: (a -> Bool) -> [a] -> [a]+takeUntil f (x:xs)+ | not (f x)+ = x : (takeUntil f xs)++ | otherwise+ = []++-- | 'firstJust' returns of a list of 'Maybe' values the first actual+-- 'Just' value or nothing if none is within the list.+firstJust :: [Maybe a] -> Maybe a+firstJust x = find (const True) (catMaybes x)+
+ src/System/KSP/DataConstructors.hs view
@@ -0,0 +1,34 @@+{-|+Module : DataConstructors+Description : The Module "System.KSP.DataConstructors" imports everything + that is a data constructor and exports them.+License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.DataConstructors+ ( Object(..)+ , Celestial(..)+ , Body(..)+ , Orbit(..)+ , mkOrbit+ , mkCircOrbit+ , Height+ , System(..)+ , GravConst+ , KSystem+ )+where++import System.KSP.Datatype.Body+import System.KSP.Datatype.Orbit+import System.KSP.Datatype.System++-- | 'GravConst' is the type of the gravitation constant, which is+-- obious a double.+type GravConst = Double++-- | 'KSystem' creates a data constructor, that binds the+-- 'System.KSP.Datatype.System' to a 'System.KSP.Datatype.System' of+-- 'System.KSP.Datatype.Orbit's around 'System.KSP.Datatype.Body's.+type KSystem = System Body
+ src/System/KSP/DataDestructors.hs view
@@ -0,0 +1,156 @@+{-|+Module : DataDestructors+Description : This module defines functions to deconstruct the types+License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.DataDestructors+ ( getNextUp+ , getPathUp+ , getDivid+ , sOrbitInSystem+ , pathOBetween+ , pathOBetween'+ , pathBetween_+ , pathBetween'+ , pathBetween+ , pathSpeeds+ , orbitalSpeed+ , updateOrbit+ , burnFromCircOrb+ , burnAt+ , burnAtApoapsis+ , burnAtPeriapsis+ )+where++import System.KSP.DataConstructors+import System.KSP.Auxiliary+import System.KSP.OrbitalMechanics++import Data.Maybe (fromJust)+++-- | 'getNextUp' takes a 'KSystem' system and a 'Body'. It returns the+-- body that the supplied body orbits. 'Nothing' is returned if the+-- supplied body is not found within the system.+getNextUp :: KSystem Body -> Body -> Maybe Body+getNextUp Empty _ = Nothing+getNextUp (System s) f+ | (length $ filter ((== f) . snd) s) > 0+ = Just $ centerBody . fst . head $ filter ((== f) . snd) s++ | (length $ filter ((== f) . snd) s) == 0+ = firstJust $ map (((flip getNextUp) f) . system . celestial . snd) s++ | otherwise+ = Nothing++ +-- | 'getPathUp' takes a 'KSystem' system and a 'Body'. It returns the+-- chain of body's that are orbiting each other. +getPathUp :: KSystem Body -> Body -> [Body]+getPathUp s f+ = func (Just f)+ where+ func (Nothing) = []+ func (Just b) = b : func (getNextUp s b)+ ++-- | 'getDivid' takes a 'KSystem' system and a __from__ 'Body' and a+-- __to__ 'Body'. For both bodys, the path up is calculated by+-- 'getPathUp' and the position, where they reach the same body is+-- returned (as Position and with the actual body).+getDivid :: KSystem Body -> Body -> Body -> (Int, Body)+getDivid s f t+ = ((fst res), (fst . snd $ res))+ where fU = reverse $ getPathUp s f+ tU = reverse $ getPathUp s t+ ftU = zip fU tU+ res = head $ reverse $ filter (\(_,(x1,x2)) -> x1 == x2) $ zip [1..] ftU+++-- | 'sOrbitInSystem' takes a body, a 'KSystem' system and maybe+-- returns the orbit of the body. +sOrbitInSystem :: Body -> KSystem Body -> Maybe (Orbit Body)+sOrbitInSystem b Empty = Nothing+sOrbitInSystem b s@(System sys)+ | (length $ filter ((== b) . snd) sys) > 0+ = Just . fst . head $ (filter ((== b) . snd) sys)++ | (length $ filter ((== b) . snd) sys) == 0+ = firstJust $ map (\x -> (sOrbitInSystem b) . system . celestial . snd $ x) sys++-- | 'pathOBetween' takes a 'KSystem' system and a __from__ 'Body' and a+-- __to__ 'Body'. If one want's to reach the __to__ body from __from__ body+-- the bodys between and their orbit around their centerBody are+-- returnd.+pathOBetween :: KSystem Body -> Body -> Body -> [(Body, (Orbit Body))]+pathOBetween Empty _ _ = []+pathOBetween s f t+ = (zip fU fU') ++ (zip tUR tUR')+ where (fU, d, tUR) = pathBetween' s f t+ fU', tUR' :: [Orbit Body]+ fU' = map (\x -> fromJust $ x `sOrbitInSystem` s) fU+ tUR' = map (\x -> fromJust $ x `sOrbitInSystem` s) tUR+ d' = (\x -> fromJust $ x `sOrbitInSystem` s) d++-- | 'pathOBetween'' takes a 'KSystem' system and a __from__ 'Body'+-- and a __to__ 'Body'. If one want's to reach the __to__ body from+-- __from__ body the bodys between and their orbit around their+-- centerBody are returnd. They are returnd as triple, with the+-- overlapping body in the center of the triple and the path of the+-- __from__ body in the first element of the triple. The path of the+-- __to__ body in the last element of the triple.+pathOBetween' :: KSystem Body -> Body -> Body -> ([(Body, (Orbit Body))], (Body, (Orbit Body)), [(Body, (Orbit Body))])+pathOBetween' s f t+ = ((zip fU fU'), (d,d'), (zip tUR tUR'))+ where (fU, d, tUR) = pathBetween' s f t+ fU', tUR' :: [Orbit Body]+ fU' = map (\x -> fromJust $ x `sOrbitInSystem` s) fU+ tUR' = map (\x -> fromJust $ x `sOrbitInSystem` s) tUR+ d' = (\x -> fromJust $ x `sOrbitInSystem` s) d++-- | 'pathBetween' takes a 'KSystem' system and a __from__ 'Body' and+-- a __to__ 'Body'. If one want's to reach the __to__ body from+-- __from__ body the bodys between are returnd, including the common+-- body.+pathBetween :: KSystem Body -> Body -> Body -> [Body]+pathBetween s f t+ = fU ++ (d:tUR)+ where (fU, d, tUR) = pathBetween' s f t+++-- | 'pathBetween_' takes a 'KSystem' system and a __from__ 'Body' and+-- a __to__ 'Body'. If one want's to reach the __to__ body from+-- __from__ body the bodys between are returnd, without the common+-- body.+pathBetween_ :: KSystem Body -> Body -> Body -> [Body]+pathBetween_ s f t+ = fU ++ tUR+ where (fU, d, tUR) = pathBetween' s f t++ +-- | 'pathBetween' takes a 'KSystem' system and __from__ 'Body' and a+-- __to__ 'Body'. If one want's to reach the __to__ body from __from__+-- body the bodys between and their orbit around their centerBody are+-- returnd. They are returnd as triple, with the overlapping body in+-- the center of the triple and the path of the __from__ body in the+-- first element of the triple. The path of the __to__ body in the+-- last element of the triple.+pathBetween' :: KSystem Body -> Body -> Body -> ([Body], Body, [Body])+pathBetween' s f t+ = (fU, d, (reverse tU))+ where fU = takeUntil (== d) $ getPathUp s f+ tU = takeUntil (== d) $ getPathUp s t+ d = snd $ getDivid s f t ++-- | 'orbitalSpeed' returns the orbital velocity of the given orbit.+orbitalSpeed :: (Orbit Body) -> Speed+orbitalSpeed o = v o (semiMajor o)++-- | 'pathSpeeds' takes the result of 'pathOBetween' and calculates the+-- corresponding orbital speeds.+pathSpeeds :: [(Body, (Orbit Body))] -> [Speed]+pathSpeeds = map (orbitalSpeed . snd)
+ src/System/KSP/Datatype/Body.hs view
@@ -0,0 +1,126 @@+{-|+Module : Body+Description : The Body module contains the type definition of a Body. +License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.Datatype.Body+ ( Body(..)+ , DeltaV+ , Celestial(..)+ , Object(..)+ )+where++import System.KSP.Datatype.Object+import System.KSP.Datatype.System++ --------+-- Body --+ --------++-- | 'DeltaV' is an alias for a 'Double' value.+type DeltaV = Double++-- | The 'Body' type is the central data type within the KSP+-- library. It could be either 'Railed' or 'Movable'+-- +-- * 'Railed' is everything withing ksp that is a star, a planet+-- or a moon. They are static in their orbits and are therefore+-- called railed.+-- +-- * 'Movable' is every other part in ksp, that is physical. Here+-- they include deltaV counter, but are also modelled as celestial+-- objects. Actually in ksp orbits around movable parts arent+-- possible. Anyhow, within this data type such constructs are+-- doable.+data Body+ = Railed { object :: Object, celestial :: Celestial }+ | Movable { object :: Object, celestial :: Celestial, deltaV :: DeltaV }+ -- deriving (Show)++-- | Make 'Body' an instance of Equalty+instance Eq Body where+ (Railed o1 _) == (Railed o2 _) = o1 == o2+ (Movable o1 _ _) == (Movable o2 _ _) = o1 == o2++-- | Make 'Body' an instance of Show+instance Show Body+ where+ showsPrec p (Railed o c)+ = (showString "R/")+ . (showString (name o))+ showsPrec p (Movable o c d)+ = (showString "M/")+ . (showString (name o))+-- instance Show Body+-- where+-- showsPrec p (Railed o c)+-- = ((name o) ++)+-- . (showString ": ")+-- . ((show c) ++)+-- showsPrec p (Movable o c d)+-- = ((name o) ++)+-- . (showString ", dV:")+-- . ((show d) ++)+-- . ((show c) ++)+++ -------------+-- Celestial --+ -------------++-- | The 'Celestial' type defines a celestial object within this+-- library. Every celestial object has+-- +-- * 'r' [m] the radius (from the bodys center) in meter+-- +-- * 'm' [kg] the mass of the object in kilo gramms+-- +-- * 'soi' [m] the /s/phere /o/f /i/nfluence of the object in meter+-- +-- * 'system' empty or a system of surronding objects.+-- +data Celestial+ = Celestial { r :: Double+ , m :: Double+ , soi :: Double+ , system :: System Body Body+ } deriving (Eq, Show)++++-- | Make 'Celestial' an instance of Show+-- instance Show Celestial+-- where+-- showsPrec d (Celestial r m soi Empty)+-- = (showString "r:")+-- . ((show r) ++)+-- . (showString ", ")+-- . (showString "m:")+-- . ((show m) ++)+-- . (showString ", soi:")+-- . (if (soi < (1/0))+-- then ((show soi) ++)+-- else (showString "inf"))+-- showsPrec d (Celestial r m soi (System s))+-- = (showChar '(')+-- . (showString . show $ length s)+-- . (showChar ')')+-- . (showString "r:")+-- . ((show r) ++)+-- . (showString ", ")+-- . (showString "m:")+-- . ((show m) ++)+-- . (showString ", soi:")+-- . (if (soi < (1/0))+-- then ((show soi) ++)+-- else (showString "inf"))+-- where+-- -- fun [] = (showChar '\n')+-- -- fun (x:xs) = (showChar '\n') . (showsPrec d $ snd x) . (fun xs)+ + + +
+ src/System/KSP/Datatype/Object.hs view
@@ -0,0 +1,27 @@+{-|+Module : Object+Description : The Object module contains the type definition of a Object. +License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.Datatype.Object+where++++ ----------+-- Object --+ ----------++-- | An 'Object' is something named.+data Object+ = Object { name :: String }+ deriving (Eq)+++-- | Make 'Object' an instance of 'Show'+instance Show Object+ where+ show = name+
+ src/System/KSP/Datatype/Orbit.hs view
@@ -0,0 +1,75 @@+{-|+Module : Orbit+Description : The "Orbit" module contains the type definition of a 'Orbit'. +License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.Datatype.Orbit+where+++ ---------+-- Orbit --+ ---------++-- | The 'Orbit a' data type defines an orbit around a central body+-- 'centerBody'.+-- +-- * 'centerBody' is the body the orbit is around+-- +-- * 'apoapsis' is the height of the heighest point of the orbit+-- +-- * 'periapsis' is the height of the lowest point of the orbit+-- +-- * 'inclination' is the angle that the orbit is inclined against+-- the aquatorial plane+-- +-- * 'omega_big' is the longitude of the ascending node+-- +-- * 'omega_small' is the argument of the periapsis+data Orbit a+ = Landed+ | O { centerBody :: a+ , apoapsis :: Double+ , periapsis :: Double+ , inclination :: Maybe Double+ , omega_big :: Maybe Double -- Longitude of Ascending Node+ , omega_small :: Maybe Double -- Argument of Periapsis+ }+ deriving (Eq)++-- | The 'Height' is the height above ground level.+type Height = Double++-- | 'mkOrbit' takes a body as well as apoapsis and periapsis and+-- of that creates an orbit.+mkOrbit :: a -> Height -> Height -> Orbit a+mkOrbit b ap per+ = O { centerBody = b+ , apoapsis = ap+ , periapsis = per+ , inclination = Nothing+ , omega_big = Nothing+ , omega_small = Nothing }+ +-- | 'mkCircOrbit' is similar to 'mkOrbit' with the difference that it+-- creates a circular orbit.+mkCircOrbit :: a -> Height -> Orbit a+mkCircOrbit b h = mkOrbit b h h + ++-- | An orbit is only showable if the type of the centerBody is also+-- showable. As @ a @ should normaly be a 'Body' that should be not a+-- problem.+instance (Show a) => Show (Orbit a)+ where+ showsPrec _ Landed = showString "Landed"+ showsPrec _ obt+ = (showString "Around ")+ . (showString $ show . centerBody $ obt)+ . (showString " (")+ . (showString $ show . apoapsis $ obt)+ . (showChar '|')+ . (showString $ show . periapsis $ obt)+ . (showChar ')')
+ src/System/KSP/Datatype/System.hs view
@@ -0,0 +1,37 @@+{-|+Module : System+Description : This module defines a system type.+License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.Datatype.System+where+++import System.KSP.Datatype.Orbit++-- | The "System" module contains the type definition of a 'System'. +data System b a+ = Empty+ | System [(Orbit b, a)]+ deriving (Eq)+++-- | A 'System' could be shown, if both type parameters are also+-- filled with types, that are showable.+instance (Show a, Show b) => Show (System b a)+ where+ showsPrec _ (Empty) = (showString "")+ showsPrec _ (System []) = (showString "")+ showsPrec _ (System (sys:syss))+ = (showString . show . snd $ sys)+ . (showString . show . fst $ sys)+ . (showChar '\n')+ . (showString . show $ (System syss))++-- | Making 'System b' a member of class functor. With this instance,+-- one could use map over 'System b'. +instance Functor (System b) where+ fmap f (System xs) = System $ zip os (fmap f xs')+ where (os, xs') = unzip xs
+ src/System/KSP/Datatypes.hs view
@@ -0,0 +1,34 @@+{-|+Module : Datatypes+Description : Helper module to get data types and functions on them.+License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.Datatypes+ ( Object(..)+ , Celestial(..)+ , Body(..)+ , Orbit(..)+ , mkOrbit+ , mkCircOrbit+ , Height+ , System(..)+ , GravConst+ , KSystem+ , getNextUp+ , getPathUp+ , getDivid+ , sOrbitInSystem+ , pathOBetween+ , pathOBetween'+ , pathBetween_+ , pathBetween'+ , pathSpeeds+ , orbitalSpeed+ )++where++import System.KSP.DataConstructors+import System.KSP.DataDestructors
+ src/System/KSP/KSP.hs view
@@ -0,0 +1,131 @@+{-|+Module : KSP+Description : Kind of the main module. Start the interactive haskell+ session with this module loaded to try things out.+License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental++= Simple Calculation++The folowing should show some basic calculations that can be done+with this library.++== Orbital Velocity++The orbital velocity of something in an 80k orbit around kerbin could+be calculated by:++>>> v_orbKerbin 80e3+2278.9316462467027++The corresponding velocity of a 100k orbit is calculated via:++>>> v_orbKerbin 100e3+2246.1395532335027++== Paths++Paths are always calculated within an existing system. Typically is+such a system the one around kerbol.++>>> let ksp_system = (system . celestial $ kKerbol) :: KSystem Body+>>> :t ksp_system+ksp_system :: KSystem Body++An easy path is the one between mun and minmus, via kerbin. This one+is calculated via:++>>> pathBetween ksp_system kMun kMinmus+[R/Mun,R/Kerbin,R/Minmus]++A much wieder path would be the one between kerbins moon minmus and+jools moon tylo. The path could be calculated via:++>>> pathBetween ksp_system kMinmus kTylo+[R/Minmus,R/Kerbin,R/Kerbol,R/Jool,R/Tylo]++== Paths with Orbits++The function 'pathOBetween' calculates not only the path between two+given bodys. It also calculates the orbit, of each body. For the path+between mun and minmus, the orbits of mun and minmus (each around+kerbin) are also returned.++>>> pathOBetween ksp_system kMun kMinmus+[(R/Mun,Around R/Kerbin (1.14e7|1.14e7)),(R/Minmus,Around R/Kerbin+(4.64e7|4.64e7))]++== Path speeds++To calculate the differences in deltaV between different orbits, do+the following. First calculate the 'pathOBetween', then take that+result and feed it into 'pathSpeeds' to get the orbital speeds along+the path.++>>> let pathMunMinmus = pathOBetween ksp_system kMun kMinmus+>>> pathSpeeds pathMunMinmus+[542.4942415070719,274.11754059162286]++The orbital velocity of the Mun is 542.5 m/s, the one around Minmus is+274.1 m/s.++== Hohmann Transfair++To do a hohmann transfair of a low kerbin orbit (100km) to the orbit+of Mun (47Mm) the following burns must be done.++>>> let o1 = mkCircOrbit kKerbin 100e3+>>> let o2 = mkCircOrbit kKerbin 47000e3+>>> hohmann o1 o2+(907.2791882798308,226.01062520890378)++Lets save these two speeds:++>>> let (v1, v2) = hohmann o1 o2++To calculate the transfair orbit from orbit o1 to orbit o2, the speed+v1 has to be applied within the orbit o1.++>>> burnFromCircOrb o1 v1+Around R/Kerbin (4.7000000000000596e7|100000.0)++Again save that orbit into o12++>>> let o12 = burnFromCircOrb o1 v1++And apply the speed v2 to the transfair orbit o12:++>>> burnAtApoapsis o12 v2+Around R/Kerbin (4.700000000000125e7|4.7000000000000596e7)++Which is the desired, circular orbit, with the height of round 47Mm.++-}+++module System.KSP.KSP+where++import System.KSP.DataConstructors+import System.KSP.DataDestructors+import System.KSP.Universe ++import System.KSP.OrbitalMechanics+++++-- | To calculate the orbital velocity of a circular orbit around+-- kerbin, 'v_orbKerbin' uses 'v_orb' with 'kKerbin' as default+-- parameter.+v_orbKerbin :: Height -> Speed+v_orbKerbin = flip v_orb $ kKerbin++-- | 'v_orb' calculates the velocity within an orbit around 'Body' b,+-- 'Height' h meters above the ground.+v_orb :: Height -> Body -> Speed+v_orb h b+ = v (mkCircOrbit b h) ((r . celestial $ b) + h)++
+ src/System/KSP/OrbitalMechanics.hs view
@@ -0,0 +1,123 @@+{-|+Module : OrbitalMechanics+Description : This module contains basic orbital mechanic functions.+License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.OrbitalMechanics+where++import System.KSP.DataConstructors+++-- | 'Radius' of 'Orbit' at the current Position+type Radius = Double ++-- | 'Speed' is an alias for 'Double'+type Speed = Double+++-- | 'var_G' [Nm^2/kg^2] is the Gravitation constant in newton meter+-- squared over kilo gramms squared+var_G :: GravConst+var_G = 6.674e-11+++-- | 'semiMajor' calculates the semi major axis of an orbit.+semiMajor :: Orbit Body -> Double+semiMajor o+ = 0.5 * ((apoapsis o) + (periapsis o) + (2 * (r . celestial . centerBody $ o)))+++-- | 'v' takes an orbit and a radius (from the center of the+-- centerBody) and calculates the orbital speed at that position.+v :: Orbit Body -> Radius -> Speed+v o radius = sqrt $ mue * ( (2/radius) - (1/(semiMajor o)) ) + where+ mue = var_G * (m . celestial . centerBody $ o)+++-- | 'v_e' calculates the escape velocity of that body.+v_e :: Body -> Speed+v_e b = sqrt $ 2 * mue / (r . celestial $ b) + where+ mue = var_G * (m . celestial $ b)++ +-- | 'burnProgradeFromCircOrb' calculates the transformed orbit, after+-- the supplied delta V is applied to the initial orbit.+-- +-- A prograde burn is done through a positive 'Speed' parameter, a+-- retrograde burn respective through a negative 'Speed'.+burnFromCircOrb :: Orbit Body -> Speed -> Orbit Body+burnFromCircOrb o dV+ = updateOrbit o (periapsis o) ((2 * a_new) - (2 * r_body) - (periapsis o))+ where+ a_new = 1/((2/(semiMajor o))-(((v_circ+dV)^2)/mue))+ r_body = (r . celestial . centerBody $ o)+ m_body = (m . celestial . centerBody $ o)+ v_circ = v o (semiMajor o)+ mue = var_G * m_body++-- | 'updateOrbit' is a function that takes an orbit and two+-- heights. It updates the apoapsis with the bigger height and the+-- periapsis with the smaller.+updateOrbit :: Orbit Body -> Double -> Double -> Orbit Body+updateOrbit o h1 h2+ | h1 > h2+ = o { apoapsis = h1, periapsis = h2 }++ | otherwise+ = o { apoapsis = h2, periapsis = h1 }++-- | 'burnAt' calculates the new orbit after a burn of 'Speed' delta V+-- is applied to the given orbit.+-- +-- * 'f' is the function that calculates returns the distance of+-- the body within orbit, to the center body. Typical this is one+-- of 'apoapsis' or 'periapsis'+-- +-- * 'o' is the initial orbit+-- +-- * 'dV' is the amount of delta V to apply to the orbit. +burnAt :: (Orbit Body -> Double) -> Orbit Body -> Speed -> Orbit Body +burnAt f o dV+ = updateOrbit o (f o) ((2 * a_new) - (2 * r_body) - (f o))+ where+ a_new = 1/( (2/dist_body) - (((v_atPos+dV)^2)/mue) )+ dist_body = (f o) + r_body+ r_body = (r . celestial . centerBody $ o)+ m_body = (m . celestial . centerBody $ o)+ v_atPos = v o dist_body+ mue = var_G * m_body+++-- | 'burnAtPeriapsis' calculates the new orbit after a burn of+-- 'Speed' delta V is applied to the given orbit at the periapsis.+burnAtPeriapsis :: Orbit Body -> Speed -> Orbit Body+burnAtPeriapsis = burnAt periapsis++-- | 'burnAt' calculates the new orbit after a burn of 'Speed' delta V+-- is applied to the given orbit at the apoapsis.+burnAtApoapsis :: Orbit Body -> Speed -> Orbit Body+burnAtApoapsis = burnAt apoapsis+++-- | 'hohmann' takes two orbits around the same centerBody. It+-- calculates both (v1 and v2 ) delta V changes for a hohmann+-- transfair.+hohmann :: Orbit Body -> Orbit Body -> (Double, Double)+hohmann o1 o2+ | centerBody o1 /= centerBody o2+ || o1 == o2+ = (0,0)+hohmann o1 o2+ = ( sqrt(mue/r1) * (sqrt((2*r2)/(r1+r2)) - 1) + , sqrt(mue/r2) * (1 - (sqrt((2*r1)/(r1+r2))))+ )+ where + mue = var_G * (m . celestial . centerBody $ o1)+ r1 = (r . celestial . centerBody $ o1) + (apoapsis o1)+ r2 = (r . celestial . centerBody $ o2) + (apoapsis o2)+
+ src/System/KSP/Universe.hs view
@@ -0,0 +1,274 @@+{-|+Module : Universe+Description : This module contains planets moons and kerbol + as well as the corresponding orbits+License : CC0+Maintainer : frosch03@frosch03.de+Stability : experimental+-}+module System.KSP.Universe+where++import System.KSP.Datatypes++-- | 'kMoho' is the definition of Moho+kMoho+ = Railed (Object "Moho" )+ (Celestial 250e3 2.5263617e21 9646663 Empty)++-- | 'kGilly' is the definition of Gilly+kGilly+ = Railed (Object "Gilly" )+ (Celestial 13e3 1.2420512e17 126123.27 Empty) ++-- | 'kEve' is the definition of Eve+kEve+ = Railed (Object "Eve")+ (Celestial 700e3 1.2244127e23 85109365+ (System [ (kGillyOrbit, kGilly) ])) ++-- | 'kMun' is the definition of Mun+kMun+ = Railed (Object "Mun" )+ (Celestial 200e3 9.7600236e20 2429559.1 Empty)++-- | 'kMinmus' is the definition of Minmus+kMinmus+ = Railed (Object "Minmus")+ (Celestial 60e3 2.6457897e19 2247428.4 Empty)++-- | 'kKerbin' is the definition of Kerbin+kKerbin+ = Railed (Object "Kerbin")+ (Celestial 600e3 5.2915793e22 84159286+ (System [ (kMunOrbit, kMun)+ , (kMinmusOrbit, kMinmus) ]))++-- | 'kIke' is the definition of Ike+kIke+ = Railed (Object "Ike" )+ (Celestial 130e3 2.7821949e20 1049598.9 Empty)++-- | 'kDres' is the definition of Dres+kDres+ = Railed (Object "Dres" )+ (Celestial 138e3 3.2191322e20 32832840 Empty)++-- | 'kDuna' is the definition of Duna+kDuna+ = Railed (Object "Duna" )+ (Celestial 320e3 4.5154812e21 47921949+ (System [ (kIkeOrbit, kIke)+ , (kDresOrbit, kDres) ]))++-- | 'kLaythe' is the definition of Laythe+kLaythe+ = Railed (Object "Laythe")+ (Celestial 500e3 2.9397663e22 3723645.8 Empty)++-- | 'kVall' is the definition of Vall+kVall+ = Railed (Object "Vall" )+ (Celestial 300e3 3.1088028e21 2406401.4 Empty)++-- | 'kTylo' is the definition of Tylo+kTylo+ = Railed (Object "Tylo" )+ (Celestial 600e3 4.2332635e22 10856518 Empty)++-- | 'kBop' is the definition of Bop+kBop+ = Railed (Object "Bop" )+ (Celestial 65e3 3.7261536e19 1221060.9 Empty)++-- | 'kPol' is the definition of Pol+kPol+ = Railed (Object "Pol" )+ (Celestial 44e3 1.0813636e19 1042138.9 Empty)++-- | 'kJool' is the definition of Jool+kJool+ = Railed (Object "Jool" )+ (Celestial 6e6 4.2332635e24 2.4559852e9+ (System [ (kLaytheOrbit, kLaythe)+ , (kVallOrbit, kVall)+ , (kTyloOrbit, kTylo)+ , (kBopOrbit, kBop)+ , (kPolOrbit, kPol) ]))++-- | 'kEeloo' is the definition of Eeloo+kEeloo+ = Railed (Object "Eeloo" )+ (Celestial 210e3 1.1149358e21 1.1908294e8 Empty)++-- | 'kKerbol' is the definition of Kerbol+kKerbol+ = Railed (Object "Kerbol")+ (Celestial 261.6e6 1.7565670e28 (1/0)+ (System [ (kMohoOrbit, kMoho)+ , (kEveOrbit, kEve)+ , (kKerbinOrbit, kKerbin)+ , (kDunaOrbit, kDuna)+ , (kJoolOrbit, kJool)+ , (kEelooOrbit, kEeloo) ]))++++-- | 'kGillyOrbit' is the definition of the Orbit of Gilly+kGillyOrbit+ = O { centerBody = kEve+ , apoapsis = ( 8.825e6 - 700e3)+ , periapsis = (14.175e6 - 700e3)+ , inclination = Just 12+ , omega_big = Just 80+ , omega_small = Just 10 }+ ++-- | 'kMunOrbit' is the definition of the Orbit of Mun+kMunOrbit+ = O { centerBody = kKerbin+ , apoapsis = ( 12e6 - 600e3)+ , periapsis = (12e6 - 600e3)+ , inclination = Nothing+ , omega_big = Nothing+ , omega_small = Nothing }+ ++-- | 'kMinmusOrbit' is the definition of the Orbit of Minmus+kMinmusOrbit+ = O { centerBody = kKerbin+ , apoapsis = ( 47e6 - 600e3)+ , periapsis = (47e6 - 600e3)+ , inclination = Just 6+ , omega_big = Just 78+ , omega_small = Just 38 }+ ++-- | 'kIkeOrbit' is the definition of the Orbit of Ike+kIkeOrbit+ = O { centerBody = kDuna+ , apoapsis = ( 3.296e6 - 320e3)+ , periapsis = (3.104e6 - 320e3)+ , inclination = Just 0.03+ , omega_big = Nothing+ , omega_small = Nothing }+ ++-- | 'kLaytheOrbit' is the definition of the Orbit of Laythe+kLaytheOrbit+ = O { centerBody = kJool+ , apoapsis = ( 27.184e6 - 6e6)+ , periapsis = ( 27.184e6 - 6e6)+ , inclination = Nothing+ , omega_big = Nothing+ , omega_small = Nothing }+ ++-- | 'kVallOrbit' is the definition of the Orbit of Vall+kVallOrbit+ = O { centerBody = kJool+ , apoapsis = ( 43.152e6 - 6e6)+ , periapsis = ( 43.152e6 - 6e6)+ , inclination = Nothing+ , omega_big = Nothing+ , omega_small = Nothing }+ ++-- | 'kTyloOrbit' is the definition of the Orbit of Tylo+kTyloOrbit+ = O { centerBody = kJool+ , apoapsis = ( 68.5e6 - 6e6)+ , periapsis = ( 68.5e6 - 6e6)+ , inclination = Just 0.025+ , omega_big = Nothing+ , omega_small = Nothing }+ ++-- | 'kBopOrbit' is the definition of the Orbit of Bop+kBopOrbit+ = O { centerBody = kJool+ , apoapsis = (158.6975e6 - 6e6)+ , periapsis = ( 98.3025e6 - 6e6)+ , inclination = Just 15+ , omega_big = Just 10+ , omega_small = Just 25 }+ ++-- | 'kPolOrbit' is the definition of the Orbit of Pol+kPolOrbit+ = O { centerBody = kJool+ , apoapsis = (210.624206e6 - 6e6)+ , periapsis = (149.155794e6 - 6e6)+ , inclination = Just 4.25+ , omega_big = Just 2+ , omega_small = Just 15 }+ ++-- | 'kMohoOrbit' is the definition of the Orbit of Moho+kMohoOrbit+ = O { centerBody = kKerbol+ , apoapsis = ( 6315765980 -261.6e6)+ , periapsis = ( 4210510628 -261.6e6)+ , inclination = Just 7+ , omega_big = Just 70+ , omega_small = Just 15 }+ ++-- | 'kEveOrbit' is the definition of the Orbit of Eve+kEveOrbit+ = O { centerBody = kKerbol+ , apoapsis = ( 9931011387 -261.6e6)+ , periapsis = ( 9734357701 -261.6e6)+ , inclination = Just 2.1+ , omega_big = Just 15+ , omega_small = Nothing }+ ++-- | 'kKerbinOrbit' is the definition of the Orbit of Kerbin+kKerbinOrbit+ = O { centerBody = kKerbol+ , apoapsis = ( 13599840256 -261.6e6)+ , periapsis = (13599840256 -261.6e6)+ , inclination = Nothing+ , omega_big = Nothing+ , omega_small = Nothing }+ ++-- | 'kDunaOrbit' is the definition of the Orbit of Duna+kDunaOrbit+ = O { centerBody = kKerbol+ , apoapsis = ( 21783189163 -261.6e6)+ , periapsis = (19669121365 -261.6e6)+ , inclination = Just 0.06+ , omega_big = Just 135.5+ , omega_small = Nothing }+ ++-- | 'kDresOrbit' is the definition of the Orbit of Dres+kDresOrbit+ = O { centerBody = kKerbol+ , apoapsis = ( 46761053522 -261.6e6)+ , periapsis = (34917642884 -261.6e6)+ , inclination = Just 5+ , omega_big = Just 280+ , omega_small = Just 90 }+ ++-- | 'kJoolOrbit' is the definition of the Orbit of Jool+kJoolOrbit+ = O { centerBody = kKerbol+ , apoapsis = ( 72212238387 -261.6e6)+ , periapsis = (65334882253 -261.6e6)+ , inclination = Just 1.302+ , omega_big = Just 52+ , omega_small = Nothing }+ ++-- | 'kEelooOrbit' is the definition of the Orbit of Eeloo+kEelooOrbit+ = O { centerBody = kKerbol+ , apoapsis = (113549713200 -261.6e6)+ , periapsis = (66687926800 -261.6e6)+ , inclination = Just 6.15+ , omega_big = Just 50+ , omega_small = Just 260 }