Exemple #1
0
def manejar_archivo(archivo, request):
    if archivo == '/':
        archivo = '/index.html'
        index_generado = bytearray(Index.generar(args['documentroot']),
                                   'utf-8')
        pathsize = len(index_generado)
        encabezado("OK", "html", pathsize, request)
    else:
        f, filtro, escala = search(archivo)
        archivo = args['documentroot'] + f
        try:
            if "favicon.ico" in archivo:
                archivo = "./web/favicon.ico"
            file = open(archivo, "rb")
            cod = "OK"
        except FileNotFoundError:
            archivo = "./web/404error.html"
            file = open(archivo, "rb")
            cod = "NOT"
        except IsADirectoryError:
            archivo = "./web/500error.html"
            file = open(archivo, "rb")
            cod = "ERROR"
        pathsize = pathlib.Path(archivo).stat().st_size
        encabezado(cod, archivo.split(".")[-1], pathsize, request)
    if archivo.split(".")[-1] == "ppm":
        if args['size'] % 3 != 0:
            args['size'] = int(math.floor(args['size'] / 3) * 3)
        c, lista = PPM.magic(file, args['size'], filtro, escala)
        request.sendall(bytes.fromhex(c))
        hilos = futures.ThreadPoolExecutor()
        for i in hilos.map(PPM.cambiar_colores, lista):
            request.sendall(i)
    else:
        if archivo == '/index.html':
            request.sendall(index_generado)
        else:
            texto = file.read()
            request.sendall(texto)
Exemple #2
0
from matrixImage import *
from math import *

dim = (600, 800)
I = matrixImage(dim)
#mapear i gerando (i=0,1,2,...dim[0]) e para cada i calcular f(i)=y,onde x=j e y = i.
#antes deslocar todos os x,y em k_x e k_y unidades afim de centralizar o gráfico.
k_j, k_i = 300, 400
f = lambda x: sin(x)


def drawGraph(f, intervalo_x):
    """
    f is function
    intervalo_x lista (k1,k2) intervalos das coordenadas x.
    """


file_name = "test.ppm"
I2PPM = PPM(file_name, dim[0], dim[1])
for i in range(0, 600):
    I.Matrix[i][800 / 2].g = 255
for j in range(0, 800):
    I.Matrix[600 / 2][j].r = 255

#teste requer correçoes
for j in range(0, 800):
    I.Matrix[int(-j / 2)][j].b = 255
I.Matrix[1][2].b = 23
I2PPM.write(I.Matrix)
Exemple #3
0
if __name__ == "__main__":

    import pandas as pd
    import time
    import PPM
    import pigpio

    df = pd.read_excel('dataset/dummy.xlsx')

    print(df)

    pi = pigpio.pi()

    pi.wave_tx_stop()  # start with a clean start

    ppm = PPM.X(pi, 6, frame_ms=20)

    updates = 0

    for pw in range(450, 600, 20):
        for chan in range(8):
            ppm.update_channel(chan, pw)
            updates += 1
        time.sleep(2)

    for i in range(len(df)):
        pwm_lst = df.iloc[i, 1:7].tolist()
        final_lst = list(map(int, pwm_lst))
        print(final_lst)
        ppm.update_channels(final_lst)
        updates += 1
