[英]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.