Discussion Observations on the "UCGO Unpack" problem

mjanicki

Addon Developer
Addon Developer
Donator
Joined
Apr 4, 2008
Messages
106
Reaction score
0
Points
0
Location
Spokane
I don't use UCGO unpackable cargo all that often, but I became interested in trying to determine what exactly is causing the reported problem of unpacked cargo returning to packed state after a scenario save/reload. The discussion always seemed to be centered around AFCMODE numbers so I started there, did a lot of tests, recorded a lot of results, and came up with a Lua script that I think could be the start of finding a 'fix' for the problem.


The difficulty that most run into when trying to find information about what AFCMODE in a scenario file is for is that within the Orbiter internals, it's not called AFCMODE. It's called something more akin to ADCMODE. Specifically, the Orbiter SDK information one wants to look for is information pertaining to:

DWORD VESSEL::GetADCtrlMode() const
and
void VESSEL::SetADCtrlMode(DWORD mode) const

ADCtrlMode is AeroDynamic Control Surfaces Mode, while AFCMODE as appears in scenario files could simply be a typo in the internals which would be a nightmare to correct since every scenario file out there uses that spelling; or, AFCMODE might be read as Aerodynamic Flight Control Surfaces Mode. Whatever the reason, scenario files use AFC and internals use ADC.

Now that that's out of the way, what do the numbers for AFCMODE mean? The number used for AFCMODE is a sequence of bit flags defining which types of control surfaces can be manually controlled by the user. Only 3 bits are used. bit 0 indicates whether elevators are enabled (1) or disabled (0); bit 1 is for rudder; and bit 2 is for ailerons. So, you can see that as far as Orbiter is concerned, values for AFCMODE should be between 0 (all disabled) and 7 (all enabled) inclusive. However, the mode used to set these flags is a DWORD long, so there are plenty of other bits to fiddle with. It's just that the outcome of doing so is not defined by Orbiter.

So here's where the UCGO 'odd-looking' AFCMODE numbers come in. UCGO appears to be using additional bits of the AFCMODE to store information. Through trial and error I've come up with the following observations:

1) Unpacked cargo always has bit 3 set.
(2^3 = 8 ; note that the oft-recommended AFCMODE value of 120 is equal to 8, MOD 16. More on this later.)

2) Packed cargo always has bit 4 set, and may set higher bits as well.
(However, the use of "CargoUnpacked 0" in the scenario file seems capable of overriding these higher bits. Perhaps there is some legacy code in UCGO 2.0.)

3) Packed cargo which is unpacked during a simulation will set bit 3 but does not unset the correct bits 4 or higher. I think the UCGO internals which handle these bit manipulations might be off by a bit which creates new bits set that are unneeded (ex: AFCMODE 48 while packed) or fails to unset the proper bits when the cargo is unpacked (ex: AFCMODE 24 when unpacked).
(This results in unpacked cargo which seems to function, but does not display the appropriate 'unpacked' meshes. Bit 3 is indicating unpacked, "CargoUnpacked" is indicating unpacked, but the higher bits are indicating packed. My guess is that UCGO internals are doing bit checks such that having multiple bits set allows the cargo to appear to be in both packed and unpacked states at the same time.)

4) Upon scenario load, some unpackable cargo (whether packed or unpacked) will receive an additional bit being set, above that specified in the scenario file AFCMODE for that cargo. This seems to be related to #3 above.
(This is why you might get the cargo working by manually editing the scenario file, but it all goes haywire once you create a new save. Internally the mode is not what it was when the scenario started.)

So to try and correct this in the sim we need the following:

A) Bits 0, 1, and 2 must be preserved since those are defined within the Orbiter SDK and are used to indicate the usable state of control surfaces.

B) If the cargo is unpacked, bit 3 needs to be set and bits 4 and higher need to be cleared.

C) If the cargo is packed, the UCGO internal "CargoUnpacked 0" information seems to work to correctly identify that it is packed. But, bits 4 and higher are going to be set for some reason that I cannot discern. So we need to disable those bits after the scenario loads, or before a save to prevent 'incorrect' AFCMODE settings being written into the scenario save file.

The easiest way to accomplish these that I can think of is to cycle through each vessel, mod its adcmode with 16, and if the mode changed then write the new mode back to the vessel. This will ensure that all AFCMODE numbers written to a save file will be between 0 and 15 inclusive (0-7 for control surfaces with packed cargo, 8-15 for control surfaces with unpacked cargo).

To test whether or not a small correction like this will help overcome the problem people have had with unpacked UCGO cargo, I wrote a short Lua script to modify the adcmode of vessels on the fly. I've never used Lua before so this is really just a way to start discussion for a possible fix to the unpacked cargo problem. I think a small plugin module to handle this automatically during scenario load and save would be appreciated by users who don't want to mess with Lua scripts; but, that can wait until we hear some test results back.

Below is the script I've been using to test out 'correcting' packed and unpacked cargo. It seems to work for me, but I don't use unpackable cargo all that often. Better testing by cargo geeks is needed. Note also that there is no way I know of from Lua script to tell whether a vessel is a UCGO cargo or not, so this just cycles through every vessel in the scenario. If there are other add-on vessels out there that use higher bits of AFCMODE for their own purpose, then this is going to break those vessels most likely. But I don't think I've ever come across anything else that modifies AFCMODE beyond bit 2.

It would be wonderful if folks could test this out. It would be even better if some real programmers and some folks who understand Orbiter internals better could improve upon this proof of concept to make a module that would automatically handle this for users.

When the function fixcargo() is run within the sim, cargo should take on the state that it was supposed to have been left in -- packed or unpacked. It should not unpack things that are supposed to be packed, nor should it pack things up that should be unpacked. Getting cargo to take on the correct state can be accomplished by running this script function after the scenario loads. To ensure that the AFCMODEs are correct for the next time the scenario is loaded, run this script function again prior to saving.

Thanks to those who test and provide feedback or add to the discussion of how we might all come up with a fix for the unpacking problem.

-- Mike


Code:
-- UCGO unpack fix script
-- Proof of Concept to provide information and encourage discussion
-- toward finding a good fix.
term.out('')
term.out('UCGO unpack fix script')
term.out('ALPHA testing stage')
term.out('Run function \'fixcargo()\' to start')
term.out('')

-- cycle through vessels in the scenario looking for strange adcmode numbers
-- there is ABSOLUTELY no guarantee that only UCGO cargos use such adcmode
-- numbers, so other things might break
function fixcargo()

    local n = vessel.get_count()
    if n > 0 then
        term.out('Total Vessels: '..n)
        for i=0, n-1 do
            vif = vessel.get_interface(i)
            if vif == nil then
                term.out('Bad Vessel Interface.  Stopping.')
                break
            end
            name = vif:get_name()
            oldmode = vif:get_adcmode()
            newmode = (oldmode % 16)
            if oldmode ~= newmode then
                vif:set_adcmode(newmode)
            end
            term.out('Vessel: '..i..'    Name: '..name..'    Old Mode: '..oldmode..'    New Mode: '..newmode)
        end
    else
        term.out('No vessels to process.')
    end
end
 

laukejas

New member
Joined
Dec 21, 2010
Messages
120
Reaction score
0
Points
0
Dan, it's so great to see that you will update UCGO. But please tell, will this update be available to default Orbiter 2010 P1, or just DX9 and DX11 versions? Because I have default - too many addons are incompatible with DX9 and DX11.
 

laukejas

New member
Joined
Dec 21, 2010
Messages
120
Reaction score
0
Points
0
Thank you! Any approximate date for this release?
 

dansteph

Addon Developer
Addon Developer
Beta Tester
Joined
Apr 30, 2008
Messages
788
Reaction score
64
Points
28
Website
orbiter.dansteph.com
Soon, I have a problem with the Arrow to resolve else everything is already packed.
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,886
Reaction score
2,139
Points
203
Location
between the planets
Dan, it's great to see that you're still on to it! :cheers:

I have one question. It probably won't fit into your roadmap, but well, man's got to ask (it might even make things easier for you. Maybe).

Could you consider using the [ame="http://www.orbithangar.com/searchid.php?ID=4976"]extended planetary parameters[/ame] in UMMU? it would provide a much more flexible and complex way to implement habitability and breathability of planetary atmospheres. Indeed, most of the code for checking breathability is already contained in the code, the only thing left would be to check density at the current UMMU altitude, but you're already doing that anyways.
There's also temperatures in there, but there's no code to calculate temperatures at a specific point, but If you'd like I probably could whip something up (I already have working thermodynamics code on my disc, it wouldn't be too much trouble to adapt it to planets, I think...)

For what it's worth, the epp file in the download for sol-system isn't complete, but If you'd consider using it, I'll finish it. There just wasn't a lot of incentive to do so, and it's pretty tedious work.
 
Top