<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/python

import Tkinter as tk
import tkFont
import time
import math
import sys
import gc

# Globals
run = True
window = tk.Tk()

font6 = tkFont.Font(size=6)
font8 = tkFont.Font(size=8)
font9 = tkFont.Font(size=9)
font12B = tkFont.Font(size=12, weight="bold")

# Top Frame - GPS / Attitude / Pressure data
pressure = 1013
tFrame = tk.Frame(master = window)
bFrame = tk.Frame(master = window)
aiCanvas = tk.Canvas(master=tFrame)
magCompassCanvas = tk.Canvas(master=tFrame)
gpsCompassCanvas = tk.Canvas(master=tFrame)
prsAltCanvas = tk.Canvas(master=tFrame)
gpsAltCanvas = tk.Canvas(master=tFrame)
speedCanvas = tk.Canvas(master=tFrame)
balCanvas = tk.Canvas(master=tFrame)
turnCanvas = tk.Canvas(master=tFrame)
pDecrButton = tk.Button(master=tFrame)
pIncrButton = tk.Button(master=tFrame)


###########################################################################################

# Redraw AI 
def ai(aiCanvas, aob, pitch):
	pitchScaling = 1.3
	aiCanvas.delete("all")
	aiCanvas.configure(bg="#000000")

	# Blank
	aiTop = aiCanvas.create_rectangle(20, 20, 186, 186, fill="#000000")

	# Draw white arc, overlay blue circle, then brown arc
	aiTop = aiCanvas.create_arc(28, 28, 178, 178, start=0, extent=180, style=tk.CHORD, fill="#FFFFFF")
	aiTop = aiCanvas.create_oval(30, 30, 176, 176, fill="#0000FF")
	aiTop = aiCanvas.create_arc(30, 30, 176, 176, start=180 + aob + (pitchScaling * pitch), extent=180 - (pitchScaling * 2 * pitch), style=tk.CHORD, fill="#663300")

	# Pitch up/down lines
	if pitch &gt;= -30:
        	pitchLine = 5
        	vertOrigin = 103 - (pitchLine * 1.2 * pitchScaling) + (pitchScaling * 1.25 * pitch)
        	aiCanvas.create_line(93, vertOrigin, 113, vertOrigin, width=2, fill="#FFFFFF")
	if pitch &gt;= -25:
        	pitchLine = 10
        	vertOrigin = 103 - (pitchLine * 1.2 * pitchScaling) + (pitchScaling * 1.25 * pitch)
        	aiCanvas.create_line(83, vertOrigin, 123, vertOrigin, width=2, fill="#FFFFFF")
		aiCanvas.create_text(73, vertOrigin, fill="#FFFFFF", font=font6, text="10")
		aiCanvas.create_text(133, vertOrigin, fill="#FFFFFF", font=font6, text="10")
	if pitch &gt;= -20:
        	pitchLine = 15
        	vertOrigin = 103 - (pitchLine * 1.2 * pitchScaling) + (pitchScaling * 1.25 * pitch)
        	aiCanvas.create_line(93, vertOrigin, 113, vertOrigin, width=2, fill="#FFFFFF")
	if pitch &gt;= -15:
        	pitchLine = 20
        	vertOrigin = 103 - (pitchLine * 1.2 * pitchScaling) + (pitchScaling * 1.25 * pitch)
        	aiCanvas.create_line(73, vertOrigin, 133, vertOrigin, width=2, fill="#FFFFFF")
		aiCanvas.create_text(63, vertOrigin, fill="#FFFFFF", font=font6, text="20")
		aiCanvas.create_text(143, vertOrigin, fill="#FFFFFF", font=font6, text="20")
	if pitch &lt;= 30:
        	pitchLine = -5
        	vertOrigin = 103 - (pitchLine * 1.2 * pitchScaling) + (pitchScaling * 1.25 * pitch)
        	aiCanvas.create_line(93, vertOrigin, 113, vertOrigin, width=2, fill="#FFFFFF")
	if pitch &lt;= 25:
        	pitchLine = -10
        	vertOrigin = 103 - (pitchLine * 1.2 * pitchScaling) + (pitchScaling * 1.25 * pitch)
        	aiCanvas.create_line(83, vertOrigin, 123, vertOrigin, width=2, fill="#FFFFFF")
		aiCanvas.create_text(73, vertOrigin, fill="#FFFFFF", font=font6, text="10")
		aiCanvas.create_text(133, vertOrigin, fill="#FFFFFF", font=font6, text="10")
	if pitch &lt;= 20:
        	pitchLine = -15
        	vertOrigin = 103 - (pitchLine * 1.2 * pitchScaling) + (pitchScaling * 1.25 * pitch)
        	aiCanvas.create_line(93, vertOrigin, 113, vertOrigin, width=2, fill="#FFFFFF")
	if pitch &lt;= 15:
        	pitchLine = -20
        	vertOrigin = 103 - (pitchLine * 1.2 * pitchScaling) + (pitchScaling * 1.25 * pitch)
        	aiCanvas.create_line(73, vertOrigin, 133, vertOrigin, width=2, fill="#FFFFFF")
		aiCanvas.create_text(63, vertOrigin, fill="#FFFFFF", font=font6, text="20")
		aiCanvas.create_text(143, vertOrigin, fill="#FFFFFF", font=font6, text="20")

	# Aitcraft wings
	aiCanvas.create_line(50, 103, 90, 103, 90, 111, width=3, fill="#FF9900")
	aiCanvas.create_line(101, 103, 105, 103, width=5, fill="#FF9900")
	aiCanvas.create_line(116, 111, 116, 103, 156, 103, width=3, fill="#FF9900")

	# Add roll marks
	radius = 75
	markLen = 10
	startX = 103
	startY = 103 - radius
	aiCanvas.create_polygon(startX, startY, startX + 5, startY - 15, startX - 5, startY - 15, startX, startY, fill="#FFFFFF")
	roll = math.radians(45)
	startX = 103 + (math.sin(roll) * (radius + 5))
	startY = 103 - (math.cos(roll) * (radius + 5))
	aiCanvas.create_line(startX - 2, startY - 2, startX + 2, startY + 2, width=5, fill="#FFFFFF")
	roll = math.radians(-45)
	startX = 103 + (math.sin(roll) * (radius + 5))
	aiCanvas.create_line(startX - 2, startY - 2, startX + 2, startY + 2, width=5, fill="#FFFFFF")
        for roll in -20, -10, 10, 20:
		rollRad = math.radians(roll)
		startX = 103 + (math.sin(rollRad) * (radius + 3))
		startY = 103 - (math.cos(rollRad) * (radius + 3))
		aiCanvas.create_line(startX - 1, startY - 1, startX + 1, startY + 1, width=3, fill="#FFFFFF")
        for roll in -90, -60, -30, 30, 60, 90:
		rollRad = math.radians(roll)
		startX = 103 + (math.sin(rollRad) * radius)
		startY = 103 - (math.cos(rollRad) * radius)
		endX = 103 + (math.sin(rollRad) * (radius + markLen))
		endY = 103 - (math.cos(rollRad) * (radius + markLen))
		aiCanvas.create_line(startX, startY, endX, endY, width=2, fill="#FFFFFF")
	
	# Add yellow triangle
	rollRad = math.radians(aob)
	startX = 103 - (math.sin(rollRad) * radius)
	startY = 103 - (math.cos(rollRad) * radius)
	triAngle = math.radians(aob + 30)
 	x1 = startX + (math.sin(triAngle) * 15)
 	y1 = startY + (math.cos(triAngle) * 15)
	triAngle = math.radians(aob - 30)
 	x2 = startX + (math.sin(triAngle) * 15)
 	y2 = startY + (math.cos(triAngle) * 15)
	
	aiCanvas.create_polygon(startX, startY, x1, y1, x2, y2, startX, startY, fill="#FFFF00")

	aiCanvas.update()
# End def ai()

###########################################################################################

# Draw Compass tape 
def drawCompass(canvas, hdg):
	canvas.delete("all")

	tape = tk.Canvas(master=canvas, width=210, height=15, bg="#000000", borderwidth=0, highlightthickness=0)
	tape.place(x=1, y=1)
	val = tk.Canvas(master=canvas, width=40, height=30, bg="#000000", borderwidth=0, highlightthickness=0)
	val.place(x=86, y=1)

	val.create_text(20, 15, fill="#FFFFFF", font=font12B, text="%03d" % hdg)

	tapeText = ""
	hdgDec = hdg / 10
	for h in range(hdgDec - 9, hdgDec + 10):
		ho = h * 10
		if ho &lt; 0:
			ho = ho + 360
		elif ho &gt; 350:
			ho = ho - 360
		tapeText += "- %03d -" % ho 
	rem = hdg % 10
	tape.configure(bg="#000000")
	tape.create_text(105 - (rem * 3.5), 8, fill="#FFFFFF", font=font8, text=tapeText)

	canvas.update()
	
# End def drawCompass()

###########################################################################################

# Draw Alt tape 
def drawAlt(canvas, ht):
	canvas.delete("all")

	tape = tk.Canvas(master=canvas, width=30, height=210, bg="#000000", borderwidth=0, highlightthickness=0)
	tape.place(x=31, y=1)
	val = tk.Canvas(master=canvas, width=60, height=30, bg="#000000", borderwidth=0, highlightthickness=0)
	val.place(x=1, y=91)

	val.create_text(30, 15, fill="#FFFFFF", font=font12B, text=ht)
	
	low = ((ht - 3000) / 1000) * 1000
	hi = ((ht + 3000) / 1000) * 1000

	for h in range(low, hi, 500):
		tape.create_text(15, 105 - (h - ht) / 20, fill="#FFFFFF", font=font6, text=h)

	canvas.update()


# End of def drawAlt()

###########################################################################################

# Draw Speed tape 
def drawSpeed(canvas, spd):
	canvas.delete("all")

	tape = tk.Canvas(master=canvas, width=30, height=210, bg="#000000", borderwidth=0, highlightthickness=0)
	tape.place(x=1, y=1)
	val = tk.Canvas(master=canvas, width=60, height=30, bg="#000000", borderwidth=0, highlightthickness=0)
	val.place(x=1, y=91)

	val.create_text(30, 15, fill="#FFFFFF", font=font12B, text=spd)
	
	low = ((spd - 100) / 100) * 100
	hi = ((spd + 100) / 100) * 100

	for s in range(low, hi, 20):
		if s &gt;= 0:
			tape.create_text(15, 105 - (s - spd) * 1.25, fill="#FFFFFF", font=font6, text=s)

	canvas.update()


# End of def drawAlt()

###########################################################################################

# Slip ball
def slipBall(canvas, angle):
	canvas.delete("all")

	slot = tk.Canvas(master=canvas, width=146, height=20, bg="#FFFFFF", borderwidth=3, highlightthickness=3, relief=tk.SUNKEN)
	slot.place(x=0, y=1)
        slot.create_line(68, 0, 68, 26, width=3, fill="#000000")
        slot.create_line(88, 0, 88, 26, width=3, fill="#000000")

	if angle &gt; 10: 
		angle = 10
	elif angle &lt; -10:
		angle = -10
        x = 70 + (angle * 6.4)
	ball = slot.create_oval(x, 6, x + 16, 25, fill="#000000")

	canvas.update()

# End of def slipBall()

###########################################################################################

# Turn indicator
def turnCoord(canvas, rate):
	canvas.delete("all")

	canvas.create_line(40, 15, 50, 15, width=10, fill="#FFFFFF")
	canvas.create_line(22, 19, 26, 19, width=4, fill="#FFFFFF")
	canvas.create_line(64, 19, 68, 19, width=4, fill="#FFFFFF")
	canvas.create_text(10, 20, fill="#FFFFFF", font=font9, text="L")
	canvas.create_text(80, 20, fill="#FFFFFF", font=font9, text="R")

	if rate &gt; 7:
		rate = 7
	elif rate &lt; -7:
		rate = -7
	rate *= 7
	x = 55 * math.sin(math.radians(rate))
	y = 55 * math.cos(math.radians(rate))
	canvas.create_line(45, 75, 45 - x, 75 - y, width = 4, fill="#FFFFFF")
	canvas.create_line(45, 75, 45 - (x / 5), 75 - (y / 5), width = 6, fill="#000000")
	canvas.create_text(45, 75, fill="#FFFFFF", font=font9, text="2 MIN TURN")

	canvas.update()

# End of def turnCoord()

###########################################################################################

# Window close button
def closeButton():
	global run
	run = False
	print "Exit requested"
	#global window
	#window.destroy()
	#sys.exit()
	#raise SystemExit

# End closeButton()

###########################################################################################

# Redraw pressure window
def drawPressWin():
	global pressure
	global pressText
	pressText.configure(text=pressure)
	pressText.update()

# End def drawPressWin()

###########################################################################################

# Pressure up / down buttons
def pressUpButton():
	global pressure
	pressure += 1
	drawPressWin()

def pressDownButton():
	global pressure
	pressure -= 1
	drawPressWin()

# End closeButton()

###########################################################################################

print gc.isenabled()

window.title("Andy's EFIS")
window.resizable(False, False)
window.protocol("WM_DELETE_WINDOW", closeButton)
window.geometry("480x800")
window.configure(bg="#DDDDDD")

tFrame.configure(width=470, height=400, relief=tk.GROOVE, borderwidth=5, bg="#DDDDDD")
bFrame.configure(width=470, height=400, relief=tk.GROOVE, borderwidth=5, bg="#DDDDDD")

tFrame.place(x=5, y=0)
bFrame.place(x=5, y=400)

aiCanvas = tk.Canvas(master=tFrame, width=200, height=200, relief=tk.RIDGE, borderwidth=5)
aiCanvas.configure(bg="#000000")
aiCanvas.place(x=103, y=80)

magLabel = tk.Label(master=tFrame, text="MAG", fg="#000000", font=font12B)
magLabel.place(x=60, y=5)
magCompassCanvas.configure(width=210, height=30)
magCompassCanvas.configure(bg="#DDDDDD")
magCompassCanvas.place(x=103, y=8)
drawCompass(magCompassCanvas, 0);

gpsLabel = tk.Label(master=tFrame, text="GPS", fg="#000000", font=font12B)
gpsLabel.place(x=60, y=45)
gpsCompassCanvas.configure(width=210, height=30)
gpsCompassCanvas.configure(bg="#DDDDDD")
gpsCompassCanvas.place(x=103, y=48)
drawCompass(gpsCompassCanvas, 0);

prsLabel = tk.Label(master=tFrame, text="BARO", fg="#000000", font=font12B)
prsLabel.place(x=325, y=55)
prsAltCanvas.configure(width=60, height=210)
prsAltCanvas.configure(bg="#DDDDDD")
prsAltCanvas.place(x=315, y=80)
drawAlt(prsAltCanvas, 12500)

gpsLabel = tk.Label(master=tFrame, text="GPS", fg="#000000", font=font12B)
gpsLabel.place(x=405, y=55)
gpsAltCanvas.configure(width=60, height=210)
gpsAltCanvas.configure(bg="#DDDDDD")
gpsAltCanvas.place(x=385, y=80)
drawAlt(gpsAltCanvas, 12500)

speedCanvas.configure(width=60, height=210)
speedCanvas.configure(bg="#DDDDDD")
speedCanvas.place(x=38, y=80)
drawSpeed(speedCanvas, 100)

balCanvas.configure(width=150, height=30)
balCanvas.configure(bg="#DDDDDD")
balCanvas.place(x=133, y=295)
slipBall(balCanvas, 0)

turnCanvas.configure(width=90, height=90)
turnCanvas.configure(bg="#000000")
turnCanvas.place(x=38, y=295)
turnCoord(turnCanvas, 3)

pressText = tk.Message(master=tFrame, width=40, padx=2, pady=3, font=font9, text=pressure, bg="#FFFFFF")
pressText.place(x=353, y=296)
pDecrButton.configure(width=1, height=1, padx=2, pady=2, font=font8, text="-", command=pressDownButton)
pDecrButton.place(x=335, y=295)
pIncrButton.configure(width=1, height=1, padx=2, pady=2, font=font8, text="+", command=pressUpButton)
pIncrButton.place(x=390, y=295)

thrtCanvas = tk.Canvas(master=bFrame, width=300, height=300, relief=tk.RIDGE, borderwidth=5)
thrtCanvas.place(x=72, y=40)

window.update()

turnCoord(turnCanvas, -8)
slipBall(balCanvas, -12)

# Play with ai
while 1 == 1:
	window.update()
	print gc.get_count()
	#gc.collect()
	#print gc.get_count()

	drawCompass(magCompassCanvas, 211);
	drawCompass(gpsCompassCanvas, 350);
	drawAlt(prsAltCanvas, 0)
	drawAlt(gpsAltCanvas, 0)
	ai(aiCanvas, 0, 0)
	turnCoord(turnCanvas, -8)
	slipBall(balCanvas, -12)
	drawSpeed(speedCanvas, 0)
	time.sleep(1)
	drawCompass(magCompassCanvas, 212);
	drawCompass(gpsCompassCanvas, 351);
	drawAlt(prsAltCanvas, 100)
	drawAlt(gpsAltCanvas, 100)
	ai(aiCanvas, 0, 10)
	turnCoord(turnCanvas, -7)
	slipBall(balCanvas, -11)
	drawSpeed(speedCanvas, 50)
	time.sleep(1)
	drawCompass(magCompassCanvas, 213);
	drawCompass(gpsCompassCanvas, 352);
	drawAlt(prsAltCanvas, 150)
	drawAlt(gpsAltCanvas, 150)
	ai(aiCanvas, 0, 20)
	turnCoord(turnCanvas, -6)
	slipBall(balCanvas, -10)
	drawSpeed(speedCanvas, 100)
	time.sleep(1)
	drawCompass(magCompassCanvas, 214);
	drawCompass(gpsCompassCanvas, 353);
	drawAlt(prsAltCanvas, 200)
	drawAlt(gpsAltCanvas, 200)
	ai(aiCanvas, 0, 30)
	turnCoord(turnCanvas, -5)
	slipBall(balCanvas, -9)
	drawSpeed(speedCanvas, 101)
	time.sleep(1)
	drawCompass(magCompassCanvas, 215);
	drawCompass(gpsCompassCanvas, 354);
	drawAlt(prsAltCanvas, 500)
	drawAlt(gpsAltCanvas, 500)
	ai(aiCanvas, 0, 20)
	turnCoord(turnCanvas, -4)
	slipBall(balCanvas, -8)
	drawSpeed(speedCanvas, 102)
	time.sleep(1)
	drawCompass(magCompassCanvas, 216);
	drawCompass(gpsCompassCanvas, 355);
	drawAlt(prsAltCanvas, 750)
	drawAlt(gpsAltCanvas, 750)
	ai(aiCanvas, 0, 10)
	turnCoord(turnCanvas, -3)
	slipBall(balCanvas, -7)
	drawSpeed(speedCanvas, 103)
	time.sleep(1)
	drawCompass(magCompassCanvas, 217);
	drawCompass(gpsCompassCanvas, 356);
	drawAlt(prsAltCanvas, 1000)
	drawAlt(gpsAltCanvas, 1000)
	ai(aiCanvas, 0, 0)
	turnCoord(turnCanvas, -2)
	slipBall(balCanvas, -6)
	drawSpeed(speedCanvas, 104)
	time.sleep(1)
	drawCompass(magCompassCanvas, 218);
	drawCompass(gpsCompassCanvas, 357);
	drawAlt(prsAltCanvas, 1500)
	drawAlt(gpsAltCanvas, 1500)
	ai(aiCanvas, 0, -10)
	turnCoord(turnCanvas, -1)
	slipBall(balCanvas, -5)
	drawSpeed(speedCanvas, 105)
	time.sleep(1)
	drawCompass(magCompassCanvas, 219);
	drawCompass(gpsCompassCanvas, 358);
	drawAlt(prsAltCanvas, 2000)
	drawAlt(gpsAltCanvas, 2000)
	ai(aiCanvas, 0, -20)
	turnCoord(turnCanvas, 0)
	slipBall(balCanvas, -4)
	drawSpeed(speedCanvas, 106)
	time.sleep(1)
	drawCompass(magCompassCanvas, 220);
	drawCompass(gpsCompassCanvas, 359);
	drawAlt(prsAltCanvas, 5000)
	drawAlt(gpsAltCanvas, 5000)
	ai(aiCanvas, 0, -10)
	turnCoord(turnCanvas, 1)
	slipBall(balCanvas, -3)
	drawSpeed(speedCanvas, 107)
	time.sleep(1)
	drawCompass(magCompassCanvas, 221);
	drawCompass(gpsCompassCanvas, 0);
	drawAlt(prsAltCanvas, 10000)
	drawAlt(gpsAltCanvas, 10000)
	ai(aiCanvas, 0, 0)
	turnCoord(turnCanvas, 2)
	slipBall(balCanvas, -2)
	drawSpeed(speedCanvas, 108)
	time.sleep(1)
	drawCompass(magCompassCanvas, 222);
	drawCompass(gpsCompassCanvas, 1);
	drawAlt(prsAltCanvas, 11000)
	drawAlt(gpsAltCanvas, 11000)
	ai(aiCanvas, 30, -10)
	turnCoord(turnCanvas, 3)
	slipBall(balCanvas, -1)
	drawSpeed(speedCanvas, 109)
	time.sleep(1)
	drawCompass(magCompassCanvas, 223);
	drawCompass(gpsCompassCanvas, 2);
	drawAlt(prsAltCanvas, 5000)
	drawAlt(gpsAltCanvas, 5000)
	ai(aiCanvas, 30, -20)
	turnCoord(turnCanvas, 4)
	slipBall(balCanvas, 0)
	drawSpeed(speedCanvas, 110)
	time.sleep(1)
	drawCompass(magCompassCanvas, 224);
	drawCompass(gpsCompassCanvas, 3);
	drawAlt(prsAltCanvas, 4000)
	drawAlt(gpsAltCanvas, 4000)
	ai(aiCanvas, 30, -30)
	turnCoord(turnCanvas, 5)
	slipBall(balCanvas, 1)
	drawSpeed(speedCanvas, 109)
	time.sleep(1)
	drawCompass(magCompassCanvas, 225);
	drawCompass(gpsCompassCanvas, 4);
	drawAlt(prsAltCanvas, 3000)
	drawAlt(gpsAltCanvas, 3000)
	ai(aiCanvas, 30, -10)
	turnCoord(turnCanvas, 6)
	slipBall(balCanvas, 2)
	drawSpeed(speedCanvas, 108)
	time.sleep(1)
	drawCompass(magCompassCanvas, 226);
	drawCompass(gpsCompassCanvas, 5);
	drawAlt(prsAltCanvas, 2000)
	drawAlt(gpsAltCanvas, 2000)
	ai(aiCanvas, 30, 0)
	turnCoord(turnCanvas, 7)
	slipBall(balCanvas, 3)
	drawSpeed(speedCanvas, 107)
	time.sleep(1)
	drawCompass(magCompassCanvas, 227);
	drawCompass(gpsCompassCanvas, 6);
	drawAlt(prsAltCanvas, 1000)
	drawAlt(gpsAltCanvas, 1000)
	ai(aiCanvas, 30, 10)
	turnCoord(turnCanvas, 8)
	slipBall(balCanvas, 4)
	drawSpeed(speedCanvas, 106)
	time.sleep(1)
	drawCompass(magCompassCanvas, 228);
	drawCompass(gpsCompassCanvas, 7);
	drawAlt(prsAltCanvas, 900)
	drawAlt(gpsAltCanvas, 900)
	ai(aiCanvas, 30, 20)
	turnCoord(turnCanvas, 7)
	slipBall(balCanvas, 5)
	drawSpeed(speedCanvas, 105)
	time.sleep(1)
	drawCompass(magCompassCanvas, 229);
	drawCompass(gpsCompassCanvas, 8);
	drawAlt(prsAltCanvas, 750)
	drawAlt(gpsAltCanvas, 750)
	ai(aiCanvas, 30, 10)
	turnCoord(turnCanvas, 6)
	slipBall(balCanvas, 6)
	drawSpeed(speedCanvas, 104)
	time.sleep(1)
	drawCompass(magCompassCanvas, 230);
	drawCompass(gpsCompassCanvas, 9);
	drawAlt(prsAltCanvas, 600)
	drawAlt(gpsAltCanvas, 600)
	ai(aiCanvas, 30, 0)
	turnCoord(turnCanvas, 5)
	slipBall(balCanvas, 7)
	drawSpeed(speedCanvas, 103)
	time.sleep(1)


window.update()

time.sleep(30)
</pre></body></html>