Exemple #4
0
    def Read(self, data):
        #Filestructure:
        #	- Header
        #	- Table of Contents
        #	- Padding, normally of length 2
        #	- Extra Data
        #	- Padding
        #The padding seems to do zipaligning to a length of 4
        global HasPPM

        #Header:
        if data[:4] != "UGAR": return False  #The file isn't a UGO file
        Sections = AscDec(data[4:8], True)  #could also be version
        if Sections >= 1:
            self.TableLength = AscDec(data[8:12], True)
        if Sections >= 2:
            self.ExtraLength = AscDec(data[12:16], True)
        if Sections > 2:
            print("Warning: This UGO file has more than the 2 known sections:",
                  Sections)
            print("Please send this UGO file to pbsds over at pbsds.net")
            print("This file could possibly be read incorrectly...")
        headerlength = 8 + Sections * 4

        #Read table of contents:
        #A table where the rows are seperated with newlines, and colons with tabs
        if Sections >= 1:
            TableOfContents = tuple(
                (i.split("\t") for i in data[headerlength:headerlength +
                                             self.TableLength].split(b"\n")))
        else:
            TableOfContents = []

        #Extra data:
        if Sections >= 2:
            ExtraData = data[zipalign(headerlength + self.TableLength
                                      ):zipalign(headerlength +
                                                 self.TableLength) +
                             self.ExtraLength]

        #Parse data:
        self.Items = []

        #todo: implement this:
        self.Files = []  #[i] = (filename, filecontent)
        #see todo.txt

        pos = 0  #Extra Data position
        tmbcount = 1  #used if HasPPM is False
        ntftcount = 1  #used if no label
        names = []
        for i in TableOfContents:
            type = int(i[0])
            if type == 0:  #layout
                #I've always seen just numbers here.
                #The amount of numbers also differ.
                #maybe related to color scheme? or the button scheme/layout

                #all pages containing TMBs have so far been: i = ["0", "2", "1"]
                self.Items.append(("layout", list(map(int, i[1:]))))
                continue
            elif type == 1:  #Text on topscreen
                num = int(i[1])  #always seen as 0, unknown purpose
                labels = [
                    b64decode(i[n]).decode("UTF-16LE") for n in range(2, 7)
                ]  #5 labels probably one label for each line of text

                self.Items.append(("topscreen text", labels, num))
                continue
            elif type == 2:  #catogories(like "reccomended" and "new flipnotes" and "most popular")
                #this one may visually change greatly depending on what layout is set in type==0

                link = i[1]
                label = b64decode(i[2]).decode("UTF-16LE")
                selected = int(i[3]) != 0  #bool

                self.Items.append(("category", link, label, selected))
                continue
            elif type == 3:  #POST button/link to POST form. "Post Flipnote" uses this
                link = i[1]
                label = b64decode(i[2]).decode("UTF-16LE")

                self.Items.append(("post", link, label))
                continue
            elif type == 4:  #Button
                link = i[1]
                trait = int(i[2])
                label = b64decode(i[3]).decode("UTF-16LE")
                other = i[4:]  #varies

                #extra data
                file = None  #== ("filename", "filedata")
                if trait < 100 and ExtraData:
                    if ExtraData == "\x20":  #empty
                        pass  #no files
                    elif ExtraData[pos:pos + 4] == "PARA":  #tmb file
                        file = ExtraData[pos:pos + 0x6A0]
                        pos += 0x6A0

                        if HasPPM:
                            tmb = PPM.TMB().Read(file)
                            name = tmb.CurrentFilename[:-4]
                            del tmb
                        else:
                            name = "embedded tmb #%i" % tmbcount
                            tmbcount += 1

                        if name + ".tmb" in names:
                            j = 2
                            while "%s_%i.tmb" % (name, j) in names:
                                j += 1
                            name = "%s_%i" % (name, j)

                        file = (name + ".tmb", file)
                        names.append(name + ".tmb")
                    else:  #ntft icon
                        name = label.encode("ascii", "ignore")
                        if not name:
                            name = "nameless ntft %i" % ntftcount
                            ntftcount += 1

                        if name + ".ntft" in names:
                            j = 2
                            while "%s_%i.ntft" % (name, j) in names:
                                j += 1
                            name = "%s_%i" % (name, j)

                        file = (name + ".ntft", ExtraData[pos:pos + 2048])
                        names.append(name + ".ntft")
                        pos += 2048

                self.Items.append(("button", trait, label, link, other, file))

                # if   subtype == 3:#flipnote
                # tmb = PPM.TMB().Read(ExtraData[pos:pos+0x6A0]); pos += 0x6A0
                # unknown1 = i[3]#empty
                # stars = int(i[4])#not sure
                # unknown2 = map(int, i[5:8])#unknown = [765, 573, 0]

                # self.Items.append(("flipnote", link, tmb, stars, unknown1, unknown2))
                # continue
                # elif subtype == 100: pass
                # elif subtype == 101: pass
                # elif subtype == 102: pass
                # elif subtype == 104:#list item? like mails and announcements
                # label = b64decode(i[3]).decode("UTF-16LE")
                # unknown = i[4]
                # num = int(i[5])#only seen as 0

                # # self.Items.append(("list item?", link, label, unknown, num))
                # # continue
                # pass
                # elif subtype == 115:#Labeled button link(size of a flipnote thumbnail, commonly "next page")
                # label = b64decode(i[3]).decode("UTF-16LE")
                # unknown = i[4:6]
                # self.Items.append(("thumbnail link", link, label, unknown))
                # continue
                # elif subtype == 117: pass
                continue

            #if not recognized:
            self.Items.append(("unknown", i))
            print("Unknown UGO item discovered:", i)
        self.Loaded = True
        return self
Exemple #5
0
from fractal import*
from PPM import*
from matrixImage import*

dim = (600, 800)
inter = 50
I = matrixImage(dim)
I2PPM = PPM('fractal.ppm',dim[0],dim[1])
f = fractal(I.Matrix, inter, dim[0], dim[1], [lambda i: i*sin(i)  + cos(i), lambda i: i*cos(i) + i, lambda i: cos(i) + 1 + i**5])
I2PPM.write(f)
Exemple #6
0
                             (1 - unit_h2[h2]) * w2[h2][h1] * unit_h1[h1] *
                             (1 - unit_h1[h1]) * unit_i[i])
                    w1[h1][i] -= alpha * delta

    return cost


import matplotlib.pyplot as plt
#%matplotlib inline
plt_x = []
plt_y = []

# for ppm
import subprocess
import PPM
ppm = PPM.PPM()
buf_c = 0
n_ppm = 0

for n in range(n_learn):
    forward(train[n % 4])
    c = backpropagation(teach[n % 4])
    plt_x.append(n)
    plt_y.append(c)

    # for ppm
    buf_c = c - buf_c
    if ppm.buffering2((c, buf_c), n):
        ppm.executor(ppm.new_image(), "output/output_" + str(n_ppm))
        n_ppm += 1
        if n_ppm % 20 == 0:
Exemple #7
0

if __name__ == "__main__":

    import time
    import PPM
    import pigpio

    pi = pigpio.pi()

    if not pi.connected:
        exit(0)

    pi.wave_tx_stop()  # Start with a clean slate.

    ppm = PPM.X(pi, 4, frame_ms=20)

    updates = 0
    start = time.time()
    for chan in range(8):
        for pw in range(1000, 2000, 5):
            ppm.update_channel(chan, pw)
            updates += 1
    end = time.time()
    secs = end - start
    print("{} updates in {:.1f} seconds ({}/s)".format(updates, secs,
                                                       int(updates / secs)))

    ppm.update_channels([1000, 2000, 1000, 2000, 1000, 2000, 1000, 2000])

    time.sleep(2)
