Discussion Request for Comment - MFD philosophy

kwan3217

Addon Developer
Addon Developer
Donator
Joined
Apr 29, 2008
Messages
115
Reaction score
0
Points
16
Location
Geosynchronous Orbit
This is just a request for comment, and specifically neither a promise to perform any particular action nor a requirement that others do so. It is especially not a flame targeted at anyone.

I was reading an interesting page http://www.joelonsoftware.com/uibook/fog0000000249.html talking about user interfaces. Before it delves into a bunch of details not really pertinent to Orbiter, it makes an observation which is stated elsewhere as "The Law of Least Astonishment". This law is basically that a program should act as the user intuitively expects it to, or in other words, in the way that astonishes the user the least.

In the GUI world that the page originally references, minimum astonishment is usually accomplished by doing things the way all the other programs do. In a sense it boils down to Follow Microsoft (in Windows) or Apple (on a Mac), not because they are biggest, and certainly not because they are best, but just because almost all users have their intuition trained by using the Big Guys' programs.

In the Unix model, programs are as small and simple as possible, do precisely one thing, and interact with other programs easily. It is said that "Those that do not learn the Unix model are doomed to re-implement it... poorly."

But what about MFDs? To addon developers, Orbiter and its library is the operating system, just as Windows is for Word, Mac OSX is for ITunes, and Firefox is for web pages and Javascript therein.

I bring all this up because of the Interplanetary MFD. The large community here that swears by it testifies to its utility, but I don't use it. For simpler tasks, I use TransX, and for more complicated ones, I either write a tool myself, or fly it by the seat of my pants (at much reduced accuracy) just because I can't learn how to use IMFD. And that's not from lack of trying.

As an example: A while back I asked about how to use IMFD to plan a course correction for a direct lunar-impact mission such as the old Rangers and Surveyors. These missions are launched into a trajectory which directly results in a near-vertical lunar impact without any lunar orbit insertion or powered descent. Ranger just snapped pictures through to impact, while Surveyor used a braking rocket 25 seconds before impact to start a soft-landing sequence.

I wanted to not just hit the moon, but do so at the historical time and place appropriate to the mission. Also, my launch vehicle puts the spacecraft on a lunar impact trajectory directly from the ground, so there is never a parking orbit, and therefore no time or place to set up the transfer.

The documentation for IMFD is out of date, and furthermore is more of a reference than a user guide or tutorial. This is the kind of documentation which is easy for the developer to write, and is useful to those who already know the basics of the program.

There are many tutorials out there, but the majority of them are also out of date, and all of them seem to be complete missions from launch to landing. I don't want to use IMFD for launch, because as I said my launch vehicle does it for me automatically.

I suspect that there is a way for IMFD to do what I ask of it, but I don't know how to find out. I think BaseApproach is related to the answer, but I don't know if the BaseApproach MFD is still needed, still current, or incorporated into the latest version of IMFD.

If I seem unduly harsh on IMFD, it is only because I wish to provoke a response. I learned TransX years ago, and I am quite adept with it now, but I remember that it was quite a steep learning curve for me also. I have just gotten used to it, and it astonishes me the least now. TransX shaped my user model, because I learned it first.

I am quite sure that my own MFDs have been headaches for other users, just because I don't follow the user model they learned. I try to follow the model of TransX "with improvements" in my MFDs. This resulted in the interface for PEGAutopilot. The "improvements" I thought I would make are to show more numbers at once to improve reading speed and to have a big change set of buttons and a small change set.

Now in some ways PEGAutopilot is a simple MFD. It is designed somewhat in the Unix model to solve one problem extremely well. This problem is launch from the surface of the Earth to some specified target orbit. The variables you can set are the target orbit parameters, directly in the form PEGAutopilot expects. I wrote it with basic functionality in mind, and only one user in mind, a user who has intimate knowledge of how PEG works. That user is of course myself, and PEGAutopilot astonishes me very little. However, I can imagine that many people don't even know what TPEGStart means and what are the intelligent choices for it.

PEG really is simple. Disregard the 2500 lines of code that backs it up. It just takes a target horizontal speed, vertical speed, and altitude at burnout and attemts to hit those targets. Except...

...The document I based PEG on was designed to guide a launch vehicle all the way from second stage start to a lunar impact trajectory as described above, so of course I wrote the program to do that mission also.

...You can't use PEG all the way from the ground, so I inculded a first-stage guidance program.

...You can't use PEG all the way to orbit, you must cut off guidance several seconds before you cut off the engines.

So, I included a bunch of tuning parameters that allowed a knowledgable user (myself) to take care of all the exceptions.

My point is that PEGAutopilot solves a much smaller set of problems than either TransX or IMFD, and it is still too complicated. I am posting PEGAutopilot as a BAD example, of the kind of thing I am trying to fix.

My simplest MFD is the Accelerometer. It approaches the "Dilbert Ideal" user interface in that it has only one button, and I pushed it before I published it.

My most popular MFD is BurnTimeCalc, which I can't take credit for, but likewise can't disclaim blame for. It was originally written by someone else, but after I was done with it, I had modified it beyond recognition.

I have written many MFDs that I haven't even published, to solve one or another problem that I had. It's not the Unix ideal, because the MFDs don't interact with eachother (you can't form pipelines) but at least they are small sharp tools that do one thing well.

Also, many MFDs exist because it's the easiest way to write an autopilot. Should this be? Should Orbiter support the concept of an autopilot completely distinct from an MFD?

So, what do I propose?

  1. A clean break between MFDs and autopilots. Most Autopilot MFDs are written this way anyway so that they can continue to operate when the MFD is not visible.
  2. A way for MFD/Autopilots to pipeline. This involves a way to transfer information from one to another, and a way for an MFD or autopilot to depend on another (start it as needed, complain if the dependency is not met, etc). In the Unix model this is done by the system supporting piping text from one process to another, by the shell making it easy to create pipes, and by having a large set of standard tools.
  3. A standard set of autopilots in a pipeline.
  4. Breaking up complicated MFDs or autopilots into many smaller pieces that interact well with eachother.
Let's take as a simple problem ejection from an Earth parking orbit into an arbitrary Earth departure hyperbola.

