• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

FSX Decouple lights from default battery

In the process of coding the overhead panel of the Saab I reached the lights panel and with it one of FSX's most unflexible systems.
In FS all lights are usually tied to the default battery. The aircraft.cfg offers to assign the lights to different buses, but they are way too few - at least for simulating a more complex aircraft.

Therefore, I came up with my own electrical system and simulated all the buses and relays with L:Vars.
Now I got to the point where I connected all the cables and plugs...

The easy step is to write a logic, that toggles the lights on/off depending on the VC switch position and your custom bus voltages.
The problem arises when you want to make it "keyboard-input-safe".


-> When the user toggles the landing lights via keyboard (ie Ctrl+L), the Sim doesn't know whether

a) the event came from my logic, which turned the lights on, because the bus voltage just got high enough
- or -
b) the user didn't want to use his mouse to click the VC-switch and simply toggled the VC-switch with the keyboard.

That's an important difference, but in both cases the Sim will just toggle the lights, because it sensed the event.

The later posts of this thread explain the problem far better than my horrible description could ever do.

I ended up with this:

Code:
<Element Name="Lights"><Select><Value>

0 (>L:switch_changed_LL,bool)
(L:LIGHT Landing, bool) (L:L_Main_Bus, number) 18 &gt; (L:R_Main_Bus, number) 18 &gt; or and (A:LIGHT Landing, bool) !=
if{ 1 (>L:switch_changed_LL,bool) (>K:LANDING_LIGHTS_TOGGLE) }

</Value></Select></Element>

<Keys>
<On Event="LANDING_LIGHTS_TOGGLE">
(L:switch_changed_LL,bool)
if{ 0 (>L:switch_changed_LL,bool) }
els{ (L:LIGHT Landing, bool) ! (>L:LIGHT Landing, bool) }
</On>
</Keys>

(The VC-switch is animated by (L:LIGHT Landing, bool) )

The magic lays in the key trap itself, which senses if the command comes from the logic or from the user.

...and fully adapted to the electric system:

Code:
<Element  Name="Lights">
<Select><Value>

   0 (>L:switch_changed_LL,bool)
   (L:LIGHT Landing, bool) (L:L_Main_Bus, number) 18 &gt; (L:R_Main_Bus, number) 18 &gt; or * (A:LIGHT Landing, bool) != if{ 1 (>L:switch_changed_LL,bool) (>K:LANDING_LIGHTS_TOGGLE) }
   0 (>L:switch_changed_strobes,bool)
   (L:LIGHT Strobes, bool) (L:R_Main_Bus, number) 18 &gt; * (A:LIGHT Strobe, bool) != if{ 1 (>L:switch_changed_strobes,bool) (>K:STROBES_TOGGLE) }
   0 (>L:switch_changed_nav,bool)
   (L:LIGHT Nav, bool) (L:L_Main_Bus, number) 18 &gt; (L:R_Main_Bus, number) 18 &gt; or * (A:LIGHT Nav, bool) != if{ 1 (>L:switch_changed_nav,bool) (>K:TOGGLE_NAV_LIGHTS) }
   0 (>L:switch_changed_wing,bool)
   (L:LIGHT Wing, bool) (L:R_Main_Bus, number) 18 &gt; * (A:LIGHT Wing, bool) != if{ 1 (>L:switch_changed_wing,bool) (>K:TOGGLE_Wing_LIGHTS) }
   0 (>L:switch_changed_logo,bool)
   (L:LIGHT Logo, bool) (L:R_Main_Start_Bus, number) 18 &gt; * (A:LIGHT Logo, bool) != if{ 1 (>L:switch_changed_logo,bool) (>K:TOGGLE_Logo_LIGHTS) }
   0 (>L:switch_changed_beacon,bool)
   (L:LIGHT Beacon, bool) (L:L_Bat_Bus, number) 18 &gt; * (A:LIGHT Beacon, bool) != if{ 1 (>L:switch_changed_beacon,bool) (>K:TOGGLE_BEACON_LIGHTS) }
   0 (>L:switch_changed_taxi,bool)
   (L:LIGHT Taxi, bool) (L:L_Bat_Bus, number) 18 &gt; * (A:LIGHT Taxi, bool) != if{ 1 (>L:switch_changed_taxi,bool) (>K:TOGGLE_Taxi_LIGHTS) }

</Value></Select>
</Element>

<Keys>
<On Event="LANDING_LIGHTS_TOGGLE">
(L:switch_changed_LL,bool) if{ 0 (>L:switch_changed_LL,bool) } els{ (L:LIGHT Landing, bool) ! (>L:LIGHT Landing, bool) }
</On>
<On Event="STROBES_TOGGLE">
(L:switch_changed_strobes,bool) if{ 0 (>L:switch_changed_strobes,bool) } els{ (L:LIGHT STROBES, bool) ! (>L:LIGHT STROBES, bool) }
</On>
<On Event="TOGGLE_NAV_LIGHTS">
(L:switch_changed_nav,bool) if{ 0 (>L:switch_changed_nav,bool) } els{ (L:LIGHT NAV, bool) ! (>L:LIGHT NAV, bool) }
</On>
<On Event="TOGGLE_WING_LIGHTS">
(L:switch_changed_wing,bool) if{ 0 (>L:switch_changed_wing,bool) } els{ (L:LIGHT WING, bool) ! (>L:LIGHT WING, bool) }
</On>
<On Event="TOGGLE_LOGO_LIGHTS">
(L:switch_changed_logo,bool) if{ 0 (>L:switch_changed_logo,bool) } els{ (L:LIGHT LOGO, bool) ! (>L:LIGHT LOGO, bool) }
</On>
<On Event="TOGGLE_BEACON_LIGHTS">
(L:switch_changed_beacon,bool) if{ 0 (>L:switch_changed_beacon,bool) } els{ (L:LIGHT BEACON, bool) ! (>L:LIGHT BEACON, bool) }
</On>
<On Event="TOGGLE_TAXI_LIGHTS">
(L:switch_changed_taxi,bool) if{ 0 (>L:switch_changed_taxi,bool) } els{ (L:LIGHT TAXI, bool) ! (>L:LIGHT TAXI, bool) }
</On>
<On Event="ALL_LIGHTS_TOGGLE">
(L:LIGHT TAXI, bool) ! (>L:LIGHT TAXI, bool)
(L:LIGHT BEACON, bool) ! (>L:LIGHT BEACON, bool)
(L:LIGHT LOGO, bool) ! (>L:LIGHT LOGO, bool)
(L:LIGHT WING, bool) ! (>L:LIGHT WING, bool)
(L:LIGHT NAV, bool) ! (>L:LIGHT NAV, bool)
(L:LIGHT STROBE, bool) ! (>L:LIGHT STROBE, bool)
(L:LIGHT Landing, bool) ! (>L:LIGHT Landing, bool)
</On>
</Keys>

Conclusion:
- User can toggle the VC-switch via keyboard commands and via mouse
- lights will only turn on when the corresponding bus is powered and the VC-switch is on
- keyboard commands won't work from external view (works perfectly with XMLTools though)
- you need one extra L:Var for every switch (dunno if this works with G:Vars...)
- coding effort is still manageable

I'm pretty happy with the results. (*)
Most important advantage is that you can fully customize the conditions when the lights are on and when not without worrying about the key commands.

I'm sorry, if this has already been known, I just thought it might be helpful for some developers.


(*) Follow up question: [SOLVED]
The key traps only work in the VC, which is realistic for me. But is there any way to make them work from the external as well?
Maybe putting the key trap code in the modeldef and attaching it to a poly in the VC?
 
Last edited:

Heretic

Resource contributor
With access to the model source files, one could simply make the visibility of the attachpoints of the light effects respond to the L: var of the custom lighting system. That would make things mildly easier.
 

taguilo

Resource contributor
I'm sorry, if this has already been known, I just thought it might be helpful for some developers.

It is indeed very helpful. I for one use the following kind of code placed in the Event capture itself, which gives the advantage of not being parsed on every gauge cycle. Short and simple:

Code:
<On Event="LANDING_LIGHTS_TOGGLE">
   (L:LandLightToggleByCode,bool) !
   if{
        (A:LIGHT LANDING,bool) ! (L:LandingMustBeOff,bool) and
        if{ 1 (>L:LandLightToggleByCode,bool) (>K:LANDING_LIGHTS_TOGGLE) }
        els{ (A:LIGHT LANDING,bool) ! (>L:Light Landing,bool) }
      }
   0 (>L:LandLightToggleByCode,bool)
</On>

(L:LandingMustBeOff,bool) should be a conditional that prevents the light to turn on when commanded by the VC switch or keyboard key.
(L:LandLightToggleByCode,bool) is a flag to avoid entering an endless loop.

Notice that <On Event="LANDING_LIGHTS_TOGGLE"> must exists only once in the entire gaugeset (2D and VC gauges)

Tom

EDIT: Forgot the switch control part (L:Light Landing,bool) .
 
Last edited:
I for one use the following kind of code placed in the Event capture itself, which gives the advantage of not being parsed on every gauge cycle.
But how would your code notice, if the corresponding bus voltage dropped off? I think there must be code that checks this condition in every cycle.

[EDIT]
Tom, I understood that you would implement my <Element> part straight into the Event block and your (L:LandingMustBeOff,bool) would still be set in an <Element>. If this is the case, then see my concerns above. (The Event block won't be executed if the L:Var changes...)
If I misunderstood your intention, then please elaborate the main difference to my code.
[/EDIT]

--
With the XMLTools solution I probably won't need the "0 (>L:switch_changed_LL,bool)" in my <Element> anymore. However, I'll leave it in the original code for the ones, who don't use XMLTools yet.
 
Last edited:

taguilo

Resource contributor
Steven,

Yes, (L:LandingMustBeOff,bool) would still be set in an <Element>or <Update> tag, just turning lights off if no power available, or on if switch in On and power regains.

(L:LandingMustBeOff,bool) (A:LIGHT LANDING,bool) ==
if{ 1 (>L:LandLightToggleByCode,bool) (>K:LANDING_LIGHTS_TOGGLE) }

And in modelfef callback :
(L:Light Landing,bool) ! (>L:Light Landing,bool)

The difference with your code is that the events "cancels" itself in the capture when invalid conditions are met, so there is no risk that the lights flickers for an instant if off conditions should prevail. Perhaps it is not much important with the light but is a factor in other controls (ie throttle, Flaps handle, etc).

Tom
 
The difference with your code is that the events "cancels" itself in the capture
Ah, now I see it. Good idea.

But then you should leave out the ! behind both (A:LIGHT LANDING,bool), I think.


The extra L:Var in your code brings me to an off topic question: Has anybody ever noticed a limit in the number of L:Vars?
I hope there isn't, because I've got about 300 of them in my Saab already and only have around 30% of the systems coded.
 

taguilo

Resource contributor
But then you should leave out the ! behind both (A:LIGHT LANDING,bool), I think.

No, because the event capture triggers before the AVar value changes.

Regarding extra vars, it seems there is no limit for them. I have a project with more than 1,500 detected with LocalVarsLogger.

Tom
 
Top