I'm working on an addon which simulates the effects of gravity in Celestia.It's only a prototype at this stage, but if there's any interest I'd be prepared to take the idea as far as I can (or as far as it's reasonable to do so).

Object "test_01" # Object name from the declaration above (so that the script can identify object) Parent "Sol" # Parent from the declaration above (so that the script can identify object) Mass 100 # Mass of the object in kg

# The following 8 fields define the "initial state" of the object... StartTime 2456900.00000 # The start time for the position and velocity specified below... Reference "Sol/Earth" # Initial OrbitFrame for declaration of starting position and velocity below...

# After initial conditions are set, the script takes over and determines future orbit x,y,z positions based # solely on the gravitational influence of the object specified below...- At this stage, just a single object to keep it simple. # In future, the aim is to allow multiple "Influence(r)s", but this will be specified in a more general and flexible way. # The trajectory will be calculated by considering the impact of all specified gravitational "Influences". Influence "Sol/Earth" }

. . . . .

}

NOTES:Although the orbitframe of this prototype is currently determined by the:

Code:

OrbitFrame { BodyFixed { Center "Sol/Earth" } }

statement, I would like to be able to set and/or change the frame dynamically within LUA.This is necessary in order to allow the position and velocity of the initial trajectory to be specified relative to the "Reference" object, but once initiated, the frame IMO needs to switch to either "heliocentric" or "universal" so that all position and vector calculations are working within a consistent reference frame.You can use setframe() in LUA to change frames, but AFAIK this can only be used to set the observer's frame.EG.

Yes, I think you misunderstood a little.... when I said "consistent reference frame", I mean "unchanging" or "always the same" for the purposes of vector calculations within the script itself.ie.As a design decision, I think it's advantageous if the xyz position is always calculated relative to a consistent "origin", in order to avoid multiple conversions between different reference frames. (For an object in the Solar System, IMO it makes sense for these calculations to always be heliocentric, but I'm open to other opinions / points of view.)

I think it's OK for the initial conditions to be specified WRT. another body such as the Earth or Venus, however the initial position and velocity vector will need to be converted to heliocentric or universal before the script begins doing it's job (which is to continuously add small velocity vectors and make the corresponding positional changes to the trajectory of the object based on the specified gravitational influences.)

NOTE: Because the script will be executed very frequently (whenever Celestia gets a chance between render cycles) it is effectively performing a numeric integration of the object's position over time. The downside is that as the simulation-rate is increased... 10x, 100x, etc, the script will become less accurate, as it will have less opportunities (in simulation time) to perform it's calculations, with correspondingly "coarser" results.

CC

_________________CITIZENS OF CM - JOIN THE REVOLUTION...black out your avatar THE AVATARS ARE REVOLTING !!!

NOTE: Because the script will be executed very frequently (whenever Celestia gets a chance between render cycles) it is effectively performing a numeric integration of the object's position over time.The downside is that as the simulation-rate is increased... 10x, 100x, etc, the script will become less accurate, as it will have less opportunities (in simulation time) to perform it's calculations, with correspondingly "coarser" results.

As i recall lua is processed on the CPU it could be moved to the GPU , but nvidia only

NOTE: Because the script will be executed very frequently (whenever Celestia gets a chance between render cycles) it is effectively performing a numeric integration of the object's position over time.The downside is that as the simulation-rate is increased... 10x, 100x, etc, the script will become less accurate, as it will have less opportunities (in simulation time) to perform it's calculations, with correspondingly "coarser" results.

As i recall lua is processed on the CPU it could be moved to the GPU , but nvidia only

Making code run correctly on a GPU is not quite a trivial task from what I understand, and I'm not even sure if LUA can run on a GPU.... and this wouldn't solve the accuracy issue, which is simply a computational issue which will remain an issue / feature regardless of where the code was executed.

Fenerit,

On the subject of those reference frame ideas, they're mostly irrelevant in this context. It might be possible to specify different "Initial" reference frames for different parts of a scriptedorbit in a Timeline scenario, but this is somewhat more complicated. At the end of the day what is needed for simplicity's sake initially is the ability to convert the "initial" coordinates into the "working" coordinates at script kick-off (in LUA code, rather than SSC code). The only important aspect is where is the "Center".

I think we're perhaps talking a little cross-purposes, so perhaps the heavily commented code of the LUA script will give some clarity so that our discussions are on the same page. (Note that this isn't working correctly yet ... there are some issues I need to debug in the script ... but it may give some insight into the mechanism I'm trying to implement):

-- Set the required fields boundingRadius and position; note that position is actually a function

orbit.boundingRadius = 7.025

-- The position function will be called whenever Celestia needs the position of the object function orbit:position(tjd) local t = (tjd - self.LastTime) * 86400; self.LastTime = tjd; now = celestia:gettime()

-- Create an "object" for the object: local test = celestia:find(self.parent.."/"..self.object) -- and get it's current position... local testpos = test:getposition(now)

