# SDK QuestionVessel orientation

Hello,

I am developing the ground release code for UCSO. I am using this code:

Code:
	if (vessel->GetFlightStatus() & 1) {
VESSELSTATUS2 status;
memset(&status, 0, sizeof(status));
status.version = 2;
vessel->GetStatusEx(&status);

double angularDistance = releaseDistance / radius;
double trueCourse = 180 * (PI / 180);

double releaseLatitude = asin(sin(latitude) * cos(angularDistance) + cos(latitude) * sin(angularDistance) * cos(trueCourse));

double dLongitude = atan2(sin(trueCourse) * sin(angularDistance) * cos(latitude),
cos(angularDistance) - sin(latitude) * sin(releaseLatitude));

double releaseLongitude = fmod(longitude + dLongitude + PI, 2 * PI) - PI;

status.surf_lng = releaseLongitude;
status.surf_lat = releaseLatitude;

if (vessel->DetachChild(attachsMap[pair.first], 0.0)) {
cargo->DefSetStateEx(&status);
if (isTotalMassGet) totalCargoMass -= cargo->GetMass();
cargoReleased = true;
}
else cargoReleased = false;
}

The orientation should be the same as the parent vessel orientation, but this isn't the case:

Scenario parameters:
Code:
ShuttlePB:ShuttlePB_UCSO ;Parent vessel
STATUS Landed Earth
POS -80.6758980 28.5227620
[COLOR="Red"]ALT 1.287[/COLOR]
[COLOR="Red"]AROT -86.168 -72.488 146.453[/COLOR]
AFCMODE 7
PRPLEVEL 0:1.000000
NAVFREQ 0 0
END
ShuttlePB1:ShuttlePB_UCSO ;Cargo
STATUS Landed Earth
POS -80.6758980 28.5227170
[COLOR="Red"]ALT 0.000[/COLOR]
[COLOR="Red"]AROT -54.479 -64.756 112.835[/COLOR]
AFCMODE 7
PRPLEVEL 0:1.000000
NAVFREQ 0 0
END

You can see the difference in the orientation and altitude. If I copied the orientation and the altitude from the parent to the cargo, it appears correctly. How to do that in code?

Last edited:

#### fred18

Donator
Take a look at the source code of my generalvehicle addon, it shows how to deal with landed vessels and vesselstatus. The arot parameter isn't trivial, have a look at the code i mentioned. while to set the altitude from the ground you need iirc to set the vrot.x parameter. I can t attach links now because i m from the phone.

In anycase i d say that what you are experiencing is this: the arot and the altitude change meaning when a vessel is landed, especially arot. It becomes relative to the planet and not to the general reference system (this allows orbiter s core to manage landed vessels easily also at high time accelerations). So i think that somehow the issue is around this point. I will give it a deeper look when i ll have a pc available

#### N_Molson

Donator
I'm not a specialist but I would say it has (a lot) to do with VESSELMATRIX

#### Woo482

##### Moderator
Moderator
GFX Staff
If you're wanting to copy the attitude / heading of the vessel that deployed the cargo vessel it should be possible to avoid touching arot at all - this is how I've solved it in oMMU:
Code:
/* New MMU status variables */
VESSELSTATUS2 vesselStatus;
memset(&vesselStatus, 0, sizeof(vesselStatus));
vesselStatus.version = 2;
pParentVessel->GetStatusEx(&vesselStatus); // Copy parent state

/* Calculate degrees / meter */
double metersPerDegree = (planetRadius * 2 * PI) / 360;

VECTOR3 rotatedPosition; // Holds the airlock position after being converted to horizon frame
pParentVessel->HorizonRot(airlock.position, rotatedPosition);

/* Update the position of the MMU vessel to be at the airlock */
vesselStatus.surf_lat += (rotatedPosition.z / metersPerDegree) * RAD;
vesselStatus.surf_lng += (rotatedPosition.x / metersPerDegree) * RAD;

auto mmuVessel = oapiCreateVesselEx(mmuName, "oMMU", &vesselStatus);

It's probably not as robust a solution as calculating a new arot - but there's definitely a lot less math involved :lol:

Many thanks Fred! Your GenericVehicle code worked perfectly. I've modified it slightly (just removed xyz parameter from RotationMatrix, as it's always true) Here is the code:

Code:
		MATRIX3 rot1 = RotationMatrix({ 0 * RAD, 90 * RAD - releaseLongitude, 0 * RAD });
MATRIX3 rot2 = RotationMatrix({ -releaseLatitude + 0 * RAD, 0, 0 * RAD });
MATRIX3 rot3 = RotationMatrix({ 0, 0, 180 * RAD + status.surf_hdg });
MATRIX3 rot4 = RotationMatrix({ 90 * RAD, 0, 0 });
MATRIX3 RotMatrix_Def = mul(rot1, mul(rot2, mul(rot3, rot4)));

status.arot.x = atan2(RotMatrix_Def.m23, RotMatrix_Def.m33);
status.arot.y = -asin(RotMatrix_Def.m13);
status.arot.z = atan2(RotMatrix_Def.m12, RotMatrix_Def.m11);

I found that the GetMeshLowerPoint always returns 0, so it's unnecessary to change vrot. I've added your name to the credits list

@Woo482: Thanks for your code, but the same problem happened. Maybe it's due to mesh/touchdown points difference, as I am using 2010 touchdown points, not 2016 ones.

Last edited:

If you're wanting to copy the attitude / heading of the vessel that deployed the cargo vessel it should be possible to avoid touching arot at all - this is how I've solved it in oMMU:
Code:
/* New MMU status variables */
VESSELSTATUS2 vesselStatus;
memset(&vesselStatus, 0, sizeof(vesselStatus));
vesselStatus.version = 2;
pParentVessel->GetStatusEx(&vesselStatus); // Copy parent state

/* Calculate degrees / meter */
double metersPerDegree = (planetRadius * 2 * PI) / 360;

VECTOR3 rotatedPosition; // Holds the airlock position after being converted to horizon frame
pParentVessel->HorizonRot(airlock.position, rotatedPosition);

/* Update the position of the MMU vessel to be at the airlock */
vesselStatus.surf_lat += (rotatedPosition.z / metersPerDegree) * RAD;
vesselStatus.surf_lng += (rotatedPosition.x / metersPerDegree) * RAD;

auto mmuVessel = oapiCreateVesselEx(mmuName, "oMMU", &vesselStatus);

It's probably not as robust a solution as calculating a new arot - but there's definitely a lot less math involved :lol:

Thank you very much! Your code made my life much easier without a lot of distance calculations for the cargo deployment position! I still need Fred18 code.

Code:
		VECTOR3 pos;
vessel->GetAttachmentParams(attachsMap[slot], pos, VECTOR3(), VECTOR3());

pos.x += releaseDistance;

double metersPerDegree = (oapiGetSize(status.rbody) * 2 * PI) / 360;

vessel->HorizonRot(pos, pos);

status.surf_lng += (pos.x / metersPerDegree) * RAD;
status.surf_lat += (pos.z / metersPerDegree) * RAD;

status.vrot.x = 0.65;