Премини към съдържанието
  • Добре дошли!

    Добре дошли в нашите форуми, пълни с полезна информация. Имате проблем с компютъра или телефона си? Публикувайте нова тема и ще намерите решение на всичките си проблеми. Общувайте свободно и открийте безброй нови приятели.

    Моля, регистрирайте се за да публикувате тема и да получите пълен достъп до всички функции.

     

Python проблем с threading...вероятно.


Препоръчан отговор


Здравейте, доста се чудих дали да пиша, но след прекарано доста време в търсене и пробване, не успях да намеря решение. Надявам се някой тук да даде поне насока.

С няколко думи - проекта ми е за бот,който лови риба на емулирана игра за телефон. Докато действията на самия бот са в main, няма проблем и фунционира. Когато се опитам да отделя бота в отделен клас ,както и да пренаписвам фунцията в run, тя не получава ъпдейтнатите данни от update метода на новия ми клас.

Извинявам се предварително че кода ми не е толкова подреден и коментиран, но съм се захванал отскоро с това и нямам още навиците на професионалистите. А и като цяло всеки елемент поотделно функционира. Както и другите ми класове подредени по същия начин с ъпдейт методи фунционират.

Това е работещата версия:

import cv2 as cv
import numpy as np
from time import time,sleep
from windowcapture import WindowCapture
from vision import Vision
import pyautogui
from hsvfilter import HsvFilter
from threading import Thread
from detection import Detection



DEBUG = True

wincap = WindowCapture('BlueStacks')


hsv_filter_angeln = HsvFilter(42,255,255,46,255,255,153,0,91,0)
detector_angeln = Detection('hsv_angeln.png', hsv_filter_angeln)


hsv_filter_einholen = HsvFilter(12,182,255,35,255,255,120,0,50,0)
detector_einholen = Detection('hsv_einholen.png',hsv_filter_einholen)


hsv_filter_leiste = HsvFilter(15,229,240,40,255,255,9,0,0,0)
detector_leiste = Detection('hsv_leiste.png',hsv_filter_leiste)

hsv_filter_fordern = HsvFilter(43,0,207,45,255,255,255,0,89,41)
detector_fordern = Detection('hsv_fordern.png', hsv_filter_fordern)


wincap.start()
detector_angeln.start()
detector_einholen.start()
detector_leiste.start()
detector_fordern.start()

global is_bot_in_action
is_bot_in_action = False

def bot_actions(detector,rectangles,rectangles_leiste):
    if len(rectangles)>0:
        targets = detector.vision_object.get_click_points(rectangles)
        target = wincap.get_screen_position(targets[0])
        pyautogui.moveTo(x=target[0], y=target[1])
        pyautogui.mouseDown()
        if len(rectangles_leiste)>0:
            pyautogui.mouseUp()
        #sleep(5)
    global is_bot_in_action
    is_bot_in_action = False




loop_time = time()

while True:

    if wincap.screenshot is None:
        continue
    detector_angeln.update(wincap.screenshot)
    detector_leiste.update(wincap.screenshot)
    detector_einholen.update(wincap.screenshot)
    detector_fordern.update(wincap.screenshot)

    if DEBUG:

        output_image=detector_einholen.vision_object.draw_rectangles(wincap.screenshot,detector_einholen.rectangles)
        cv.imshow('Result',output_image)

    if not is_bot_in_action:
        is_bot_in_action= True
        t= Thread(target=bot_actions, args=(detector_angeln,detector_angeln.rectangles,detector_einholen.rectangles,))
        t.start()

    if not is_bot_in_action:
        is_bot_in_action= True
        t = Thread(target=bot_actions, args=(detector_einholen,detector_einholen.rectangles,detector_leiste.rectangles,))
        t.start()

    if not is_bot_in_action:
        is_bot_in_action= True
        t = Thread(target=bot_actions, args=(detector_fordern,detector_fordern.rectangles,detector_angeln.rectangles,))
        t.start()


    print('FPS {}'.format(1/(time()- loop_time)))
    loop_time = time()


    key = cv.waitKey(1)
    if key == ord('q'):
        wincap.stop()
        detector_angeln.stop()
        detector_einholen.stop()
        detector_leiste.stop()
        detector_fordern.stop()
        cv.destroyAllWindows()
        break



print('done.')

A това неработещата:

import cv2 as cv
import numpy as np
from time import time,sleep
from windowcapture import WindowCapture
from vision import Vision
import pyautogui
from hsvfilter import HsvFilter
from threading import Thread
from detection import Detection
from bot import BotState,FCBot



DEBUG = True

wincap = WindowCapture('BlueStacks')

hsv_filter_angeln = HsvFilter(42,255,255,46,255,255,153,0,91,0)
detector_angeln = Detection('hsv_angeln.png', hsv_filter_angeln)

hsv_filter_einholen = HsvFilter(12,182,255,35,255,255,120,0,50,0)
detector_einholen = Detection('hsv_einholen.png',hsv_filter_einholen)

hsv_filter_leiste = HsvFilter(15,229,240,40,255,255,9,0,0,0)
detector_leiste = Detection('hsv_leiste.png',hsv_filter_leiste)

hsv_filter_fordern = HsvFilter(43,0,207,45,255,255,255,0,89,41)
detector_fordern = Detection('hsv_fordern.png', hsv_filter_fordern)


bot = FCBot((wincap.offset_x,wincap.offset_y),(wincap.w , wincap.h))

bot.start()
wincap.start()
detector_angeln.start()
#detector_einholen.start()
#detector_leiste.start()
#detector_fordern.start()


loop_time = time()

