Page 1 of 1

Anatomy of an Add-on: Buran

Posted: 23.02.2008, 23:41
by chris
This topic is a discussion about best practices for creating complex add-ons using some of the constructs coming in the next version of Celestia: Timelines, the Clickable and Visible properties, and the new component and surfacefeature object types. I'll be using the Flight of Buran add-on from Runar, Christophe, and Andrea as an example. By re-working this add-on, I in no way mean to criticize the original work. There are new features coming in Celestia that make it complex add-on creation much more straightforward that before, and a lot of the tricks that used to be required for putting objects in the right place are no longer necessary.

I'll start by describing the overall structure of the Buran mission. For simplicity, I'm going to consider just a few of the components:

- the Launch platform
- the Buran spacecraft
- the Energia rocket
- four Zenit boosters

Let's first consider Buran itself. Initially, it is on the surface of the Earth; it then lifts off from the launch pad, goes around the Earth twice, then reenters the atmosphere to land on a runway. If Buran remained on the ground the entire time, we could define it in the ssc file like this:

Code: Select all

"Buran" "Sol/Earth"
{
    Class "spacecraft"
    Mesh "th_buran.cmod"
    Radius 0.058765

    OrbitFrame { BodyFixed { Center "Sol/Earth" } }
    BodyFrame { BodyFixed { Center "Sol/Earth" } }
    FixedPosition [ ... ]
    FixedRotation { ... }
}


(I'm omitting values for the position and rotation right now to just focus on the structure of the add-on.)

The key thing in this SSC definition is that Buran is in the body fixed frame of Earth. Giving it a fixed position and orientation means that Buran will not appear relative to the surface of the Earth. BodyFixed is the appropriate reference frame to use for objects on the surface of a planet.

Once Buran lifts off from the surface, we'll use a SampledTrajectory (xyz file) for it's motion. A crucial question to ask now is what reference frame are the xyz file coordinates in? There are three reasonable choices:

- Earth-centered
- Earth-fixed
- Earth-fixed, centered on the launch site

The Earth-centered coordinate system has the same origin as the Earth-fixed system--the center of the Earth--but it doesn't rotate with the Earth. If you're working with an actual mission trajectory or simulator output, your choice of reference frame will depend on the data. With Buran, we have a bit more latitude, since we're working with a trajectory that has been hand reconstructed. If Buran was bound for the Moon, the choice would be obvious: Earth-centered, since the trajectory is essentially decoupled from the rotation of the Earth. On the other hand, if Buran remained in Earth's atmosphere, the rotating Earth-fixed frame would make more sense. Now, It looks like the xyz file that comes with the Buran add-on is in an Earth-fixed frame, but we'll going to break the trajectory into multiple phases so that we've got the flexibility to change the reference frame of the flight phase:

Code: Select all

"Buran" "Sol/Earth"
{
    Class "spacecraft"
    Mesh "th_buran.cmod"
    Radius 0.058765

    Timeline [
   
    # Phase 1: on the launch platform
    {
        Beginning  2447457.5       # 23 Oct 1988, on launch platform
        Ending     2447480.62566   # 15 Nov 1988 03:00 GMT, liftoff

        OrbitFrame { BodyFixed { Center "Sol/Earth" } }
        BodyFrame { BodyFixed { Center "Sol/Earth" } }
        FixedPosition [ ... ]
        FixedRotation { ... }
    }

    # Phase 2: lift off, orbit, reentry
    {
        Ending 2447480.76802       # 15 Nov 1988 06:25:00, touchdown in Baikonur

        OrbitFrame { BodyFixed { Center "Sol/Earth" } }
        BodyFrame { BodyFixed { Center "Sol/Earth" } }
        SampledTrajectory { Source "th_buran.xyz" }
        SampledOrientation "th_buran.q"
    }

    # Phase 3: back on the ground
    {
        OrbitFrame { BodyFixed { Center "Sol/Earth" } }
        BodyFrame { BodyFixed { Center "Sol/Earth" } }
        FixedPosition [ ... ]
        FixedRotation { ... }
    }
    ] # end timeline
}


So that's Buran . . . We still need to fill in values for the FixedPosition and FixedRotation, but we'll get to that later. The important thing is that we have the skeleton for the mission. Unlike in 1.5.0, there are no unnamed or invisible objects required: the same Buran object is used throughout the mission.

On to Part 2: Energia and Boosters . . .

--Chris

Posted: 24.02.2008, 00:04
by ElChristou
Many TX Chris, this is really, really welcome! Can't wait part 2! :D

Posted: 24.02.2008, 00:05
by chris
Anatomy of an Add-on Part 2: Energia and Boosters

The Energia rocket and four Zenit boosters all leave the launch pad attached to each other. The boosters are jettisoned in pairs 165 seconds after liftoff. At eight minutes after liftoff, Buran separates from Energia. The are separate xyz files for Energia and each of the boosters that give their trajectories from separation to splashdown. Until separation, we want Energia and the boosters to move and rotate together with Buran. We could provide SampledTrajectories and SampleOrbits for the rockets that were identical to Buran's up to the point of separation, but the new Timeline feature gives us a more convenient way to define the mission. We'll use two phases: one for when the booster is attached to Buran, and a second phase for the independent trajectory after separation.

When the boosters are attached to Buran, they don't move or rotate relative to the spacecraft. This suggests that we should use Buran's body-fixed reference frame for the first phase. In the second phase, we'll want to use the same reference frame we did for Buran's flight phase, since presumably the trajectories are all given in the same coordinate system. Here are the ssc definitions for Energia and one of the Zenit boosters:

Code: Select all

"Energia" "Sol/Earth/Buran"
{
   Class "spacecraft"
   Mesh "th_energia.cmod"
   Radius 0.058765
   # Albedo            0.5

   Timeline [

   # Phase 1: attached to Buran
   {
       Beginning 2447457.5      # 23 Oct 1988, on launch platform
       Ending    2447480.63122  # 15 Nov 1988 03:08:00, Energia separation, 160 km altitude

       OrbitFrame { BodyFixed { Center "Sol/Earth/Buran" } }
       BodyFrame { BodyFixed { Center "Sol/Earth/Buran" } }
       FixedPosition [ 0 0 0 ]
       FixedRotation { }
        }

   # Phase 2: separation and reentry       
        {
       OrbitFrame { BodyFixed { Center "Sol/Earth" } }
       BodyFrame { BodyFixed { Center "Sol/Earth" } }
       SampledTrajectory { Source "th_energia.xyz" }
       FixedRotation { }
   }
   ]
}

"Zenit1" "Sol/Earth/Buran"
{
   Class "spacecraft"
   Mesh "th_zenit1.cmod"
   Radius 0.058765

   Timeline [

   # Phase 1: attached to Buran
   {
       Beginning 2447457.5   # 23 Oct 1988
       Ending    2447480.62757  # Jettison 15 Nov 1988 03:02:45
       OrbitFrame { BodyFixed { Center "Sol/Earth/Buran" } }
       BodyFrame { BodyFixed { Center "Sol/Earth/Buran" } }
       FixedPosition [ 0 0 0 ]
       FixedRotation { }
        }
       
   # Phase 2: separation and reentry       
        {
       OrbitFrame { BodyFixed { Center "Sol/Earth" } }
       BodyFrame { BodyFixed { Center "Sol/Earth" } }
       SampledTrajectory { Source "th_booster1.xyz" }
       FixedRotation { }
   }
   ]
}


In the example definition, Energia and the boosters have FixedRotations after separation. This could eventually be replaced by a SampledOrientation if we wanted to make the objects tumble as they entered Earth's atmosphere.

Another thing to pay attention to is that I made the objects children of "Sol/Earth/Buran". This means that the objects will be associated with Buran in the solar system browser, helping to reduce clutter that can appear if you simply make everything a child object of Earth. Since we've overridden the default frame in the SSC definitions, this parent-child relationship is distinct from the reference frame relationship, e.g. even when the trajectory of Energia is relative to the Earth, Energia will still be a child of Buran in the solar system browser.

Next, Part 3: Trajectory of Buran

--Chris

Posted: 24.02.2008, 01:35
by Chuft-Captain
Looking forward to all these new features Chris. :)

