SDK Question Data from another module

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
580
Reaction score
40
Points
43
Location
Happy Wherever
Hi All.
How can one module in a scenario receive data generated in another module?
(Want to place one module a given distance from another in flight).....
 

fred18

Addon Developer
Addon Developer
Donator
Joined
Feb 2, 2012
Messages
1,659
Reaction score
88
Points
63
yes it is possible. There are many possibilities to achieve this. If you are coding both modules easiest way is to use clbkGeneric
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
8,879
Reaction score
2,628
Points
203
Location
Toulouse
That's something I always dreamed to do, but never understood... It would make things SO easy... :shrug:

I once found a very ugly way to transmit data between two VESSEL modules, using dummy fuel tanks. You create a fuel tank on VESSEL A, you set a value like 0.60, then in the VESSEL B module you write a loop that checks the fuel status of VESSEL A. From there, with things like (if vessel->getpropellantlevel > 0.60...) you can do some stuff. But that's painful and more a hack than anything else.

I think that the proper way to do that is related to the "classes" concept, but its exactly where I lost myself in the way of addon devloppement. :(
 

Enjo

Mostly harmless
Addon Developer
Tutorial Publisher
Donator
Joined
Nov 25, 2007
Messages
1,658
Reaction score
6
Points
38
Location
Hildesheim, Germany
Website
www.enderspace.de
I don't know the clbkGeneric solution, but there's a library dedicated to inter-module communication:
[ame="http://www.orbithangar.com/searchid.php?ID=6412"]ModuleMessaging SDK v. 1.1[/ame]
 

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,664
Reaction score
2
Points
38
Enjo's Module Messaging is the way to go. Simple to use and rock-solid.
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
580
Reaction score
40
Points
43
Location
Happy Wherever
Hi Guys.
Trying to implement this and am hitting the famous LNK2019 just for including
Code:
#include <EnjoLib/IMessagingSender.hpp>
Error:

Code:
error LNK2019: unresolved external symbol "public: virtual __thiscall EnjoLib::IMessagingSender::~IMessagingSender(void)" ([email protected]@@[email protected]) referenced in function "public: virtual void * __thiscall EnjoLib::IMessagingSender::`vector deleting destructor'(unsigned int)" ([email protected]@@[email protected])

Libraries/Headers seem to be in place in
Code:
Orbiter_Beta2015\Orbitersdk\lib
and
Code:
D:\Orbiter_Beta2015\Orbitersdk\include\EnjoLib

Thought I would get stuck at some point in this, but not THIS EARLY.....
any ideas please......
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,358
Reaction score
513
Points
153
Location
Vienna
Hi All.
How can one module in a scenario receive data generated in another module?
(Want to place one module a given distance from another in flight).....

Can you please elaborate on that? I get the feeling you're going to crack this nut with a sledgehammer by using a communication framework here.

Do you perhaps want to implement a feature in a vessel to put it some predefined distance away from another vessel? For that you don't have to communicate between the vessels at all.
 

francisdrake

Addon Developer
Addon Developer
Joined
Mar 23, 2008
Messages
848
Reaction score
330
Points
78
Website
francisdrakex.deviantart.com
Not being a specialist in these things, but it seems you only need simple information from the remote vessel. These can be obtained via oapiGetVesselInterface(). Shown below is an example how to manipulate a thruster of a remote vessel, when the vessel name and structure is known:


OBJHANDLE h1;
VESSEL *v1;

h1 = oapiGetVesselByName (char *name);
v1 = oapiGetVesselInterface( h1 );
...
v1->SetThrusterLevel( th_lhb_aux, 0.07 );
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
580
Reaction score
40
Points
43
Location
Happy Wherever
Sorry Enjo, not understanding....
ModuleMessaging.lib is in D:\Orbiter_Beta2015\Orbitersdk\lib folder.
Is that not correct?
Where else do I need to put it....? (in the nicest possible way;-))

Other guys,
I'm attempting to compile a function to target a point a few 100 metres ahead of the craft in flight.
To check my calculations are correct I wanted to place another "craft" (anything) at the point that I calculate. ie: ongoing in the parent module.

If there's a more simple way, that's great! (Think I'll still be curious about ModuleMessaging - it sounds real cool to get that working)
 

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,664
Reaction score
2
Points
38
Sorry Enjo, not understanding....
ModuleMessaging.lib is in D:\Orbiter_Beta2015\Orbitersdk\lib folder.
Is that not correct?
Where else do I need to put it....? (in the nicest possible way;-))

Other guys,
I'm attempting to compile a function to target a point a few 100 metres ahead of the craft in flight.
To check my calculations are correct I wanted to place another "craft" (anything) at the point that I calculate. ie: ongoing in the parent module.

