Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

Orbiter SDK Orbiter software developers post your questions and answers about the SDK, the API interface, LUA, meshing, etc.

Reply
 
Thread Tools
Old 09-16-2016, 03:17 AM   #1
dbeachy1
O-F Administrator
 
dbeachy1's Avatar


Default Cancelling out a vessel's surface-relative motion using DefSetStateEx?

I've been digging into adding a hack to the XR vessels to work around this Orbiter core bug, but I'm seeing some odd behavior with DefSetStateEx, and now I'm wondering if I can even use that method to do what I want.

My goal with this hack is to cancel out any vessel motion relative to the surface of the body on which it's landed, but I can't even get that far. Right now I have added this code as a test to my ParkingBrakePreStep, which should not change the ship's velocity at all, but invoking DefSetStateEx even without changing any fields in it causes the vessel to spin wildly while landed:

Code:
VESSELSTATUS2 status;
// Initialize entire structure to zero before invoking the read from the core since the core does not initialize all the fields in GetStatusEx, which can crash DefSetStateEx
memset(&status, 0, sizeof(status));
status.version = 2;   // retrieve version 2 = VESSELSTATUS2
GetXR1().GetStatusEx(&status);
// PROBLEM: invoking DefSetStateEx even with no changes causes the vessel to spin wildly while landed
GetXR1().DefSetStateEx(&status);
I also looked into using VESSEL::SetElements, but that won't work because the docs say:

Quote:
Originally Posted by VESSEL::SetElements
 Calling SetElements will always put a vessel in freeflight mode, even if it had been landed before.
I am already successfully using VESSEL::DefSetState to spawn or move cargo vessels, but it seems that when I use it on a landed vessel, chaos ensues. Any advice would be much appreciated -- I'm stuck on this one.
dbeachy1 is offline   Reply With Quote
Old 09-16-2016, 05:24 AM   #2
fred18
Addon Developer

Default

Hi,

there is an issue with the default orbiter2016 distribution (which should be solved in the svn version) because GetStateEx and DefSetState had issues about rotation of landed vessels.

I solved it in the following way:

Get the status of the vessels you want to be landed, impose the status =1, save it to a ghost scenario file, recall it with clbkloadstateex and that works.

Here's the code snippet I used in MS2015:
Code:
VESSELSTATUS2 vs2;
	memset(&vs2,0,sizeof(vs2));
	vs2.version=2;
	GetStatusEx(&vs2);
        vs2.status=1;

	if(oapiGetOrbiterVersion()<160903)
		{
		FILEHANDLE fh=oapiOpenFile("\\Multistage2015\\__Crawl",FILE_OUT,CONFIG);
		oapiWriteScenario_string(fh,"STATUS","Landed Earth");
		oapiWriteScenario_float(fh,"HEADING",vs2.surf_hdg*DEG);
		char position[256];
		sprintf(position,"%.20f %.20f",vs2.surf_lng*DEG,vs2.surf_lat*DEG);
		oapiWriteScenario_string(fh,"POS",position);
		oapiCloseFile(fh,FILE_OUT);
		fh=oapiOpenFile("\\Multistage2015\\__Crawl",FILE_IN,CONFIG);
		clbkLoadStateEx(fh,&vs2);
		oapiCloseFile(fh,FILE_IN);	
		}
		DefSetStateEx(&vs2);
fred18 is offline   Reply With Quote
Old 09-16-2016, 04:37 PM   #3
dbeachy1
O-F Administrator
 
dbeachy1's Avatar


Default

Thanks for the info about the Orbiter core bug with DefSetStateEx. I'll have to see if I can get your hack working in my ParkingBrakePreStep (hopefully it will perform well enough since I only need to do it if the ship is not already landed and the parking brakes have engaged).

I have to say, that's probably the ugliest (and cleverest) hack I've seen in a long time, and now I will have to implement a hack in order to implement another hack. I'm glad the DefSetStateEx core bug is fixed in the latest Orbiter beta -- hopefully the 'restless spacecraft' bug that I am trying to hack around will also get fixed soon.
dbeachy1 is offline   Reply With Quote
Thanked by:
Old 09-17-2016, 02:08 AM   #4
dbeachy1
O-F Administrator
 
dbeachy1's Avatar


Default

Well, I got the hack working! I also had to save the ship's landing gear status and retrieve the name of the planet it is landed on when constructing the temporary scenario file, but it appears to work! Now why do I feel so dirty?
dbeachy1 is offline   Reply With Quote
Thanked by:
Old 09-17-2016, 07:15 AM   #5
fred18
Addon Developer

Default

well I needed just a few parameters with the crawler of multistage, maybe you can call the entire savestate by clbkSaveState(...) with the handle of your file, I don't know if it works that way. It's really a dirty hack, I know, but with the official 2016 is the only way I found to overcome the issue
fred18 is offline   Reply With Quote
Old 09-13-2017, 10:08 AM   #6
fred18
Addon Developer

Default

Since the one I used above was just a dirti hack and in the meantime I came up with a clean solution in the general vehicle module, before people start to use the solution above as a "good" one, here's below the correct solution to this:



Code:
        VESSELSTATUS2 vs2;
        memset(&vs2, 0, sizeof(vs2));
	vs2.version = 2;
	GetStatusEx(&vs2);

	double lng, lat, hdg;
	lng = vs2.surf_lng;
	lat = vs2.surf_lat;
	hdg = vs2.surf_hdg;

////OR MAKE SURE THAT LATITUDE, LONGITUDE AND HEADING ARE THE ONE YOU WANT!


                MATRIX3 rot1 = RotationMatrix(_V(0 * RAD, (90 * RAD - lng), 0 * RAD), TRUE);
		MATRIX3 rot2 = RotationMatrix(_V(-lat + 0 * RAD, 0, 0 * RAD), TRUE);
		MATRIX3 rot3 = RotationMatrix(_V(0, 0, 180 * RAD + hdg), TRUE);
		MATRIX3 rot4 = RotationMatrix(_V(90*RAD, 0, 0), TRUE);


	
		MATRIX3 RotMatrix_Def = mul(rot1, mul(rot2, mul(rot3, rot4)));


		vs2.arot.x = atan2(RotMatrix_Def.m23, RotMatrix_Def.m33);
		vs2.arot.y = -asin(RotMatrix_Def.m13);
		vs2.arot.z = atan2(RotMatrix_Def.m12, RotMatrix_Def.m11);
		vs2.vrot.x = Height_From_Ground ;
		
		DefSetStateEx(&vs2);
Where the rotation matrix function is:
Code:
MATRIX3 GeneralVehicle::RotationMatrix(VECTOR3 angles, bool xyz = FALSE)
{
	MATRIX3 m;
	MATRIX3 RM_X, RM_Y, RM_Z;
	RM_X = _M(1, 0, 0, 0, cos(angles.x), -sin(angles.x), 0, sin(angles.x), cos(angles.x));
	RM_Y = _M(cos(angles.y), 0, sin(angles.y), 0, 1, 0, -sin(angles.y), 0, cos(angles.y));
	RM_Z = _M(cos(angles.z), -sin(angles.z), 0, sin(angles.z), cos(angles.z), 0, 0, 0, 1);
	if (!xyz) {
		m = mul(RM_Z, mul(RM_Y, RM_X));
	}
	else {
		m = mul(RM_X, mul(RM_Y, RM_Z));
	}
	return m;
}
fred18 is offline   Reply With Quote
Thanked by:
Reply

  Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 06:55 AM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright 2007 - 2017, Orbiter-Forum.com. All rights reserved.