C++ Question How to use "clbkLoadStateEx" within a MFD ?

turtle91

Active member
Joined
Nov 1, 2010
Messages
319
Reaction score
7
Points
33
Hi there :hello:

Currently I am trying to implement Fred18's MS2015 "hack" to force a vessel to be in "idle" state, to avoid endless slipping over the surface.

I just want this workaround available for all vessels.


I need to underline, that I have very low knownledge in C++.
And I know, starting writing an Orbiter-MFD to learn C++ is not the best idea.

However...no risk..no fun.

Because I need just one button (BRAKE), I thought LUA might be a better option...but I was wrong.
Quering EQU-POS crashed Orbiter, while using i.e. "Heading" was no problem.
Also there seem to be no way to set a vessel to IDLE state in LUA.
All in all LUA seems to be a bit unstable (i.e. the EQU-POS-query was no problem when using the LUA-console, but within SCRIPT-MFD, I just got a CTD...same for GLOBAL-POS....+no feedback from the LUAinterpreter to trouble-shoot this....so...I am finished with LUA.....:compbash2:


Ok...:eek:fftopic:...back to my problem.
I got to the point, where I can write the POS,HEADING and VESSEL-STATE into a temp. SCN-file...just to re-read it in again(to force a vessel to IDLE-sate).

But when it comes to re-read the SCN, I am stuck with the syntax.
According to the API, there is only an example where the SCN-file will be read-out from an own VESSEL-(class).

But what syntax to use, when I just want to use the current-focused-vessel within a MFD ?

Something like this, seems to be complete wrong:

Code:
void apiGetFocusInterface()::clbkLoadStateEx(FILEHANDLE scn,void *vs2)

:OMG:

So this:

Code:
clbkLoadStateEx(fh,&vs2)

..cannot be used...the IDE complains about not defined (I guess caused by the previous wrong syntax).

All I need is "just" the MFD'ish version of what can be found within the API-Reference on page 630.


Code:
class MyVessel: public VESSEL2 {
public:
...
clbkLoadStateEx (FILEHANDLE scn, void * status);
...
};
void MyVessel::clbkLoadStateEx (FILEHANDLE scn, void * status)
{
char * line;
int my_value;
while (oapiReadScenario_nextline (scn, line)) {
if (!strnicmp (line, "my_option", 9)) { // custom item
sscanf (line+9, "%d", &my_value);
} else if (...) { // more items
...
} else { // anything not recognised is passed on to Orbiter
ParseScenarioLineEx (line, vs);
}
}
}


This like seems to be my main-problem (+the lack of C++ knownledge):

"void MyVessel::clbkLoadStateEx (FILEHANDLE scn, void * status)"

How to write this in a MFD-instance for the current active-vessel?
I guess I need to access the vessel-class via a "handler(?)" or "interface(?)" (again...C++....I am more on C-- level...).
Maybe somebody could give me a hint ?

:thankyou:
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,564
Reaction score
2,298
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
You are on the wrong track there. I think you want to manipulate the vessel state during run-time, which is usually better done by the VESSELSTATUSx structure.

The parser code for vessels is highly vessels specific and can't be used outside a vessel class. Orbiter calls this parser when it loads the state of a new vessel and lets it read the file until the block for the vessel ends. Then the next vessel is read and so on.

If you really want to manipulate saved scenarios off-line (when Orbiter is not running), I would recommend Lua and the powerful regular expression functions of it. You need no full parser then, just something intelligent enough.
 

turtle91

Active member
Joined
Nov 1, 2010
Messages
319
Reaction score
7
Points
33
So....something like this: http://www.orbiter-forum.com/showthread.php?t=37527
..is not possible via a MFD ?

IMHO it should at least for basic vessels without any special custom "flags", which might be used to be in a sensefull "landed IDLE" state.

I mean all I need for a standard vessel is to set:

-the IDLE flag
-the (local)HEADING
-the EQU-POS

But to your question...yes...changing the state during runtime like the MS2015-Crawler or the XR-Vessels, where this workaround has been implemented.
I know...it's just a workaround...but it seems workarounding the Orbiter-slip-forever-problem quite nicely.


That's what needs to be re-read and re-aplied to the current active vessel(example RW33 KSC... full stop):

STATUS Landed Earth
HEADING 330.06
POS -80.68303660000000800000 28.59759629999999900000

If I get this working, all I need is to query the major-body, which is still hardcoded to Earth at the moment.
 
Last edited:

turtle91

Active member
Joined
Nov 1, 2010
Messages
319
Reaction score
7
Points
33
Many thanks for looking into this.
It might would help others, esp to avoid crashing Orbiter while Orbiter is doing surface-contact-calculations-overkill during time-warp.

And...yes....it's about Orbiter 2016(standard release).
I guess I have just some kind of a syntax-error...which I am not able to resolve. :idk:
I checked the sources for many other MFD's (to learn), but it seems to be, that nobody has done something like this before within a MFD.
 
Last edited:

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,666
Reaction score
100
Points
78
I have to light a warning here:

In the post you linked there's my old hack for official orbiter 2016 edition. That works, but it's a hack. The issue that makes the hack needed has been solved by martin and the hack is not needed anymore in the svn edition of orbiter.

The issue was that during save and restore of a vesselstatusX the arot parameter was not saved/reloaded for landed vessels.

Moreover, during the development of the new Space Network plugin I think I solved also the issue that made the hack needed by calculating the AROT parameters for a landed vessel by myself. Now I don't have the code available immediatly but if that's the issue I can dig a bit in the HD and post it. That could make the hack not needed anymore.

EDIT: I have to say that I read the original post too quickly and didn't realize that it's exactly this :lol: let me look at the code and get back

---------- Post added at 18:56 ---------- Previous post was at 18:48 ----------

ok found it:

this is a code snippet that I'm using to create landed vessels (dsn stations in this case), that stay where I want and upright, after that I paste also the "RotationMatrix" function that I use, feel free to ask if it's not clear

Code:
oapiWriteLog("Space Network: Creating DSNs");
		dsn_h=new OBJHANDLE[n_dsn+1];
		
		VESSELSTATUS2 vsdsn;
		memset(&vsdsn,0,sizeof(vsdsn));
		vsdsn.version=2;
		OBJHANDLE hearth=GetHomePlanet();//oapiGetObjectByName("Earth");
		vsdsn.rbody=hearth;
		vsdsn.status=1;
		for(UINT i=1;i<=n_dsn;i++)
		{
			
			
			vsdsn.surf_lng=dsn_data[i].Long*RAD;
			vsdsn.surf_lat=dsn_data[i].Lat*RAD;
			vsdsn.surf_hdg=dsn_data[i].Heading*RAD;
			
			MATRIX3 rot1=RotationMatrix(_V(0,(90-dsn_data[i].Long)*RAD,0*RAD),TRUE);
			MATRIX3 rot2=RotationMatrix(_V((-dsn_data[i].Lat)*RAD,0,0*RAD),TRUE);
			MATRIX3 RotMatrix_Def=mul(rot1,rot2);
		
			vsdsn.arot.x=atan2(RotMatrix_Def.m23,RotMatrix_Def.m33);
			vsdsn.arot.y=-asin(RotMatrix_Def.m13);
			vsdsn.arot.z=atan2(RotMatrix_Def.m12,RotMatrix_Def.m11);
			
			
		
			
			dsn_h[i]=oapiCreateVesselEx(dsn_data[i].name.c_str(),dsn_data[i].module.c_str(),&vsdsn);
			VESSEL *v;
			v=oapiGetVesselInterface(dsn_h[i]);
			v->SetEnableFocus(dsn_data[i].Focus);
			
			RP->AddNetworkElement(dsn_data[i].name,Dsn);
		}
	}

