How to write an IGC file

aerofiles has the aerofiles.igc.Writer class for writing IGC files. The first thing you need to do is instantiate it by passing an file-like object into its constructor:

with open('sample.igc', 'w') as fp:
    writer = aerofiles.igc.Writer(fp)

Headers

After that you can use the writer object to write the necessary file headers:

writer.write_headers({
    'manufacturer_code': 'XCS',
    'logger_id': 'TBX',
    'date': datetime.date(1987, 2, 24),
    'fix_accuracy': 50,
    'pilot': 'Tobias Bieniek',
    'copilot': 'John Doe',
    'glider_type': 'Duo Discus',
    'glider_id': 'D-KKHH',
    'firmware_version': '2.2',
    'hardware_version': '2',
    'logger_type': 'LXNAVIGATION,LX8000F',
    'gps_receiver': 'uBLOX LEA-4S-2,16,max9000m',
    'pressure_sensor': 'INTERSEMA,MS5534A,max10000m',
    'competition_id': '2H',
    'competition_class': 'Doubleseater',
})

Note that the write_headers() method will take care of writing the headers in the right order and it will alert you if you failed to pass a mandatory header. Those mandatory headers that are allowed to be blank will be written without value if you don’t specify any values.

The result of the call above is the following lines being written to the sample.igc file:

AXCSTBX
HFDTE870224
HFFXA050
HFPLTPILOTINCHARGE:Tobias Bieniek
HFCM2CREW2:John Doe
HFGTYGLIDERTYPE:Duo Discus
HFGIDGLIDERID:D-KKHH
HFDTM100GPSDATUM:WGS-1984
HFRFWFIRMWAREVERSION:2.2
HFRHWHARDWAREVERSION:2
HFFTYFRTYPE:LXNAVIGATION,LX8000F
HFGPSuBLOX LEA-4S-2,16,max9000m
HFPRSPRESSALTSENSOR:INTERSEMA,MS5534A,max10000m
HFCIDCOMPETITIONID:2H
HFCCLCOMPETITIONCLASS:Doubleseater

Next you might want to define what extensions your GPS fix records will use. Make sure that you specify at least the highly recommended FXA extension as specified in the official IGC file specification. You can add the extensions description by using the write_fix_extensions() method:

writer.write_fix_extensions([('FXA', 3), ('SIU', 2), ('ENL', 3)])

This will result in the following line being written:

I033638FXA3940SIU4143ENL

There is also a write_k_record_extensions() method if you are planning to use K records with extensions.

Task

Following the headers should be the task declaration. There are two main methods for writing that: write_task_metadata() and write_task_points(). The first method writes the task declaration metadata like date and time of declaration, the intended date of the flight, the task id and the number of turnpoints in the declared task. The second method is used to write the task points in the specified order:

writer.write_task_metadata(
    datetime.datetime(2014, 4, 13, 12, 53, 02),
    task_number=42,
    turnpoints=3,
)

writer.write_task_points([
    (None, None, 'TAKEOFF'),
    (51.40375, 6.41275, 'START'),
    (50.38210, 8.82105, 'TURN 1'),
    (50.59045, 7.03555, 'TURN 2', 0, 32.5, 0, 180),
    (51.40375, 6.41275, 'FINISH'),
    (None, None, 'LANDING'),
])

These calls will write the following lines to the sample.igc file:

C140413125302000000004203
C0000000N00000000ETAKEOFF
C5124225N00624765ESTART
C5022926N00849263ETURN 1
C5035427N00702133E00000000032500000000180000TURN 2
C5124225N00624765EFINISH
C0000000N00000000ELANDING

GPS Fixes

Writing GPS fixes is accomplished through the write_fix() method:

writer.write_fix(
    datetime.time(12, 34, 56),
    latitude=51.40375,
    longitude=6.41275,
    valid=True,
    pressure_alt=1234,
    gps_alt=1432,
    extensions=[50, 0, 12],
)

All parameters essentially optional and will be filled with sensible defaults. The time parameter will use the current UTC time, while the other parameters will be set to invalid values.

If the write_fix_extensions() method was used before, the extensions parameter becomes mandatory and has to contain a list of values for the declared fix extensions. The above call would result in the following fix record:

B1234565124225N00624765EA012340143205000012

Security Signature

The IGC file specification is using a security signature for authenticity verification. This signature is generated by the flight recorder and should be verifiable be an external tool. If you are able to generate such a signature according to the specification then you can use the write_security() method to append it to the file:

writer.write_security('ABCDEFGHIJKLMNOPQRSTUVWXYZ')

will write

GABCDEFGHIJKLMNOPQRSTUVWXYZ

while using multiple lines for the security signature if it is longer than 75 bytes.