Canaan Avionics Canvas


Canvas is a muliti-protocol application that provides display of data with an Inter-Connect Definition (ICD) that decodes the payloads. Canvas displays the real-time data in Engineering Units defined by the ICD, and provides scripting interfaces (such as Python) that enable maipulation and recording of the interfaces. Canvas is perfect for things like Acceptance Test Procedures (ATP) and for simulators.

Canvas works with several protocols:

  • ARINC 429, tools such as the U2004 ARINC 429 Server, Matt's Business Card, and even some 3rd Party hardware
  • Honeywell Avionics Standard Comunications Bus (ASCB) {versions A, B and C}

    Note: Canaan Avionics has an ASCB version of the U2004 coming soon

  • Discrete In/Out and Analog Signals
  • Commercial Standard Digital Bus

Canaan Avionics offers a Dll that enables any 3rd-party interfaces to be added.



The Interconnect Definition is Open Source

** open an ICD file from the above downloads in a text editor and follow along **

ARINC 429 is often transmitted from one avionics system to another via a bus. The ICD is how that bus is documented and organized so that transmissions can be interpreted by the receiving systems. The ICD has the interconnect (the point-to-point wiring, i.e. the physical PHY layer), and the bit-level definition of the 1’s and 0’s which are transmit on the wire. An air data computer has pressure transducers which sense the airspeed of the aircraft. Those pressures are converted to into a memory register and are transmitted out of the computer. Ultimately, the transmitter only has about 24 bits to transmit what appears to be a parametric value (such as 112.125 knots). However, how does 112.125 knots get mapped to 24 or less bits? A decoder ring is needed to interpret the binary data, and this is commonly referred to as Engineering Unit display. There are some attempts of open-souring the data definitions, but manufacturers inevitably define parameters according to their needs.

Canvas uses an XML file to encode and decode ARINC 429. To update the ICD, simply open the *.icd file with a text editor and edit the XML. Examples of the schema are as followed:

<!-- This is an example ICD file that is compatible with Canaan Avionics Canvas-->
        <!-- Start with an s2309 tag, this is just a tag to let Canvas know that the file is intended to be compatible.
            This tag is not necessary, but help with other scripts and functions which may use this system. -->
        <s2309 name='Example ICD' > 
            
            <!-- An a429Bus element allows for the icd for this bus to be bound to Canvas-connected hardware. 
                The 'name' gets displayed by Canvas, and the speed is used to configure the data rate 'High' or 'Low'.
                The speed can be configured in the ICD, but also selected manually in Canvas -->
            <a429Bus name='Test Bus' speed='High'>
                
                <!-- Below is an example of a binary word for Selected Altitude.  This is transmitted and received as 'label' 102.
                
                    'label'   - can be written as "0o???" which is octal notation for the octal ARINC 429 label.  All of the attributes
                                can be written in different notation/base, just so long as it is a compatible way with python notation.
                    
                    'rate'    - is how often the word should be transmitted or received on the bus in Hz.
                    
                    'parity'  - 'Odd' or 'Even' configures the A429 word for either type of parity.  'None' is an option as well, where
                                words are transmitted exactly as they are updated. -->
                <a429Word name='Selected Altitude' label='0o102' rate='5' parity='Odd' >
                    
                    <!-- All parameters are documented with the parameter element.  These are all accessible through python.  A parameter
                        needs to be defined in a way where the system knows where the parameter starts/stops and what its encoding is.
                        
                        'name'    - defines the parameter.  If the name is written as XXX_YYY_ZZZZ (capital letters/numbers with spaces represented 
                                    as underscores), then the parameter is "well known" meaning that Canvas exposes the parameter to python and other
                                    means of scripting (see 'SELECTED_ALTITUDE').  If the name has lower case or spaces, then it is not well known.
                                    [required]
                                    
                        'bit'     - is starting point for parameter.  For ARINC 429 this can be 1-thru-32.  [required, default is 1]
                        
                        'length'  - the length of the field in bits, which would include the sign bit if signed parameters. [required]
                        
                        'resolution'  an always positive number, which represents what the least significant bit of this parameters.  The default for this is '1.0', 
                                    but can be set to any positive number, such as '0.125' or '1000.0'.
                        
                        'signed'    'True' means that the bits will translate into both positive and negative numbers, otherwise this attribute is 'False', meaning that 
                                    there is no sign bit for BNR encoding.  
                        
                        'units'   - if it is desired for the Engineering Units of the parameter to also display the units, then this is set to units such as 'Feet' or 'Hz'.
                        
                        'format'  - if the display of the number needs special formatting, then this can be be put in as a C-compatible composite format.  For example, 
                                    "{0:X}" will show the number as hex value when showing engineering units.  This supports rounding of floating point numbers.  
                                    This also supports contextual strings, such as "Hello! You are {0} years old."
                        
                        'encoding'  if this optional tag is in a parameter, then it may be set to "UTF_8" or "UTF_7" if the bits of the parameters are 
                                    intended to be character instead of a number.
                                    
                        'index'   - this is for adding a fixed value before the number is displayed.  Some parameters, such as Localizer Frequency, are indexed in a way
                                    where zero on the bits actually means 108.0 MHz.  This attribute enables for the user to enter a value which indexes the Engineering Unit.
                        
                        'factor'  - just like with index, factor enables a multiplication factor to be applied to the engineering unit before displayed.
                        
                        Note: parameter elements may have field elements as children, if the parameter is broken up to different fields, such as in cases were bits within a 
                            parameter need to be ignored, or in cases where there are sub-parameters which have different resolutions (this is how BCD parameters are encoded). 
                    -->
                    <parameter name='Sdi' bit='9' length='2' >
                        
                        <!-- enumerations are represented below, enabling the user to define what bit combinations mean, such as for SDI's and SSM's.  Any parameter can
                            utilize enum elements, and Canvas will use these enums to display the parameters-->
                        <enum desc='Left' value='0b01' />
                        <enum desc='Right' value='0b10' />
                        <enum desc='Third' value='0b11' />
                    </parameter>
                    
                    <!-- this parameter is an example well-known-name, where the notation is XXX_YYY_ZZZ and is globally unique 
                    <     in the Canvas memory and available in Python-->
                    <parameter name='PSEL_KNOB_IN_MOTION' bit='11' length='1' />
                    <parameter name='PSEL_ALTERT' bit='12' length='1' />
                    <parameter name='SELECTED_ALTITUDE' bit='13' length='17' resolution='1.0' signed='True'  units='Feet' />
                    <parameter name='Ssm' bit='30' length='2' >
                        <enum desc='Fail' value='0b00' />
                        <enum desc='No Computed Value' value='0b01' />
                        <enum desc='Test' value='0b10' />
                        <enum desc='Valid' value='0b11' />
                    </parameter>
                </a429Word>
                
                
                <a429Word name='Set Position Latitude BCD' label='0o041' rate='5' parity='Odd'>
                    
                    <!-- this parameter uses multiple fields to define a Binary Coded Decimal (BCD)-->
                    <parameter name='SET_POSITION_LATITUDE_BCD' units='Degrees' >
                        <field bit='9' length='4' resolution='0.001666667' />
                        <field bit='13' length='4' resolution='0.016666667' />
                        <field bit='17' length='4' resolution='0.166666667' />
                        <field bit='21' length='4' resolution='1.0' />
                        <field bit='25' length='4' resolution='10.0' />
                        <field bit='29' length='1' resolution='100.0' />
                    </parameter>
                    <parameter name='Ssm' bit='30' length='2' >
                        <enum desc='North' value='0b00' />
                        <enum desc='No Computed Value' value='0b01' />
                        <enum desc='Test' value='0b10' />
                        <enum desc='South' value='0b11' />
                    </parameter>
                </a429Word>
                
                <a429Word name='Message Characters 7-9' label='0o301' rate='5' parity='Odd'>
                    
                    <!-- this parameter uses encoding to display parameters as ascii-encoded values-->
                    <parameter name='MESSAGE_CHAR_7' bit='9' length='7' encoding='UTF-7' />
                    <parameter name='MESSAGE_CHAR_8' bit='16' length='7' encoding='UTF-7' />
                    <parameter name='MESSAGE_CHAR_9' bit='23' length='7' encoding='UTF-7' />
                    <parameter name='Ssm' bit='30' length='2' >
                        <enum desc='Fail' value='0b00' />
                        <enum desc='No Computed Value' value='0b01' />
                        <enum desc='Test' value='0b10' />
                        <enum desc='Valid' value='0b11' />
                    </parameter>
                </a429Word>
                
            </a429Bus>
            
        </s2309>
        

Programming ARINC 429 with Python Example

In this example, the U1507 Air Data Computer will transmit air temperature in degrees Celsius into the U2004, then the U2004 will re-transmit that word in degrees Kelvin (using python to create a new label and to change the units).