Posted: 24.02.2008, 02:21
by chris
Chuft-Captain wrote:Looking forward to all these new features Chris. :)


Timeline is already checked into SVN. I'll make a build for people to test very soon.

--Chris

Re: Anatomy of an Add-on: Buran

Posted: 24.02.2008, 10:25
by Fenerit
chris wrote:This topic is a discussion about best practices for creating complex add-ons using some of the constructs coming in the next version of Celestia: Timelines, the Clickable and Visible properties, and the new component and surfacefeature object types.

...

--Chris


Just curious, the Visible propriety will permit to hide model's parts within an unique .ssc? (Topic close here wheter the explanation of this new feature require another thread).

Posted: 24.02.2008, 11:14
by ElChristou
chris wrote:Anatomy of an Add-on Part 2...


Excellent, will be the same config for the opening of the Saturn V SLA...

Posted: 01.03.2008, 21:21
by chris
Anatomy of an Add-on Part 3: Trajectory and Attitude of Buran

I made an incorrect assumption about the the reference plane of the Buran trajectory. The actual frame used for the trajectories of Buran, Energia, and the Zenit boosters are not rotating with the Earth. The trajectories are defined relative to the location of the Baikonur launch site and the fundamental is the Earth equator. This is called a topocentric equatorial coordinate system, and it can be expressed in Celestia like this:

Code: Select all

OrbitFrame {
    MeanEquator {
        Center "Sol/Earth/Baikonur"
        Object "Sol/Earth"
    }
}


Center sets the origin, Object specifies the body whose equatorial plane is the fundamental plane of the frame. If Object isn't specified, it defaults to the same object as Center. We can thus take a slight shortcut, because Baikonur happens to be defined so that it has the identical rotation as Earth:

Code: Select all

OrbitFrame {
    MeanEquator {
        Center "Sol/Earth/Baikonur"
    }
}


The choice of reference frame depends completely on the coordinates given in the xyz file. The Buran coordinates could have been given relative to Earth's center, but since Runar hand-edited parts of the trajectory file, he understandably found it more convenient to produce coordinates relative to the launch site.

With the OrbitFrame above, Buran travels on its expected trajectory from Baikonur, around the Earth twice, to a touchdown at Baikonur. Next, we want to get the orientation of Buran right. The fact that we're recreating the mission effectively by hand will determine our choice of reference frame for the orientation of the shuttle. We're going to be adding rotation keyframes to SampleOrientation file based on documents of maneuvers during the mission. We want to add as few as possible, so we'd like to choose a reference frame in which the attitude of Buran isn't always changing. A good choice is a two-vector frame in which the primary axis is the velocity. This gives a plausible orientation for Buran even with a constant orientation: it will always be pointed along the direction of flight. For a secondary vector, we'll pick the the vector from Buran to the center of the Earth:

Code: Select all

BodyFrame {
    TwoVector {
        Center "Sol/Earth/Buran"
        Primary {
            Axis "z"
            RelativeVelocity { Target "Sol/Earth" }
        }
        Secondary {
            Axis "y"
            RelativePosition { Target "Sol/Earth" }
        }
    }
}


If you've used reference frames in Celestia before, you'll note something odd: the center of the frame is Buran itself. This is allowed in the latest SVN version of Celestia--in early versions, you would have had to define the object, and the replace the BodyFrame using modify.

The Buran timeline provided by Runar gives two manuevers that involve changing the orientation of the spacecraft:

Code: Select all

2447480.72288   05:20:00      Buran turns, tail in direction of flight, retrofire. Over the South Pacific.
[ 2447480.724   05:21:37 ]      Engine shutdown, shuttle turns again, nose in direction of flight, going for reentry.


We'll want to create a SampledOrientation file that describes these maneuvers. SampledOrientation files contain quaternions giving the orientation of the object at different times. The orientation is smoothly interpolated between times given in the file. Trying to figure out what quaternion produces the rotation you want is extremely tricky, so we'll use the rotator script described this thread to let us manipulate Buran interactively in Celestia.

The resulting orientation file looks like this:

Code: Select all

2447480.62566 0.707107 -0.707107 0 0

2447480.72288 0.707107 -0.707107 0 0
2447480.72328 0.998135 -0.061049 0 0
2447480.72368 0.707107 0.707107 0 0

2447480.724   0.707107 0.707107 0 0
2447480.7244  0.5      0.5      -0.5 -0.5
2447480.7248  0 0 0.707107 0.707107


I've split the seven keyframes into three sections. The first is the initial orientation of the spacecraft at launch. The next section describes the first maneuver. The initial orientation is repeated at the start of the maneuver; otherwise, the first maneuver would occur in slow motion starting at launch! The third orientation in the file is midway through the first maneuver. This is only necessary because the spacecraft is rotating 180 degrees; without the middle orientation, the direction in which the spacecraft is rotating will be undefined. The fourth rotation gives the Buran's orientation at the end of the maneuver. The entire maneuver takes about a minute--Runar's timeline gives the start time, but the duration is a complete guess by me. A more detailed description of the Buran flight might give us this value.

Here's what the SSC definition of Buran looks like now:

Code: Select all

"Buran" "Sol/Earth"
{
   Class "spacecraft"
   Mesh "th_buran.cmod"
   Radius  0.058765

   Timeline [

   # Phase 1: on launch platform
   {
       Beginning  2447457.5       # 23 Oct 1988, on launch platform
       Ending     2447480.62566   # 15 Nov 1988 03:00 GMT, liftoff

       OrbitFrame { MeanEquator { Center "Sol/Earth/Buran Launch Pad" } }
       BodyFrame { MeanEquator { Center "Sol/Earth/Buran Launch Pad" } }

       FixedPosition [ 0 0 0 ]
       FixedRotation { ... }
    }

    # Phase 2: liftoff, flight, and reentry
    {
        Ending 2447480.76802       # 15 Nov 1988 06:25:00, touchdown in Baikonur

        OrbitFrame { MeanEquator { Center "Sol/Earth/Baikonur" } }
        BodyFrame {
        TwoVector {
            Center "Sol/Earth/Buran"
            Primary {
                Axis "z"
                RelativeVelocity { Target "Sol/Earth" }
            }
            Secondary {
                Axis "y"
                RelativePosition { Target "Sol/Earth" }
            }
        }
        }

        SampledTrajectory { Source "th_buran.xyz" }
        SampledOrientation "th_buran.q"
    }

   # Phase 3: after touchdown
   {
       OrbitFrame { BodyFixed { Center "Sol/Earth" } }
       BodyFrame { BodyFixed { Center "Sol/Earth" } }
       FixedPosition [ 0 0 0 ]
       FixedRotation { }
        }

   ]

   Albedo      0.5   
}


--Chris