If there's a more simple way, that's great! (Think I'll still be curious about ModuleMessaging - it sounds real cool to get that working)


In your Visual C++ Express, you need to change the Linker additional libraries to add Enjo's module alongside Orbiter.lib, etc.

If you need, I can pull up a demo for you of how to do the most basic pair of MFD's pushing strings and ints between them.

It's not a scary library ... really nothing much more than a put/get interface for well-known variables from well-known MFD's. It deserves more attention for sure. Now I am getting into BaseSync, I will probably use Module Messaging to hook Glideslope into BaseSync to share data on target and reentry, etc.
 

Enjo

Mostly harmless
Addon Developer
Tutorial Publisher
Donator
Joined
Nov 25, 2007
Messages
1,658
Reaction score
6
Points
38
Location
Hildesheim, Germany
Website
www.enderspace.de
Sorry Enjo, not understanding....
ModuleMessaging.lib is in D:\Orbiter_Beta2015\Orbitersdk\lib folder.
Is that not correct?
The problem is that I sit on Linux and don't have VC++ at hand. ADSWNJ answered right.

Now I am getting into BaseSync, I will probably use Module Messaging to hook Glideslope into BaseSync to share data on target and reentry, etc.
Cool!
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,358
Reaction score
513
Points
153
Location
Vienna
Other guys,
I'm attempting to compile a function to target a point a few 100 metres ahead of the craft in flight.
To check my calculations are correct I wanted to place another "craft" (anything) at the point that I calculate. ie: ongoing in the parent module.

If there's a more simple way, that's great! (Think I'll still be curious about ModuleMessaging - it sounds real cool to get that working)

I still don't understand completely what it is you want to do, but let me guess:

  • You have a plugin, perhaps an MFD mode.
  • This plugin calculates a relative position with respect to the vessel that uses the MFD mode.
  • You want to display something there, preferably another vessel.
This can be done without inter-module communication. Get the owner vessel position via its vessel interface, apply the relative vector after GlobalRot rotation, create a display vessel and then DefSetStateEx() the target position via the display vessel's interface. That's all Orbiter API.


Of course, having a KISS solution to a problem is no reason to stop wanting to try new things out ;) .
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
8,879
Reaction score
2,628
Points
203
Location
Toulouse
I still don't understand completely what it is you want to do, but let me guess:

In my personal case, sharing variables between modules :tiphat:
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,358
Reaction score
513
Points
153
Location
Vienna
In my personal case, sharing variables between modules :tiphat:
As I understood it, this is a possible means to an end. The end is what I would like to understand. Perhaps the OP just thought he needs to share variables between modules to solve a particular problem. Is it a problem that I'd like to clarify that? :hmm:
 

Xyon

Puts the Fun in Dysfunctional
Administrator
Moderator
Addon Developer
Webmaster
GFX Staff
Donator
Beta Tester
Joined
Aug 9, 2009
Messages
6,871
Reaction score
668
Points
203
Location
10.0.0.1
Website
www.orbiter-radio.co.uk
Preferred Pronouns
she/her
XRRR and its MFD perform this kind of interoperation, though when I wrote it I wasn't aware of Enjo's solution and I may look to incorporate that in the future.

The source for XRRR is open, and it is in bitbucket here; the relevant portions that deal with intercommunication are kind of all over the place (refactoring is in progress in another branch, but it breaks everything at the moment).

If I recall correctly (it's been some years since I wrote it), it works like this; since I'm writing both modules, they can and thus do share a header file (XRRR.h) which contains most of the definitions for data structures and so on. Then each module also has a private header, to contain things which only need be present in one module. That approach means both modules know about my data structures and I can handle the same objects in each module.

The plugin interacts with vessel objects, and the MFD interacts with the data the plugin generates, using an exported method from XRRR.dll which the MFD calls;

plugin.h (XRRR.dll)
Code:
// Export our method to return a pointer to the hash map object
// Check the .def file for export stuff too.
XRRR_FleetReference * __stdcall MFDGetter(XRRR_FleetClasses::XRClass_t *VesselClass);

extern XRRollingRepair *g_XRRR;
bitbucket view

XRRR.def (export definitions);
Code:
LIBRARY XRRR
DESCRIPTION "XR Rolling Repair"
EXPORTS
	MFDGetter	@1
Bitbucket view

And the method itself, which is really basic, is just:
Code:
XRRR_FleetReference * __stdcall MFDGetter(XRRR_FleetClasses::XRClass_t *VesselClass)
{
    return &XRRR_VesselReference[*VesselClass];
}
Bitbucket view

This works, but, I needed the actual data the plugin DLL was currently using, not a null pointer (which is all I got when I called it as-was), so the MFD makes use of LoadLibrary to reference the currently loaded copy of XRRR.dll;

Code:
// Load the XRRR module and pull in the function address of our MFD helper function

	hXRRRModule = LoadLibrary("Modules\\Plugin\\XRRR.dll");

	if (hXRRRModule != NULL)
	{
		XRRRData = (FindXRRRType)GetProcAddress(hXRRRModule, "MFDGetter");
	}
Bitbucket view.

That horrible little piece of code looks up the in-memory address of the exported function from the currently-running XRRR.dll, and calls it, returning a pointer to the in-memory data that the plugin is using, which the MFD can then interact with.

Cleanup - in the MFD's dtor we have to call FreeLibrary to remove that reference to XRRR.dll, otherwise it doesn't get unloaded and we have problems:
Code:
// Unload XRRR module now; We're done with it.
	FreeLibrary(hXRRRModule);
Bitbucket view

And I think that's all there was to sharing the same in-memory object between two of your own DLL modules.

Disclaimer: I wrote that code five years ago. Some of the terminology and mechanics might be nonsense but the code does work. XRRR is open source, so you're free to use that code as-is if you wish to.
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
580
Reaction score
40
Points
43
Location
Happy Wherever
Is it a problem that I'd like to clarify that? :hmm:

Not for me !! :)

"You have a plugin, perhaps an MFD mode"
Actually it's a module, but it does calc a relative position ahead of it....

"You want to display something there, preferably another vessel"
Correct.

It's just to check that the relative position calcs are correct as I suspect something is askew on them....

I have a surface hugging autopilot.
I'm trying to "see ahead" the oapiSurfaceElevation and adjust my descent accordingly so craft doesn't follow the surface elevation exactly as this continual change of altitude causes pilot fatigue and dizziness! :sweet:
Just attempting to simulate what any normal pilot would do, automatically...

Maybe my sledgehammer is getting bigger ...... :lol:

But, can DefSetStateEx() be called continually in real time, or only be used to set initial states?....
 

Face

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 18, 2008
Messages
4,358
Reaction score
513
Points
153
Location
Vienna
Not for me !! :)

I see. The overall immediate "jump" to inter-module communication confused me a bit, thanks for clarifying.

"You have a plugin, perhaps an MFD mode"
Actually it's a module, but it does calc a relative position ahead of it....

"You want to display something there, preferably another vessel"
Correct.

"Module" is a quite neutral term when it comes to Orbiter. It could be a startup module, a Gbody module, a plugin module, a vessel class module and a OVP graphics client module. I now assume you mean vessel class module. Please correct me if I'm wrong.

It's just to check that the relative position calcs are correct as I suspect something is askew on them....

I have a surface hugging autopilot.
I'm trying to "see ahead" the oapiSurfaceElevation and adjust my descent accordingly so craft doesn't follow the surface elevation exactly as this continual change of altitude causes pilot fatigue and dizziness! :sweet:
Just attempting to simulate what any normal pilot would do, automatically...

I see. So you have a vessel module with an autopilot, and you want to test/check/visualize the autopilot algorithm by means of displaying a new vessel at the algorithm's output coordinates.

Maybe my sledgehammer is getting bigger ...... :lol:

If my above assumption is right, it would be big if you try to solve that problem by means of a module-communication framework. Just my opinion, of course.

But, can DefSetStateEx() be called continually in real time, or only be used to set initial states?....

Yes, it can. This is essentially how OMP works: it continuously updates the remotely displayed vessels with the network-transmitted (and lag-compensated) position data. Of course that might confuse certain vessel codes (e.g. G-force detection to "kill" crew), but if you use e.g. Carina as indicator vessel, it should work fine.
 

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,664
Reaction score
2
Points
38
I'm doing a refresh of Enjo's ModuleMessaging that should hopefully be totally simple to use and able to handle all needs to put data out of one module and get it into another module. I'll release the ModuleMessageExt, plus a couple of very simple test MFD's (MMTest1 and MMTest2) to show how to get and set across two MFD's, either with pass by value or pass by reference.

Stand by for a day or 2.

---------- Post added at 04:31 PM ---------- Previous post was at 03:05 AM ----------

OK - please see the new ModuleMessagingExt and the showcase MMTest 1+2 packages on OrbitHangar. Hopefully this will become a standard way to move data between modules or MFD's in Orbiter, using a simple PUT/GET paradigm.

The PUT syntax is: ModuleMessagingPut( varName, varValue, {vessel} ) (Vessel is optional).

The GET syntax is: ModuleMessagingExt().Get( moduleName, varName, varValue, {vessel} )

Full details in the readme.txt for ModuleMessagingExt, and in the headers you need to include into your code to make this work.

Credits & a shout-out to my buddy Enjo, as this has been something we have discussed off and on for over a year.
 
Top