API Question How to get ordered list of GBodies

yagni01

Addon Developer
Addon Developer
Donator
Joined
Feb 8, 2008
Messages
463
Reaction score
0
Points
16
Location
Atlanta, GA
I want to get a list of planets and their moons as an object graph to create an external selection dialog. I don't see anything, but is there a method to get these relationships directly from Orbiter or perhaps a way to get the name of the system from the currently executing scenario so that I can parse the system config file myself?

Any suggestions would be helpful.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
I can't help you with functions for hierarchy or the system name, although Orbiter obviously knows what they are internally.

Is the dialog like the default celestial body selection dialog that Orbiter provides? Do you need it to be external to Orbiter? If not, you might want to check out cjp's hack for the default dialogs contained in FreeOrbitMFD.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Is the dialog like the default celestial body selection dialog that Orbiter provides? Do you need it to be external to Orbiter? If not, you might want to check out cjp's hack for the default dialogs contained in FreeOrbitMFD.
It does need to be external to Orbiter. This is for OrbConnect, and would allow an external MFD (say, like the Orbit MFD) to display a hierarchical selection dialog.

---------- Post added at 11:40 PM ---------- Previous post was at 11:29 PM ----------

I haven't actually done more than glanced at the API, but is it possible that the list of gbodies you'd get by iterating through oapiGetGbodyByIndex() already has some kind of implicit ordering? I'm pretty sure the star is always 0, it might be logically laid out from there.

oapiGetBarycentre knows the children of any given body, so the information is around, we might just not have access to it. That function could also be used to determine if an object is a childmost object...

I don't see a way in the API to see what a planet's parent is...
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Yeah, I thought it might be for OrbConnect.

Alternative solution 1: Populate a list by oapiGetGbodyByIndex and get the associated Gbody positions. For each item call oapiGetBarycentre. If there is another Gbody within one semi-major axis distance of that barycentre then it is the parent body (the limiting case is an equal binary system). If there are multiple masses in that volume, then the one with the highest mass is the parent. So, the outstanding question for this option is how to get a Gbody's semi-major axis?

Alternative solution 2: Populate a list by oapiGetGbodyByIndex. For each Gbody, use oapiGetRelativePos/oapiGetRelativeVel and KOST (or similar) to calculate a Gbody's elements with respect to all other Gbodies (the State Vector MFD shows how to do this, including the approriate coordinate systems conversions). The solution with the lowest eccentricity should reveal the parent for any sensible system.
 
Last edited:

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Yeah, I thought it might be for OrbConnect.

Alternative solution 1: Populate a list by oapiGetGbodyByIndex and get the associated Gbody positions. For each item call oapiGetBarycentre. If there is another Gbody within one semi-major axis distance of that barycentre then it is the parent body (the limiting case is an equal binary system). If there are multiple masses in that volume, then the one with the highest mass is the parent. So, the outstanding question for this option is how to get a Gbody's semi-major axis?
Not bad, although you can't call oapiGetBarycentre on a childmost body (since GetBarycentre gets the barycentre of the system which is centered on the body you call it on).

Alternative solution 2: Populate a list by oapiGetGbodyByIndex. For each Gbody, use oapiGetRelativePos/oapiGetRelativeVel and KOST (or similar) to calculate a Gbody's elements with respect to all other Gbodies (the State Vector MFD shows how to do this, including the approriate coordinate systems conversions). The solution with the lowest eccentricity should reveal the parent for any sensible system.
And my inner algorithm analyzer whimpers at the thought of that O(n^2) algorithm...

It just seems like there should be a better way.
 

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,668
Reaction score
796
Points
128
This feature have been requested ever since the Orbiter was first released. But a mathematical solution as pointed by tblaxland can do the job. IMFD finds a reference body for 'x' using using following technique that may not be perfect. Also it's good idea to create a reference table for all objects for faster access.

1. Find all G-bodies with higher mass than 'x'
2. Find from remaining bodies all those witch will give Ecc<1.0 for 'x' (i.e. SMa>0)
3. Finally choose the closest one to 'x'
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Not bad, although you can't call oapiGetBarycentre on a childmost body (since GetBarycentre gets the barycentre of the system which is centered on the body you call it on).
Ah, I misunderstood how GetBarycentre worked then.

1. Find all G-bodies with higher mass than 'x'
2. Find from remaining bodies all those witch will give Ecc<1.0 for 'x' (i.e. SMa>0)
3. Finally choose the closest one to 'x'
That looks good because filtering out the larger masses at least reduces the number of calculations. I think there may be cases where 3. may fail (small moon orbiting a binary planet?) but they probably occur infrequently enough to not worry about, given that the solutions would like involve more O(n^2) calculations.
 

agentgonzo

Grounded since '09
Addon Developer
Joined
Feb 8, 2008
Messages
1,649
Reaction score
4
Points
38
Location
Hampshire, UK
Website
orbiter.quorg.org
I've already done this for TransX. I think that oapiGetGbodyByIndex gets the GBodies in order of Mass. From this you can test to see which SOI each GBody is in and as such derive a tree of nodes representing the solar system.

