Skip to content

Latest commit

 

History

History
executable file
·
488 lines (390 loc) · 16.1 KB

File metadata and controls

executable file
·
488 lines (390 loc) · 16.1 KB

Notes pre2025

Software architecture

classless solar system data objects

  • contain physical characteristics of solar system objects

class AnimatedSpaceObject

  • any kind of objects that is in space
  • has attributes:
    • object3d: its three.js object3d added to the scene
    • initAnimation(newDate) for initialization
    • animate(msecTimestamp) for animation

class PlanetArtist:

  • handles artistic aspect of planet itself (sphere, color, etc...)

idea:

  • separate orbital positions components of:
    • plane the orbiter is on relative to orbital system and...
    • path orbiter is following on that plane (circular, ecliptic, other...) -> allows for better separation of circular/elliptic and tilted/not tilted -> how to do it?
    • Orbit abstract class, with children CircularOrbit and EllipticOrbit: defines x,y position relative to center
    • OrbitPlane class: basically an object3d, that may or may not be tilted (actually) idea bis:
  • get rid of Orbiter classes and rename PlanetArtist Planet:
    • Orbit and Planet take an object3d in constructor + their required metadata
    • Both modify only the object3d data relevant to their role (Orbit: x,z positions; Planet: sphere & appearance)

Todolist:

  • DONE 1) create elliptic orbit with constant orbital speed, sun center-centered
  • DONE 2) sun in 1 of the 2 focal point
  • DONE 3) ellipse correctly oriented
  • DONE 4) tilted elliptic orbits
  • DONE 5) orbital speed is keplerian speed
  • DONE 6) create KeplerOrbit object
  • DONE 7) add meanAnomaly
  • DONE 8) OrbitalSystem
  • DONE 9) better separation of animation&position calculation
    • position calculation (from given date or interval) in a set of functions?
    • adding "listeners" (=?orbiters) called as part of animation?
    • shared position Vector3D?
    • not having intermediary object3ds? but only a global shared position vector?
    • challenges with computeState() approach:
      • Orbit/spaceObject do not only compute positions, but also rotations and scale
      • why do we need a "plane" object3d for KeplerOrbits? -> because rotations are in object3d's local world: rotating them fucks their x/y positioning
      • we want children object3ds to have proper rotations/orientation as well as positions (typically: CircularOrbit rotates instead of setting position) -> DONE a) set a initDate and currentTimestamp property for Orbits -> initTimestamp from data!! -> DONE FOR ELLIPTIC b) currently: initAnimation() is never used -> sets currentTimestamp & updates positions according to it -> DONE c) create Orbit's "mobile" object3d -> computeState() computes the mobile new position, by default by making a kopy with an option to updates its properties' instead -> animate() calls computeState() with mobile update -> DONE d) computeState(): -> using a Date or an interval from currentTimestamp -> doesn't update any state variable -> DONE e) animate() and initAnimation() use computeState()
  • DONE 10) .computeState() improvement:
    • re-separate computeStateAtDate from computeState? -> it is weird to mix dates & interval in same function -> what does computeState() needs to compute Orbit?
      • intervalTimestamp, posOnOrbit (=x&y), and THAT'S ALL! -> makes sense to do only this computation in computeState() -> returns posOnOrbit and vector3
    • DONE a) new architecture:
      • computeState() takes a posOnOrbit and interval timeStamp -> computes all from it
      • animate calls computeState for new pos & then updates state
    1. A single file per Orbit in Orbit.js: Orbit, CircularOrbit, EllipticOrbit, KeplerOrbit, Planes
    1. Orbit getPoint(), getPoints(), getPointAt(), getPointsAt(), , getPointAtDate()

low priority: gravitational:

