簡體   English   中英

在python中同時運行交互功能

[英]Running interacting functions simultaneously in python

所以我正在嘗試構建一個可以自動駕駛的機器人。 為此,我需要機器人前進並同時檢查距離。 如果距離小於首選距離,則停止向前移動。 到目前為止,我已經在下面編寫了這段代碼,但它似乎並沒有同時運行,也沒有進行交互。 我怎樣才能確保這兩個函數確實相互作用。 如果需要更多信息,我很樂意為您提供。 謝謝!

from multiprocessing import Process
from TestS import distance
import Robot
import time

constant1 = True
min_distance = 15

def forward():
    global constant1:
    robot.forward(150)                       #forward movement, speed 150
    time.sleep(2)

def distance_check():
    global constant1
    while constant1:
        distance()                           #checking distance
        dist = distance()
        return dist
        time.sleep(0.3)

        if dist < min_distance:
            constant1 = False
            print 'Something in the way!'
            break

def autonomy():                              #autonomous movement
    while True:
        p1 = Process(target=forward)         
        p2 = Process(target=distance_check)
        p1.start()                           #start up 2 processes
        p2.start()
        p2.join()                            #wait for p2 to finish

因此,您發布的代碼存在一些嚴重問題。 首先, 您不希望distance_check進程完成 ,因為它正在運行while循環。 您不應該執行p2.join() ,也不應該在while循環中始終啟動新進程。 你在這里混合了太多的做事方式 - 要么兩個孩子永遠奔跑,要么他們每個人跑一次,而不是混合。

但是,主要問題是原始進程無法與原始進程通信,即使是通過global進程 (除非您做更多工作)。 線程更適合這個問題。

你還在distance_check()函數中有一個return值,因此不會執行該語句下面的代碼 (包括sleep ,以及constant1的設置(應該有更好的名字)。

總之,我認為你想要這樣的東西:

from threading import Thread
from TestS import distance
import Robot
import time

can_move_forward = True
min_distance = 15


def move_forward():
    global can_move_forward
    while can_move_forward:
        robot.forward(150)
        time.sleep(2)
        print('Moving forward for two seconds!')


def check_distance():
    global can_move_forward
    while True:
        if distance() < min_distance:
            can_move_forward = False
            print('Something in the way! Checking again in 0.3 seconds!')
        time.sleep(0.3)


def move_forward_and_check_distance():
    p1 = Thread(target = move_forward)
    p2 = Thread(target = check_distance)
    p1.start()
    p2.start()

由於您在標簽中指定了python-3.x,因此我也更正了您的print

顯然我無法檢查這是否會按照您的要求運行,因為我沒有您的機器人,但我希望這至少在某種程度上有所幫助。

與多解決方案的一個問題是, distance_check回報和停止

    dist = distance()
    return dist        # <------ 
    time.sleep(0.3)

    if dist < min_distance:
        ....

您似乎正在嘗試在進程之間交換信息:通常使用隊列或管道來完成。

你的問題的行之間閱讀並提出以下規范:

  • 如果機器人的速度大於零,機器人就會移動
  • 不斷檢查機器人前方的障礙物
  • 如果它接近某物就停止機器人。

我認為你可以在不使用多處理的情況下實現目標。 這是一個使用生成器/協同程序的解決方案。

出於測試目的,我編寫了自己的機器人版本和障礙物傳感器 - 試圖模仿我在代碼中看到的內容

class Robot:
    def __init__(self, name):
        self.name = name
    def forward(self, speed):
        print('\tRobot {} forward speed is {}'.format(self.name, speed))
        if speed == 0:
            print('\tRobot {} stopped'.format(speed))

def distance():
    '''User input to simulate obstacle sensor.'''
    d = int(input('distance? '))
    return d

裝飾師啟動協程/發電機

def consumer(func):
    def wrapper(*args,**kw):
        gen = func(*args, **kw)
        next(gen)
        return gen
    wrapper.__name__ = func.__name__
    wrapper.__dict__ = func.__dict__
    wrapper.__doc__  = func.__doc__
    return wrapper

生產者不斷檢查是否可以安全移動

def can_move(target, min_distance = 15):
    '''Continually check for obstacles'''
    while distance() > min_distance:
        target.send(True)
        print('check distance')
    target.close()

發生器/協程, 消耗安全移動信號並根據需要改變機器人的速度。

@consumer
def forward():
    try:
        while True:
            if (yield):
                robot.forward(150)
    except GeneratorExit as e:
        # stop the robot
        robot.forward(0)

機器人的速度應該改變以最快的速度障礙物傳感器可以產生距離。 機器人將向前移動,直到它接近某個東西,然后停下來,它們都會關閉 通過forward調整邏輯和can_move可以改變行為,以便生成器/協同程序繼續運行,但只要有東西在它前面就會發送零速命令然后當事物不在路上時(或者機器人轉動)它將再次開始移動。

用法:

>>> 
>>> robot = Robot('Foo')
>>> can_move(forward())
distance? 100
    Foo forward speed is 150
check distance
distance? 50
    Foo forward speed is 150
check distance
distance? 30
    Foo forward speed is 150
check distance
distance? 15
    Foo forward speed is 0
    Robot 0 stopped
>>>

雖然這在Python 3.6中有效,但它基於對生成器和協同程序的可能過時的概念/理解。 使用Python 3+的一些async添加可能有不同的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM