[Feature] Is there any function like "thread" (not multitask) implement in pybricks with SPIKE Prime?
a10036gt opened this issue · comments
In robotics programing, we ofter using thread or multi task to do some staff, for example, WRO RoboSport we have a main task to do, and other task will doing sensor processing, odometry task..., like following image:
Here is the video about robot run: https://youtu.be/a0pwdxfojIo?si=5DHkKBV64Dm3L_QP&t=1384
The Pybricks provide the multitask but it works not well for us, because the task is in while loop and can't get out. We want to import _thread but it has been remove in firmware.
Is there anyway to doing this kind of function? Following code is a arduino with FreeRTOS, that's the things we want to do:
Thanks!
And As I know the SPIKE App doing in similar way to solve the thread problem:
Compiled Code:
async def stack(this):
while True:
with this as event:
await event
# Control repeat
for _ in range(10):
# Light display image on for time
hub.light_matrix.show([int((int(p) * (global_state[DISPLAY_BRIGHTNESS] / 9)) + 0.5) for p in "9909999099000009000909990"])
try:
await this.wait(2000)
except scratch._StackStop as ex:
hub.light_matrix.clear()
raise ex
hub.light_matrix.clear()
yield
async def stack_1(this):
while True:
with this as event:
await event
# Control forever
while True:
# Play sound until done
if tunnel.connected():
corr = (global_state[TUNNEL_CORRELATION] + 1) % 255
global_state[TUNNEL_CORRELATION] = corr
await send_tunnel_data(struct.pack(">BBIBhb", 23, corr, 2365347937, int(global_state[SOUND_VOLUME] + 0.5), int(global_state[SOUND_PITCH] + 0.5), int(global_state[SOUND_PAN] + 0.5)))
try:
await request_tunnel_data(corr, False)
except scratch._StackStop as ex:
await send_tunnel_data(struct.pack(">BB", 27, corr))
raise ex
yield
vm = scratch.VM()
vm.add_start(stack)
vm.add_start(stack_1)
vm.run()
OK I give a try and it work, but seems if I have any while loop in task, I need add await wait(1), or other task will be block?
I need add await wait(1), or other task will be block?
This is done for your automatically.
If you have an example where that was not done correctly, please let us know and we'll fix it.
Maybe we'll also add an option to omit the wait(1)
so advanced users can turn it off. After all, they aren't needed in this example since the loops contain other awaitables.
I using Python mode not block mode, I mean seems it is necessary to add wait(1) in any loop I use in task? Because When I remove it, seems other task will be block.
Yes, it is generally necessary in loops that take a some time (or forever) if they don't already have anything awaitable inside. This is how async
/await
works, also in official MicroPython or the standard LEGO firmware.
Having such a wait allows your code on other "tasks" to be executed.
If you'd like to share some of your code, perhaps we can help with that.
OK, I see, thanks!