general:

  • X) set date/speed using variable UI modifiers
  • X) light source: sun
  • X) planet imaged texture
  • X) open wikipedia widget on click descriptive solar system
  • X) CircularOrbit.computeState()
  • X) OrbitArtist class:
    • disappearing&static orbits
    • DONE distance to ecliptic markers
    • different shades depending on above/below on ecliptic
    • Orbit.showPath() takes an OrbitArtist argument (default to the simplest static orbit)
  • X) Fix Orbit and Artist weaknesses:
    • fromOrbiterData() center Argument

Separation of position calculations & three.js object3ds to put in the scene

discussion:

  • separation is desirable for:
    • compute positions without any three.js overhead
  • separation not desirable for:
    • on the three.js side, it doesn't make sense to separate: the tiltedOrbitalPlane of a KeplerOrbit is essential to the proper positioning of a planetArtist (orientation of planet rotational tilt/etc...)

current:

  • object3ds (both orbit&artist) are all clumsily gathered in the planet's data object literal -> no proper separation!
  • proposal: -> the OrbitalSystem creates an object that gathers the object's data, artist & orbit -> simply put everything in that object

Software architecture for Newtonian gravitation

A gravitationally affected body needs properties:

  • mass
  • position
  • speed A gravitational system needs:
  • a list of bodies
  • ...what else?

Needs:

  • good optimization:
    • avoid duplication
    • efficient code (call-stack)
  • precision:
    • resists to different animation step deltaT interval
  • separation of visual&computational part

Proposition:

  • NewtonianBody class -> mass, position, speed, acceleration, force properties -> only a data-repository for computations!
  • GravitationalSystem -> bodies property: list of NB -> reimplements computeState(), computeStateAtDate() -> computes positions/speeds/accelerations/forces only, no three.js!
  • AnimatedNewtonianBody class extends ASOG -> takes a NB property -> unifies ANB.object3d.position = NB.position -> reimplements initAnimation(), animate()
  • AnimatedGravitationalSystem class extends ASOG -> bodies property=children = list of ANB -> creates a GS from the ANBs' NBs -> reimplements initAnimation(), animate() -> calling GS.computeState() / GS.computeStateAtDate()

Computational/Precision optimization:

  • add cache: CachingGraviationalSystem -> has a dict of dates -> NB -> has a caching step arguments -> caches at every caching step -> computes in between caching steps
  • precision next order derivations:
    • compute instantaneous acceleration -> add acceleration to speed, and speed to position using smaller deltaTs

DEBUGGING

  • earth revolves around sun in a matter of days -> probably handling time/forces computation wrong somewhere

Relevant space units

distance:

  • AU, astronomical unit = avg earth-sun distance = 1.495978707×10^11 m -> within solar system measurement
  • parsecm = 3.08567758149137×10^16 m = 648000/pi AU -> astronomy/astrophysics measurement unit

time:

  • J2000 12h on 1 January 2000

orbit:

  • periapsis: closest point in orbit to primary body (peri=close) (periphelion = periapsis when primary=sun)
  • apoapsis: furthest point in orbit to primary body (ap=far) (aphelion = apoapsis when primary=sun)
  • Argument of periapsis (- semi-major-axis: half of segment going through peri- and a-phelion)
  • mean anomaly: fraction of elliptical orbit elapsed since last periapsis at given time -> useful to determine orbital starting point!
  • orbital eccentricity: determines shape of ellipse
  • inclination

position

mass

Useful links:

https://github.com/orbitalindex/awesome-space#astronomy-apis

best introduction to Keplerian orbits: https://en.wikipedia.org/wiki/Orbital_elements

website dowing the same: http://planetoweb.net/app/

stylish orbital simulator: https://github.com/TheHappyKoala/Harmony-of-the-Spheres

Planetary satellites: https://ssd.jpl.nasa.gov/?sat_elem#legend

JPL Horizon API (hard to use) https://ssd.jpl.nasa.gov/horizons.cgi

nasa spice: https://naif.jpl.nasa.gov/naif/

Astroquery, python package for querying astronomical datasets: https://astroquery.readthedocs.io/en/latest/

other web service: https://minorplanetcenter.net//web_service

for earth satellites: http://celestrak.com/NORAD/elements/

