Project Vessel Parameters MFD

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
Vessel Parameters MFD is a simple MFD meant to give various statistics about your spacecraft.

Among the things that it will display:

Name: Name of the vessel.
Class: Class of the vessel.

Mass: This will have a toggle to switch between mass in kilograms and metric tons.
-Dry: Total mass without propellant in kilograms or metric tons.
-Wet: Total mass with all propellant tanks fully filled in kilograms or metric tons.
-Current: Total mass of the vessel at the present time in kilograms or metric tons.

Tanks: This will have a toggle to switch to each tank sequentially.
-Full: Maximum capacity of the tank in kilograms.
-Current: Present mass of propellant in the tank, as either a value in kilograms or a percentage of total capacity. This will have a toggle to switch between the two modes.
-Engines serviced: Which engines or thrusters use this tank for propellant. All engines serviced are displayed at one time.

Engines and Thrusters: There will be a toggle to switch between engines sequentially.
-Thrust: Nominal thrust at full throttle, in kilonewtons.
-Specific Impulse: This is the vacuum ISP of the engine, given in N*s/kg.
-Acceleration:
--Linear: Current acceleration in m/s^2 and the axis relative to the vessel that it accelerates along, again assuming nominal full thrust.
--Rotational: Current acceleration in degrees/s^2 or radians/s^2, again assuming nominal full thrust. This also provides the direction of the acceleration.
--Tanks: Which tanks the engine draws propellant from.

Now, there is a limitation to how much can be done with this MFD. Staging can't be taken into account as Orbiter considers all vessels to be single-staged. The staging is created by the code that controls the vessel.

Does anyone have any thoughts, comments, or suggestions for this? Also, if you think of any other statistics that would be useful or interesting to see, let me know and I'll add them to the list.

vesselparametersmfdimag.png


Picture of the first working version of the MFD.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,665
Reaction score
2,386
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
You do know that you are currently not displaying much more, than CTRL + I shows?

Also what sense makes such an MFD, it is not really flight critical information like that.
 

ar81

Active member
Joined
Jun 19, 2008
Messages
2,350
Reaction score
3
Points
38
Location
Costa Rica
Website
www.orbithangar.com
Instead of Kg, could it use tons?
I still think your MFD is interesting.

There is a status MFD

StatusMFD_adv.jpg


I think that if you could enhance it, it would be even more interesting.

Another idea: As you approach a base, sometimes you miss the target. Some other times there are obstacles to reach a certain pad. An MFD that provides graphical awareness about your ship and pad position, an improved VTOL MFD, would be nice.

3D map MFD did a great work improving Orbit MFD.
I bet you can do the same with VTOL MFD.
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
Actually, much of that information would not be shown with Ctrl-I. ISP, the fill level of the various tanks, and acceleration of the engines are some examples.

However, the main purpose of this MFD is to help me learn how to make an MFD. That image just shows what I have done in order to put something together that works. I'm going to add on to it.

I wasn't aware of the Status MFD. However, after taking a look, it would seem that my MFD and the Status MFD display different kinds of information. From what I can tell, the Status MFD is about displaying qualitatively what the various controls are doing at that moment in time. Vessel Parameters is qualitative.

Also, it considers all engines and thrusters in groups while mine will display information on individual engines and thrusters.

It already has a function to display mass in tons.

I don't plan on doing anything graphical for too reasons. One, this MFD is meant to display numerical information about the vessel not its surroundings. Second, I don't have a clue where to begin with anything graphics related.
 

ar81

Active member
Joined
Jun 19, 2008
Messages
2,350
Reaction score
3
Points
38
Location
Costa Rica
Website
www.orbithangar.com
Your work will be deeply appreciated, for sure.
When you make things that you feel useful for you, probably it may be useful for all the many orbinauts.
Congratulations for using Orbiter to practice coding.
Keep up the good work!!:cheers::speakcool:
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
Thank you!

I've hit a bit of a snag, though. It looks like quite a few individual thrusters don't link directly to their propellant source. Maybe the groups link as one to their propellant source. Maybe I'm missing something.

Any thoughts on this one?

If I don't find a way to link thrusters with their propellant sources, I can just scrap that part and do the other things. This one is mostly out of curiosity.
 

ar81

Active member
Joined
Jun 19, 2008
Messages
2,350
Reaction score
3
Points
38
Location
Costa Rica
Website
www.orbithangar.com
You are asking me something I do not know.
But logic tells me that if you keep track of fuel and thrust, you may find that consumption and thrust would be linked between time steps, so if you do not know the exact link, you still may represent both separately, so users can connect in their minds.
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
The trouble is, the only way to figure it out that way is to fire all of the engines, one by one, for at least a brief period of time and see which tanks change their propellant mass. This has several problems. Each thruster firing changes the ship's linear and rotational velocity components, which may mess up a pilot's carefully planned maneuver. This one would be difficult to avoid. The other problem is if a thruster changes source tanks. This one can't be avoided and would necessitate refiring all of the engines every so often to ensure up to date information. This is wasteful of precious fuel that the pilot needs.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Do you mean that VESSEL::GetThrusterResource does not return a valid propellant handle for some thrusters? If so, what value does it return? NULL would indicate that the thruster is not connected at all.
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
I figured out the problem. I was using the iterator index in the GetPropellantHandleByIndex function instead of the stored tank index.

Doh! I also noticed that the list also seems to creep off the edge of the MFD. Hmm...a linebreak needs to be added if too many characters are used.
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,891
Reaction score
2,141
Points
203
Location
between the planets
If I might put in a suggestion, showing the remaining amount of DeltaV would be quite a usefull thing to display too.
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
I thought that that might be a useful statistic to have. I'll put that in as well.
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
I've finished the Tanks display mode for the MFD.

vesselparametersmfdimag.png


I currently have it counting from zero for the first engine. However, I will change this so that it counts from one.

This mode has actually revealed some interesting things. I used it with a spacecraft using Vinka's Multistage .dll and found that the tanks for boosters are numbered in ascending order of ignition. Tanks for the stages are numbered in descending order of ignition. In other words, the tank for stage 3 is listed first, then the second and first are listed, in that order.

I also had a strange result with the Delta Glider. Two of the engines that the Delta Glider should have weren't being listed with any of its propellant tanks. Then I realised that the retro doors were closed and opening them added those two engines to the list.

I have run into a problem, though. I'm not sure how to write the tank number to the scenario file and then read it afterwords. Does anyone have any ideas?

Available delta-v is a tricky number to come up with. If the vessel has only one tank, coming up with it is easy. Just run through all of the thrusters until you have the one with the highest ISP and then use Tsiolkovsky's rocket equation. However, if the vessel has more than one propellant tank, things are more complicated. If the value of the highest ISP thruster attached to each tank is different, then the available delta-v depends on which tank is used up first.

One solution is to find the highest ISP thruster for the given tank and determine the available delta-v as if that tank alone were used to depletion. Any thoughts on this one?

---------- Post added at 08:22 PM ---------- Previous post was at 08:49 AM ----------

I've run into a minor problem. I'm trying to get things so that if the user had two instances of Vessel Parameters MFD open at the same time, with different settings, and they exited Orbiter, they could open it with the same settings they had the last time.

However, only one of the two MFD's settings are loaded. In other words, if I have one set to Mass display and the other set to Tanks display, exit out and reload, I get two MFDs open to Mass display or Tanks display, not one for each.

The latest version of the MFD is here. If anyone can tell me what I'm doing wrong, I'd greatly appreciate it.
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
Where exactly do you want tons used? There is already a toggle to switch between kilograms and tons in the Mass display mode.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
However, only one of the two MFD's settings are loaded. In other words, if I have one set to Mass display and the other set to Tanks display, exit out and reload, I get two MFDs open to Mass display or Tanks display, not one for each.
Have you reviewed the LoadState and SaveState fuctions in State Vector MFD (I know you have been using it already)?
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
There doesn't seem to be anything in the source code which would allow it to determine which set of data it's supposed to read from.
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
There doesn't seem to be anything in the source code which would allow it to determine which set of data it's supposed to read from.
My apologies, I gave you the wrong function names (I was going from memory). Have a look at StateVectorMfd::ReadStatus and StateVectorMfd::WriteStatus. These functions are virtual members of the MFD base class and are called by Orbiter whenever your MFD should read/write to the scenario file. They are non-static members so they are called for each instance of your MFD so that each instance can write its own info.

StateVectorMFD also has functions (StateVectorMfdManager::loadState and StateVectorMfdManager::saveState) that read/write info about MFDs that are inactive.
 

Nemoricus

Addon Developer
Addon Developer
Joined
Jul 7, 2009
Messages
286
Reaction score
0
Points
0
I understood what you were talking about.

However, I should clarify my problem. It only occurs with MFDs loaded on the focus vessel, i.e., the one that the user was controlling just before the scenario was saved. It is possible to open two instances of Vessel Parameters MFD with different settings in each one. However, upon loading the scenario, the settings from only one of the MFDs' saved data is used. Thus, both MFDs display the same information.

Inactive MFDs are unaffected. Their unique settings will be retained when the scenario is loaded.

Code:

Reading and saving active MFD instances.

Code:
// *********************************************************************
// WriteStatus - Writes information to the scenario file.
// *********************************************************************
void VesselParametersMfd::WriteStatus(FILEHANDLE scn) const
{
    oapiWriteScenario_int(scn,"MFD_ID", vpMfdInfo->mfdId);
    switch(vpMfdInfo->parametersMode)
    {
        default: //Fall through.
        case MASS:
            oapiWriteScenario_string(scn,"PARAMETERSMODE", "MASS");
            break;
        case TANKS:
            oapiWriteScenario_string(scn,"PARAMETERSMODE", "TANKS");
            break;
        case ENGINES:
            oapiWriteScenario_string(scn,"PARAMETERSMODE", "ENGINES");
            break;
    }

    if(vpMfdInfo->massdisplay == METRIC_TONS)
        oapiWriteScenario_string(scn,"MASSDISPLAY", "METRIC_TONS");
    else if(vpMfdInfo->massdisplay == PERCENTAGE)
        oapiWriteScenario_string(scn,"MASSDISPLAY", "PERCENTAGE");
    else
        oapiWriteScenario_string(scn,"MASSDISPLAY", "KILOGRAMS");

    if(vpMfdInfo->enginesdisplay == DEGREES)
        oapiWriteScenario_string(scn,"ENGINESDISPLAY", "DEGREES");
    else
        oapiWriteScenario_string(scn,"ENGINESDISPLAY", "RADIANS");
}

// *********************************************************************
// ReadStatus - Loads information from the scenario file.
// *********************************************************************

void VesselParametersMfd::ReadStatus(FILEHANDLE scn)
{
    char *line;

    while(oapiReadScenario_nextline(scn,line)) //My futile attempt to get each MFD to load its own information.
    {
        if(!_strnicmp(line, "MFD_ID", 6))
        {
            if(!_strnicmp(line+7, "0", 1))
            {
                if(vpMfdInfo->mfdId == 0)
                    break;
            }

            else if(!_strnicmp(line+7, "1", 1))
            {
                if(vpMfdInfo->mfdId == 1)
                    break;
            }
        }
    }

    while (oapiReadScenario_nextline(scn,line))
    {
        if ( !_strnicmp(line, "PARAMETERSMODE", 14) )
        {
            if ( !_strnicmp(line+15, "TANKS", 5) )
                vpMfdInfo->parametersMode = TANKS;
            else
                vpMfdInfo->parametersMode = MASS;
        }

        else if ( !_strnicmp(line,"MASSDISPLAY", 11) )
        {
            if ( !_strnicmp(line+12, "METRIC_TONS", 11) )
                vpMfdInfo->massdisplay = METRIC_TONS;
            else if ( !_strnicmp(line+12, "PERCENTAGE", 10) )
                vpMfdInfo->massdisplay = PERCENTAGE;
            else
                vpMfdInfo->massdisplay = KILOGRAMS;
        }

        else if ( !_strnicmp(line,"ENGINESDISPLAY", 13) )
        {
            if ( !_strnicmp(line+14, "DEGREES", 7) )
                vpMfdInfo->enginesdisplay = DEGREES;
            else
                vpMfdInfo->enginesdisplay = RADIANS;
        }
    }
}

Writing and reading information for inactive MFD instances.
Code:
// *********************************************************************
// saveState - save state to scenario file
// *********************************************************************
void VesselParametersMfdManager::saveState(FILEHANDLE scn)
{
    std::vector<VesselParametersMfdInfo*>::iterator i;

    for (i = vesselParametersMfdInfos.begin(); i != vesselParametersMfdInfos.end(); i++)
    {
        if((*i)->vpMfd == NULL) //The active MFD instances have stored their own status.
        {
            oapiWriteScenario_string(scn,"BEGIN_VP_MFD_INFO","");

            oapiWriteScenario_string(scn,"  VESSEL",(*i)->vessel->GetName());
            oapiWriteScenario_int(scn, "  MFD_ID", (*i)->mfdId);

            //Record the Vessel Parameters display mode.
            switch ( (*i)->parametersMode )
            {
                default: //Fall through
                case MASS:
                    oapiWriteScenario_string(scn,"  PARAMETERSMODE", "MASS");
                    break;
                case TANKS:
                    oapiWriteScenario_string(scn,"  PARAMETERSMODE", "TANKS");
                    break;
            }

            //Record the mass display mode.
            switch ( (*i)->massdisplay )
            {
                default: //Fall through
                case KILOGRAMS:
                    oapiWriteScenario_string(scn,"  MASSDISPLAY", "KILOGRAMS");
                    break;
                case PERCENTAGE:
                    oapiWriteScenario_string(scn,"  MASSDISPLAY", "PERCENTAGE");
                    break;
                case METRIC_TONS:
                    oapiWriteScenario_string(scn,"  MASSDISPLAY", "METRIC_TONS");
                    break;
            }

            //Record the mass display mode.
            switch ( (*i)->enginesdisplay )
            {
                default: //Fall through
                case RADIANS:
                    oapiWriteScenario_string(scn,"  ENGINESDISPLAY", "RADIANS");
                    break;
                case DEGREES:
                    oapiWriteScenario_string(scn,"  ENGINESDISPLAY", "DEGREES");
                    break;
            }

            oapiWriteScenario_string(scn,"END_VP_MFD_INFO","");
        }
    }
}


// *********************************************************************
// loadState - save state to scenario file
// *********************************************************************

void VesselParametersMfdManager::loadState(FILEHANDLE scn)
{
char *line;
    char cbuf[sizeOfBuffer];
    VesselParametersMfdInfo *vpibuf;

    while (oapiReadScenario_nextline(scn,line))
    {
        if ( !_strnicmp(line,"BEGIN_VP_MFD_INFO",17) )
        {
            vpibuf = new VesselParametersMfdInfo(NULL, NULL, 0);
            
            while (oapiReadScenario_nextline(scn,line))
            {
                if ( !_strnicmp(line,"VESSEL",6) )
                {
                    sscanf_s(line+7,"%s", cbuf, sizeOfBuffer);
                    if ( !(vpibuf->vessel = oapiGetVesselInterface(oapiGetVesselByName(cbuf))) )
                        break; // go no further if the vessel is not valid
                }

                else if ( !_strnicmp(line, "MFD_ID", 6) )
                {
                    sscanf_s(line+7,"%d",&(vpibuf->mfdId));
                }

                else if ( !_strnicmp(line, "PARAMETERSMODE", 14) )
                {
                    if ( !_strnicmp(line+15, "TANKS", 5) )
                        vpibuf->parametersMode = TANKS;
                    else
                        vpibuf->parametersMode = MASS; // defaults to MASS if not TANKS
                }

                else if ( !_strnicmp(line, "MASSDISPLAY", 11) )
                {
                    if ( !_strnicmp(line+12, "METRIC_TONS", 12) )
                        vpibuf->massdisplay = METRIC_TONS;
                    else if ( !_strnicmp(line+12, "PERCENTAGE", 10) )
                        vpibuf->massdisplay = PERCENTAGE;
                    else
                        vpibuf->massdisplay = KILOGRAMS; // defaults to KILOGRAMS
                }

                else if ( !_strnicmp(line, "ENGINESDISPLAY", 14) )
                {
                    if ( !_strnicmp(line+15, "DEGREES", 7) )
                        vpibuf->enginesdisplay = DEGREES;
                    else
                        vpibuf->enginesdisplay = RADIANS; // defaults to RADIANS
                }

                else if ( !_strnicmp(line,"END_VP_MFD_INFO",15) )
                    break;
            }

            if ((vpibuf->vessel)) // check info has valid handles
                vesselParametersMfdManager->vesselParametersMfdInfos.push_back(vpibuf); // add it to the list if OK
            else
                delete vpibuf; // discard it otherwise

            if ( (!_strnicmp(line,"END",3)) && (strlen(line) == 3) )
                break; // stop reading if we've reached the end of the block
        }
    }
}
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
I believe your problem is in reading the parameters, rather than in writing them.

In VesselParametersMfd::ReadStatus you need to check for "END_MFD". oapiReadScenario_nextline only returns false on "END" or EOF, not "END_MFD". In addition, all MFDs are loaded during the same pass of the scenario file by Orbiter, so by the time your second instance gets given the scenario file handle, the position in the scenario file is down in the vessel section somewhere. It could be considered a minor bug in oapiReadScenario_nextline, I guess.

Another sanity check you should do is to load up a couple of MFDs, quicksave and then open up the quicksaved scenario file in a text editor. Check that each MFD has written the expected parameters to the scenario file.
 
Top