Code:
MATRIX3 SpaceNetwork2016::RotationMatrix(VECTOR3 angles,bool xyz)
 {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;
 }
 
Last edited:

turtle91

Active member
Joined
Nov 1, 2010
Messages
319
Reaction score
7
Points
33
Many thanks Fred,

I realy like this hack, it would make landing on rough terrain much easier(or even possible).
The problem is.

to CREATE landed vessels (dsn stations in this case), that stay where I want and upright

So you are creating new vessels with correct LAT/LNG, AROT and STATUS parameter.
But how to change this parameters in allready existing vessels using an MFD ..(or dialog-box)?

Btw...thanks to your post, I got another idea how this (possible) MFD would be extended: a "FLIP-OVER-BUTTON (FOB)".
Just in case someone experiments with this complicated touchdown-points-damping-stuff. If something goes wrong just hit "BRAKE(for SCN-IDLE) and FOB(for flip-over...using SCN-AROT)". :)
 

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,666
Reaction score
100
Points
78
The problem is.

So you are creating new vessels with correct LAT/LNG, AROT and STATUS parameter.
But how to change this parameters in allready existing vessels using an MFD ..(or dialog-box)?

use DefSetStateEx function to set the vessel state what you want.

I suggest to do something like (pseudo code):
Code:
VESSELSTATUS2 vs2;
memset(&vs2,0,sizeof(vs2));
vs2.version=2;
v->GetStatusEx(vs2);  ///OR GetStatusEx(&vs2); can't remember
vs2.status=1;
...
... arot calcs
...

v->DefSetStateEx(vs2);
 

turtle91