One way to do it now is:

  1. Calculate the departure hyperbola we want in TransX. This then reports a time to eject and a DeltaV.
  2. Manually copy those numbers into BurnTimeCalc. The time one is especially hard because it depends on pushing a button manually at just the right time.
  3. Before the burn, turn to prograde using the [ autopilot key.
  4. Let BurnTimeCalc control the burn with the main engine throttle, and let the prograde autopilot maintain attitude
There is an autoburn in TransX and IMFD now, but

  • It is a new feature, so that old-timers like me don't use it.
  • TransX and IMFD both had to write one, even though BurnTimeCalc predated the autoburn in both (in fact, BurnTimeCalc was written precisely to fill this hole in TransX, long long ago.)
So, onto some proposed implementation details:

1. Clean break between MFD and Autopilot
This one is pretty easy, and probably doable already with Orbiter '06. It's just that no one does it, and if an autopilot has no MFD, it has no user interface at all. So, we just need a convention that when you make an autopilot, you don't make an MFD to go with it, you use the standard Terminal MFD for your interface (see below). We will call either an MFD or an autopilot a Plugin.
2. Pipelining
Each plugin has a method called receiveCommand() which takes a commanding plugin identifier and a string command of arbitrary length. Strings for flexibility, but each receiving plugin gets to define its own protocol on top of it. Maybe after using this model for some time, a standard protocol evolve. Each plugin would have to document well its own interface, in human-readable form. There also needs to be a way to find out if BurnTimeCalc is loaded, load it if needed and available, and complain if it is not. Maybe some plugins would continue to work with some functions not available, but probably most would refuse to run if its dependencies were not met. This refusal to run would need to be handled in a clean non-CTD manner also.
3. Standard library
The library plugins would be like 'ls' and 'cat' in Unix. As an example, the lowest level plugin might take a steering command and translate it into a combination of engine steering, RCS jet firing, or control surface setting to implement the steering. This might be a function of the vessel rather than any plugin. The next level would take a requested attitude and attitude rate and use the lower level to steer to it. Higher level things like TransX would request their burn attitude from the mid-level attitude autopilot rather than displaying a manual vector plot and having the (human) pilot steer to it. Also, a standard MFD would be a terminal, which just takes commands and prints them out (and perhaps logs them) and perhaps enables command-line strings to be sent to an arbitrary plugin.

So, in the example:

  1. Calculate the departure hyperbola we want in TransX, as before, then press 'Execute'.
  2. TransX commands a BurnTime library autopilot to burn so much DeltaV centered on a particular time.
  3. TransX commands the Attitude library autopilot to point at the average prograde vector during the burn
  4. BurnTime commands the main engines to start and stop at the right time, and reports to TransX when done.
Complicated MFDs like TransX and IMFD could be shattered into many specialized pieces. You'd only have to get and learn the pieces you need, and since each individual piece is smaller, it should be easier to learn each piece.

In order to be successful, this system needs to be supported and mandated by Orbiter itself. This way every vessel and plugin is required to play nicely with every other.

This needs to be mandated from the top. The counter-example is CVE, the Common Vessel Extensions. This library extended the functionality of vessels, and allowed vessels to interact with each other and be stacked. It proved to be too heavy and no one used it, so CVELite was developed in response. It still wasn't used. Instead, the Attachment API was added to Orbiter and vessels which wanted to interact were required to use it. Attachment largely made CVE obsolete.

I have no illusions that anything I propose will be implemented in Orbiter '09, or even ever. It would require cooperation from Martin, and perhaps breaking all existing MFDs, autopilots, and vessels.

So, what do you all think? Is this interaction model any good? Would anyone like to propose an alternative?
 

Zatnikitelman

Addon Developer
Addon Developer
Joined
Jan 13, 2008
Messages
2,302
Reaction score
6
Points
38
Location
Atlanta, GA, USA, North America
Hmm, what you propose is quite interesting and probably doable even without changing the Orbiter core. All that really needs to be written is a basic attitude-program, and burn-program, then a standard interface into the ships (th_group_main, etc. already accomplishes this though right?). Then all the calculations can run on top of that and then simply "call" the attitude and burn programs.
The terminal idea is great in my opinion. What I'm seeing (correct me if I'm wrong) is basically a command line system in one of the current MFD slots and then accesses the various plugins (can they be called MFDs any more?) through a standardized syntax like: ">>PEG.setApa(200); PEG.setPea(150)"
The caveat here however is in programs like TransX and IMFD where people might like seeing their route. Of course, there's always extmfd and the second MFD display that can be used for a map or whatever.
I'm not into programming MFDs yet so the implementation may not be what works, but it sounds like a pretty good idea!
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
This is a timely post as I am currently rewriting AttitudeMFD from the ground up.

The user interface issue is an interesting one. On my latest works I have attempted to separate the user interface from the plugin's functionality. [ame="http://www.orbithangar.com/searchid.php?ID=3824"]StateVectorMFD[/ame] is written like this, even if it does not appear so to the user. It is open source, so feel free to check the code out.

AttitudeMFD v4 will also be written like this. The current object model is attached. Note in particular, that the attitude control is in a DLL by itself. The plan is for AttitudeMFD to have it own mini-API so that custom attitude control modules can be written. I have plans for at least two attitude control modules myself (one using the standard RCS thruster groups and another that simulates control moment gyros). The whole thing will be open source so other developers can write there own modules for it, or include an interface in their vessel modules (which I may do for Ananke), so that custom thruster groups, magentic torquers, etc, could be used.

I fully agree with comments on pipelining. I suspect that this could be done with a minimum of disruption by using a modules msgproc function. For a particular message id, one of the parameters could be a pointer to a message string. The other parameter could be a pointer for an acknowledge or for setting up some other direct two way communication channel. I think I would support any initiative in this direction and would like to think that AttitudeMFD could support it in its rebuilt form.