Incredible planet visualiser, with terrain pictures and exagerable height maps: http://planetmaker.wthr.us/#

http://podgorskiy.com/KeplerOrbits/KeplerOrbits.html

Notes 2025

todolist

  • DONE switch to ts
  • fix NewtonianBody GravitationalSystem
    • Animation bug when leaving window
    • divergence from KeplerOrbit
  • DONE improve software architecture
    • more flexible time handling
    • DONE clear separation of computation and artistry

switch to TypeScript

following https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html

Improved Software architecture

Current signatures

core:

  • Animated initAnimation() animate() <- MOST IMPORTANTE used by global animate() doing the animation!
  • AnimatedSpaceObject (ASO) extends Animated object3d
  • AnimatedSpaceObjectsGroup (ASOG) extends AnimatedSpaceObject
    • mobile (=this.object3d? why?)
    • children: ASO[]

descriptive:

  • AbstractOrbit (AO) extends ASOG data: initDate currentSimulTimestamp pathObject3d UNUSED computeState() <- MOST IMPORTANTE computeStateAtDate()
  • CircularOrbit computeState() <- not implemented -> uses simple constant speed across circle, very
  • EllipticOrbit lastAnimateTimestamp currentPosOnOrbit _initPosOnOrbit -> nothing to ordinary, pretty fine

Current folder organization

  • core/
    • minimal
  • data/
  • descriptive/
    • AbstractOrbit
    • CircularOrbit
    • EllipticOrbit
    • KeplerOrbit and System
    • OrbitArtist
  • newtonian/
    • GravitationalSystem
    • NewtonianBody

proposition:

  • new artist/ folder with artistry stuff

Goals:

  • DONE clear separation of computation and artistry
  • DONE clear folder structure
  • metadata flowing freely between parts

Proposition:

Orbits

  • remove the AnimatedSpaceObjectsGroup (ASOG) inheritance and animate() method
  • removes currentPosition and currentTimestamp properties
  • computes position, orientation (and velocity, optional)
  • NONO is a "XxxSpaceObjectsGroup" and can compute positions for multiple objects, i.e. the earth orbit computes position, orientation and velocity for the earth and its moon
  • only return raw position and orientation in the global frame of reference
  • can use THREE objects, but by default those are not added to the THREE scene
  • are stateless: no currentTimestamp, etc SpaceCache:
  • Orbits can take advantage of caching
  • Caching by timestamp OrbitalSystem
  • has a list of SpaceObjects
  • computes states for all SpaceObjects
  • is responsible for optimizations of computations DescriptiveOrbitalSystem child class of OS

Artists:

  • take a position and rotation to draw stuff in global reference frame

  • SpaceCache:

    • param: a buffer size
    • Map<timestamp, {position, rotation, velocity, ...other}>
    • once bufferSize reached, removes random cache entry -> pitfall: coordinate random cache deletion across caches

OrbitCache/SpaceCache

Question:

  • does the orbitCache have a orbit property...
  • or the orbit have a cache property?
  • or the XxSpaceCache be a child class of XxOrbit

orbitCache.orbit:

  • interacts with the cache directly
  • harder access to orbit.data

SELECTED pro orbit.cache:

  • MAIN REASON any orbit does need a initialPosition anyway
  • easier access to orbit.data stuff
  • ?less clean code-wise? (an orbit doesn't actually need a cache -> yes it does!)

XxSpaceCache child class of XxOrbit:

  • neat access to orbit.data and cache

SpaceObjects Hierarchy and OrbitalSystems

Question:

  • How to organize objects which orbit objects that orbit other objects? (orbiters2)
  • How to organize objects efficiently for 1) computation and 2) artistry and drawing

goals:

  • being able to efficiently compute global position for orbiters2
  • being able to efficiently compute&cache "local" position for orbiters2
  • no code duplication
  • easy transition from descriptive/kepler orbits to newtonian orbits
  • what about re-creating the hierarchy in the THREE.js artistry part?

Propositions: a) AbstractOrbit has a "parent" property, which references the parent orbit, with getGlobalState() method b) "OrbitalSystem" class keeps a flat list of all the orbits/objects it has. Each AO object has a system property (ref to OS), a parent property (string to AO id), and a getGlobalState() method c) "OrbitalSystem" class keeps a flat list of all the orbits/objects it has. Each AO object has a parent property (string to AO id). OS takes care of composing each object's globalState() from AO.getState() d) CompositeOrbit class has a "parent" and "orbit" property and computes the global getState()

Proposition a) AO parent ref + getGlobalState():

  • each AO is able to compute its globalState
  • easy to pass an AO to a NewtonianOrbit and get Initial State
  • ref mumbo-jumbo
  • footgun with AO.getGlobalState/getState()
  • less tight control on optimization: might re-compute parents' state multiple times

Proposition b) OS AO flatlist + AO.getGlobalState()

  • each AO is able to compute its globalState
  • easy to pass an AO to a NewtonianOrbit and get Initial State
  • footgun with AO.getGlobalState/getState()

Proposition c) OS AO flatlist + OS.getGlobalState()

  • no footgun between getState() getGlobalState()
  • OS is responsible for optimization of computations
  • AO unaware of its globalState()

Proposition d) CompositeOrbit class

  • NewtonianOrbit non-compatible
  • too focused on hierarchized orbits

Decision:

  • hard to choose between c) and b)
  • will go for c):
    • in b) AO must go through OS -> so as well skip this step and go directly to OS computing everything -> leaves freedom for the OS to use Three.group or single globally positionned Three.object3d

Computation and artistry

  • Computation: DescriptiveOrbitalSystem
    • takes OrbiterData[] and fromData: (data)=> Orbit
  • Artistry:
    • <Hierarchical/Descriptive>OrbitalSystemArtist -> child class of DescriptiveOrbitalSystem
    • HierarchicalOrbitArtist -> Takes all the old object3d/group artistry properties/quirks of the old Orbits -> orbit property -> builds a hierarchical tree of Orbit&children -> draws them in hierarchical order -> avoids "world" position/rotation computations

Roadmap

  • DONE create OrbitCache
  • DONE refactor ASOG
  • DONE think of and write up new way of hierarchyzing orbits&objects
  • DONE rewrite artistry
  • DONE rewrite NewtonianBody as a stateless with cache object
  • DONE rewrite GravitationalSystem using the new NewtonianBody

Fixing Newtonian GravitationalSystem

Ideas:

  • allow for better visualisation of state/vector properties
    • be able to see a state's properties by clicking (velocity, etc)
  • create a mock solar system where parameters are known -> errors will be easily identified
  • compare velocity values from GS to KOS
    • ?compute GS values at KOS places?

better visualisation

steps:

  • DONE show each step with a sphere
  • click on a sphere
    • shows vectors
    • shows velocity/Acc/force values in a html elment
    • ?shows comparable value from KOS

visualisation/events architecture

AnimatedSpaceObject (ASO) renamed to Artist AnimatedSpaceObjectsGroup (ASO) renamed to ArtistsGroup

needs:

  • keeps track of currently selected feature
  • allows hover/click interaction
  • different places to show stuff?

Proposition:

  • EventListener3D class to listen events
    • id property
    • .onClick() & .onHover() methods
  • singleton global EventManager3D object
    • addEventListener(click/hover, EventListener3D) method
    • listens to hover/click events
    • triggers EventListener3D methods
  • Artists
    • have "eventListeners" array with ids of eventListener, addEventListener(elId) -> each EventListener3D is responsible to add itself to the proper artists
  • Selector?
    • object with "selected", "clicked" attribute
    • select/unselect method

onClick/onHover() arguments signature:

  • three.intersection
  • artist
  • whatelse?

DEBUGGING GS

currently:

  • compute forces
  • compute acc
  • update velocity
  • update position

with initialStates:

  • wrongly adds the initial acc to the initial velocity!!