If you want the code, it's in the TransX repository, specifically the mapfunction class.
 

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,668
Reaction score
796
Points
128
I think there may be cases where 3. may fail (small moon orbiting a binary planet?)
You are right about that, Pluto-Charon binary would be such case.
 

cjp

Addon Developer
Addon Developer
Donator
Joined
Feb 7, 2008
Messages
856
Reaction score
0
Points
0
Location
West coast of Eurasia
It seems there are a lot of existing solutions to this problem. My Lagrange MFD also contains a solution in planettree.h/planettree.cpp. It is in no way intended to be optimized, except that it analyzes all 'parent/child' relations at startup, and then searches through the resulting table on every new request.

My test is as follows:

  • A parent body always has to have a larger mass than its child bodies
  • The eccentricity of the parent/child orbit needs to be smaller than 1
  • From all parent candidates that satisfy these conditions, the one that generates the largest gravity force on the child is selected.
This seems to work for all bodies in my Orbiter installation. I don't have any comets though.
 

yagni01

Addon Developer
Addon Developer
Donator
Joined
Feb 8, 2008
Messages
463
Reaction score
0
Points
16
Location
Atlanta, GA
Yea, I was hoping for a 'non-mathematical' solution, but it is what it is. The good thing is there is some code out there.

Thanks everyone.
 

yagni01

Addon Developer
Addon Developer
Donator
Joined
Feb 8, 2008
Messages
463
Reaction score
0
Points
16
Location
Atlanta, GA
Very few things in astrodynamics have non-mathematical solutions! :)
And here I thought it was merely a configuration problem. Its sheer discrimination that vessels get a peek at the scenario file but the rest of us poor plugins don't. ;)
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
You want these undocumented functions:

Code:
DLLCLBK void opcSaveState(FILEHANDLE scn);
DLLCLBK void opcLoadState(FILEHANDLE scn);

See my [ame="http://www.orbithangar.com/searchid.php?ID=3824"]State Vector MFD[/ame] for an example usage.
 

yagni01

Addon Developer
Addon Developer
Donator
Joined
Feb 8, 2008
Messages
463
Reaction score
0
Points
16
Location
Atlanta, GA
You want these undocumented functions:

Code:
DLLCLBK void opcSaveState(FILEHANDLE scn);
DLLCLBK void opcLoadState(FILEHANDLE scn);
See my State Vector MFD for an example usage.
Awesome.:speakcool: I'm not one to normally use undocumented features, but I'll force myself. Do you know if these are still valid in the new release?
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Do you know if these are still valid in the new release?
New release? As in the as-yet-unreleased OrbiterXX*? I don't know definitively, but I would be surprised if they weren't valid. Put it this way - there is no good reason for their support to be removed.

* Insert year to suit optimism level :p
 

yagni01

Addon Developer
Addon Developer
Donator
Joined
Feb 8, 2008
Messages
463
Reaction score
0
Points
16
Location
Atlanta, GA
New release? As in the as-yet-unreleased OrbiterXX*? I don't know definitively, but I would be surprised if they weren't valid. Put it this way - there is no good reason for their support to be removed.

* Insert year to suit optimism level :p
:) Yes, that one. :)
 

yagni01

Addon Developer
Addon Developer
Donator
Joined
Feb 8, 2008
Messages
463
Reaction score
0
Points
16
Location
Atlanta, GA
Well, I added the code below to my OrbConnect.cpp file, and the log message is not appearing. My other Orbiter callbacks work, so I'm not sure why this one is not being called.
Code:
DLLCLBK void opcLoadState(FILEHANDLE scn)
{
    char* line;
    char key[8];
    char value[256];

    oapiWriteLog("Orb:Connect Loading state");  // <<< not being written

    while (oapiReadScenario_nextline(scn, line))
    {
        if ( !_strnicmp(line,"BEGIN_ENVIRONMENT", 17) )
        {
            while (oapiReadScenario_nextline(scn, line))
            {
                if ( !_strnicmp(line,"System", 6) )
                {
                    int tokens = sscanf_s(line, "%s %s", key, value);
                    if (tokens == 2) {
                        strcat_s(value, ".cfg");
                        readSystemFile(value);
                    }
                }
            }
        }
    }
}
I have ORBITER_MODULE defined. Any ideas?
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Well, I added the code below to my OrbConnect.cpp file, and the log message is not appearing. My other Orbiter callbacks work, so I'm not sure why this one is not being called.
This callback only gets called if the scenario file contains an entry for your module. Put this at the bottom of your scenario file:
Code:
BEGIN_PluginModuleName
;your module's scenario specific info here
END
Replace "PluginModuleName" with whatever the name of your plugin module is, ie, the dll file name without the ".dll" file extension.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
This callback only gets called if the scenario file contains an entry for your module. Put this at the bottom of your scenario file:
Code:
BEGIN_PluginModuleName
;your module's scenario specific info here
END
Replace "PluginModuleName" with whatever the name of your plugin module is, ie, the dll file name without the ".dll" file extension.
That's really not a suitable solution, then, since this module would need to run regardless of what scenario was being loaded...
 
Top