Getting back to the user interface, I am interested in your comments on IMFD. In particular, my plans for AttitudeMFD are for it to interface in a similar way, ie, a system of heirachical pages. I'll try and put together a sketch to better demonstrate what I mean. Would that be un-astonishing enough?

EDIT: I left off the class diagram, now attached. Note that AMFDUI class handles only the user interface. All other functions are handled by other classes. The are classes are persistent so that the auto-pilot can operate whilst the vessel does not have focus.

EDIT2: A page flow diagram is now attached, adapted from my working documents. I haven't mapped the "Main Menu" button because its function is pretty obvious. Any thoughts would be appreciated. Maybe not a bad diagram for inclusion in the manual :hmm:
 

Attachments

  • AttitudeMFDv4_ClassDiagram.pdf
    7.1 KB · Views: 10
  • AttitudeMFD_PageLayouts_Flow.pdf
    8.6 KB · Views: 9
Last edited:

EtherDragon

Addon Developer
Addon Developer
Joined
Mar 20, 2008
Messages
106
Reaction score
0
Points
0
Location
Ellensburg
A agree in the thought that an MFD should have a specific purpose. Not be a huge multi-use tool that "does it all - if you kno whow."

IMFD is a great example. Much of what it does can be broken into several MFDs for ease of use.

The "Map" "Course" and "Orbital" tabs from IMFD should all be separate MFDs, for instance. Then each of the Functions within the "Course" MFD could be menu options.
 

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
UPCOM - Universal Plugin Communication

Attached is a prototype which consists of the following modules:

Cruise - A cruise autopilot module, no user interface
Cruise MFD - A MFD that contains no autopilot code, accepts input from the user, and sends it to the cruise module via UPCOM interface
UCOMVES.dll - For communication between modules

The design is quite simple. We have a singleton class UP_COM inside UCOMVES.dll. Any module can register itself to the class by first acquiring an instance of the class via the static method UP_COM::getCom(), then calling it's methods such as addPlugin, getPlugin, getPluginCount, etc. addPlugin returns the position of the plug-in in the plugin list. Any plugin can check how many plugins are registered, their names, etc. They can then send messages to the plug-ins with the addMessage call. The messages will be stored inside that plug-in's message queue, and the plug-in can decide weather to handle them or not.

So you register your plug-in with:
Code:
// should be called only once
int id = com->addPlugin("RemoteEngine");

Browsing through the message queue and handling:
Code:
    char cbuf[255];
    char * pline;
    while(com->getMessage(id, cbuf))
    {
        pline=cbuf;
        if (!strnicmp(cbuf, "toggle", 6))
        {
            active=!active;
        }else if (!strnicmp(cbuf, "set", 3))
        {
            pline+=4;
            sp=atoi(pline);
        }
    }

Just a preliminary attempt. Suggestions/critisicm welcome. Maybe we can start up a community project for this at sourceforge or something. BTW pretty much all of my MFDs/other plug-ins follow the instance based design. Example: http://orbithangar.com/searchid.php?ID=3661 Each vessel gets it's own copy of the autopilots, etc. They continue to function regardless of the MFD's state. The MFD serves solemnly as a user interface.
 

Attachments

  • upcom.zip
    130.4 KB · Views: 11

Tommy

Well-known member
Joined
Aug 14, 2008
Messages
2,019
Reaction score
86
Points
48
Location
Here and now
My primary OS is Linux, and I've gained a lot of admiration for the "Unix Model". This kind of compartmentalization of function can be a very good thing - as long as there is a clear standard that everyone adheres to. This applies to more than just MFD's also.

UMMU is a good example, it provides a standard which developers can follow (making ships "compatible" with each other, as well as UMMU), has a specific function (adding "people" to the sim), and has a well documented API making it easy for "3rd party" developers to use.

Probably the biggest obstacle to this is a habit of isolation among the developers. Each developer, or team, works out their own particulr way of doing same things. This trend has been changing, and I've seen many threads dealing with ways for modules to communicate with each other. The DGIV handles cargo differently from the XR series, who are different from everyone else. Then we have UCD, which seems to offer a more unified solution. The only problem is that I like the 2D panel view, and having to open a "window" to adjust cargo, or try to do it in a tiny MFD, kinda breaks the immersion. Now, if the ship could communicate with UCD, then a ship designer could create a panel view that incorporated a UCD control. Also, UCD could be "upgraded" to work with an economics module like Orbitrader, etc.

I'd say the first job is to create a few basic standards, such as communication protocol, heirarcy, etc. Get all the bigger developers to post ideas and requests for the actual method the modules will use to communicate, and a "base set" of messages/commands that all modules would need. It should be a simple set, since different types of modules will have specific commands.

We would have to decide which way modules communicate - up or down. For example, lets say I'm using TransX, Attitude, and BurnTime. Does TransX initiate the communication or do Attitude and BurnTime query TransX? The protocol needs to allow for different combinations of modules also, such as different navigation tools or different vessel "controllers". it would be nice if vessel designers could implement there own "controller" that could interact with TransX if it had unusual controls and a more "generic" controller such as BurnTime (if the vessel uses some weird "custom" engine that Burntime can't operate).

Eventually, the goal could be to create an "Add-On SDK", with code examples, perhaps a library of usefull functions.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Just a preliminary attempt. Suggestions/critisicm welcome. Maybe we can start up a community project for this at sourceforge or something. BTW pretty much all of my MFDs/other plug-ins follow the instance based design. Example: http://orbithangar.com/searchid.php?ID=3661 Each vessel gets it's own copy of the autopilots, etc. They continue to function regardless of the MFD's state. The MFD serves solemnly as a user interface.
Nice! It sounds like we are thinking along the same lines as far as modularity goes. Mention of singleton classes always raises the hair on the back of my neck but perhaps there is no real way to avoid that here. I guess it is up to each plugin developer to use it responsibly, ie, keep the number of calls to UP_COM::getCom() a minimum - preferably one.

I'd like to see a bit more verbosity in your function names, eg, UP_COM: UP implies "Universal Plugin", yet this could be used by vessels too. COM should also be COMM, the abbreviated form of "COMMunication". Overall I would prefer to see UP_COM change to UniversalComm or something similar, and getCom change to getInstance(). There should also be a removePlugin(int id).

On the messaging side, I'd like to see some sort of broadcast support in addition to unicast, along with message lifetimes. We could also evolve a set standard messages over time.

