remote.py
1 # -*- coding: utf-8 -*-
2 
3 import sys
4 from ev3dev import *
5 
6 # Motor speed for linear motion, in percents
7 SPEED_LINEAR = 75
8 # ... for circular motion
9 SPEED_CIRCULAR = 50
10 
11 # Motor maximal speed (will be detected)
12 max_speed = 0
13 
14 MOTOR_LEFT = OUTC
15 MOTOR_RIGHT = OUTB
16 MOTOR_BOTH = MOTOR_LEFT | MOTOR_RIGHT
17 
18 IR_CHANNEL = 0
19 
20 # IR sensor port (will be detected)
21 ir = SOCKET__NONE_
22 
23 STOP = 0
24 FORTH = 1
25 BACK = 2
26 LEFT = 3
27 RIGHT = 4
28 
29 # Command for `drive` coroutine
30 command = STOP
31 
32 # Program is alive
33 alive = True
34 
35 def init():
36  global max_speed, ir
37 
38  if tacho_is_plugged( MOTOR_BOTH, TACHO_TYPE__NONE_ ): # any type of motor
39  max_speed = tacho_get_max_speed( MOTOR_LEFT )
40  tacho_reset( MOTOR_BOTH )
41  else:
42  print '''Please, plug LEFT motor in C port,
43  RIGHT motor in B port and try again.'''
44  # Quit, inoperative without motors
45  return False
46 
47  ir = sensor_search( LEGO_EV3_IR )
48  if ir:
50  print '''IR remote control:
51  RED UP & BLUE UP - forward
52  RED DOWN & BLUE DOWN - backward
53  RED UP | BLUE DOWN - left
54  RED DOWN | BLUE UP - right'''
55  else:
56  print '''IR sensor is NOT found,
57  use the EV3 brick buttons.'''
58 
59  print 'Press BACK on the EV3 brick for EXIT...'
60  return True
61 
62 IR_ACTIONS = {
63  RED_UP_BLUE_UP : FORTH,
64  RED_DOWN_BLUE_DOWN : BACK,
65  RED_UP : LEFT,
66  RED_UP_BLUE_DOWN : LEFT,
67  BLUE_DOWN : LEFT,
68  RED_DOWN : RIGHT,
69  RED_DOWN_BLUE_UP : RIGHT,
70  BLUE_UP : RIGHT,
71 }
72 
73 def coro_handle_ir_control():
74  """
75  Coroutine of IR remote control handling.
76  """
77  global command
78 
79  if ir == SOCKET__NONE_:
80  # Do nothing if no IR sensor
81  while True:
82  yield
83 
84  pressed = btns = IR_REMOTE__NONE_
85  while True:
86  # Waiting any IR RC button is pressed or released
87  while btns == pressed:
88  btns = sensor_get_value( IR_CHANNEL, ir )
89  yield
90 
91  pressed = btns
92  # Set command for `drive` coroutine
93  if pressed in IR_ACTIONS:
94  command = IR_ACTIONS[ pressed ]
95  else:
96  command = STOP
97  yield
98 
99 KEY_ACTIONS = {
100  EV3_KEY_UP : FORTH,
101  EV3_KEY_DOWN : BACK,
102  EV3_KEY_LEFT : LEFT,
103  EV3_KEY_RIGHT : RIGHT,
104 }
105 
106 def coro_handle_brick_control():
107  """
108  Coroutine of the EV3 brick keys handling.
109  """
110  global command, alive
111 
112  pressed = keys = EV3_KEY__NONE_
113  while True:
114  # Waiting any brick's key is pressed or released
115  while keys == pressed:
116  keys = brick_keys()
117  yield
118 
119  pressed = keys
120  # Set command for `drive` coroutine
121  if pressed in KEY_ACTIONS:
122  command = KEY_ACTIONS[ pressed ]
123  else:
124  command = STOP
125  if pressed == EV3_KEY_BACK:
126  alive = False # Quit
127  yield
128 
129 def coro_drive():
130  """
131  Coroutine of control the motors.
132  """
133  speed_linear = max_speed * SPEED_LINEAR / 100
134  speed_circular = max_speed * SPEED_CIRCULAR / 100
135  state = STOP
136 
137  while True:
138  # Waiting new command
139  while state == command:
140  yield
141 
142  if command == STOP:
143  tacho_stop( MOTOR_BOTH )
144  # Waiting the vehicle is stopped
145  while tacho_is_running( MOTOR_BOTH ):
146  yield
147 
148  elif command == FORTH:
149  tacho_set_speed_sp( MOTOR_BOTH, -speed_linear )
150  tacho_run_forever( MOTOR_BOTH )
151 
152  elif command == BACK:
153  tacho_set_speed_sp( MOTOR_BOTH, speed_linear )
154  tacho_run_forever( MOTOR_BOTH )
155 
156  elif command == LEFT:
157  tacho_set_speed_sp( MOTOR_LEFT, speed_circular )
158  tacho_set_speed_sp( MOTOR_RIGHT, -speed_circular )
159  tacho_run_forever( MOTOR_BOTH )
160 
161  elif command == RIGHT:
162  tacho_set_speed_sp( MOTOR_LEFT, -speed_circular )
163  tacho_set_speed_sp( MOTOR_RIGHT, speed_circular )
164  tacho_run_forever( MOTOR_BOTH )
165 
166  state = command
167  yield
168 
169 if __name__ == '__main__':
170  print 'Waiting the EV3 brick online...'
171  if not brick_init(): sys.exit( 1 )
172 
173  print '*** ( EV3 ) Hello! ***'
174  alive = init()
175 
176  handle_ir_control = coro_handle_ir_control()
177  handle_brick_control = coro_handle_brick_control()
178  drive = coro_drive()
179 
180  while alive:
181  handle_ir_control.next()
182  handle_brick_control.next()
183  drive.next()
184  sleep_ms( 10 )
185 
186  brick_uninit()
187  print
188  print '*** ( EV3 ) Bye! ***'