{"id":24841586,"url":"https://github.com/daniilgalahov/celnav","last_synced_at":"2026-05-27T21:31:59.069Z","repository":{"id":273889471,"uuid":"919433895","full_name":"DaniilGalahov/celnav","owner":"DaniilGalahov","description":"Celestial navigation algorithms library","archived":false,"fork":false,"pushed_at":"2026-03-05T18:46:05.000Z","size":543,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-03-05T21:34:37.266Z","etag":null,"topics":["astronomical-algorithms","astronomy","celestial-navigation","geolocation","geomatics","navigation"],"latest_commit_sha":null,"homepage":"https://www.nibrasgamestudio.com/2025/01/22/celnav/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DaniilGalahov.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-20T11:36:13.000Z","updated_at":"2026-03-05T18:42:34.000Z","dependencies_parsed_at":"2025-01-23T15:46:25.363Z","dependency_job_id":null,"html_url":"https://github.com/DaniilGalahov/celnav","commit_stats":null,"previous_names":["daniilgalahov/celnav"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/DaniilGalahov/celnav","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilGalahov%2Fcelnav","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilGalahov%2Fcelnav/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilGalahov%2Fcelnav/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilGalahov%2Fcelnav/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DaniilGalahov","download_url":"https://codeload.github.com/DaniilGalahov/celnav/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaniilGalahov%2Fcelnav/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33585203,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["astronomical-algorithms","astronomy","celestial-navigation","geolocation","geomatics","navigation"],"created_at":"2025-01-31T07:18:56.430Z","updated_at":"2026-05-27T21:31:59.044Z","avatar_url":"https://github.com/DaniilGalahov.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Celestial navigation algorithms library\n![celnav logo by Amiko Panda](https://www.nibrasgamestudio.com/wp-content/uploads/2025/01/CelNavLogo_low.png)\n\n## Purpose\n**celnav** is a library contains a set of algorithms for solving typical [astronavigational](https://en.wikipedia.org/wiki/Celestial_navigation) and navigational tasks, especially:\n - Observer position fix using observed position of **celestial** objects.\n - Observer position fix using observed position of **known** objects (via triangulation or trilateration).\n - Orthodromy and great circle route waypoints calculation.\n - Required heading at current waypoint calculation.\n - True heading and magnetic compass correction calculation using observed positions of **celestial** objects.\n - True heading and magnetic compass correction calculation using observed positions of  **known** objects.\n - Solving navigational triangle problem.\n\n## Main features\n - **minimum external dependencies** - the only thing you utterly need is NumPy. System requires 3 other packages, but they are optional.\n - **offline and standalone** - library has its own \"astronomy engine\", so you would not face a need to download ephemerides somewhere in the middle of North Atlantic.\n - **precision** - [CEP](https://en.wikipedia.org/wiki/Circular_error_probable) of position fix via stars - about 1/5 nmi in autonomous mode and about 1/10 nmi (~180 m) with AstroPy ephemeris. *(Not something extra… But this is not for to-the-door pizza delivery!)*\n - **simplicity** - code kept as simple as possible on purpose. No advanced programming techniques - just plain functions and math.\n - **universal** - all essential functions included\n - **lightweight** - 228 Kb of code.\n - **solid** - over 95% of code covered with unit tests\n\n## Detailed description\n\n### Algorithms\n\n**celnav** includes algorithms for:\n - determination of current GMT from local time\n - sight reduction (different than sight reduction algorithm of Sumner and [Bowditch](https://thenauticalalmanac.com/2019_Bowditch-_American_Practical_Navigator.html))\n - position fix (using 2 or 3 sight reductions)\n - 3 points 3 angles position fix (using [Tienstra](https://en.wikipedia.org/wiki/Tienstra_formula) method)\n - 3 points 3 ranges position fix (using modified trilateration algorithm from this [article](https://www.ajol.info/index.php/tjs/article/view/212601))\n - orthodromy calculation (based on information from Wikipedia [article](https://en.wikipedia.org/wiki/Great-circle_navigation))\n - ortodromy waypoint \u0026 heading calculation\n - true heading and magnetic deviation (compass correction) calculation via angular coordinates of celestial objects\n - true heading and magnetic deviation (compass correction) calculation via angular coordinates of known surface objects\n - DR (\"dead reckoning\") calculation through solving navigation triangle problem\n\n***IMPORTANT!*** *3P3A fix, 3P3R fix and DR calculation are not counting Earth oblateness, using spherical (geocentric) Earth model. In long ranges they can produce errors! I will fix this in later releases.*\n\n### Astronomical data sources\n\n**celnav** provided with two sources of astronomical information:\n- [AstroPy](https://www.astropy.org/)\n- local and standalone \"astronomical engine\", utilizing algorithms from \"[*Fundamentals of Astrodynamics and Applications, Fourth Edition*](http://celestrak.org/software/vallado-sw.php)\" by **David Vallado** and \"_Astronomical Algorithms_ (1998), 2nd ed.\" by [Jean Meeus](https://en.wikipedia.org/wiki/Jean_Meeus).\n\nYou can choose \"engine\", switching it in [config.ini](src/config.ini). See [below](#Choosing-astronomical-data-source) (or follow comments in this file) for additional info.\n\nAstroPy provides more precise sight reduction, but will require downloading of ephemeris, which can be inconvenient in case if you have no internet connection.\n\nLocal \"almanac engine\" is standalone. Using it system does not need internet connection, but provide slightly less precision.\n\n### Celestial bodies for sight reduction\n**celnav** can operate with all celestial bodies mentioned in [Nautical Almanac](https://www.thenauticalalmanac.com/). This includes:\n- Sun\n\nNavigation planets, i.e.,\n- Venus\n- Mars\n- Jupiter\n- Saturn\n\n59 navigation stars, includes:\n - Acamar\n - Achernar \n - Acrux \n - Adhara \n - Albireo \n - Aldebaran\n - Alioth\n - Alkaid\n - Al Na-ir\n - Alnilam\n - Alphard\n - Alphecca\n - Alpheratz\n - Altair\n - Ankaa\n - Antares\n - Arcturus\n - Atria\n - Avior\n - Bellatrix\n - Betelgeuse\n - Canopus\n - Capella\n - Castor\n - Deneb\n - Denebola\n - Diphda\n - Dubhe\n - Elnath\n - Eltanin\n - Enif\n - Fomalhaut\n - Gacrux\n - Gienah\n - Hadar\n - Hamal\n - Kochab\n - Markab\n - Menkar\n - Menkent\n - Miaplacidus\n - Mirfak\n - Nunki\n - Peacock\n - Polaris\n - Pollux\n - Procyon\n - Rasalhague\n - Regulus\n - Rigel\n - Sabik\n - Schedar\n - Shaula\n - Sirius\n - Spica\n - Suhail\n - Vega\n - Zuben-ubi\n\nAlso, system supporting sight reduction for the Moon. \n\n***IMPORTANT!*** *Because of very complex motion of the Moon, local almanac provides it's position not-so-precise. I am not recommend to use it for Moon sight reduction for practical purposes. With the time, I'll fix this by implementation of more precise Moon motion model.*\n\n## Usage\n### Installation\n#### Requirements\n- Python\u003e=3.7\n- Internet connection (**optional**, for downloading updated astronomical data).\n\n#### Dependencies\n- [numpy](https://pypi.org/project/numpy/)\u003e=1.2\n- [astropy](https://pypi.org/project/astropy/)\u003e=5.0\n- [requests](https://pypi.org/project/requests/)\u003e=2.0\n- [setuptools](https://pypi.org/project/setuptools/)\u003e=65.0\n\n*Modern Python suffers from heavy dependency hell, which nowadays looks more not like a dependency but as an addiction. To avoid this, I tried to reduce number of dependencies as hard as possible.*\n\n#### Setup\n1. Clone (or download and extract) this repo into local folder.\n2. In local repository folder open console and execute command:\n```\npython -m pip install -e .\n```\n(or if you are using Windows, you can just run [install.bat](install.bat) in the root of the repo).\n\n3. Done.\n\n### Updating astronomical catalog\nUp-to-date astronomical catalog provided with this repo in [src/data/catalog.dat](src/data/catalog.dat). Normally, **you should not touch it**. If you need to refresh it, you can run [src/catalog.py](src/catalog.py) in your repo. Follow instructions of the app - system will connect to online astronomical catalog and download all required data.\n\n***IMPORTANT!*** *You need internet connection for this operation.*\n\n### Choosing astronomical data source\nAs I mentioned earlier system can use as data source AstroPy or local \"astronomical almanac\". AstroPy require internet but provide better precision, local almanac is offline, but less precise. You may switch data source whenever you want.\nTo switch data source, open [src/config.ini](src/config.ini) and change value of parameter *AlmanacEngine* to\n- ```AlmanacEngine=0``` (for AstroPy)\n- ```AlmanacEngine=1``` (for local almanac, default value)\n\n### Importing\nJust add import instruction in the head of your file, like this:\n``` \nimport celnav \n```\nAnd you're done!\n\n### Functions\n---\n#### AngleToDecimal(string)\nConverting string with geographical coordinates, like \"**E100°36.31'**\" to decimal degrees.\n```\nphi=celnav.AngleToDecimal(\"N13°55.28'\") #latitude of Bangkok\n\n# phi == 13.921333333333333\n```\n---\n#### LTToGMT(Y, M, D, h, m, s, lambdaAP)\nConverts local time to GMT, depending on current longitude.\n```\nY,M,D,h,m,s=(2025,1,20,12,0,0) #local time of Bangkok (GMT+7)\nlambda_=celnav.AngleToDecimal(\"E100°36.31'\") #longitude of Bangkok\nY,M,D,h,m,s=celnav.LTToGMT(Y,M,D,h,m,s,lambda_)\n\n# Y,M,D,h,m,s == (2025 1 20 5 0 1.341104507446289e-05) #GMT\n```\n---\n#### SightReduction(phiAP, lambdaAP, Y, M, D, h, m, s, celestialObjectName, el, indexCorrection=0, hoe=0, T=10, P=1010.0, limb=0)\nCalculate sight reduction from assumed position, date and parameters of sighted celestial object. Getting in count all corrections you need to do for precise measurement.\n```\nphiAP=33.0 \t\t\t#latitude of assumed position\nlambdaAP=-117.0 \t#longitude of assumed position\n\nY=2024 \t#year\nM=4 \t \t#month\nD=12\t\t#day\nh=16\t\t#hour, GMT\nm=0\t\t\t#minute\ns=0\t\t\t#second\n\ncelestialObjectName=\"Sun\"\n\nel=32.394512\t#elevation of sighted celestial object over horizon\n\nIC=0\t\t\t#index correction of sextan\nhoe=20\t\t\t#height of an eye, m.\nT=15.0\t\t\t#environment temperature, degrees Celsius\nP=1013.25 \t\t#environment pressure, millibars\nlimb=-1\t\t\t#limb we choosing (Like in Bowditch \"-1\": for Sun and Moon, \"0\" for stars and planets)\n\na,Z=celnav.SightReduction(phiAP, lambdaAP, Y, M, D, h, m, s, celestialObjectName, el, IC, hoe, T, P, limb)\n\n#a,Z == (0.1809029519340868 -100.92368252258527)\n```\n---\n#### TwoObjectFix(phiAP, lambdaAP, a1, Z1, a2, Z2)\nCalculating position from AP (assumed position) and results of 2 sight reductions.\n```\nphiAP=33.0\nlambdaAP=-117.0\n\na1=-0.25997911530550155\nZ1=-151.72526130264336\n\na2=-0.3220529491543829 \nZ2=-166.80424087813753\n\nphi,lambda_=celnav.TwoObjectFix(phiAP,lambdaAP,a1,Z1,a2,Z2)\n\n#phi,lambda_ == (33.358288093 -116.859574639)\n#observation point is Palomar observatory, with phi0,lambda0 == (33.3562811,-116.8651156)\n#i.e., error=533.32 m.\n```\n---\n#### ThreeObjectFix(phiAP, lambdaAP, a1, Z1, a2, Z2, a3, Z3)\nCalculating position from AP (assumed position) and results of 3 sight reductions.\n```\nphiAP=33.0\nlambdaAP=-117.0\n\na1=-0.22178062985341995\nZ1=-143.8725861697037\n\na2=-0.29762793886806804 \nZ2=-160.01234344989314\n\na3=-0.35566029746129857\nZ3=-178.50219034779053\n\nphi,lambda_=celnav.ThreeObjectFix(phiAP,lambdaAP,a1,Z1,a2,Z2,a3,Z3)\n\n#phi,lambda_ == (33.358716255 -116.861853266)\n#observation point is Palomar observatory, with phi0,lambda0 == (33.3562811,-116.8651156)\n#now error=401.10 m.\n```\n---\n#### ThreeAnglesFix(phi1, lambda1, phi2, lambda2, phi3, lambda3, alpha12, alpha23, alpha31)\nDetermine position from 3 known points on surface and angles between them. Implemented Tienstra method.\n***IMPORTANT!*** *Angles named this way on purpose. Alpha12 means angle BETWEEN p1 and p2 (not an azimuth from North) and so on.*\n```\nphi1=51.0731459 #Grand Mosque\nlambda1=71.410925\nphi2=51.1256397 #Harzat Sultan Mosque\nlambda2=71.4724698\nphi3=51.1090188 #Barys Arena\nlambda3=71.3953671\n\nalpha12=96.6\nalpha23=144+83.4\nalpha31=36\n\nphi,lambda_=celnav.ThreeAnglesFix(phi1,lambda1,phi2,lambda2,phi3,lambda3,alpha12,alpha23,alpha31)\n\n#phi,lambda_ == (51.134704256 71.432621797)\n#observation point was Baiterek tower, Astana, with phi0,lambda0 == (51.1282921,71.4305781)\n#error is about 726 m.\n```\n---\n#### ThreeRangesFix(phi1, lambda1, phi2, lambda2, phi3, lambda3, r1, r2, r3)\nDetermine position from 3 known points on surface and ranges towards them. Trilateration.\n***IMPORTANT!*** *Ranges ALWAYS in KILOMETERS!*\n```\nphi1=51.0731459 #Grand Mosque\nlambda1=71.410925\nphi2=51.1256397 #Harzat Sultan Mosque\nlambda2=71.4724698\nphi3=51.1090188 #Barys Arena\nlambda3=71.3953671\n\nr1=6.31 #km;\nr2=2.97\nr3=3.25\n\nphi,lambda_=celnav.ThreeRangesFix(phi1,lambda1,phi2,lambda2,phi3,lambda3,r1,r2,r3)\n\n#phi,lambda_ == (51.136092319 71.430788396)\n#observation point was Baiterek tower, Astana, with phi0,lambda0 == (51.1282921,71.4305781)\n#error is about 873 m.\n```\nAs you can see, 3P3A and 3P3R fixes are not so precise in short ranges. For better precision you should use points on longer distances spread more equally.\n\n---\n#### Orthodromy(phi1, lambda1, phi2, lambda2)\nCalculating orthodromy, returning heading at start, heading at destination, degrees of arc of great circle and distance in kilometers.\n```\nphi1=59.7986813 \t\t#Pulkovo airport\nlambda1=30.2689333\nphi2=51.0257228 \t\t#Astana airport\nlambda2=71.4493939\n\nalpha1,alpha2,delta12,s12=celnav.Orthodromy(phi1,lambda1,phi2,lambda2)\n\n#alpha1 == 92.4963366599314 \t\t#HDG at start\n#alpha2 == 126.96312067753773\t\t#HDG at destination\n#delta12 == 24.489647649865553\t\t#degrees of arc of GC between points\n#s12== 2726.1751060897222\t\t\t#actual distance between points, km\n```\n---\n#### HeadingAtWaypoint(phi1, lambda1, alpha1, d)\nCalculating coordinates of waypoint on the orthodromy and heading at it, if orthodromy starting at [*phi1, lambda1*], with heading *alpha1*, and waypoint is placed on distance *d*.\n```\nphi1=59.7986813 \t\t#Pulkovo airport\nlambda1=30.2689333\nalpha1=92.4963366599314 \t#exact heading to Astana, from prev. example\nd=2726.1751060897222 \t\t#exact distance to Astana, from prev. example\n\nphi2,lambda2,alpha2=celnav.HeadingAtWaypoint(phi1,lambda1,alpha1,d)\n\n#phi2 == 51.0257228 \t\t\t#Astana airport latitude\n#lambda2== 71.4493939 \t\t\t#Astana airport longitude\n#alpha2 == 126.96312067753773 \t#Arrival direction to airport\n```\n---\n#### CompassCorrectionCOZ(magHdg, phi, lambda_, Y, M, D, h, m, s, celestialObjectName, celestialObjectAz)\nCalculating current true heading and compass correction from current magnetic heading and parameters of observed celestial object.\n***IMPORTANT!*** *celestialObjectAz here is RAW MAGNETIC azimuth, straightly read from compass.*\n```\nmagHdg=0.0\n\nphi=51.1282921 #Baiterek, Astana\nlambda_=71.4305781\n\nY=2025\nM=1\nD=17\nh=6 #UTC\nm=0\ns=0\n\ncelestialObjectName=\"Sun\"\ncelestialObjectAz=149.421395 \t#RAW azimuth to celestial object from MAGNETIC COMPASS\n\ntrueHdg,corr=celnav.CompassCorrectionCOZ(magHdg,phi,lambda_,Y,M,D,h,m,s,celestialObjectName,celestialObjectAz)\n\n#trueHdg,corr == (10.517144451964327 10.517144451964327)\n#magnetic deviation in Astana at January 2025 equals -10.1\n```\n---\n#### CompassCorrectionPOZ(magHdg, phiPos, lambdaPos, phiObj, lambdaObj, azObj)\nCalculating current true heading and compass correction from position of known object and magnetic azimuth to it.\n***IMPORTANT!*** *Same as above, azObj here is RAW MAGNETIC azimuth, straightly read from compass.*\n```\nmagHdg=0.0\n\nphiPos=51.1282921 #Baiterek, Astana\nlambdaPos=71.4305781\nphiObj=51.0731459 #Grand Mosque\nlambdaObj=71.410925\n\nazObj=360.0-166.8\n\ntrueHdg,corr=celnav.CompassCorrectionPOZ(magHdg,phiPos,lambdaPos,phiObj,lambdaObj,azObj)\n\n#trueHdg,corr == (6.415140248887724 6.415140248887724)\n#magnetic deviation in Astana at January 2025 equals -10.1. \n#Not so precise as with celestial objects, but if there is no other way...\n```\n---\n#### DeadReckoning(phi0, lambda0, V, Vdir, D, Ddir, dt)\nCalculating DR point from velocity, drift and time.\n```\nphi0=0    \t\t#initial position latitude\nlambda0=0\t\t#initial position longitude\n\nV=110*1.852\t\t#speed, km/h\nVhdg=90\t\t\t#flight direction\n\nD=10*1.852\t\t#drift, km/h\nDhdg=90\t\t\t#drift direction\n\ndt=0.5\t\t\t#time of flight, h\n\nphi1,lambda1=celnav.DeadReckoning(phi0,lambda0,V,Vhdg,D,Dhdg,dt)\n\n#phi1,lambda1 == (0.0, 1.0)\n```\n## Further improvements\n1. Precise ephemeris for Moon, Mars, Saturn, Sun\n2. Improvement precision of 3P3A fix, 3P3R fix and DR calculation.\n3. Additional methods of position fix.\n4. Improvements for usage on other planets of Solar System (Moon, Mars, Jupiter satellites).\n\n## Feedback and questions\nFeel free to ask me through PM if you have any questions or offers.\n\n## Practical usage notice\nTHIS IS EDUCATIONAL PROJECT. PRECISE CALCULATIONS AND ALGORITHMS ARE IMPLEMENTED BUT **CELNAV** NEVER BEEN TESTED ENOUGH IN PRACTICE.\n\nBEFORE PRACTICAL APPLICATION CHECK RESULTS MULTIPLE TIMES IN SAFETY ENVIRONMENT.\n\n## Disclaimer\nThe \"**celnav**\" Python library is provided on an \"AS IS\" and \"AS AVAILABLE\" basis, without any warranties or representations, express or implied. To the fullest extent permissible under applicable law, the author disclaims all warranties, express or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose, and non-infringement.\n\nThe author does not warrant that the functions contained in the library will meet your requirements, that the operation of the library will be uninterrupted or error-free, or that any defects in the library will be corrected. No oral or written information or advice given by the author shall create a warranty.\n\nIn no event shall the author be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.\n\nThe user assumes all responsibility for any damages resulting from the use of the \"celnav\" library, including, but not limited to, errors or inaccuracies in the data produced, misuse of the library, or any harm that may occur in reliance on its functionality. This includes any incidents leading to personal injury, death, or significant physical or environmental damage.\n\nBy using the \"**celnav**\" library, you acknowledge that you have read this disclaimer and agree to its terms.\n\n## Legal notice\nThis software is distributing under MIT license with Attribution Clause. You may read it in file [LICENSE.md](LICENSE.md)\n\nArtwork of **celnav** official logo was made by sci-fi digital artist [Anna Apalkova (Amiko Panda)](https://www.instagram.com/_amiko.panda_/). Used and published with all required permissions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniilgalahov%2Fcelnav","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaniilgalahov%2Fcelnav","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniilgalahov%2Fcelnav/lists"}