Here's a simple application, from :class:`.SimpleApp`:
from BrickPython.CommandLineApplication import CommandLineApplication
class SimpleApp(CommandLineApplication):
def __init__(self):
CommandLineApplication.__init__(self)
self.addSensorCoroutine( self.doActivity() ) #A
def doActivity(self):
'Coroutine to rotate a motor forward and backward'
motorA = self.motor('A')
motorA.zeroPosition() #B
while True:
for i in motorA.moveTo( 2*90 ): #C
yield #D
for i in motorA.moveTo( 0 ):
yield
if __name__ == "__main__":
SimpleApp().mainloop()
It uses the simplest scheduler: the :class:`.CommandLineApplication`.
Line A creates a coroutine from the coroutine method doActivity() and adds it to the scheduler. A coroutine method must have one or more yield calls, such as the one at line D, so that calling the method returns a coroutine which the scheduler can invoke using next(). For more about such 'generator functions', see https://wiki.python.org/moin/Generators
To get the most benefit from coroutines we want to be able to call other coroutines, and to wait until they've finished. Lines C,D show how this is done. motorA.moveTo(2*90) is itself a coroutine - one that implements the Servo motor PID algorithm - and thus we can invoke it using Python's iteration syntax:
for i in coroutine():
yield
The dummy variable i is ignored.
We could, of course, add extra code between C and D - for example to check a sensor. It will be executed for each work call. :class:`.DoorControl` shows how this can work.
We can also combine coroutines.
The coroutine method :meth:`.Scheduler.runTillFirstCompletes` creates a new coroutine from a list of coroutines and terminates them all (and itself) when the first completes. The coroutine method :meth:`.Scheduler.runTillAllComplete` similarly runs until all of a list of coroutines complete.
The :meth:`.Scheduler.withTimeout` coroutine method adds a timeout to a coroutine, terminating it if it hasn't completed after the given timeout.
:meth:`.Scheduler.waitFor` answers a coroutine that terminates when a given function returns true.
:meth:`.Motor.moveTo` and :meth:`.Motor.setSpeed` are coroutines that control a motor.