Included in the following section is a demonstration of a potential use case for Canvas along with a few Canaan Avionics products. The components seen in the below from left to right is the U1507 Air Data Computer that is transmitting ARINC 429 into the U2004. The U2004 is receiving the Air Data on port RX0. The U2004 is connected to Canvas via USB (TCP/IP connection options are available) Finally, to the right the U2004, there is a ARINC 429 Data Reader (Matt's Business Card) that is also connected to the same PC via USB. The u2004 is sending data to the business card via TX0.

Once the hardware is setup, the PC that the U2004 and card are connected to launches and runs Canvas. Next, both the U2004 and business card are added manually as devices. Following that, the business card must have a custom ICD loaded onto it titled "KelvinTemp.icd". From there, the "web_example.py" script is run: (Note that both the custom ICD and the script can be downloaded from this page. The other files used in this example may also be downloaded from the Canaan Avionics website.)

           
        import time
        import sys
        import clr
        import math

        # Assumes the first bit is parity, then 2 ssm, 19 for data, 2 for sdi, and 8 for label
        def ConstructA429Word(SSM: int, Data: int, SDI: int, Label: int):
            word = 0x000000FF & Label
            word += 0x00000300 & (SDI << 8)
            word += 0x1FFFFC00 & (Data << 10)
            word += 0x60000000 & (SSM << 29)

            parity = 0
            wordCop = word
            while wordCop:
                parity ^= wordCop & 1
                wordCop >>= 1

            word += 0x80000000 & (parity << 31)
            return word

        # Takes a double and converts it to a data field to be used in BNR word construction
        def FloatToDataBNR(f: float, minResolution: float, numDataBits: int, isSigned: bool):
            assert f >= 0 or isSigned
            sinBit = 0
            if isSigned:
                numDataBits -= 1
                if f < 0:
                    sinBit = (1 << numDataBits)
                    f += minResolution*(2**(numDataBits))
    
            posBits = round(f*(2**(math.log(1/minResolution, 2))))

            return sinBit + posBits

        ###############################ENTRY############################

        # sys.path.append() - path to the U2004 Dll
        clr.AddReference("U2004_11_Dll_Library")
        from U2004_11_Dll_Library import U2004

        # Create an instance of the U2004
        u2004 = U2004()
        u2004.CanvasConnect("127.0.0.1", 11076)
        u2004.Initialize() 

        # load icd onto rx0 and start ports
        u2004.LoadIcdFromPath(r"[absolute path on the host pc]\Canaan_GAMA.icd", "RX0", "Canaan Air Data Computer")
            
        # Start RX0
        u2004.PortHs(U2004.A429Port.RX0)
        u2004.PortStart(U2004.A429Port.RX0)

        # Start TX0
        u2004.PortLs(U2004.A429Port.TX0)
        u2004.PortStart(U2004.A429Port.TX0)

        # super loop
        while True:
                
            # get a floating point value of the static air temperature from the ARINC 429 coming from the U1507 Air Data Computer
            tempC = u2004.GetWkn("STATIC_AIR_TEMPERATURE")

            # convert the temp in celcius to kelvin
            tempK = tempC + 273.15

            # create a 19-but kelvin data field 
            # note this can be done in Canvas too by loading an *.icd and by calling SetWkn()]
            tempKData = FloatToDataBNR(tempK, .0625, 19, False)

            # construct a new 32-bit ARINC 429 Data Word
            newWord = ConstructA429Word(0, tempKData, 0, 0o001)

            # transmit this word as an unscheduled word on TX0 using TxWord()
            u2004.TxWord(U2004.A429Port.TX0, newWord)
                
            # loop for about a 10Hz operation
            time.sleep(.1)            
        

After declaring some helper functons, we use the clr utility to import the u2004 DLL, allowing us to make c# function calls from Python. Canvas brokers the connection between the script and all the hardware used. An Interconnect Definition (ICD) enables the system to display ARINC 429 in Engineering Units, and for out script to work in Engineering Units. The script programmatically loads an ICD onto the RX0 port of the U2004 which decodes all of the Air Data words rfom the ADC. Without this ICD, Canvas would have no way of knowing what the data coming from the air data computer is meant to represent or how it's formatted, and it will just display the binary data. The ICD is just an XML file format, and custom ICD’s are easily created with a text editor.

A super loop will keep the program alive after it is run. 10 times per second the script will survey all ports on the U004 for a corresponding double that matches the Well Known Name "STATIC_AIR_TEMPERATURE" (This WKN was established by the ICD loaded previously.) Next, the temperature read-in is converted to Kelvin and formatted into a BNR bit-field. This bit field is then further packaged into a 32-bit A429 word to be sent back to Canvas. The specifics of how this word is constructed is explained in the A429 specification and the "KelvinTemp.icd" file.