How to stop on ongoing motor motion using another condition? #1621
-
This was asked via email, so I've opened a discussion here so everyone can see the possible answer, and share other solutions.
As a concrete example, let's say we want to rotate motor A for 3600 degrees (10 rotations), but stop earlier if we see an obstacle or the motor gets stuck, so we don't keep waiting forever. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
Another way of phrasing this more systematically, is to say we want to rotate the motor
... whichever comes first. There are a few solutions. The easy way with Pybricks You can implement this quite literally with the multitask block, and set it to complete when one task finishes: It will do three tasks at once: rotate, wait for stall, and wait for sensor. It completes when one of them completes, which is exactly what we wanted! Then the program continues with the rest, which is just a sound in this case. The hard way 1 (synchronously using classic apps/solutions) In the classic solution, you could:
The hard way 2 (asynchronously using classic apps/solutions)
|
Beta Was this translation helpful? Give feedback.
-
Thank you! We will give this a try! |
Beta Was this translation helpful? Give feedback.
-
so something like this in Python: from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor
from pybricks.parameters import Button, Color, Direction, Port, Side, Stop
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch, multitask, run_task, hub_menu
from umath import sin, pi
hub = PrimeHub()
topAttachment = Motor(Port.D,Direction.CLOCKWISE,gears=[20,28],reset_angle=True)
async def isStalled() -> bool :
print("isStalled()",topAttachment.stalled())
while topAttachment.stalled() == False:
await wait(1)
print("stalled")
return topAttachment.stalled()
async def moveArm(speed,angle) -> bool:
print ("moveArm() speed=",speed," angle=",angle)
await topAttachment.run_target(speed,angle,then=Stop.HOLD)
return True
async def main():
print("topAttachment Angle=",topAttachment.angle())
topAttachment.reset_angle(0)
print("start")
await multitask(moveArm(50,180),isStalled(),race=True)
await multitask(moveArm(50,-180),isStalled(),race=True)
print ("end")
run_task(main()) |
Beta Was this translation helpful? Give feedback.
Another way of phrasing this more systematically, is to say we want to rotate the motor
... whichever comes first.
There are a few solutions.
The easy way with Pybricks
You can implement this quite literally with the multitask block, and set it to complete when one task finishes:
It will do three tasks at once: rotate, wait for stall, and wait for sensor. It completes when one of them completes, which is exactly what we wanted!
Then the program continues with the rest, which is just a sound in this case.
The hard way 1 (synchronously using classic apps/solutions)
In the classic soluti…