-
-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OSError when using MultiProcessing in PyBricks #80
Comments
Threading and processing is not officially supported in this release. Some things might work, but it has not been designed or tested for that use case. However, Pybricks for EV3 has an experimental feature that you may want to try: from pybricks.experimental import run_parallel
from pybricks.tools import wait
def task1():
wait(1000)
return 'OK1'
def task2():
wait(500)
return 'OK2'
result = run_parallel(task1, task2)
print('task1:', repr(result[task1]))
print('task2:', repr(result[task2]))
# prints:
# task1: 'OK1'
# task2: 'OK2' |
Hi @laurensvalk , |
Running multiple things at the same time, yes, but not using threads. That is why the EV3 feature is experimental. We'd much rather have one simple way of doing it across all hubs. |
@laurensvalk thank you for letting me know of the I've tried it out but I'm reporting this problem with Thank you. #!/usr/bin/env pybricks-micropython
from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor, TouchSensor, ColorSensor, InfraredSensor
from pybricks.media.ev3dev import ImageFile, SoundFile
from pybricks.robotics import DriveBase
from pybricks.parameters import Button, Color, Direction, Port, Stop
from pybricks.tools import wait
from pybricks.experimental import run_parallel
from random import randint
class Ev3rstorm(EV3Brick):
WHEEL_DIAMETER = 26 # milimeters
AXLE_TRACK = 102 # milimeters
def __init__(
self,
left_foot_motor_port: Port = Port.B, right_foot_motor_port: Port = Port.C,
ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1):
self.drive_base = DriveBase(left_motor=Motor(port=left_foot_motor_port,
positive_direction=Direction.CLOCKWISE),
right_motor=Motor(port=right_foot_motor_port,
positive_direction=Direction.CLOCKWISE),
wheel_diameter=self.WHEEL_DIAMETER,
axle_track=self.AXLE_TRACK)
self.ir_sensor = InfraredSensor(port=ir_sensor_port)
self.ir_beacon_channel = ir_beacon_channel
def drive_once_by_ir_beacon(
self,
speed: float = 1000, # mm/s
turn_rate: float = 90 # rotational speed deg/s
):
ir_beacon_button_pressed = set(self.ir_sensor.buttons(channel=self.ir_beacon_channel))
# forward
if ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_UP}:
self.drive_base.drive(
speed=speed,
turn_rate=0)
# backward
elif ir_beacon_button_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}:
self.drive_base.drive(
speed=-speed,
turn_rate=0)
# turn left on the spot
elif ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_DOWN}:
self.drive_base.drive(
speed=0,
turn_rate=-turn_rate)
# turn right on the spot
elif ir_beacon_button_pressed == {Button.RIGHT_UP, Button.LEFT_DOWN}:
self.drive_base.drive(
speed=0,
turn_rate=turn_rate)
# turn left forward
elif ir_beacon_button_pressed == {Button.LEFT_UP}:
self.drive_base.drive(
speed=speed,
turn_rate=-turn_rate)
# turn right forward
elif ir_beacon_button_pressed == {Button.RIGHT_UP}:
self.drive_base.drive(
speed=speed,
turn_rate=turn_rate)
# turn left backward
elif ir_beacon_button_pressed == {Button.LEFT_DOWN}:
self.drive_base.drive(
speed=-speed,
turn_rate=turn_rate)
# turn right backward
elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}:
self.drive_base.drive(
speed=-speed,
turn_rate=-turn_rate)
# otherwise stop
else:
self.drive_base.stop()
def keep_driving_by_ir_beacon(
self,
speed: float = 1000, # mm/s
turn_rate: float = 90 # rotational speed deg/s
):
while True:
self.drive_once_by_ir_beacon(
speed=speed,
turn_rate=turn_rate)
wait(1)
def dance_whenever_ir_beacon_pressed(self):
while True:
while Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel):
self.drive_base.turn(angle=randint(-360, 360))
wait(1)
def main(self,
driving_speed: float = 1000 # mm/s
):
self.screen.load_image(ImageFile.TARGET)
run_parallel(
self.keep_driving_by_ir_beacon,
# *** the below parallel thread doesn't run ***
self.dance_whenever_ir_beacon_pressed)
if __name__ == '__main__':
EV3RSTORM = Ev3rstorm()
EV3RSTORM.main() |
As in the example and mentioned in the documentation linked to above, the parallel functions must not have arguments. In your code, there is one argument (self). It would be possible to account for that but it probably isn’t going to be very efficient. Can you try a more basic example first? |
I don't think MicroPython will ever support multiprocessing but anyone just wanting to run tasks in parallel should have a look at #917. |
I'm trying out multiprocessing in pybricks programs. A simple program with a parallel process is pasted below: whenever the Touch Sensor is pressed, the Motor shall run.
When I run this program, however, it fails as soon as I press the Touch Sensor, with the following error:
May I check what may be the problem? Thank you very much!
The text was updated successfully, but these errors were encountered: