One issue with your multiprocessing solution is that distance_check returns and stops
dist = distance()
return dist # <------
time.sleep(0.3)
if dist < min_distance:
....
It seems like you are trying to exchange information between the processes: which is typically done using Queues or Pipes.
I read between the lines of your question and came up with the following specs:
- a robot moves if its speed is greater than zero
- continually check for obstacles in front of the robot
- stop the robot if it gets to close to something.
I think you can achieve your goal without using multiprocessing. Here is a solution that uses generators/coroutines.
For testing purposes, I have written my own versions of a robot and an obstacle sensor - trying to mimic what I see in your code
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
Decorator to start a coroutine/generator:
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
A producer to continually check to see if it is safe to move
def can_move(target, min_distance = 15):
'''Continually check for obstacles'''
while distance() > min_distance:
target.send(True)
print('check distance')
target.close()
A generator/coroutine that consumes safe-to-move signals and changes the robot's speed as needed.
@consumer
def forward():
try:
while True:
if (yield):
robot.forward(150)
except GeneratorExit as e:
# stop the robot
robot.forward(0)
The robot's speed should change as fast as the obstacle sensor can produce distances. The robot will move forward till it gets close to something and just stop and it all shuts down. By tweaking the logic a bit in forward and can_move you could change the behaviour so that the generators/coroutines keep running but send a zero speed command as long as something is in front of it then when the thing gets out of the way (or the robot turns) it will start moving again.
Usage:
>>>
>>> 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
>>>
While this works in Python 3.6, it is based on a possibly outdated notion/understanding of generators and coroutines. There may be a different way to do this with some of the async additions to Python 3+.