SDK Question Vessel orientation

Abdullah Radwan

Addon Developer
Addon Developer
Joined
Aug 20, 2017
Messages
206
Reaction score
2
Points
18
Location
Cairo
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 longitude, latitude, radius;
		vessel->GetEquPos(longitude, latitude, radius);

		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
  HEADING 109.16
  [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
  HEADING 109.16
  [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

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,629
Reaction score
3
Points
38
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

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
6,856
Reaction score
0
Points
0
Location
Toulouse
I'm not a specialist but I would say it has (a lot) to do with VESSELMATRIX
 

Woo482

Moderator
Moderator
Addon Developer
GFX Staff
Joined
Feb 13, 2008
Messages
3,048
Reaction score
0
Points
61
Location
Earth?
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 planetRadius = oapiGetSize(pParentVessel->GetSurfaceRef());
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:
 

Abdullah Radwan

Addon Developer
Addon Developer
Joined
Aug 20, 2017
Messages
206
Reaction score
2
Points
18
Location
Cairo
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:

Abdullah Radwan

Addon Developer
Addon Developer
Joined
Aug 20, 2017
Messages
206
Reaction score
2
Points
18
Location
Cairo
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 planetRadius = oapiGetSize(pParentVessel->GetSurfaceRef());
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;

		MATRIX3 rot1 = RotationMatrix({ 0 * RAD, 90 * RAD - status.surf_lng, 0 * RAD });
		MATRIX3 rot2 = RotationMatrix({ -status.surf_lat + 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);
		status.vrot.x = 0.65;
 
Top