Perhaps also a "typedef int PLUGIN_HANDLE;" (I tend to use ints for numbers and using them for handles/IDs makes the code look wrong to my eye)
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
I'd like to see a bit more verbosity in your function names, eg, UP_COM: UP implies "Universal Plugin", yet this could be used by vessels too. COM should also be COMM, the abbreviated form of "COMMunication". Overall I would prefer to see UP_COM change to UniversalComm or something similar, and getCom change to getInstance(). There should also be a removePlugin(int id).
Agree on this. "COM" to me implies this: http://en.wikipedia.org/wiki/Component_Object_Model
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
We would have to decide which way modules communicate - up or down. For example, lets say I'm using TransX, Attitude, and BurnTime. Does TransX initiate the communication or do Attitude and BurnTime query TransX? The protocol needs to allow for different combinations of modules also, such as different navigation tools or different vessel "controllers". it would be nice if vessel designers could implement there own "controller" that could interact with TransX if it had unusual controls and a more "generic" controller such as BurnTime (if the vessel uses some weird "custom" engine that Burntime can't operate).
Good point. What computerex has proposed allows for bidirectional communication which is useful but perhaps a better standard could be developed, along the lines of a pipeline that Kwan mentioned. For example, a plugin could register itself on the pipeline (say TransX), followed by Attitude, followed by BurnTime. At each time step, the comms handler executes the pipeline, ie, asks TransX for its messages and passes them to Attitude. Attitude processes them, removes some, adds some and then the message stack gets passed down the line. This allows TransX to send out messages without having to know who is going to read them - much more extensible. Each controller would need to insert itself in the correct place in the pipeline, like: Plan->Attitude->Burn.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
My concern with these proposed methods is that it creates a lot of dependencies. Modules using this stop being "plug and play" in the sense that you have to make sure all of their dependencies are also enabled.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
My concern with these proposed methods is that it creates a lot of dependencies. Modules using this stop being "plug and play" in the sense that you have to make sure all of their dependencies are also enabled.
Are you talking about dependency on UP_COM (or whatever name) or dependencies like TransX depending on AttitudeControl, BurnTime, etc? In the case of the latter, I see that as a plus, since you can swap out the AttitudeControl module, for example, with another one of your choosing. The developer can also optionally include their own modules for that function. For example, in my current plans for AttitudeMFD (which don't include UP_COM) there will be an AttitudeMFD module (the user interface) and a default AttitudeControl module. AttitudeMFD can then use either the default AttitudeControl or some other one (or none, that won't break it - "HOLD" won't work, but all other functions will).
 
Last edited:

Imagineer

New member
Joined
Feb 11, 2008
Messages
47
Reaction score
0
Points
0
Location
N42 2.9 W 91 35.4
In some cases a vessel may have specialized attitude or thrust capability. A solar sail is one example. These specialized capabilities would need to be operated by ship-specific code which, of course, should be provided in the ship's DLL.

Currently some ships implement a custom autopilot, but there is no way for a higher-level instrument, like IMFD, to communicate an arbitrary attitude to the custom autopilot, which would be the logical component to perform that function.

Unless the next version of Orbiter has already changed this, there is currently no standardized method to transfer attitude and planned burn information from a MFD to the ship's autopilot.

This communication would need to be two-way. The MFD would tell the ship what the desired delta-V is. The ship would be responsible for accomplishing the required delta-V in the most appropriate manner using it's available resources. The ship would tell the MFD how long it will take to turn the ship and get the main engine ready. This latter information is important for large ships (ICOVD Windmill Class) which turn slowly and require complex startup procedures.

This way the MFD can display the time until the engines must be started in order to complete the burn, start turning the ship soon enough, etc. This concept would, ideally, free the MFD from having to implement a generic autopilot and allow the MFD author to concentrate on the problem at hand. Since there are a lot of ships which do not support this interface, this ideal will have to wait.

Somewhere I remember seeing an MFD which provided some kind of interface for the ship's autopilot. I don't remember the details, but what I am thinking of is an expanded and standardized version of it. Ideally it would be a library which can be linked with the vessel and MFD as appropriate and be as easy to incorporate as UMMU.

Since it requires cooperation from MFD developers I am not in a big rush to stick it into ICOVD right now, but if MFD developers are interested, I'm willing to work with you from the vessel side.

-- Imagineer
 
Last edited:

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
In some cases a vessel may have specialized attitude or thrust capability. A solar sail is one example. These specialized capabilities would need to be operated by ship-specific code which, of course, should be provided in the ship's DLL.

Currently some ships implement a custom autopilot, but there is no way for a higher-level instrument, like IMFD, to communicate an arbitrary attitude to the custom autopilot, which would be the logical component to perform that function.

Unless the next version of Orbiter has already changed this, there is currently no standardized method to transfer attitude and planned burn information from a MFD to the ship's autopilot.

This communication would need to be two-way. The MFD would tell the ship what the desired delta-V is. The ship would tell the MFD how long it will take to turn the ship and get the main engine ready. This latter information is important for large ships (ICOVD Windmill Class) which turn slowly and require complex startup procedures. The ship would be responsible for accomplishing the required delta-V in the most appropriate manner using it's available resources.

This way the MFD can display the time until the engines must be started in order to complete the burn, start turning the ship soon enough, etc. This concept would, ideally, free the MFD from having to implement a generic autopilot and allow the MFD author to consentrate on the problem at hand. Since there are a lot of ships which do not support this interface, this ideal will have to wait.

Somewhere I remember seeing an MFD which provided some kind of interface for the ship's autopilot. I don't remember the details, but what I am thinking of is an expanded and standardized version of it. Ideally it would be a library which can be linked with the vessel and MFD as appropriate and be as easy to incorporate as UMMU.

Since it requires cooperation from MFD developers I am not in a big rush to stick it into ICOVD right now, but if MFD developers are interested, I'm willing to work with you from the vessel side.

-- Imagineer

What you describe can be done by KeyComm, but there has been no push for that sort of thing to become standardized. You'd need a standardized message and some kind of standardized data struct to pass as the payload, but it could be done. Since there's no standardization, though, it's not currently useful.

The other problem with KeyComm is that it's a very "dirty" method of doing things. If there was a better standardized method of doing things, I'd be all for it.

AttitudeMFD can then use either the default AttitudeControl or some other one (or none, that won't break it - "HOLD" won't work, but all other functions will).
At which point you get a lot of people asking why HOLD doesn't work, and it's because they didn't enable the second plugin they needed to.
 

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
I'd like to see a bit more verbosity in your function names, eg, UP_COM: UP implies "Universal Plugin", yet this could be used by vessels too. COM should also be COMM, the abbreviated form of "COMMunication". Overall I would prefer to see UP_COM change to UniversalComm or something similar, and getCom change to getInstance(). There should also be a removePlugin(int id).

I don't think of names too strongly. Good thing naming conventions are easy to deal with.

On the messaging side, I'd like to see some sort of broadcast support in addition to unicast, along with message lifetimes. We could also evolve a set standard messages over time.

Message lifetimes are easy to implement, but I can't see them being too useful here. As for broadcast support:

Code:
for(int i=0;i<com->getPluginCount();i++)
{
     com->addMessage(i, "fire");
}


Perhaps also a "typedef int PLUGIN_HANDLE;" (I tend to use ints for numbers and using them for handles/IDs makes the code look wrong to my eye)

That could be useful for readability.

Good point. What computerex has proposed allows for bidirectional communication which is useful but perhaps a better standard could be developed, along the lines of a pipeline that Kwan mentioned. For example, a plugin could register itself on the pipeline (say TransX), followed by Attitude, followed by BurnTime. At each time step, the comms handler executes the pipeline, ie, asks TransX for its messages and passes them to Attitude. Attitude processes them, removes some, adds some and then the message stack gets passed down the line. This allows TransX to send out messages without having to know who is going to read them - much more extensible. Each controller would need to insert itself in the correct place in the pipeline, like: Plan->Attitude->Burn.

I could see issues with this pipeline design. If some standard were to be developed, what if there were two plug-ins that were expecting the same input, but that input was already stripped by a previous plug-in. It wouldn't take too much work to modify this into a pipeline sort of thing, but I don't know how stable it will be for the long term. I think the existing model is more fool proof. If TransX wants some input, it can request it directly. If some other plug-in wants input from TransX, it could request that.
 

Tommy

Well-known member
Joined
Aug 14, 2008
Messages
2,019
Reaction score
86
Points
48
Location
Here and now
Each controller would need to insert itself in the correct place in the pipeline, like: Plan->Attitude->Burn.

I was thinking that Attitude and Burn should each get the info they need from TransX, Although I suppose giving Attitude the ability to prevent a burn if out of alignment might be a good idea. But it would also be good if Burn can talk to Attitude, perhaps giving it a two minute warning. No point in using RCS fuel to maintain attitude when you're half an orbit from ejection. Sounds like we need either a web, or a server-client with a "modulecomm.dll" that "registers" submodules and acts as a switchboard.

We also need a way to ensure that a particular instance of one module connects to the correct instance of another. This is crucial if there are to be more than one vessel, it wouldn't do to have GL-01's TransX trying to use SH-01's Attitude, etc. It would also be good to have these "connections" saved in the scenario file, either by the individual modules if using an ad-hoc method, or by the comm module in a server/client method.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
At which point you get a lot of people asking why HOLD doesn't work, and it's because they didn't enable the second plugin they needed to.
My plan was to make the attitude control modules loaded directly by AttitudeMFD, ie, they need not be Orbiter plugins but they can be also. The config file(s) (and hopefully a config GUI, at some stage) will specify, per vessel class, what attitude control module to use. So on a standard install, it will use the default module. If you want to use something else for a specific vessel class, you make a config file for it. Addon developors developing attitude control modules (could be included in their vessel modules provided they are compilied against the attitude control api) just need to publish an appropriate config file with their addon. I'm also being pretty careful to protect against malformed cofig files.

---------- Post added at 14:46 ---------- Previous post was at 14:25 ----------

I don't think of names too strongly. Good thing naming conventions are easy to deal with.
I know, I've read some of your code ;). I see you haven't broken your commentaphobia either :lol:

Message lifetimes are easy to implement, but I can't see them being too useful here.
Well there is nothing to guarantee that a plugin is going to check its messages every time step. In fact, it may do so only in response to some user input, or only while the vessel it is associated with has a valid VISHANDLE. By the time the plugin receives the message, it may no longer be valid. Not all messages will be to do with auto-pilots - we want this to be a universal as possible.

I could see issues with this pipeline design. If some standard were to be developed, what if there were two plug-ins that were expecting the same input, but that input was already stripped by a previous plug-in.
Yeah, but it would only be stripped for a valid reason. For example, if you had to two attitude controllers in the pipeline, unless you strip the message from the stack you would have them "fighting" over the thrusters (not really fighting as such, since Orbiter is single threaded, but unpredictable results anyway).

It wouldn't take too much work to modify this into a pipeline sort of thing, but I don't know how stable it will be for the long term. I think the existing model is more fool proof. If TransX wants some input, it can request it directly. If some other plug-in wants input from TransX, it could request that.
How does TransX know what plugins to send it to? A user config file perhaps? If TransX puts an attitude or burn message out to a pipeline, any other controller can decide what, if anything, to do with it.
 

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
I know, I've read some of your code ;). I see you haven't broken your commentaphobia either :lol:

Real Programmers don't comment their code ;).

Well there is nothing to guarantee that a plugin is going to check its messages every time step. In fact, it may do so only in response to some user input, or only while the vessel it is associated with has a valid VISHANDLE. By the time the plugin receives the message, it may no longer be valid. Not all messages will be to do with auto-pilots - we want this to be a universal as possible.
It may be that some module checks the queue only after a certain number of messages accumulate. But in any case, some messages could have an 'infinite' lifetime flag, so I think life time may be a good thing to implement.
When you are creating something like this, there is hardly any certainty. The best one can do is to make the design as simple, therefore flexible as possible.

Yeah, but it would only be stripped for a valid reason. For example, if you had to two attitude controllers in the pipeline, unless you strip the message from the stack you would have them "fighting" over the thrusters (not really fighting as such, since Orbiter is single threaded, but unpredictable results anyway).
Yes, but as you just said, not all the things this will be used for is going to be autopilot related. If two modules are waiting for output from the TransX for planning updates, the one that comes first will strip the information leaving the second one nothing.

How does TransX know what plugins to send it to? A user config file perhaps? If TransX puts an attitude or burn message out to a pipeline, any other controller can decide what, if anything, to do with it.

This functionality is already here. You can already broadcast a message to all the registered plug-ins. The problematic part will be possible conflicts. You end up having two controllers perform the same procedure. But this could be easily bypassed using a broadcastGlobal(const char* msg) method. The first input will go to the first plug-in in the list. That plug-in will then redirect the output to the next plug-in in the list, and so on.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Yes, but as you just said, not all the things this will be used for is going to be autopilot related. If two modules are waiting for output from the TransX for planning updates, the one that comes first will strip the information leaving the second one nothing.
Exactly. Only strip the messages it acts on therefore, no fighting. So burn and attitude info should be in separate messages.

The first input will go to the first plug-in in the list. That plug-in will then redirect the output to the next plug-in in the list, and so on.
Like a pipeline? I think we are talking about the same thing, just different smell...
 
Top