Active member
Joined
Nov 1, 2010
Messages
319
Reaction score
7
Points
33
That's what I hve tried, but the problem seems to be to access the vessel from the MFD.
Here is what I have, it's more or less a copy+paste from your crawler: :embarrassed:

Code:
VESSELSTATUS2 vs2;
	memset(&vs2,0,sizeof(vs2));
	vs2.version=2;
	
	v->GetStatusEx(&vs2);
	
	{
		FILEHANDLE fh=oapiOpenFile("\\brake_hack\\__STATE",FILE_OUT,CONFIG);
		oapiWriteScenario_string(fh,"STATUS","Landed Earth");  ///still hardcoded t 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("\\brake_hack\\__STATE",FILE_IN,CONFIG);
		  
		
void VesselHandle::clbkLoadStateEx(FILEHANDLE scn,void *vs) {   //This line seems to be very wrong
	
        char *line;
	while(oapiReadScenario_nextline(scn,line)){
		
		
		
			  ParseScenarioLineEx(line,vs);
		  
	}
 clbkLoadStateEx(fh,&vs2);


		oapiCloseFile(fh,FILE_IN);	
		}
		  v->DefSetStateEx(&vs2);
 

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,666
Reaction score
100
Points
78
There's no need of the vesselhandle::... part

Just do v->clbkloadstateex
 

turtle91

Active member
Joined
Nov 1, 2010
Messages
319
Reaction score
7
Points
33
If I do this, I get a complaint about:

"clbkloadstateex " is not a member of class "VESSEL".


Main problem in Orbiter 2016 is this vessel-on-ice-issue, IMHO.
The hardest part in every Orbiter 2016 mission is NOT:
-to set up transx to perform i.e. complicated slingshots
-to do all LOX/FUEL planning
-to do an aerocapture + reentry

No...the hardest most complicated part is just to stop a vessel.
 
Last edited:

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,564
Reaction score
2,298
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
C++ is case-sensitive, never forget this. Also VESSEL does not have this callback, its part of VESSEL2.

Next.... why, oh, why? Why are you even doing this?
 
Last edited:

turtle91

Active member
Joined
Nov 1, 2010
Messages
319
Reaction score
7
Points
33
But as you can see, I have no VESSEL2 or VESSEL defined.
And this seems to be the problem.
According to Fred, I have just to call "v->clbkLoadStateEx".
However, I have expected this. How should the "v->" know, where to belong ?
That's the reason, why I want to use the handler (or interface...I don't know...).
The "v->..." should be used the focused-vessel, that was the plan.

But the most important thing:

...why, oh, why? Why are you even doing this?
Because it's a bit frustrating that after landing, many vessels never stop.
Fighting with RCS and/or brakes and still have 0.04 m/s.
So mulitiple vessels-missions are mostly not possible.
As soon as you switch to the i.e. "in-orbit-vessel" and use time-accell, this happens in most cases:
-the "landed/slipping" vessel jumps into outer-space
and/or
-Orbiter crashes (might be caused by surface-contact-calculations-overkill during time-accel.)

And quiting Orbiter right after landing, just to change the vessel-state to "IDLE landed" is not really an option.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,564
Reaction score
2,298
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
I reordered this a bit for clarity:

Because it's a bit frustrating that after landing, many vessels never stop.

No, why are you trying to call clbkLoadStateEx() of a vessel? You are the wrong caller and you are calling it at the wrong time. You should not do this.

But as you can see, I have no VESSEL2 or VESSEL defined.

You have, in VesselAPI.h, which is part of the OrbiterSDK.

And yes, I know the issue of getting a vehicle to stop. For that you often need to REALLY make the vessel inert.
 

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,666
Reaction score
100
Points
78
No, why are you trying to call clbkLoadStateEx() of a vessel? You are the wrong caller and you are calling it at the wrong time. You should not do this.

he wants to exploit the hack of reloading the vessel from a hidden scenario file when the vessel is written as landed so it force it to idle. if you save only position, heading and the status as landed the vehicle will load them and just stop there.

Anyway, as said above, I strongly suggest to use the other workaround I gave. Mostly because the hack was made for the crawler, which I coded so I had control over the clbkLoadStateEx function. If you put it into an MFD you have the risk of getting strange behaviours there. Many addons use clbkLoadState to reset their variables or many other things, so it will probably not work for a general purpose.

You have, in VesselAPI.h, which is part of the OrbiterSDK.

And yes, I know the issue of getting a vehicle to stop. For that you often need to REALLY make the vessel inert.

I have to say that regarding this it's very hard to REALLY make the vessel inert, I had many hard times, let's say that a "parking breaks" options that force the idle status of a vessel is a good to have.

