Showing posts with label In-Depth. Show all posts
Showing posts with label In-Depth. Show all posts

2015-09-26

Basics - Part 3: Tidying up numeric output

In Part 2 last week I explained how to display numeric output when you have no mechanism to actually "print to the screen". Hopefully you've got a modified attitude indicator that has the speed and altitude displayed in the simplest of forms: a numeric readout. Click here to see what you should have so far.

Dual Digit
Number Strip
The problem as discussed so far is where you have a number that changes too rapidly; you may, for example, be holding an altitude of 15000 feet very well, but your indicated altitude will be fluctuating up and down by a few feet which means the final digits of your readout could be fluctuating so much as to be unreadable or inaccurate.

In such circumstances it's better to make your number strip twice as wide, listing numbers in tens, so that at any time the pilot can see which direction the numbers are moving and be able to maintain height properly. You can see such a strip here to the right.

You will, of course, need to make a mask to cover the double-digit size, and adjust your XML accordingly, but you can then remove the "%" operator from the expression and have a smooth-scrolling number.
Dual Digit
Mask

When you're making the mask, remember that for this kind of  "rolling readout" you'll need a bit of extra space at the top and bottom so that when between one or another of the number marks the pilot can still easily tell which two marks it's between.

So we can change our final two elements by replacing them with this single-element dual-digit display - here's the complete xml for our modified gauge, assuming we've named the two new images "HSIb_dual_figure_scale.bmp" and "HSIb_dual_character_mask.bmp":

<?xml version="1.0" encoding="utf-8"?>
<Gauge Name="Attitude Indicator" Version="2.0">
  <Image Name="Attitude_Background2.bmp" ImageSizes="320,240,320,240"/>
  <Element>
    <Position X="160"  Y="120"/>
    <Image Name="Attitude_Card.bmp" ImageSizes="240,240,240,240">
      <Axis X="120" Y="120"/>
    </Image>
    <Rotate>
      <Value>(A:sim/cockpit2/gauges/indicators/roll_AHARS_deg_pilot, ndegree)</Value>
    </Rotate>
  </Element>
  <Element>
    <Position X="160"  Y="120"/>
    <Image Name="Attitude_Inner.bmp" ImageSizes="240,240,240,240">
      <Axis X="120" Y="120"/>
    </Image>
    <Shift>
      <Value Minimum="-25" Maximum="25">(A:sim/cockpit2/gauges/indicators/pitch_AHARS_deg_pilot, negative)</Value>
      <Scale Y="0.85"/>
    </Shift>
    <Rotate>
      <Value>(A:sim/cockpit2/gauges/indicators/roll_AHARS_deg_pilot, ndegree)</Value>
    </Rotate>
  </Element>
  <Element>
    <Position X="160"  Y="120"/>
    <Image Name="Attitude_Outer.bmp" ImageSizes="240,240,240,240">
      <Axis X="120" Y="120"/>
    </Image>
    <Rotate>
      <Value>(A:sim/cockpit2/gauges/indicators/roll_AHARS_deg_pilot, ndegree)</Value>
    </Rotate>
  </Element>
  <Element>
    <Position X="5" Y="5"/>
    <MaskImage Name="HSIb_character_mask.bmp" ImageSizes="12,14,12,14">
      <Axis X="0" Y="0"/>
    </MaskImage>
    <Image Name="HSIb_figure_scale.bmp" ImageSizes="12,168,12,168">
      <Nonlinearity>
        <Item Value="0" X="0" Y="140"/>
        <Item Value="9" X="0" Y="14"/>
      </Nonlinearity>
    </Image>
    <Shift>
      <Value>(A:sim/cockpit2/gauges/indicators/airspeed_kts_pilot) 100 div</Value>
    </Shift>
  </Element>
  <Element>
    <Position X="17" Y="5"/>
    <MaskImage Name="HSIb_character_mask.bmp" ImageSizes="12,14,12,14">
      <Axis X="0" Y="0"/>
    </MaskImage>
    <Image Name="HSIb_figure_scale.bmp" ImageSizes="12,168,12,168">
      <Nonlinearity>
        <Item Value="0" X="0" Y="140"/>
        <Item Value="9" X="0" Y="14"/>
      </Nonlinearity>
    </Image>
    <Shift>
      <Value>(A:sim/cockpit2/gauges/indicators/airspeed_kts_pilot) (A:sim/cockpit2/gauges/indicators/airspeed_kts_pilot) 100 div 100 * - 10 div</Value>
    </Shift>
  </Element>
  <Element>
    <Position X="29" Y="5"/>
    <MaskImage Name="HSIb_character_mask.bmp" ImageSizes="12,14,12,14">
      <Axis X="0" Y="0"/>
    </MaskImage>
    <Image Name="HSIb_figure_scale.bmp" ImageSizes="12,168,12,168">
      <Nonlinearity>
        <Item Value="0" X="0" Y="140"/>
        <Item Value="9" X="0" Y="14"/>
      </Nonlinearity>
    </Image>
    <Shift>
      <Value>(A:sim/cockpit2/gauges/indicators/airspeed_kts_pilot) (A:sim/cockpit2/gauges/indicators/airspeed_kts_pilot) 10 div 10 * - %</Value>
    </Shift>
  </Element>
  <Element>
    <Position X="255" Y="5"/>
    <MaskImage Name="HSIb_character_mask.bmp" ImageSizes="12,14,12,14">
      <Axis X="0" Y="0"/>
    </MaskImage>
    <Image Name="HSIb_figure_scale.bmp" ImageSizes="12,168,12,168">
      <Nonlinearity>
        <Item Value="0" X="0" Y="140"/>
        <Item Value="9" X="0" Y="14"/>
      </Nonlinearity>
    </Image>
    <Shift>
      <Value>(A:sim/cockpit2/gauges/indicators/altitude_ft_pilot) 10000 div</Value>
    </Shift>
  </Element>
  <Element>
    <Position X="267" Y="5"/>
    <MaskImage Name="HSIb_character_mask.bmp" ImageSizes="12,14,12,14">
      <Axis X="0" Y="0"/>
    </MaskImage>
    <Image Name="HSIb_figure_scale.bmp" ImageSizes="12,168,12,168">
      <Nonlinearity>
        <Item Value="0" X="0" Y="140"/>
        <Item Value="9" X="0" Y="14"/>
      </Nonlinearity>
    </Image>
    <Shift>
      <Value>(A:sim/cockpit2/gauges/indicators/altitude_ft_pilot) (A:sim/cockpit2/gauges/indicators/altitude_ft_pilot) 10000 div 10000 * - 1000 div</Value>
    </Shift>
  </Element>
  <Element>
    <Position X="279" Y="5"/>
    <MaskImage Name="HSIb_character_mask.bmp" ImageSizes="12,14,12,14">
      <Axis X="0" Y="0"/>
    </MaskImage>
    <Image Name="HSIb_figure_scale.bmp" ImageSizes="12,168,12,168">
      <Nonlinearity>
        <Item Value="0" X="0" Y="140"/>
        <Item Value="9" X="0" Y="14"/>
      </Nonlinearity>
    </Image>
    <Shift>
      <Value>(A:sim/cockpit2/gauges/indicators/altitude_ft_pilot) (A:sim/cockpit2/gauges/indicators/altitude_ft_pilot) 1000 div 1000 * - 100 div</Value>
    </Shift>
  </Element>
  <Element>
    <Position X="291" Y="5"/>
    <MaskImage Name="HSIb_dual_character_mask.bmp" ImageSizes="24,14,24,14">
      <Axis X="0" Y="0"/>
    </MaskImage>
    <Image Name="HSIb_dual_figure_scale.bmp" ImageSizes="24,168,24,168">
      <Nonlinearity>
        <Item Value="0" X="0" Y="140"/>
        <Item Value="90" X="0" Y="14"/>
      </Nonlinearity>
    </Image>
    <Shift>
      <Value>(A:sim/cockpit2/gauges/indicators/altitude_ft_pilot) (A:sim/cockpit2/gauges/indicators/altitude_ft_pilot) 100 div 100 * -</Value>
    </Shift>
  </Element>
  <Element>
    <Position X="40"  Y="0"/>
    <Image Name="Attitude_Overlay.bmp" ImageSizes="240,240,240,240"/>
  </Element>
</Gauge>


You'll notice that I have modified the ImageSizes attributes, the Nonlinearity and the expression - the expression is probably the hardest bit to understand, so for clarity we'll break down exactly how this works:


  • Get the altitude and push to the stack
  • Get the altitude and push to the stack again
  • Push "100" to the stack
  • Integer division (altitude/100 as an integer) and push result back to the stack
  • Push "100" to the stack
  • Multiply (result of previous integer division * 100) and push result back to stack
  • Subtract (altitude - result from the above multiplication )
Notice that we do not end with an integer division, and nor do we use the modulo operator (%) to round the number. Because we now have our nonlinearity between 0 and 90 rather than 0 and 99, the result is a smooth-scrolling double digit at the end.

I'll be honest - I'm thoroughly bored of describing this now! I'm really hoping that these last 3 lessons have given you a good handle on how to produce numeric displays; Please do give me comments and suggestions - if you're stuck feel free to ask and I will try and help you out!

Next up will be my custom Attitude Indicator (created from scratch rather than modifying the default Saitek one), a gauge that I hope will be the perfect complement to my HSI. I'll see you all then!


2015-09-20

Basics Part 2: Portraying Numeric Output

Back again, as promised, and we're going to be following on from Yesterday's in-depth dissection of one of the simpler default gauges. You should, if you'd followed this, now have the following XML file called "Attitude2.xml":

2015-09-18

Basics - Part 1: Hacking the standard Saitek Attitude Indicator to use the full screen

I'm conscious that I've promised you all a how to this week, but having finished my HSI at the weekend I've enjoyed flying with it, and in the process have found a couple of quirks that I want to fix in it... After all, the hobby is supposed to be flying, not designing gauges!

I'm also aware that if I launch into "how to make my HSI" then the post is going to be unwieldy and long, even more so than this post is, and a quick scroll down will reveal that I'm going pretty in-depth and as much for a beginner as possible.

So that we can ease into the process without me being able to sell a hardcover edition of the post, I've decided that a better beginning example would be to modify the existing Saitek Attitude Indicator so that it gives me speed and altitude readouts - something I'm sorely lacking on my current 2-FIP setup.

The end result is by no means going to be spectacular (I'll be making my own "FPD" to compliment the HSI soon anyway), but it will give me the missing information to allow me to fly without such reliance on the sim's view being that of the cockpit instruments, and hopefully it should be good for you as the reader too because most of the hard work is done and we can take our time picking through what's already there in order to get a real grasp of how these gauges are constructed.