Skip to content

Commit ac18ae1

Browse files
committed
Merge pull request #80 from ddemidov/demo
Adding auto-drive demo
2 parents 7922aaf + deb9753 commit ac18ae1

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

demo/README.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The examples in this folder, unless stated otherwise, are based on Explor3r
2+
robot by Laurens Valk. The assembling instructions for the robot may be found
3+
here: http://robotsquare.com/2015/10/06/explor3r-building-instructions.

demo/auto-drive.py

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/python
2+
3+
# -----------------------------------------------------------------------------
4+
# Copyright (c) 2015 Denis Demidov <dennis.demidov@gmail.com>
5+
#
6+
# Permission is hereby granted, free of charge, to any person obtaining a copy
7+
# of this software and associated documentation files (the "Software"), to deal
8+
# in the Software without restriction, including without limitation the rights
9+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
# copies of the Software, and to permit persons to whom the Software is
11+
# furnished to do so, subject to the following conditions:
12+
#
13+
# The above copyright notice and this permission notice shall be included in
14+
# all copies or substantial portions of the Software.
15+
#
16+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
# THE SOFTWARE.
23+
# -----------------------------------------------------------------------------
24+
25+
# In this demo an Explor3r robot with touch sensor attachement drives
26+
# autonomously. It drives forward until an obstacle is bumped (determined by
27+
# the touch sensor), then turns in a random direction and continues. The robot
28+
# slows down when it senses obstacle ahead (with the infrared sensor).
29+
#
30+
# The program may be stopped by pressing any button on the brick.
31+
#
32+
# This demonstrates usage of motors, sound, sensors, buttons, and leds.
33+
34+
from time import sleep
35+
from random import choice, randint
36+
37+
from ev3dev.auto import *
38+
39+
# Connect two large motors on output ports B and C:
40+
motors = [LargeMotor(port) for port in (OUTPUT_C, OUTPUT_B)];
41+
42+
# Every device in ev3dev has `connected` property. Use it to check that the
43+
# device has actually been connected.
44+
assert all([m.connected for m in motors]), \
45+
"Two large motors should be connected to ports B and C"
46+
47+
# Connect infrared and touch sensors.
48+
ir = InfraredSensor(); assert ir.connected
49+
ts = TouchSensor(); assert ts.connected
50+
51+
# Put the infrared sensor into proximity mode.
52+
ir.mode = 'IR-PROX'
53+
54+
# We will need to check EV3 buttons state.
55+
btn = Button()
56+
57+
def start():
58+
"""
59+
Start both motors. `run-direct` command will allow to vary motor
60+
performance on the fly by adjusting `duty_cycle_sp` attribute.
61+
"""
62+
for m in motors:
63+
m.run_direct()
64+
65+
def backup():
66+
"""
67+
Back away from an obstacle.
68+
"""
69+
70+
# Sound backup alarm.
71+
Sound.tone([(1000, 500, 500)] * 3)
72+
73+
# Turn backup lights on:
74+
for light in (Leds.LEFT, Leds.RIGHT):
75+
Leds.set_color(light, Leds.RED)
76+
77+
# Stop both motors and reverse for 1.5 seconds.
78+
# `run-timed` command will return immediately, so we will have to wait
79+
# until both motors are stopped before continuing.
80+
for m in motors:
81+
m.stop(stop_command='brake')
82+
m.run_timed(duty_cycle_sp=-50, time_sp=1500)
83+
84+
# When motor is stopped, its `state` attribute returns empty list.
85+
# Wait until both motors are stopped:
86+
while any(m.state for m in motors):
87+
sleep(0.1)
88+
89+
# Turn backup lights off:
90+
for light in (Leds.LEFT, Leds.RIGHT):
91+
Leds.set_color(light, Leds.GREEN)
92+
93+
def turn():
94+
"""
95+
Turn the robot in random direction.
96+
"""
97+
98+
# We want to turn the robot wheels in opposite directions from 1/4 to 3/4
99+
# of a second. Use `random.choice()` to decide which wheel will turn which
100+
# way.
101+
power = choice([(1, -1), (-1, 1)])
102+
t = randint(250, 750)
103+
104+
for m, p in zip(motors, power):
105+
m.run_timed(duty_cycle_sp=p*75, time_sp=t)
106+
107+
# Wait until both motors are stopped:
108+
while any(m.state for m in motors):
109+
sleep(0.1)
110+
111+
# Run the robot until a button is pressed.
112+
start()
113+
while not btn.any():
114+
115+
if ts.value():
116+
# We bumped an obstacle.
117+
# Back away, turn and go in other direction.
118+
backup()
119+
turn()
120+
start()
121+
122+
# Infrared sensor in proximity mode will measure distance to the closest
123+
# object in front of it.
124+
distance = ir.value()
125+
126+
if distance > 60:
127+
# Path is clear, run at full speed.
128+
dc = 90
129+
else:
130+
# Obstacle ahead, slow down.
131+
dc = 40
132+
133+
for m in motors:
134+
m.duty_cycle_sp = dc
135+
136+
sleep(0.1)
137+
138+
# Stop the motors before exiting.
139+
for m in motors:
140+
m.stop()

0 commit comments

Comments
 (0)