In any case I think that it's not working anyway because v is just a VESSEL, while you need to cast it to VESSEL2, that's because IIRC v is the pointer passed on the MFD class creation, so it refers to the focus vessel. So maybe something like:
Code:
(VESSEL2*)v->...
could work?
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,564
Reaction score
2,298
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
So maybe something like:
Code:
(VESSEL2*)v->...
could work?

Yes, should work, though there are better suited operators for it.

reinterpret_cast<VESSEL2*>(vessel)-> ...

for example
 

turtle91

Active member
Joined
Nov 1, 2010
Messages
319
Reaction score
7
Points
33
Here the working code from MS2015's crawler:

Code:
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);

My understanding:
fh=oapiOpenFile("\\Multistage2015\\__Crawl",FILE_IN,CONFIG)
///////////read the written stuff from the temp. SCN-file
clbkLoadStateEx(fh,&vs2);
////////// brute-force the status-stuff into the VESSEL's VESSELSTATUS2' pointer (&vs2)
oapiCloseFile(fh,FILE_IN)
//////////
release/close the temp. scn-file
/////and finally:
DefSetStateEx(&vs2)
///// apply read-out SCN-stuff(the "new" VESSELSTATUS2 to the vessel( the crawler int his case)

I know, this might be a dirty hack, but it works.
And again, I am not a C++ developer or a developer in general.
That's the reason, why I tried the easy way.... using LUA.
But LUA is not reliable in Orbiter.
I.e. from ScriptMFD, I can query altitude/atm-stuff without any problems.
But if queried EQU-POS (or any other position-data), I got CTD's without any feedback from LUA.
Using the same queries within the LUA-console, all worked fine.
So...I tried to "make"(or....copy+paste) a C++ MFD-plugin to have this "emergency-brake" for all vessels.

---------- Post added at 02:43 PM ---------- Previous post was at 02:29 PM ----------

Thanks guys.

So if re-interpret might be an option, I need to perform sanity checks on the focused vessel. I.e. "is it a VESSEL or VESSEL2 ....etc).

But more and more, I believe it's better (at least for me)to stay at Orbiter2010 for the more serious/complicated/multi-vessel missions.

I don't want to hack a MFD which might cause more problems like we might have allready.

Using Orbiter2016 for a quick eye-candy flight is ok for me, but I think I will stay on 2010 for the moment.

However many thanks again.:thumbup:

---------- Post added 01-20-17 at 12:03 PM ---------- Previous post was 01-19-17 at 02:43 PM ----------

Maybe a better...more safe approach for some kind of a "surface-brake-mfd":

-MFD creates a vessel2 on currents user location
-the new created vessel2 should be created as "IDLE landed" at user (EQU)position
-the new ceated vessel2 will attach the user-vessel (so movements stops)
-on user demand, the user-vessel will be detached (release handbrake)
-the "brake"-vessel2 will then be removed from the SCN

The only problem with this approach would be, that the user must define an attachment-point on his vessel...somewhere near of one of the touch-down-points

OR...no sure if this is be possible:

The MFD will create a new temp. attachment-point close to one of the user-vessels touch-down-points.
I am not sure if the touch-down-point-coordinates can be queried outside the vessel....
:hmm:
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,564
Reaction score
2,298
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Why not like this:

  1. Get the state of the target vessel, including thruster levels
  2. Edit the state to IDLE and reset all thruster levels to 0.0, disable autopilot modes.
  3. Set the state of the vessel to the manipulated state
 

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,666
Reaction score
100
Points
78
The landed vessel can create the attachment point on the moving vessel, check in ms2015 the creation of the launchpad, by default it's an invisible vessel, pretty much what you want to do. Maybe you don't need to know the touchdown points: attachment can be anywhere, we just care about the visual, right? Then you can have the attachment point of the moving vessel in its (0,0,0), and query for its position with reference to the planet. In orbiter 2010 i would have said that the height from the ground would be the difference between distance from the planet and the planet radius, so you would just need to put the attachment point of the landed vessel at that height from the ground. In the new orbiter it's not true, but i'm sure that if you dig a bit you can find a way (i'm thinking i.e. of first creating the landed vessel, find its distance from planet center, then apply the attachment)

---------- Post added at 13:26 ---------- Previous post was at 13:25 ----------

Why not like this:

  1. Get the state of the target vessel, including thruster levels
  2. Edit the state to IDLE and reset all thruster levels to 0.0, disable autopilot modes.
  3. Set the state of the vessel to the manipulated state

This works only in svn version, in official orbiter2016 the arot parameter must be calculated by hand (see couple of posts ago)
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,564
Reaction score
2,298
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
This works only in svn version, in official orbiter2016 the arot parameter must be calculated by hand (see couple of posts ago)

Well, even if you include this fix, its still no complex algorithm.
 
Top