while True:

    if wincap.screenshot is None:
        continue
    detector_angeln.update(wincap.screenshot)


    if bot.state == BotState.ANGELN:
        print('State ANGELN')
        targets = detector_angeln.vision_object.get_click_points(detector_angeln.rectangles)
        bot.update_targets(targets)


    if DEBUG:
        output_image=detector_angeln.vision_object.draw_rectangles(wincap.screenshot,detector_angeln.rectangles)
        cv.imshow('Result',output_image)

    #detector_leiste.update(wincap.screenshot)
    #detector_einholen.update(wincap.screenshot)
    #detector_fordern.update(wincap.screenshot)

    print('FPS {}'.format(1/(time()- loop_time)))
    loop_time = time()


    key = cv.waitKey(1)
    if key == ord('q'):
        wincap.stop()
        detector_angeln.stop()
        #detector_einholen.stop()
        #detector_leiste.stop()
        #detector_fordern.stop()
        bot.stop()
        cv.destroyAllWindows()
        break



print('done.')

Или по-точно до тук явно работи,защото проста проверка с print показва и че се намира във вярното състояние и че update получава това,което трябва да ъпдейтва.

Eто и силно опростена версия на бота ми,който просто трябва да не прави друго  а да напише,че е получил targets от update_targets. Пробвах сигурно няколкостотин варианта как да стигна до там,че да получи ъпдейтнатата информация и най-вероятно пропускам нещо очевадно,но не мога да го добутам дотам,че другия метод да може да ги получи от update.

import cv2 as cv
import pyautogui
from time import time,sleep
from threading import Thread,Lock
from windowcapture import WindowCapture
from detection import Detection



class BotState:
    
    ANGELN = 0
    EINHOLEN =1
    FORDERN = 2

class FCBot:
    
    stopped = True
    lock = None

    state = None
    targets = []
    #target_pos = None
    #timestamp = None
    wincap = None
    window_offset = (0,0)
    window_w = 0
    window_h = 0



    def __init__(self,window_offset,window_size):
        self.lock = Lock()
        self.state = BotState.ANGELN
        #self.timestamp = time()
        self.window_offset = window_offset
        self.window_w = window_size[0]
        self.window_h = window_size[1]


    def start(self):
        self.stopped = False
        t = Thread(target = self.run)
        t.start

    def stop(self):
        self.stopped = True


    def update_targets(self,targets):
        if not targets is None:
            print('updated targets')
            self.lock.acquire()
            self.targets = targets
            self.lock.release()


    def start_collect(self,targets):
        if len(targets)>0:
            print('targets ok')

    '''def get_screen_position(self,pos):
        return(pos[0]+self.window_offset[0], pos[1] + self.window_offset[1])'''

    def run(self):
        while not self.stopped:
            if self.state == BotState.ANGELN:
                self.start_collect(self.targets)

Ето и две клипчета какво прави като работи и като не работи. Във втория случай е само с print във метода за ловене,но това се получава и с основната логика да хване първата цел от списъка цели подаван от update да определи къде е и да кликне там,респективно да кликне и задържи. Но това какво прави няма значение ,след като не получава целта.

 

 

Ще бъда благодарен за насока какво да прочета и с какво да се запозная за да схвана защо не се получава. Не искам някой да ми пренапише кода наготово, все пак идеята е да науча нещо от цялата работа. Иначе, не че конкретната програма ми е целта в живота, ползвам я като база да уча неща. На моите години ще ми е по-лесно с проектобазирано учене,отколкото с дебелите книги от страница 1 нататък. Затова най-вероятно изпускам базови неща,които се учат в първи клас програмиране,но предпочитам да добавям каквото ми е нужно вместо да си напълня главата с неща,които ще забравя ,докато ми потрябват. Може и да е грешка,но това е подхода ,който съм избрал с времето ,което имам в момента. Все пак се занимавам с това от лятото а по сериозно от края на септември, така че моля хората, цял живот програмирали ,за малко разбиране. Това последното го пиша,защото виждам какво става в хардуерния раздел ,някой като поиска съвет и се надявам да си спестя типичното за български форум обяснение "колко съм тъп".

Благодаря за всяка помощ предварително.

Поздрави

Линк към този отговор
Сподели в други сайтове
  • 2 седмици по-късно...

Ок, успях да огранича проблема до това, че очевидно в бота ми

def start(self):
        self.stopped = False
        t = Thread(target = self.run)
        t.start

    

не стартира run().

 def run(self):
        while not self.stopped:
           ........

Koгато в __main__  си напиша bot.run и си работи. Но другите ми класове работят и като им подам в началото само  .start(). Само при този не става. А очевидно го стартира защото нещата от конструктора работят,когато пусна run() на ръка.

 

Някаква идея? Не е нужно да е специално по моята програма, това е по-скоро принципен въпрос за threading И най странното е ,че 3 други класа със същата логика и написани по същия начин работят и взаимодействат без проблем помежду си от отделните тредове.

От последната питанка изчетох де що намерих подобни проблеми във stackoverflow, но нищо, което да ми помага. Както и цялата документация на threading няколко пъти. Но от това,което виждам и разбирам, би трябвало да работи , а не ще.

Линк към този отговор
Сподели в други сайтове

Добавете отговор

Можете да публикувате отговор сега и да се регистрирате по-късно. Ако имате регистрация, влезте в профила си за да публикувате от него.

Гост
Напишете отговор в тази тема...

×   Вмъкнахте текст, който съдържа форматиране.   Премахни форматирането на текста

  Разрешени са само 75 емотикони.

×   Съдържанието от линка беше вградено автоматично.   Премахни съдържанието и покажи само линк

×   Съдържанието, което сте написали преди беше възстановено..   Изтрий всичко

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Добави ново...

Информация

Поставихме бисквитки на устройството ви за най-добро потребителско изживяване. Можете да промените настройките си за бисквитки, или в противен случай приемаме, че сте съгласни с нашите Условия за ползване