-- Create "object(s)" for the gravitational influence(s): -- (just the one for now) local attractor = celestia:find(self.influence) -- and get their current positions.... local attractorpos = attractor:getposition(now)

-- We need a vector pointing from the object's position to each of the gravitational influences -- so that we know in which direction the object will be pulled: -- (again, just the one for now) local ivector = testpos:vectorto(attractorpos)

-- Create a unit vector in the same direction -- (We will use this later to scale velocity changes to the size of the gravitational pull.) local inormal = ivector:normalize()

-- Determine the distance from the object's current position to the influence's current position, -- so that we can calculate the magnitude of the influence's gravity on the object. local attractordist = testpos:distanceto(attractorpos) -- in km local attractordistm = attractordist * 1000 -- in meters celestia:log( "attractordistm --> "..attractordistm )

-- calculate the acceleration (m/s/s) the object will experience from the influence at -- it's current distance -- (just using Earth for now): local a = gravity( mass.Earth, attractordistm ); celestia:log( "a = "..a )

-- calculate the magnitude of the velocity change as a result of applying this -- acceleration over the very short time(t) between calls to this function: local v = deltav( a, t ); celestia:log( "deltav = "..v )

-- Create a vector of the right magnitude and direction to represent the velocity change by -- scaling the unit-vector created earlier: local ivvec = (v / uly_to_m) * inormal

-- Calculate the new velocity vector by adding the velocity change (ivvec) to the current -- velocity vector. We end up with a new velocity vector altered by the amount and direction -- of the velocity change in this timeslice (ivvec): vvec = vvec + ivvec

-- Calculate the new position by adding the effect of the resultant vector over the -- period of this timeslice. Remember that: -- t = (tjd - self.LastTime) * 86400 ie. the amount of time since the last orbit calculation local newpos = testpos + vvec

Chuft: do remove whatever reference to OrbitFrame and BodyFixed from within the object's .SSC. Then, do control it with vectors. The "ScriptedOrbit" is already an "OrbitFrame" by yourself; the LUA "parent" is where you want send it. The same could be the "influencers" in deviate it.

Chuft: do remove whatever reference to OrbitFrame and BodyFixed from within the object's .SSC. Then, do control it with vectors. The "ScriptedOrbit" is already an "OrbitFrame" by yourself; the LUA "parent" is where you want send it. The same could be the "influencers" in deviate it.

Hi Fenerit,

Getting rid of the "OrbitFrame" from the SSC is what I'd like to do, so that I have the freedom to change the frame dynamically within the script, but as far I can tell this will not be possible. It appears that the OrbitFrame can ONLY be declared statically in the SCC, in which case, the best I'll be able to do is set it to be Sun-centered. The "ScriptedOrbit" is NOT an OrbitFrame in itself - it only determines X,Y,Z coordinates (but these coordinates must be referenced to an ORIGIN ... which is either defined by the "Center" keyword in an OrbitFrame definition, or is "universal".

Celestia allows the reference frame of an "Observer" to be constantly modified (which enables all the "follow", "sync", "chase", etc functionality - ie. all the navigation functionality ). This functionality is also "exposed" in LUA via the obs:setframe() method, but unfortunately it appears that a similar method cannot be applied to objects eg. object:setframe(). It seems that object frames can only be set statically (ie. within an SSC) but not modified within LUA as observer frames can be.NOTE: It may take the wisdom of one of the developers knowledgeable in underlying code, and specifically the LUA API (eg. Vincent, Fridger) to confirm my conclusions so far.

In the meantime, I think the best I'll be able to do is to define the frame as heliocentric. Unfortunately, this will mean the initial position (and velocity vector) will also be required to be expressed in helio-centric terms, unless I find a way to use Timeframes to somehow facilitate alternate frames (a further complication I'm trying to avoid at this stage).

Although it should be fairly straight-forward to convert the coordinates between reference frames via vector subtraction, it appears that it is not possible to change the objects actual frame at the same time.

I'll probably continue to experiment with trial and error, and may stumble across a solution, but I suspect this is a fundamental limitation.

Any assistance / advice from such experts in the underlying C++ and / or LUA API, such as Fridger, Jogad, or Vincent (if he's still lurking) would be greatly appreciated (even if only to confirm my conclusions).

RegardsCC

_________________CITIZENS OF CM - JOIN THE REVOLUTION...black out your avatar THE AVATARS ARE REVOLTING !!!

Well... now that CM seem to work as usual, and because the last reply could sound a bit kiddish, attached there is a ScriptedOrbit example developed some time ago for a Shatters.net user in which there isn't any reference to either OrbitFrame or BodyFrame directives within the scripted objects and nonetheless they accomplish the job.

It is clear that the frame, in the absence of an OrbitFrame directive, defaults to the parent object. (I should have realized that as it would have worked that way long ago in 1.4 or earlier versions before Chris added all the reference frame stuff.)

Implications for this addon is that the object will have to have "Sol" as it's parent. As far as initial trajectory is concerned, I may still be able to specify this relative to Earth or another body, and then hopefully convert to heliocentric as the orbit is instantiated. -- We will see....

CheersCC

_________________CITIZENS OF CM - JOIN THE REVOLUTION...black out your avatar THE AVATARS ARE REVOLTING !!!

from the physics perspective, a proper implementation of gravitation into celestia(.Sci) represents a big challenge, indeed. That's the reason why no-one has tried it for Celestia in the past, not because no-one thought of it...

What can straightforwardly be treated is the gravitational potential arising from a sum of gravitational point charges. You surely remember that already the (non-factorizable) gravitational 3-body problem has no closed solution. In some corners of the celestia(.Sci) Universe the conditions for a decent approximative implementation are presumably met. But there are many regions where the opposite is true...and it is hard to know the boundaries!

Just think of travelling with your spaceship across the Jovian system, with Jupiter deviating substantially from a spherical shape (<->big gravitational charge without spherical symmetry!). The Saturn system with its very large number of fast-moving moons is another cracker...

What can and has long been implemented is mostly a gravitational analog of the Hartree-Fock method in Electrodynamics. In our context, it is called VSOP87 and part of celestia(.Sci). Here one lumps many gravitational charges into a phenomenological gravitational background "cloud" and then calculates the movement of a body of interest in the resulting static field.

What can straightforwardly be treated is the gravitational potential arising from a sum of gravitational point charges.

That is essentially the aim of (at least the first version) of this addon. It might be possible to cater for some of the more advanced calculations in future, but at least for the first iteration, the aim is to keep it simple. The basic idea is:On each iteration of the ScriptedOrbit.... -- re-calculate the direction and distance to each "influence" which is being considered -- calculate velocity adjustment to the trajectory in the form of a small vector for each "influence" -- the sum of all these vectors gives the overall deltaV (for the timeslice) -- calculate the new position by extension from the prior position and velocity.

The critical functions not shown in the code above (but, I'm sure everyone will recognize) are of course:

You surely remember that already the (non-factorizable) gravitational 3-body problem has no closed solution. In some corners of the celestia(.Sci) Universe the conditions for a decent approximative implementation are presumably met. But there are many regions where the opposite is true...and it is hard to know the boundaries!

Agreed. However, the aim for version 1 is to be able to do a reasonably accurate job of simulating interplanetary trajectories (eg. Hohmann transfers), and gravity assists. For the first of these aims, at interplanetary distances I think we can certainly assume most "attractors" to be gravitational points. In the case of gravity assists, these generally require getting rather close to the "attractor", and I expect that perturbations due to the non-spherical nature of the body may become significant (although these generally are of a periodic nature, so maybe for a fast encounter at low latitudes, where we're not in a highly inclined and/or low orbit for a long period, we can reasonably get away with ignoring these effects.) -- It all depends on how large these perturbations are? ... and how much error we are willing to live with. (This is surely a more serious issue with the gas giants than with the smaller rocky objects.)Likewise, I'm not planning on modeling the effects of atmospheric drag, or differences in gravity due to geologic features. (So no aero-braking scenarios possible. Sorry! )

t00fri wrote:

Just think of travelling with your spaceship across the Jovian system, with Jupiter deviating substantially from a spherical shape (<->big gravitational charge without spherical symmetry!). The Saturn system with its very large number of fast-moving moons is another cracker...

Yes, I have thought of such scenarios, and the lack of spherical symmetry is I'm sure a significant factor in any trajectory which is significantly inclined from the planet's equator. And of course the gas giants are popular targets for gravity assists, so I will probably need to model these effects at some point.As far as the fast moving moons are concerned, I think this addon can handle that scenario OK by virtue of the fact that the code will constantly (i.e. on every iteration) re-calculate the direction and magnitude of the vector from the spacecraft to each "influence":

Code:

local ivector = testpos:vectorto(attractorpos)

t00fri wrote:

What can and has long been implemented is mostly a gravitational analog of the Hartree-Fock method in Electrodynamics. In our context, it is called VSOP87 and part of celestia(.Sci). Here one lumps many gravitational charges into a phenomenological gravitational background "cloud" and then calculates the movement of a body of interest in the resulting static field.

I'm assuming of course that the VSOP87 implementation is not exposed to the LUA API.

To sum up, I expect that this addon will initially be capable of doing a reasonably accurate simulation of interplanetary trajectories, and may require some further refinement to handle accurate gravity assists as well.If I want a spacecraft to go into a close orbit, then a Timeline can always be used to insert it into an EllipticalOrbit implementation. (But then, that's not necessarily any more accurate than this technique, anyway, as EllipticalOrbit's do not access VSOP87 do they?)

Thoughts?

CheersCC

PS. All of the above is moot at this point, as I'm still struggling with the limitations of the LUA API (and my own limitations) to get a proof-of-concept up and running.

_________________CITIZENS OF CM - JOIN THE REVOLUTION...black out your avatar THE AVATARS ARE REVOLTING !!!

Who is online

Users browsing this forum: No registered users and 2 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum