CANOPY OPEN: Needs to be constantly "refreshed" (canopy closes automatically)?

Dear all,

I just noticed that the canopy seems to close automatically again, each time I set the CANOPY OPEN simulation variable to a value > 0 (with unit “Percent”: 100 = fully open, 0 = closed).

That implies that if I want to keep the canopy open I need to repeatedly - e.g. for every simulated frame - set the same value. That’s a bummer, since I just optimised my requests in such a way that I only send (the previously sampled) values when there is an actual value change. And that means that I need to make an exception for the CANOPY OPEN (and possibly other variables?) variable in that I now need to always send the value (if it is > 0, that is).

If this was the case only for one aircraft I would say that “perhaps that is an issue with the animation implementation of that particular aircraft”.

However setting the value in the SDK example SimvarWatcher application I do observe that the value of the variable CANOPY OPEN is decreased as well, the very moment after I have set it e.g. to 100 (%):

(So it is not just the animation which “closes” the canopy, but really the actual CANOPY OPEN simulatin variable value).

Furthermore I can reproduce this with two distinct aircraft:

Which again makes me believe that this is a “Flight Simulator internal behaviour” - a wanted one?

Would anyone know a good reason why this simulation variable “closes itself”? Is it part of some “physics engine” calculation which constantly updates variables (but why)? It’s not like e.g. the gear raises (or lowers) itself automatically either - so why the canopy?

Or might this indeed be a bug then? Unfortunatelly I just realised this now with the current FS2020 1.15.7.0 version, so I don’t know what the behaviour in previous versions was.

But maybe anyone with experience in “building aircraft models” (with the MSFS SDK) could confirm whether it is indeed necessary to constantly “refresh” the CANOPY OPEN state?

Does it work if you call AIReleaseControl to prevent FS2020 from taking control of the variable?

In my code I am requesting that value for the user aircraft - does “AI” actually have any impact on the user aircraft? I thought that this was only relevant for “AI aircrafts” - but it is certainly worth a try…

I do however “freeze” the user aircraft (altitude, lattitude/longitude, attitude), but that should only have an impact on the position (respectively the “simulation of the forces” that affect the position) of the aircraft.

Just in case, I will try to “release AI control” on the user’s aircraft and report back…

1 Like

I could be wrong, but I considered AIReleaseControl to mean “prevent the Sim AI from updating the variable automatically”, rather than specific AI-controlled objects.

I’ll be interested in your test results, as I may need to re-think some elements of my own code.

No, doesn’t seem to have an impact:

SimConnect_AIReleaseControl(
    d->simConnectHandle,
    SIMCONNECT_OBJECT_ID_USER,
    ReleaseAI
);

where “ReleaseAI” is the request ID as specified in an enum, as all my other request IDs, and the constant SIMCONNECT_OBJECT_ID_USER is defined in the SDK header SimConnect.h (with value 0).

The canopy still closes automatically.

I know that certain “physics related variables” (like the simulation of engine related variables: oil pressure, heat, …) are automatically updated by the simulation engine, but am a bit surprised to see that CANOPY OPEN also gets automatically updated.

And I am afraid that other simulation variables that one would expect to be “static” might also be “automatically set” (*).

But so far CANOPY OPEN is the first and only simulation variable that I “discovered” with such a behaviour. All other variables (gear, rudder, flaps, cowl flaps, …) that I am currently using behave “static” as expected.

(*) The TAILHOOK POSITION comes to mind - but I have yet to find an aircraft that actually supports that variable: e.g. the T-45C Goshawk does have a tailhook, but uses “local variables” for both the canopy and its tail hook. It doesn’t react to either CANOPY OPEN or TAILHOOK POSITION at all.

It is quite possible that this “AIReleaseControl” might also have an impact on the user aircraft (as identified by SIMCONNECT_OBJECT_ID_USER = 0), but so far I had no troubles to “control” (“replay”) the aircraft, after having (only) “frozen” its position and attitude.

But I understood that this AIReleaseControl is mostly (only?) relevant for “AI objects” which have been created with the various “AICreate” functions - if “AI is not released” then the AI object would otherwise try to follow some flight plan (or do whatever AI objects do all day long ;)).

I think I need to re-read and experiment with it a bit more to clarify it’s true purpose, at least for my own edification, otherwise it will annoy the hell out of me, I’ll see if I have any spare time at the weekend and let you know whatever I find out.

In the meantime, apologies for diverting your thread off- topic

No no no, that was fully on-topic and helpful! So thank you for your replies!

A cursory review of the API docs seems to imply the SimConnect_AIReleaseControl is intended to prevent the FS (AI) from updating a variable on any object, including the user’s own aircraft, although the docs do say this method isn’t tested yet.

It basically accepts 3 parameters, as you’ve shown above (2 for managed code - the handle is implied and re-used when SimConnect is instantiated).

Reviewing the documentation about the remaining 2 parameters:

ObjectID: Specifies the ID of the Microsoft Flight Simulator object that the data should be about. This ID can be SIMCONNECT_OBJECT_ID_USER (to specify the user’s aircraft).

ReleaseAI (aka RequestID): Specifies the client defined request ID, e.g. the ID associated with a SimVar request.

My interpretation of this (for this specific scenario) would be, you can prevent the AI (e.g. Sim auto-updates) from being applied to any SimVar you wish to control, relating to the user’s aircraft.

Thus, if you wish to control the Canopy position manually and prevent the Sim from updating it, you would call this to release control of the CANOPY OPEN variable and allow you to control it manually.

Unfortunately, I can’t test this theory just now, as my dev laptop has run out of disk space and I can see myself having to do a major clean-up this weekend to free up space.

A point worth noting, when you call the method, make sure you use the correct ENUM type for the RequestID, my code was passing the value as a SIMCONNECTDEFINITION Enum, instead of a SIMCONNECTREQUEST Enum - oops, rookie mistake!

1 Like

So you are saying that the request ID should refer to an existing request ID with which the actual simulation variable has been received (or is to be received)? Interesting theory, but I don’t think that it could possibly work that way.

That would imply that the variable is part of some record that we had previously received (and which is identified with a REQUEST_ID) - but what if we never wanted to retrieve the value in the first place, but only set it (as I just did with the SimvarWatcher example)? Or in other words: there simply would not exist any REQUEST_ID for that CANOPY OPEN variable at all?

In fact, I don’t think that the SimConnect server actually puts much thought behind the REQUEST_IDs that we define (in C/C++ plain old enums are untyped, by the way, so from an SimConnect server point of view those are just (integer) values which identify the client requests): the server simply sends the same REQUEST_ID back, together with the requested data, and the client then knows: "Ah, that response belongs to my previous request identified with REQUEST_ID, so I need to interpret the response buffer accordingly).

In fact, the data that we request is more associated with the SIMCONNECT_DATA_DEFINITION_ID rather than the actual SIMCONNECT_DATA_REQUEST_ID:

 SimConnect_RequestDataOnSimObject(HANDLE hSimConnect, SIMCONNECT_DATA_REQUEST_ID RequestID, SIMCONNECT_DATA_DEFINITION_ID DefineID, ...

So even if we had requested the CANOPY OPEN variable with some given DATA_REQUEST_ID there is hardly any reliable way for the SimConnect server to know that there is any association (“link”) between that DATA_REQUEST_ID (which me might even change for every request!) and the requested variable CANOPY OPEN (or any other variable, for that matter). The only association between that simulation variable (respectively the record it belongs to as member) and some ID is between that record and its SIMCONNECT_DATA_DEFINITION_ID - but that is conceptually a different type (*).

Or in other words: I believe that the REQUEST_ID as passed along to

SimConnect_AIReleaseControl(
    d->simConnectHandle,
    SIMCONNECT_OBJECT_ID_USER,
    ReleaseAI
);

is simply a new value, as in:

enum class DataRequest: ::SIMCONNECT_DATA_REQUEST_ID {
    AircraftInfo,
    ...
    AircraftHandle,
    Light,
    ReleaseAI
};

Of course I could try to “re-use” the REQUEST_ID AircraftHandle (with which I request the states of all the “handles and levers in the cockpit”), but again: there is no way the server could possibly know that this ID relates to the CANOPY OPEN variable (especially not in the case when I would never ever actually read that variable beforehand).

Still it is an intriguing way to think that “AI” could (should?) also be disabled for the user aircraft, and I might re-add this call “just in case”. There is a saying in German “Nützt es nichts, dann schadet es nicht” (“if it doesn’t help, then it (hopefully) doesn’t harm either”) - and who knows, this “disable AI” might have an effect in the future.

But beyond all this: I can’t get my head around why the AI would want to close the canopy all the time? Sure, flying with an open canopy cannot be healthy - but why exactly (just) the canopy, why not the gear, why not the brakes etc.?

So what I’d be curious to know: is there something special about this CANOPY OPEN variable when you “build” an aircraft like the Fiat G-91?

@PaternalSmile51, I think you are (one of) the developer of the G-91 (which I like very much btw!): is there something “unusual” about the canopy, that is, do you also need to “constantly keep the canopy open” (because it closes “automatically” otherwise)? Or is that just something that affects “the external view” (or rather: values that have been changed “from externally”, via the SimConnect API) of the aircraft state, but not the “internal state” of the aircraft?

As a quick recap: I noticed that when setting the CANOPY OPEN simulation variable to an “open” state, that is a value > 0 (also with the SimvarWatcher SDK example app) that the value decreases immediatelly thereafter “automagically” - and the canopy also closes visually. So far all other “aircraft controls” (flaps, levers, light switches, …) do not “change themselves” back to “normal state”.

And for the record: I got my solution working again by repeatedly send the CANOPY OPEN variable as soon as its value is > 0 (also when the actual value does not change).

Thanks again for your insights! And no, I havent’ used any of those AI functionalities either in practise. That’s something for later :slight_smile:

(*) in reality in C/C++ plain old enums are untyped and the values in the end simple integer values - unless C++ enum classes are used (which I do, but I need to “cast” them each time to the underlying integer type whenever I call the SimConnect API ;)).

P.S. Geee sorry, after reading my post I also realise that it is a “bit” convoluted. Sorry about that, but I hope you “get the gist” out of it :slight_smile:

1 Like

Do you have a link / reference to the documenation where it says “this method isn’t tested yet”? I did not come across this documentation just yet. E.g. I do not find such a statement for SimConnect_AIReleaseControl.

But while this “release AI control” functionality may certainly also work (in the future) for the user aircraft I just realised that I cannot use it as of now. Simply because there does not seem to be a way to "re-enable AI functionality, or in other words: there is no “AIEnableControl” function. Which would be needed in my case, because I want to re-establish the original user aircraft state after “replay”, so the user (and possibly the AI) can take control over the aircraft again :slight_smile:

Which leads me back to my initial thought that all those “AI” related functions are indeed just meant for “created AI objects” (which can be “disposed after use”, with SimConnect_AIRemoveObject)

You went too deep into the docs, look at the index page for all methods: SDK Documentation

Scroll down to the entry for AIReleaseControl…

1 Like

A lot to process in those posts but I got the gist of what you were saying.

I agree that it’s strange the Sim would want to auto-close the canopy, I can see no reason for doing so, in fact, I’ve seen pilots being trained on Harriers where they were expected to keep the canopy open at low level/speed, so the instructor could shout instructions (haven’t they heard of radios? lol).

If AI control can be released, there should be a corresponding method to re-assert control.

The documentation has always been a bit lacking (but it is getting better), maybe we’ll just need to wait a while longer for them to test that feature, so they can figure out what it does and tell us in the SDK Update documentation (or even better, supply an example/sample).

Although I can understand your approach of sending regular commands to open the canopy as a work-around, it annoys me that something so simple should be so damned infuriating - it just doesn’t feel right.

Finally, untyped enums - sadly I program in C#, where almost everything has to be cast into a type. The work-around for me was to define 2 enums, then cast the integer values for the Definition and Request into the correct enum (even though they aren’t defined as values in those enums). The base enum class is abstract, so it can’t be instantiated the same as it can in C/C++ :frowning:

Couldn’t they just ask us to use integers and be done with it? Why require an enum at all?

Yeah, the more I think about it, the less I believe that this “auto-decrease” is a wanted feature. But then again, constantly changing a value requires some explicit code and logic somewhere (or some oversight to “exclude” that variable from some “ongoing physics calculation”?), so I am not so sure what the purpose of “closing the cockpit” would be - perhaps really some “AI thingie”.

But I would still be interested what happens from an “aircraft manufacturer” point of view, whether that CANOPY OPEN simulation variable (or whatever the “internal state representation / L:var” is used - I have absolutely no idea about the SDK other than a few weeks of SimConnect experience) is also “special” in that sense (and whether it also needs to be constantly “refreshed” in order to keep the canopy open. @PaternalSmile51 - any experience to share here? :slight_smile:

I’ll file a ZenDesk issue about it and we’ll wait and see :slight_smile:

1 Like

I close the Spitfire by pulling it shut above me with the mouse (as in the real aircraft). In the F6F I use the crank on the right side of the cockpit. No keystrokes have worked for me.