Advanced Question How to create a VESSELSTATUS2 that spawns a vessel at a certain position relative to

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,882
Reaction score
2,133
Points
203
Location
between the planets
...another vessel. looks like I breached the allowed number of characters for the title :shifty:

I need to spawn a vessel at a position relative to an already existing vessel. I figured this should be fairly trivial (at least the position, we'll see about the orientation later... :shifty:) given Orbiter provides the frame conversions, but since my results aren't even close to what I expected, I must assume that I have a fundamental misunderstanding somewhere.

Here's my current code to create the VESSELSTATUS2 struct (pos is the position relative to the vessel at which the new vessel should spawn, vessel is obviously a pointer to the vessel itself):

Code:
	VESSELSTATUS2 vs;
	memset(&vs, 0, sizeof(vs));
	vs.version = 2;
	vessel->GetStatusEx(&vs);

	//transform relative position to global coordinates
	VECTOR3 globalpos;
	oapiLocalToGlobal(vessel->GetHandle(), &pos, &globalpos);
	//transform them back to coordinates relative to the reference body
	VECTOR3 equpos;
	oapiGlobalToLocal(vs.rbody, &globalpos, &equpos);
	vs.rpos = equpos;
	oapiCreateVesselEx("testsplit", _orbiter_data->getClassName().data(), &vs);

It seems like the most obvious use of the provided conversions, but the newly spawned vessel ends up nowhere near where I intended it to.

I have checked in clbkSetStateEx that the status received is the same as what's being sent, and yes, I am calling the method on the subclass, so that's the two most obvious problems I could think of out of the way.
 
Last edited:

dbeachy1

O-F Administrator
Administrator
Orbiter Contributor
Addon Developer
Donator
Beta Tester
Joined
Jan 14, 2008
Messages
9,218
Reaction score
1,566
Points
203
Location
VA
Website
alteaaerospace.com
Preferred Pronouns
he/him
XR vessels do something similar when deploying payload module vessels while the ship is landed (i.e., to unload them). Here is the code:

Code:
VECTOR3 deployToCoords = GetLandedDeployToCoords(slotNumber);   // get from the subclass; these are ship-local coordinates

// Detach the child vessel.
DetachChild(slotNumber, 0.0);    // no delta-V

// obtain the child's coordinates
VESSELSTATUS2 childVS;
VESSEL3_EXT::GetStatusSafe(*pChild, childVS, false);

// move the child to the deployToCoordinates by converting them (as a delta) from parent-local to GLOBAL coordinates
VECTOR3 globalChildDeltaCoords;
GetParentVessel().GlobalRot(deployToCoords, globalChildDeltaCoords);

// now take the parent's rpos, apply the delta, and store it in the child's VS
VESSELSTATUS2 parentVS;
VESSEL3_EXT::GetStatusSafe(GetParentVessel(), parentVS, false); 
childVS.rpos = (parentVS.rpos + globalChildDeltaCoords);
        
// WARNING: do not force status=1 (landed) here!  It will cause the "bounce bug" and crash Orbiter.
childVS.status = 0;                  // set to FREEFLIGHT
pChild->DefSetStateEx(&childVS);     // update the vessel's state with the new location

VESSEL3_EXT::GetStatusSafe, BTW, is a simple wrapper method I created that zeros out all fields inside the VESSELSTATUS2 structure before passing it to Orbiter's Vessel.GetStatusEx method. There are some fields that the core's VESSEL.GetStatusEx leaves uninitialized (I don't recall which ones now), and that was causing me some issues. :p Here is the relevant code:

Code:
void VESSEL3_EXT::GetStatusSafe(const VESSEL &vessel, VESSELSTATUS2 &status, const bool resetToDefault)
{
    // Initialize entire structure to zero before invoking the read from the core.
    memset(&status, 0, sizeof(status));
    status.version = 2;   // retrieve version 2 = VESSELSTATUS2
    vessel.GetStatusEx(&status);
    ... stuff dealing with resetToDefault parameter snipped since it's not relevant here...
}
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,882
Reaction score
2,133
Points
203
Location
between the planets
Thanks. Your code made me aware that there were some class methods of VESSEL itself to do transformations, and Local2Rel does the trick in one call.

Now for the rotation... oh dear, why does it have to be in euler angles? My mind starts doing loopings when it tries to think about those... :shifty:

---------- Post added at 11:39 PM ---------- Previous post was at 10:10 PM ----------

No dice with the rotations yet... found several tutorials on how to convert directional vectors to euler angles, but somehow they don't seem to work out. Here's to hoping the headache I incurred in the last 2 hours will be gone after a good nights rest... :shifty:
 

Capt_hensley

Captain, USS Pabilli
Donator
Joined
Oct 20, 2010
Messages
841
Reaction score
0
Points
16
Location
Alamogordo
Website
www.h-10-k.com
Dude when you get this figured out, write a tutorial video. I'm no where near your caliber and could use this for GWS.
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,882
Reaction score
2,133
Points
203
Location
between the planets
Heh, turns out I was reading the VESSELSTATUS2::arot documentation rather uncarefully. It says the angles have to be in ecliptic frame, while I figured this to mean the equatorial frame (as all the other stuff has to be in equatorial frame coordinates, but I guess that the property is called a(bsolute)rot should have tiped me off). And it turns out that the ecliptic frame is the same as the global frame. That makes things somewhat easier, I think I should be able to get it now.

Also, headache is gone. Here we go...

Dude when you get this figured out, write a tutorial video.

I never made a video ever, and I don't plan on starting, but can certainly post the procedure here when (if) I'm succesful.
 

francisdrake

Addon Developer
Addon Developer
Joined
Mar 23, 2008
Messages
1,085
Reaction score
901
Points
128
Website
francisdrakex.deviantart.com
This is what I do to create the drogue chute as a separate object near my vessel. Note it has a linear location offset "ofs" and a speed vector offset "vel", both of at a value of -2 m (m/s) in z-direction.
A cfg-file is needed for the new object, which is called at the end with oapiCreateVessel(). For the name you could use a simple string, the GetName() here is just to inherit the parent vessels name and add "-Drogue" to it.

Code:
void CEV::blowDrogue() {		// Create the drogue as an individual object
			VESSELSTATUS vs;
			GetStatus (vs);
			vs.flag[0] = 3;
			VECTOR3 ofs = {0,0,-2};
			Local2Rel (ofs, vs.rpos);

			VECTOR3 vel = _V(0,0,-2);
			VECTOR3 rofs, rvel = {vs.rvel.x, vs.rvel.y, vs.rvel.z};
			Local2Rel (ofs, vs.rpos);
			GlobalRot (vel, rofs);
			vs.rvel.x = rvel.x+rofs.x;
			vs.rvel.y = rvel.y+rofs.y;
			vs.rvel.z = rvel.z+rofs.z;

			char name[256];
			strcpy (name, GetName()); strcpy (name, "-Drogue");
			oapiCreateVessel (name, "Orion-MPCV\\Orion-MPCV-Drogue", vs);
}
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,882
Reaction score
2,133
Points
203
Location
between the planets
Thanks, that helped me figure out velocity. I had forgotten about GlobalRot and was trying to get the vector by using Local2Rel and subtracting the position, which for some reason did not work... Though I'm not sure why.

I'm also not sure why just using the vessel handle as reference body leads to switched out axes and inprecisions.

But the battle about the rotation is still wageing. I have succesfully rotated the direction by multiplying the vessels rotation matrix by the relative transformation matrix of the new vessel, but when I put the transformation for the relative rotation on top of that, it rotates around the wrong axis. Looks like I have to calculate another matrix for the rotation, but I'm not sure yet how and why...

---------- Post added at 12:10 PM ---------- Previous post was at 10:37 AM ----------

The good news is I have it working with matrix rotations and VESSEL::SetRotationMatrix(), the bad thing is that when I convert that matrix to euler angles to pass to the VESSELSTATUS2 struct, everything goes to hell. I have gone through several matrix-to-euler transformations, and none of them have worked out. I'm a bit stomped, frankly. If somebody could just post the equations how to do it for Orbiter, I'd be much obliged (it is kind of annoying to have to transform the matrix to angles, knowing that Orbiter will just transform them back anyways...).
 
Top