Exemple #8
0
	def __init__(self, useQuack=False):
		self.logger = logging.getLogger('xboxrc')
		self.devicesAvailable = False
		self.useQuack = useQuack
		self.shouldExit = False

		if not self.detectXboxDevices():
			return

		self.devicesAvailable = True

		# These constants were borrowed from linux/input.h
		self.axis_names = { 0x00 : 'lx', 0x01 : 'ly', 0x02 : 'lz', 0x03 : 'rx', 0x04 : 'ry', 0x05 : 'rz', 0x06 : 'trottle',
			0x07 : 'rudder', 0x08 : 'wheel', 0x09 : 'gas', 0x0a : 'brake', 0x10 : 'hat0x', 0x11 : 'hat0y', 0x12 : 'hat1x',
			0x13 : 'hat1y', 0x14 : 'hat2x', 0x15 : 'hat2y', 0x16 : 'hat3x', 0x17 : 'hat3y', 0x18 : 'pressure', 0x19 : 'distance',
			0x1a : 'tiltX', 0x1b : 'tiltY', 0x1c : 'toolWidth', 0x20 : 'volume', 0x28 : 'misc'
		}

		self.button_names = { 0x120 : 'trigger', 0x121 : 'thumb', 0x122 : 'thumb2', 0x123 : 'top', 0x124 : 'top2',
			0x125 : 'pinkie', 0x126 : 'base', 0x127 : 'base2', 0x128 : 'base3', 0x129 : 'base4', 0x12a : 'base5',
			0x12b : 'base6', 0x12f : 'dead', 0x130 : 'a', 0x131 : 'b', 0x132 : 'c', 0x133 : 'x', 0x134 : 'y',
			0x135 : 'z', 0x136 : 'tl', 0x137 : 'tr', 0x138 : 'tl2', 0x139 : 'tr2', 0x13a : 'select', 0x13b : 'start',
			0x13c : 'mode', 0x13d : 'thumbl', 0x13e : 'thumbr', 0x220 : 'dpad_up', 0x221 : 'dpad_down', 0x222 : 'dpad_left',
			0x223 : 'dpad_right', 0x2c0 : 'dpad_left', 0x2c1 : 'dpad_right', 0x2c2 : 'dpad_up', 0x2c3 : 'dpad_down'
		}

		self.modes = {
			"manual" : 1000,
			"altitude" : 1300,
			"position" : 1600,
			"auto" : 2000
		}

		self.submodes = {
			"idle" : 1000,
			"launch" : 1200,
			"path" : 1400,
			"land" : 1600,
			"return" : 1800,
			"failsafe" : 2000
		}

		self.axis_states = {}
		self.button_states = {}
		self.axis_map = []
		self.button_map = []
		self.eventStates = {xboxrc_capnp.Xbox.EventField.ly: (xboxrc_capnp.Xbox.EventType.axis,0), xboxrc_capnp.Xbox.EventField.lx: (xboxrc_capnp.Xbox.EventType.axis,0), xboxrc_capnp.Xbox.EventField.ry: (xboxrc_capnp.Xbox.EventType.axis,1000), xboxrc_capnp.Xbox.EventField.rx: (xboxrc_capnp.Xbox.EventType.axis,1000)}
		
		self.mode = self.modes["manual"]
		self.submode = self.submodes["idle"]

		self.channels = [1500,1500,1500,1500,self.mode,self.submode,0,0] # throttle, yaw, pitch, roll, mode, submode, 0, 0

		# open the serial device
		self.openXboxDevice()

		self.ppm = PPM(18)
		self.ppm.start() # starts a separate thread

		# spawn the read thread
		self.thread = threading.Thread(name='xpad', target=self.readXboxDevice)
		self.thread.daemon = True
		self.thread.start()

		#self.printEventStates()
		self.printChannels(0.5)
Exemple #9
0
class XboxRC():
	def __init__(self, useQuack=False):
		self.logger = logging.getLogger('xboxrc')
		self.devicesAvailable = False
		self.useQuack = useQuack
		self.shouldExit = False

		if not self.detectXboxDevices():
			return

		self.devicesAvailable = True

		# These constants were borrowed from linux/input.h
		self.axis_names = { 0x00 : 'lx', 0x01 : 'ly', 0x02 : 'lz', 0x03 : 'rx', 0x04 : 'ry', 0x05 : 'rz', 0x06 : 'trottle',
			0x07 : 'rudder', 0x08 : 'wheel', 0x09 : 'gas', 0x0a : 'brake', 0x10 : 'hat0x', 0x11 : 'hat0y', 0x12 : 'hat1x',
			0x13 : 'hat1y', 0x14 : 'hat2x', 0x15 : 'hat2y', 0x16 : 'hat3x', 0x17 : 'hat3y', 0x18 : 'pressure', 0x19 : 'distance',
			0x1a : 'tiltX', 0x1b : 'tiltY', 0x1c : 'toolWidth', 0x20 : 'volume', 0x28 : 'misc'
		}

		self.button_names = { 0x120 : 'trigger', 0x121 : 'thumb', 0x122 : 'thumb2', 0x123 : 'top', 0x124 : 'top2',
			0x125 : 'pinkie', 0x126 : 'base', 0x127 : 'base2', 0x128 : 'base3', 0x129 : 'base4', 0x12a : 'base5',
			0x12b : 'base6', 0x12f : 'dead', 0x130 : 'a', 0x131 : 'b', 0x132 : 'c', 0x133 : 'x', 0x134 : 'y',
			0x135 : 'z', 0x136 : 'tl', 0x137 : 'tr', 0x138 : 'tl2', 0x139 : 'tr2', 0x13a : 'select', 0x13b : 'start',
			0x13c : 'mode', 0x13d : 'thumbl', 0x13e : 'thumbr', 0x220 : 'dpad_up', 0x221 : 'dpad_down', 0x222 : 'dpad_left',
			0x223 : 'dpad_right', 0x2c0 : 'dpad_left', 0x2c1 : 'dpad_right', 0x2c2 : 'dpad_up', 0x2c3 : 'dpad_down'
		}

		self.modes = {
			"manual" : 1000,
			"altitude" : 1300,
			"position" : 1600,
			"auto" : 2000
		}

		self.submodes = {
			"idle" : 1000,
			"launch" : 1200,
			"path" : 1400,
			"land" : 1600,
			"return" : 1800,
			"failsafe" : 2000
		}

		self.axis_states = {}
		self.button_states = {}
		self.axis_map = []
		self.button_map = []
		self.eventStates = {xboxrc_capnp.Xbox.EventField.ly: (xboxrc_capnp.Xbox.EventType.axis,0), xboxrc_capnp.Xbox.EventField.lx: (xboxrc_capnp.Xbox.EventType.axis,0), xboxrc_capnp.Xbox.EventField.ry: (xboxrc_capnp.Xbox.EventType.axis,1000), xboxrc_capnp.Xbox.EventField.rx: (xboxrc_capnp.Xbox.EventType.axis,1000)}
		
		self.mode = self.modes["manual"]
		self.submode = self.submodes["idle"]

		self.channels = [1500,1500,1500,1500,self.mode,self.submode,0,0] # throttle, yaw, pitch, roll, mode, submode, 0, 0

		# open the serial device
		self.openXboxDevice()

		self.ppm = PPM(18)
		self.ppm.start() # starts a separate thread

		# spawn the read thread
		self.thread = threading.Thread(name='xpad', target=self.readXboxDevice)
		self.thread.daemon = True
		self.thread.start()

		#self.printEventStates()
		self.printChannels(0.5)
		
	def detectXboxDevices(self):
		# Iterate over the joystick devices.
		numDevices = 0
		try:
			for fn in os.listdir('/dev/input'):
				if fn.startswith('js'):
					numDevices = numDevices + 1
		except:
			pass

		self.logger.info("Searching for devices: Found {} devices".format(numDevices))
		return numDevices

	def openXboxDevice(self):
		if not self.devicesAvailable:
			return

		# Open the joystick device.
		fn = '/dev/input/js0'
		self.logger.info("Opening device: {}...".format(fn))
		self.jsdev = open(fn, 'rb')

		# Get the device name.
		buf = array.array('c', ['\0'] * 64)
		ioctl(self.jsdev, 0x80006a13 + (0x10000 * len(buf)), buf) # JSIOCGNAME(len)
		js_name = buf.tostring()
		self.logger.info('Device name: {}'.format(js_name))

		# Get number of axes and buttons.
		buf = array.array('B', [0])
		ioctl(self.jsdev, 0x80016a11, buf) # JSIOCGAXES
		num_axes = buf[0]

		buf = array.array('B', [0])
		ioctl(self.jsdev, 0x80016a12, buf) # JSIOCGBUTTONS
		num_buttons = buf[0]

		# Get the axis map.
		buf = array.array('B', [0] * 0x40)
		ioctl(self.jsdev, 0x80406a32, buf) # JSIOCGAXMAP

		for axis in buf[:num_axes]:
			axis_name = self.axis_names.get(axis, 'unknown(0x%02x)' % axis)
			self.axis_map.append(axis_name)
			self.axis_states[axis_name] = 0.0

		# Get the button map.
		buf = array.array('H', [0] * 200)
		ioctl(self.jsdev, 0x80406a34, buf) # JSIOCGBTNMAP

		for btn in buf[:num_buttons]:
			btn_name = self.button_names.get(btn, 'unknown(0x%03x)' % btn)
			self.button_map.append(btn_name)
			self.button_states[btn_name] = 0

		self.logger.info("{} axes found: {}".format(num_axes, ",".join(self.axis_map)))
		self.logger.info("{} buttons found: {}".format(num_buttons, ",".join(self.button_map)))

	def detectXboxDevices(self):
		# Iterate over the joystick devices.
		numDevices = 0
		try:
			for fn in os.listdir('/dev/input'):
				if fn.startswith('js'):
					numDevices = numDevices + 1
		except:
			pass

		self.logger.info("Searching for devices: Found {} devices".format(numDevices))
		return numDevices

	def readXboxDevice(self):
		if not self.devicesAvailable:
			return

		# Main event loop
		while True:
			if self.shouldExit: 
				break
			eventType = xboxrc_capnp.Xbox.EventType.none
			eventField = xboxrc_capnp.Xbox.EventField.none
			eventValue = 0.0
			evbuf = self.jsdev.read(8)
			if evbuf:
				time, value, type, number = struct.unpack('IhBB', evbuf)

				#if type & 0x80:
				#	 self.logger.info("(initial)"),

				if type & 0x01:
					eventType = xboxrc_capnp.Xbox.EventType.button
					eventValue = value
					button = self.button_map[number]
					if button == 'dpad_up': button = 'dpadUp'
					elif button == 'dpad_down': button = 'dpadDown'
					elif button == 'dpad_left': button = 'dpadLeft'
					elif button == 'dpad_right': button = 'dpadRight'
					eventField = eval("xboxrc_capnp.Xbox.EventField."+button)
					#if button:
					#	self.button_states[button] = value
					#	if value:
					#		self.logger.info("{} pressed".format(button))
					#	else:
					#		self.logger.info("{} released".format(button))

				if type & 0x02:
					eventType = xboxrc_capnp.Xbox.EventType.axis
					eventValue = value
					axis = self.axis_map[number]
					eventField = eval("xboxrc_capnp.Xbox.EventField."+axis)
					#if axis:
					#	fvalue = value / 32767.0
					#	self.axis_states[axis] = fvalue
					#	self.logger.info("{}: {:.3f}".format(axis, fvalue))
				
				# update master dict of current event state values
				self.eventStates[eventField] = (eventType, eventValue)
				# feed the mode and submode fsm's
				self.updateModes(eventField, eventValue)
				
				self.logger.debug("Type: {} Field: {} Value: {}".format(eventType, eventField, eventValue))
				
				# run the channels updater on every value
				self.updateChannels()

				if self.useQuack:
					self.sendEvent(eventType, eventField, eventValue)

	def updateChannels(self):

		def convertInt(val):
			return ((val / 32768.0) * 500) + 1500
		def convertBool(val):
			return (val * 500) + 1500
		# throttle
		self.channels[0] = convertInt(self.eventStates[xboxrc_capnp.Xbox.EventField.ly][1])
		# yaw
		self.channels[1] = convertInt(self.eventStates[xboxrc_capnp.Xbox.EventField.lx][1])
		# pitch
		self.channels[2] = convertInt(self.eventStates[xboxrc_capnp.Xbox.EventField.ry][1])
		# roll
		self.channels[3] = convertInt(self.eventStates[xboxrc_capnp.Xbox.EventField.rx][1])
		# mode
		self.channels[4] = self.mode
		# submode
		self.channels[5] = self.submode

		# update ppm class with the new values
		self.ppm.update_channels(self.channels)

		return True

	def updateModes(self, button, value):
		if value == 0:
			return # only care about press events, not release events
		# modes
		if button == xboxrc_capnp.Xbox.EventField.hat0y and value < 0: # up
			self.mode = self.modes["manual"]
		elif button == xboxrc_capnp.Xbox.EventField.hat0x and value > 0: # right
			self.mode = self.modes["altitude"]
		elif button == xboxrc_capnp.Xbox.EventField.hat0y and value > 0: # down
			self.mode = self.modes["position"]
		elif button == xboxrc_capnp.Xbox.EventField.hat0x and value < 0: # left
			self.mode = self.modes["auto"]
		# submodes
		elif button == xboxrc_capnp.Xbox.EventField.tl:
			self.submode = self.submodes["return"]
		elif button == xboxrc_capnp.Xbox.EventField.tr:
			self.submode = self.submodes["failsafe"]
		elif button == xboxrc_capnp.Xbox.EventField.x:
			self.submode = self.submodes["launch"]
		elif button == xboxrc_capnp.Xbox.EventField.y:
			self.submode = self.submodes["land"]
		elif button == xboxrc_capnp.Xbox.EventField.a:
			self.submode = self.submodes["path"]

	# def printEventStates(self):
	# 	for key,val in self.eventStates.iteritems():
	# 		self.logger.info("Field {} Type {} Value {}".format(key,val[0],val[1]))
	# 	self.printEventStatesTimer = Timer(1,self.printEventStates)
	# 	self.printEventStatesTimer.start()

	def printChannels(self, delay_s):
		if self.updateChannels():
			s = "CH: "
			for i,ch in enumerate(self.channels):
				s += str(i) + ":" + str(ch) + " "
			self.logger.info(s)
		self.printChannelsTimer = Timer(delay_s,self.printChannels,args=(delay_s,))
		self.printChannelsTimer.start()

	def signal_handler(self, signal, frame):
		self.logger.info("Shutting down...")
		self.ppm.stop()
		self.shouldExit = True
		try: self.printChannelsTimer.cancel()
		except: pass
		time.sleep(1)
		# try: self.printEventStatesTimer.cancel()
		# except: pass
		self.logger.info("Done")
		sys.exit(0)

def buzzFailure():
    GPIO.output(BUZZER, GPIO.HIGH)
    time.sleep(2)
    GPIO.output(BUZZER, GPIO.LOW)
    time.sleep(1)


pi = pigpio.pi()
if not pi.connected:
    print("error")
    exit(0)

pi.wave_tx_stop()  # Start with a clean slate.
ppm = PPM.X(pi, 6, frame_ms=27)  # GPIO 6 for PPM


class flightBehavior:
    GPS_COORDINATES = 1
    HOVER = 2
    NAVIGATE_TO_DESTINATION = 3
    GIVE_SAMPLE = 4
    RETURN_TO_HOME = 5


# important function to send signals to Arduino
def signalParameters(throttle, yaw, pitch, roll, ARM, FAILSAFE, ANGLE_MODE,
                     ALTHOLD):
    print("throttle = ", throttle)
    print("yaw = ", yaw)