VesselMass

kwan3217

Addon Developer
Addon Developer
Donator
Joined
Apr 29, 2008
Messages
115
Reaction score
0
Points
16
Location
Geosynchronous Orbit
If you have ever looked through some plans or drawings of real aircraft or spacecraft, you will see what I will call station coordinates. Some point on the spacecraft, or maybe slightly in front of the spacecraft, is arbitrarily chosen as the coordinate system origin. All spacecraft structures are positioned relative to this point, which is fixed and doesn't normally change for instance when you burn fuel and the center of gravity changes.I like to design my vehicles so that the station origin is at the tail end of the rocket, usually at the center of the first stage engines. If I am working off of a real drawing, I usually use their station coordinates directly, perhaps with a change in sign.

Most serious simulators work like this, and I intended SpaceGear, my Java-coded text-only space simulator to work like this as well.

However, the Orbiter body frame originates at the center of mass. This means that if you are not careful, all your propellant resources and structure are at the center of mass also.

I could put in a change request for Orbiter 20X6 to use station coordinates as I have described them, but that would involve waiting until Tuesday. Besides, why should I wait if I can write it myself?

So, VesselMass. This is a class intended to be used by a vessel to manage its center of mass, and inertia tensor while we are at it.

VesselMass is actually a whole hierarchy of classes. The base class is abstract and just has abstract virtual methods for calculating the center of mass and inertia tensor of one particular chunk of a vehicle.

The next concrete class is something like CylinderShell. When you construct this object, you tell it the mass, radius, position of the center of one face, and axis and length of the cylinder. Most important to note is that this is all specified in station coordinates. From this, it can calculate its own center of mass in station coordinates and inertia tensor about its center of mass.

Next in complexity is the PropellantMass. It is still abstract, but it holds a reference to a propellant resource and a mass fraction. For instance in a bipropellant rocket, we have one propellant resource representing generic 'propellant' that the engine uses, but we create two PropellantMass objects. If we are using say hydrogen-oxygen, where the proper ratio is 1:6, we create one propellant resource as always, representing both fuel and oxidizer, but two PropellantMass objects. We say that the hydrogen object is hooked to the stage propellant resource but only represents 1/7 of the mass, while the oxygen PropellantMass object represents 6/7.

This is a good point to mention wet and dry mass. You can't set the mass of a vessel, only its empty mass and propellant mass. When VesselMass manages the mass, it needs to know what part is dry mass so it can SetEmptyMass(). It also needs to know the total mass of each part so that it can calculate the center of mass and inertia tensor, but it doesn't need to SetPropellantMass() because Orbiter already tracks this. PropellantMass objects instead need to call GetPropellantMass() and then multiply by their mass fraction to get their own mass.

Anyway, PropellantMass is abstract also since there are many kinds of propellant arrangements. There is solid propellant, usually in the form of a hollow tube or sphere. The outside diameter is constant, but the inside changes with time as the propellant burns. There is liquid propellant, usually in the form of a cylinder which has a constant back end (in station coordinates) but gets shorter as propellant is used. There is gas propellant, like the nitrogen in a cold gas jet tank, which keeps the same size and shape and just gets less dense as it is used. Each of these overrides the CoM and I functions appropriate to the conditions.

Finally we have VesselMass, which is a conglomeration of multiple MassElements. It has a step() function which is called from the vessel's clbkPreStep() method and this part actually manages the center of mass and inertia tensor of the vessel. It calls the CoM and I functions for each of the constituent masses, then combines them. The inertia tensor is divided by the total mass, then the diagonal elements are fed into SetPMI(). The VesselMass object remembers where the CoM was last step, and uses ShiftCG() with the difference between the CoM in station coordinates between last time and this time. It also has to manually deal with airfoils and touchdown points. In order to manage the airfoils, you actually attach them to the VesselMass rather than to the vessel directly. VesselMass has a CreateAirfoil3() method which takes positions in station coordinates, then remembers them and creates an airfoil attached to the vessel in CoM coordinates. Whenever the CoM shifts, VesselMass calls EditAirfoil() to handle it.

VesselMass is also a MassElement, so you could potentially do a tree of mass elements. I don't know if this is a good idea yet.

If a VesselMass element knows enough, it could conceivably have a Jettison function which removes the element from the vessel and then creates a new vessel automatically with all the parts of the old stage, including engines and fractionally full propellant resources. So for instance, if a space shuttle were using this and it dropped a booster before its propellant was completely exhausted (like the real shuttle does) the code would strip the dry mass, empty the propellant resource, turn off the engine, then create a new vessel with the dry mass, airfoils, meshes, engines, and prop resources representing the still-burning booster, all automatically. Basically, you attach prop resources, thrusters, and meshes to a VesselMass like you currently attach airfoils.
 
Back
Top