Potřeboval bych pomoc s threadingem v tomto programu – Python – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Potřeboval bych pomoc s threadingem v tomto programu – Python – Fórum – Programujte.comPotřeboval bych pomoc s threadingem v tomto programu – Python – Fórum – Programujte.com

 

Webstrider
~ Anonymní uživatel
1 příspěvek
8. 8. 2014   #1
-
0
-

Napsal jsem program který vytváří grafické rozhraní zobrazující data z gps (pomocí gpsd) kompasu a časem přidám další moduly jako hc-sr04 atd.. Můj problém je, že program běží na 0,2 fps a snažím se ho zrychlit... S tímto nemám téměř žádné zkušenosti a někdo mi poradil použít threading. Snažil jsem se přijít na to sám ale moje celkové zkušenosti s programováním nejsou tak velké. Proto se obracím na různá fora s žádostmi o pomoc. Jako počítač používam raspberry pi model B. Nějaké další info k "projektu" je na této stránce: http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=76933 

#import psyco
import RPi.GPIO as GPIO
import pygame
import sys
from datetime import datetime
import threading
from gps import *
import gps
import smbus
import time
import math
import os
import pytz
from pygame.locals import *

global the_lat_string
global the_lon_string
global the_speed_string
global the_alt_string
global the_gpstme_string

the_latitude_string = "lat: --"
the_lon_string = "lon: --"
the_speed_string = "speed: --"
the_alt_string = "alt: --"
the_gpstme_string = "gpstime: --"

#boost:
"""psyco.full()
flags = FULLSCREEN | DOUBLEBUF
screen = pygame.display.set_mode(resolution, flags, bpp)
pygame.event.set_allowed([QUIT])
screen.set_alpha(None)"""


#time set:
os.system('date ' + '--set="1 JAN 2000 1:00:00"')

#change timezone:
localzone = 'Europe/Berlin'

#gps uart port:
os.system('sudo gpsd /dev/ttyAMA0 -F /var/run/gpsd.sock')

#gps setup:
session = gps.gps("localhost", "2947")
session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)

#magnetometer setup:
bus = smbus.SMBus(1)
address = 0x1e

def timeset():

	report = session.next()
	if ['class'] == 'TPV':
		if hasattr (report, 'time'):	
			tz = timezone('UTC')
			dtz = tz.normalize(tz.localize(datetime(int(report.time[0:4]), int(report.time[5:7]), int(report.time[8:10]), int(report.time[11:13]), int(report.time[14:16]), int(report.time[17:19]))))
			dgmt = dtz.astimezone(timezone(localzone))
			gpstime = dgmt.strftime('%m%d%H%M%Y.%S')
			os.system('date ' + gpstime)
		
class hmc5883l:
	__scales = {
		0.88: [0, 0.73],
		1.30: [1, 0.92],
		1.90: [2, 1.22],
		2.50: [3, 1.52],
		4.00: [4, 2.27],
		4.70: [5, 2.56],
		5.60: [6, 3.03],
		8.10: [7, 4.35],
	}

	def __init__(self, port=1, adress=0x1e, gauss=1.3, declination=(0,0)):
		self.bus = smbus.SMBus(port)
		self.address = address

		(degrees, minutes) = declination
		self.__declDegrees = degrees
		self.__declMinutes = minutes
		self.__declination = (degrees + minutes / 60) * math.pi / 180

		(reg, self.__scale) = self.__scales[gauss]
		self.bus.write_byte_data(self.address, 0x00, 0x70)
		self.bus.write_byte_data(self.address, 0x01, reg << 5)
		self.bus.write_byte_data(self.address, 0x02, 0x00)

	def declination(self):
		return (self.__declDegrees, self.__declMinutes)

	def twos_complement(self, val, len):
		if (val & (1 << len - 1)):
			val = val - (1<<len)
		return val

	def __convert(self, data, offset):
		val = self.twos_complement(data[offset] << 8 | data[offset+1], 16)
		if val == -4096: return None
		return round(val * self.__scale, 4)
	
	def axes(self):
		data = self.bus.read_i2c_block_data(self.address, 0x00)
		x = self.__convert(data, 3)
		y = self.__convert(data, 7)
		z = self.__convert(data, 5)
		return (x,y,z)
	
	def heading(self):
		(x,y,z) = self.axes()
		headingRad = math.atan2(y, x)
		headingRad += self.__declination

		if headingRad < 0:
			headingRad += 2 * math.pi
		elif headingRad > 2 * math.pi:
			headingRad -= 2 * math.pi

		headingDeg = headingRad * 180 / math.pi
		return headingDeg

	def degrees(self, headingDeg):
		global degrees
		degrees = math.floor(headingDeg)
		minutes = round((headingDeg - degrees) * 60)
		return (degrees, minutes)
	
	def _str_(self):
		(x, y, z) = self.axes()
		return "Heading: " + self.degrees(self.heading()) + "\n"


def draw_borders(screen):
	pygame.draw.rect(screen, (0, 191, 255), (0, 0, 1277, 720), 3)

def draw_lat(screen):

	global the_latitude_string

	report = session.next()	

	if report['class'] == 'TPV':
		if hasattr(report, 'lat'):
			the_latitude = round(report.lat, 6)
			the_latitude_string =  'lat : {} N'.format(the_latitude)
	else:
                pass	
        	"""the_latitude_string = 'lat : --'"""
	
	font = pygame.font.Font(None, 30)
	text = font.render(the_latitude_string, 1, (0, 191, 255))
	textpos = text.get_rect(x = 10 , centery = 20)
	screen.blit(text, textpos)

def draw_lon(screen):

	global report
	global the_lon_string

	report = session.next()
	
	if report['class'] == 'TPV':
		if hasattr(report, 'lon'):
			the_lon = round(report.lon, 6)
			the_lon_string = 'lon: {} E'.format(the_lon)
	"""else:
		the_lon_string = 'lon: --'"""

	font = pygame.font.Font(None, 30)
	text = font.render(the_lon_string, 1, (0, 191, 255))
	textpos = text.get_rect(x = 10, centery = 40)
	screen.blit(text, textpos)
	
def draw_heading(screen):
	
	global the_heading_string
	global smer
	
	the_heading = compass.degrees(compass.heading())

	if the_heading == compass.degrees(compass.heading()):
		the_heading_string = 'heading: {}'.format(the_heading)
	else:
		the_heading_string = 'heading: --'

	font = pygame.font.Font(None, 30)
	text = font.render(the_heading_string, 1, (0, 191, 255))
	textpos = text.get_rect(x = 10, centery = 60)
	screen.blit(text, textpos)

def draw_speed(screen):

	global the_speed_string

	report = session.next()	

	if report['class'] == 'TPV':
		if hasattr(report, 'speed'):
			the_speed = report.speed * gps.MPS_TO_KPH
			the_speed_string =  'speed: {} KM/H'.format(the_speed)
	"""else:
		the_speed_string = 'speed: --'"""
	
	font = pygame.font.Font(None, 30)
	text = font.render(the_speed_string, 1, (0, 191, 255))
	textpos = text.get_rect(x = 10 , centery = 80)
	screen.blit(text, textpos)

def draw_alt(screen):

	global the_alt_string

	report = session.next()	

	if report['class'] == 'TPV':
		if hasattr(report, 'alt'):
			the_alt = report.alt # * 0.3048
			the_alt_string =  'alt : {} m'.format(the_alt)
	"""else:
		the_alt_string = 'alt : --'"""
	
	font = pygame.font.Font(None, 30)
	text = font.render(the_alt_string, 1, (0, 191, 255))
	textpos = text.get_rect(x = 10 , centery = 100)
	screen.blit(text, textpos)

def draw_gpstme(screen):

	global the_gpstme_string

	report = session.next()	

	if report['class'] == 'TPV':
		if hasattr(report, 'time'):
			#the_gpstme = int(report.time[11:18]) + " " + int(report.time[8:9]) + "." + int(report.time[5:6]) + "." + int(report.time[0:3])
			the_gpstme = report.time[11:19] + " " + report.time[8:10] + "." + report.time[5:7] + "." + report.time[0:4]
			the_gpstme_string =  'gps time : {}'.format(the_gpstme)
	"""else:
		the_latitude_string = 'lat : --'"""
	
	font = pygame.font.Font(None, 30)
	text = font.render(the_gpstme_string, 1, (0, 191, 255))
	textpos = text.get_rect(x = 10 , centery = 120)
	screen.blit(text, textpos)




def draw_time(screen):
	

	the_time = datetime.now().strftime('%H:%M')
	the_time_string = '{}'.format(the_time)
	font = pygame.font.Font(None, 80)
	text = font.render(the_time_string, 1, (0, 191, 255))
	textpos = text.get_rect(centerx = 1180, centery = 40) 
	screen.blit(text, textpos)
 


def draw_date(screen):

	"""global gpsd
	global gpsdate

	try:
		gpsd = gps(mode=WATCH_ENABLE)
		gpsd.next()
		if gpsd.utc != None and gpsd.utc != '':
			tz = timezone('UTC')
			dtz = tz.normalize(tz.localize(datetime(int(gpsd.utc[0:4]), int(gpsd.utc[5:7]), int(gpsd.utc[8:10]), int(gpsd.utc[11:13]), int(gpsd.utc[14:16]), int(gpsd.utc[17:19]))))
			dgmt = dtz.astimezone(timezone(localzone))
			gpsdate = dgmt.strftime('%m%d%H%M%Y.%S')
			os.system('date ' + gpstime)
		
		else:
			pass
	except:
		pass"""


	the_time = datetime.now().strftime('%d.%m.%Y')
	the_time_string = '{}'.format(the_time)
	font = pygame.font.Font(None, 40)
	text = font.render(the_time_string, 1, (0, 191, 255))
	textpos = text.get_rect(centerx = 1180, centery = 80) 
	screen.blit(text, textpos)


def draw_input(screen):

        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(13, GPIO.IN)
        GPIO.setup(15, GPIO.IN)
	GPIO.setup(18, GPIO.IN)
	GPIO.setup(22, GPIO.IN)
	GPIO.setup(12, GPIO.IN)

	input8 = GPIO.input(13)
	input2 = GPIO.input(15)
	input1 = GPIO.input(18)
	input4 = GPIO.input(22)
       
	while input1 == False and input8 == True and input2 == True and input4 == True:
#		print "1"
		input = "1"
                while input1 == False:
        		input1 = GPIO.input(18)

        while input1 == True and input2 == False and input8 == True and input4 == True:
#               print "2"
		input = "2"
                while input2 == False:
                        input2 = GPIO.input(15)

	while input1 == False and input8 == True and input2 == False and input4 == True:
#		print "3"
		input = "3"
                while input1 == False and input2 == False:
        		input1 = GPIO.input(18)
                        input2 = GPIO.input(15)

	while input1 == True and input8 == True and input2 == True and input4 == False:
#		print "4"
		input = "4"
                while input4 == False:
        		input4 = GPIO.input(22)

	while input1 == False and input8 == True and input2 == True and input4 == False:
#		print "5"
		input = "5"
       	        while input1 == False and input4 == False:
       			input1 = GPIO.input(18)
               	        input4 = GPIO.input(22)

	while input1 == True and input8 == True and input2 == False and input4 == False:
#		print "6"
		input = "6"
       	        while input2 == False and input4 == False:
       			input2 = GPIO.input(15)
       	                input4 = GPIO.input(22)

	while input1 == False and input8 == True and input2 == False and input4 == False:
#		print "7"
		input = "7"
		while input1 == False and input2 ==False and input4 == False:
        		input1 = GPIO.input(18)
                        input2 = GPIO.input(15)
                        input4 = GPIO.input(22)

	while input1 == True and input8 == False and input2 == True and input4 == True:
#		print "8"
		input = "8"
                while input8 == False:
        		input8 = GPIO.input(13)

	while input1 == False and input8 == False and input2 == True and input4 == True:
#		print "9"
		input = "9"
                while input1 == False and input8 == False:
        		input1 = GPIO.input(18)
                        input8 = GPIO.input(13)

	while input1 == True and input8 == False and input2 == False and input4 == True:
#		print "A"
		input = "A"
                while input8 == False and input2 == False:
                        input8 = GPIO.input(13)
        		input2 = GPIO.input(15)

	while input1 == False and input8 == False and input2 == False and input4 == True:
#		print "B"
		input = "B"
                while input1 == False and input8 == False and input2 == False:
        		input1 = GPIO.input(18)
                        input8 = GPIO.input(13)
                        input2 = GPIO.input(15)

	while input1 == True and input8 == False and input2 == True and input4 == False:
#		print "C"
		input = "C"
                while input8 == False and input4 == False:
        		input8 = GPIO.input(13)
                        input4 = GPIO.input(22)

	while input1 == False and input8 == False and input2 == True and input4 == False:
#		print "D"
		input = "D"
		while input1 == False and input4 == False and input8 == False:
        		input8 = GPIO.input(13)
                        input1 = GPIO.input(18)
                        input4 = GPIO.input(22)
        
	while input1 == True and input8 == False and input2 == False and input4 == False:
#		print "E"
		input = "E"
       	        while input8 == False and input2 == False and input4 == False:
       			input8 = GPIO.input(13)
       	                input2 = GPIO.input(15)
       	                input4 = GPIO.input(22)

	while input1 == False and input8 == False and input2 == False and input4 == False:
#		print "F"
		input = "F"
                while input1 == False and input2 == False and input8 == False and input4 == False:
        		input1 = GPIO.input(18)
        		input2 = GPIO.input(15)
        		input8 = GPIO.input(13)
        		input4 = GPIO.input(22)

	while input1 == True and input8 == True and input2 == True and input4 == True:
#		print "0"
		input = "0"
        	while input1 == True and input8 == True and input2 == True and input4 == True:
        		input1 = GPIO.input(18)
        		input2 = GPIO.input(15)
        		input8 = GPIO.input(13)
        		input4 = GPIO.input(22)


        vstupni_hodnota = GPIO.input(12)
        if vstupni_hodnota == False:
#		print "tlac bylo stisk..."
                while vstupni_hodnota == False:
                        vstupni_hodnota = GPIO.input(12)


	the_input_string = '{}'.format(input)
	font = pygame.font.Font(None, 40)
	text = font.render(the_input_string, 1, (0, 191, 255))
	textpos = text.get_rect(centerx = 300, centery = 300) 
	screen.blit(text, textpos)

 

"""def draw_sync(screen):

	report = session.next()

	if ['class'] == 'TPV':
		if hasattr(report, 'time'):
			sync = "synced"
		else:
			sync = "NO_synced"
	else:
		sync = "NO_synced"

	the_sync = sync
	the_sync_string = '{}'.format(the_sync)
	font = pygame.font.Font(None, 20)
	text = font.render(the_sync_string, 1, (255, 255, 255))
	textpos = text.get_rect(x = 1090, centery = 80)
	screen.blit(text, textpos)"""

if __name__ == '__main__':
	
	compass = hmc5883l(gauss = 4.7, declination = (3,2))

	pygame.init()
	
	pygame.mouse.set_visible(0)

	#size = width, height = 650, 400
	screen_width=1280
	screen_height=720
	black = 0, 0, 0

	screen = pygame.display.set_mode([screen_width,screen_height])
	#screen = pygame.display.set_mode()
	#screen = pygame.FULLSCREEN

	while True:
		for event in pygame.event.get():
			if event.type == pygame.QUIT: sys.exit()
			if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: sys.exit()
		
		screen.fill(black)
		draw_borders(screen)
#		draw_lat(screen)
#		draw_lon(screen)
#		draw_heading(screen)
#		draw_time(screen)
#		draw_date(screen)
#		draw_speed(screen)
#		draw_alt(screen)
#               draw_gpstme(screen)
#		hmc5883l()
#               timeset()
		draw_input(screen)
		#draw_sync(screen)
		pygame.display.flip()
Nahlásit jako SPAM
IP: 88.103.74.–
hanpari0
Stálý člen
11. 8. 2014   #2
-
0
-

#1 Webstrider

Ahoj,

sotva můžeš očekávat významnější zrychlení od multiprocessingu. Opravte mne, pokud se mýlím, ale jestli máš 0,2 fps, pak rovnoměrným rozdělením (v ideálním případě) mezi dvě jádra, získáš maximálně 0,4 fps, což zdaleka není to, co bys potřeboval :)

Takže by ses měl zaměřit na hledání úzkých hrdel svého programu. Ty pak můžeš řešit pomocí vhodnějšího algoritmu, nebo knihovnou v céčku anebo na internetových fórech.  Docela jistě ale nemůžeš čekat, že se někdo bude prodírat tvým kódem ve volném čase :)

Takže sem hoď třeba jen tu pasáž, kterou bys chtěl zrychlit. V tom ti někdo snad pomůže.

Nahlásit jako SPAM
IP: 178.72.234.–
sleepy
~ Anonymní uživatel
422 příspěvků
13. 8. 2014   #3
-
0
-

Po kratuckom prebehnuti si dokumentacie, som si vsimol zopar veci. Ak pouzijes polling a ches viac threadov tak jednotlive thready uspavas na nejaku fixnu dobu napr. 10ms. Aby mohol procesor pracovat na inich veciach. Dalsia moznost je pouzit wait_for_edge() funkciu ktora blokuje applikaciu po dobu pokial nenarazi na hranu. Nemam predstavu, co to je a ako to funguje, zrejme ide o nejaky obvod. Mne osobne sa najviac pacil ten add_event_detect. Skus mozno nieco taketo:

from threading import RLock
try:
	import RPi.GPIO as GPIO
catch RuntimeError:
	print "Error importing RPi.GPIO!  This is probably because you need superuser privileges.  You can achieve this by using 'sudo' to run your script"

GPIO.setmode(GPIO.BOARD)
chanels = [13,15,18,22,12]
for chanel in chanels:
	GPIO.setup(chanel, GPIO.IN)
# ... kod ...
font = pygame.font.Font(None, 40)

class InputRendering(object):

	def __init__(self, input_map):
		self._input_map = input_map
		self._neg_input_number = 15
		self._lock = RLock()
		self.registrate_channels()

	def registrate_channels(self):
		for channel in self._input_map.keys():
			GPIO.add_event_detect(channel, GPIO.BOTH, 
					      callback=self.on_change)

	def release_channels(self):
		for channel in self._input_map.keys():
			GPIO.remove_event_detect(channel)
			GPIO.cleanup(channel)

	def on_change(self, channel):
		with self._lock: # Zamkne sa moznost pristupit k cislu _neg_input_number
			neg_channel_num = ~self._inpu_map[channel] 
			self._neg_input_number &= neg_chanel_num # ponecha vsetko okrem daneho kanalu, ten sa nastavy na 0
			if GPIO.input(channel) == GPIO.HIGH: # ak je dany kanal 1 po precitani nastavy 1 inak ponecha 0
				self._neg_input_number |= self._input_map[chanel]

	def draw(self, screen):
		hex_value = None
		with self._lock
			hex_value = hex(self._neg_input_number ^ 15) # Invertovanie hodnot ak False == GPIO.LOW a True == GPIO.HIGH
		hex_value_str[2].upper()  # Vytiahnes cislo v hex bex 0x: 0xa -> A, 0x3 ->3
		d_text = font.render(hex_value, 1, (0, 191, 255))
		d_text_pos = text.get_rect(centerx = 300, centery = 300)
		screen.blit(d_text, d_text_pos)

input_rend = InputRendering(input_map={18:1, 15:2, 22:4, 13:8})


# tam kde kreslis by som dal nieco taketo

	while True:
		# kod
		screen.fill(black)
		draw_borders()
		# kod
		input_rend.draw(screen)
		pygame.display.filp()

Cerpal som od tialto: http://sourceforge.net/p/raspberry-gpio-python/wiki/Examples/ a tu je nieco k threadingu: https://docs.python.org/2/library/threading.html

Nahlásit jako SPAM
IP: 158.195.206.–
sleepy
~ Anonymní uživatel
422 příspěvků
13. 8. 2014   #4
-
0
-

A ten catch tam ma byt except

Nahlásit jako SPAM
IP: 158.195.206.–
sleepy
~ Anonymní uživatel
422 příspěvků
13. 8. 2014   #5
-
0
-

A este netusil som na co je channel 12, tak som ho vynechal z kodu.

Nahlásit jako SPAM
IP: 158.195.206.–
KIIV
~ Moderátor
+43
God of flame
13. 8. 2014   #6
-
+1
-
Zajímavé

My eyes! My eyes are bleeding...

1. vykresluju jen, kdyz se neco zmenilo!

2. dokonce i python umi neco jako  test = input1*1 + input2*2 + input3*4 + input4*8

3. while misto ifu? Ci to ma nejaky jiny zahadny smysl ktery mi unika? Napriklad tady:

	while input1 == False and input8 == True and input2 == True and input4 == True:
#		print "1"
		input = "1"
                while input1 == False:
        		input1 = GPIO.input(18)

4. resp ne misto ifu ale dokonce misto nejakyho switche nebo jak se tomu v pythonu nadava

5. stejne je to spis na stavovy automat nez na takovouhle saskarnu

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 8 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý