# SDK QuestionData from another module

#### JMW

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

Donator
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

Donator
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
Tutorial Publisher
Donator
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]

##### Scientist
Enjo's Module Messaging is the way to go. Simple to use and rock-solid.

#### JMW

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.....

#### Face

##### Well-known member
Orbiter Contributor
Beta Tester
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

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

#### Enjo

##### Mostly harmless
Tutorial Publisher
Donator
Thought I would get stuck at some point in this, but not THIS EARLY.....

#### JMW

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)

##### Scientist
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)

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
Tutorial Publisher
Donator
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
Beta Tester
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

Donator
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
Beta Tester
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
Moderator
Webmaster
GFX Staff
Donator
Beta Tester
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

if (hXRRRModule != NULL)
{
}
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

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
Beta Tester
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.

##### Scientist
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.

Replies
0
Views
290
Replies
12
Views
743
General Question Cooperative flight
Replies
3
Views
246
Replies
6
Views
1K
Replies
13
Views
491