# Robot Educator

The education version of the Lego EV3 software proposes various example programs in a sequence called ‘Robot Educator’. You can see those programs and my commentaries HERE. Let’s see how to solve the same problems using EV3 Python. No, much better: YOU try to write a script to solve each challenge, only looking at my solution when you have have completed your own solution (or got stuck trying...).

As for all exercises on this site, it is assumed that you are using the official ‘Lego ‘Driving Base’ model, or something very similar, with motors attached to ports B and C. The official Lego  'Driving Base' model is also called the 'Educator Vehicle'.

The program solutions below can be copied into VS code so that you can test them, if you wish.

Further down this page you can find the 'Basics' exercises. Once you have completed them, follow these links for the 'Hardware' and 'Beyond Basics' exercises:

# BASICS

Lesson 1 of the official Lego lesson sequence is about configuring blocks and is not relevant to EV3 Python and therefore not discussed here.

## Lesson 2: Straight Move

### EV3 Python solution:

#!/usr/bin/env python3

from ev3dev2.motor import OUTPUT_B, OUTPUT_C, MoveSteering

from time import sleep

steer_pair = MoveSteering(OUTPUT_B, OUTPUT_C)

# Make the robot advance such that the wheels rotate 2 rotations

steer_pair.on_for_rotations(steering=0, speed=50, rotations=2)

sleep(1) # Wait one second

# Make the robot move BACKWARDS such that

# the wheels rotate 2 rotations at 50% speed

# NEVER SET THE ANGLE NEGATIVE

steer_pair.on_for_rotations(steering=0, speed=-50, rotations=2)

sleep(1) # Wait one second

# Make the robot advance for 1 second at 50% speed

steer_pair.on_for_seconds(steering=0, speed=50, seconds=1)

For comparison, here is the solution as it appears within the standard Lego icon-based programming environment:

You can find the Lego solutions to the other challenges HERE.

## Lesson 3: Curved Move

### Solution:

#!/usr/bin/env python3

from ev3dev2.motor import OUTPUT_B, OUTPUT_C, MoveSteering

from time import sleep

steer_pair = MoveSteering(OUTPUT_B, OUTPUT_C)

# Make the robot do a hard turn right (on the spot) with

# 685 deg wheel rotation (speed 40%).

steer_pair.on_for_degrees(steering=100, speed=40, degrees=685)

sleep(1) # Wait one second

# Medium turn right, meaning only the left motor (B) will turn

steer_pair.on_for_degrees(steering=50, speed=40, degrees=1380)

sleep(1) # Wait one second

# Gentle turn right (steering=25) with speed 50%

# and two rotations of the faster wheel

steer_pair.on_for_rotations(steering=25, speed=50, rotations=2)

## Lesson 4: Tank Move

### Objective:

The intended movement in the official Lego lesson 4 is exactly the same as in lesson 3 above, but the idea is to show that the same movements can be obtained with Move Tank if desired:

#!/usr/bin/env python3

from ev3dev2.motor import OUTPUT_B, OUTPUT_C, MoveTank

from time import sleep

tank_pair = MoveTank(OUTPUT_B, OUTPUT_C)

# Make the robot do a hard turn right (on the spot) with

# 685 deg wheel rotation (speed 40%).

tank_pair.on_for_degrees(left_speed=40, right_speed=-40, degrees=685)

sleep(1) # Wait one second

# Medium turn right, meaning only the left motor (B) will turn

tank_pair.on_for_degrees(left_speed=50, right_speed=0, degrees=1380)

sleep(1) # Wait one second

# Gentle turn right (steering=25) with speed 50% for the faster wheel

# and two rotations of the faster wheel

tank_pair.on_for_rotations(left_speed=50, right_speed=25, rotations=2)

## Lesson 5: Move Object

### Objective:

This program uses the medium motor to lower the robot's gripper bar, trapping an object, then it does a medium left turn backwards, pulling the object with it, then it raises the gripper bar. It is assumed that the gripper bar is attached to the medium motor which is itself attached to port A. The photo shows the gripper bar attached to the standard Lego 'Driving Base' model, also called the 'Educator Vehicle' model.

### Solution:

#!/usr/bin/env python3

from ev3dev2.motor import OUTPUT_A, OUTPUT_B, OUTPUT_C, MoveTank, MediumMotor

# Make a MediumMotor object, an instance of the MediumMmotor class

# Note that if only one medium motor is attached to the EV3

# then it is not necessary to specify the port as here

medium_motor = MediumMotor(OUTPUT_A)

tank_pair = MoveTank(OUTPUT_B, OUTPUT_C)

# Make the medium motor (on port A) turn 100 deg at -30% speed

medium_motor.on_for_degrees(speed=-30, degrees=100)

# Medium left turn backwards. The left wheel (B) should rotate backwards

# 1 rotation with speed 50% and the right wheel should not rotate.

tank_pair.on_for_rotations(left_speed=50, right_speed=0, rotations=1)

# Medium motor A turns 100 deg at +30% speed

medium_motor.on_for_degrees(speed=30, degrees=100)

## Lesson 6: Stop at line

### Objective:

This exercise assumes that a colour sensor is attached and is suspended just above (ideally 3 mm above) the ground, pointing at the ground. This program turns on the right motor to make the robot turn left, then waits until the detected brightness falls below a certain value (because the sensor has passed over a black line, for example), then turns off the motor.

### Solution:

#!/usr/bin/env python3

from ev3dev2.motor import OUTPUT_C, LargeMotor

from ev3dev2.sensor.lego import ColorSensor

from time import sleep

# Connect an EV3 color sensor.

cl = ColorSensor()

mC = LargeMotor(OUTPUT_C)

# Make the right motor (motor C) turn at 50% speed

mC.on(speed=50)

# Wait until the colour sensor detects that the brightness

# has fallen beneath a threshold value of 40 (see note).

# Loop while over white surface

while cl.reflected_light_intensity > 40:

sleep(0.01)

mC.off()

## Lesson 7: Stop at Angle

This exercise uses the gyro sensor. The gyro sensor is included in the education version of the EV3 but not in the home version, so if you have the home version you will not be able to test this program (it's always possible to buy additional sensors). Whenever you use the gyro sensor, be sure that the sensor is absolutely still when the program is launched otherwise its readings will wander away from the correct values. If you are not sure that this condition was met then simply unplug the sensor from its port and then reconnect it before running the program, while ensuring that the EV3 and the gyro sensor are perfectly still.

The gyro's angle property is the angle in which it is pointing relative to the angle that is was at when the program was launched (????). A clockwise angle is a positive angle. For example, if the sensor were to be rotated through 2 rotations counterclockwise after the program is launched then it would return an angle of -720 degrees.

### Solution:

#!/usr/bin/env python3

from ev3dev2.motor import OUTPUT_B, OUTPUT_C, MoveTank

from ev3dev2.sensor.lego import GyroSensor

from time import sleep

# Connect gyro sensor.

gyro = GyroSensor()

tank_pair = MoveTank(OUTPUT_B, OUTPUT_C)

# Start the left motor with speed 40% to initiate a medium turn right.

tank_pair.on(left_speed=40, right_speed=0)

# Wait until the gyro sensor detects that the robot has turned

# (at least) 45 deg in the positive direction (to the right)

gyro.wait_until_angle_changed_by(45)

# Robot moves straight ahead with speed 50% until the wheels

# have turned through one rotation

tank_pair.on_for_rotations(left_speed=50, right_speed=50, rotations=1)

## Lesson 8: Stop at Object

This project will use the ultrasound sensor. If you don't have the ultrasound sensor (because you bought the home edition of the EV3) you could perhaps substitute the IR sensor but it won't be possible to get exact distances because the IR sensor does not return exact distances. Also, the code will be different if you use the IR sensor. This difference means other small changes need to be made to the code. See note 2 for a solution using the infrared sensor.

### Objective:

The robot will move forward in a straight line (speed=50%) until it has moved (at least) 11 cm closer to the reflecting object in front of it, then it will stop and pause for one second, then it will back up continuously (speed=-50%) until it detects that it has moved (at least) 6 cm away from the object, then it will stop.

### Solution (using the ultrasound sensor):

We will make use of the fact that if the robot moves 11 cm closer and then 6 cm further away it will then be 5 cm from its starting position.

#!/usr/bin/env python3

from ev3dev2.motor import MoveSteering, OUTPUT_B, OUTPUT_C

from ev3dev2.sensor.lego import UltrasonicSensor

from time import sleep

steer_pair = MoveSteering(OUTPUT_B, OUTPUT_C)

us = UltrasonicSensor()

# Record the initial separation of the sensor and the object

startdistance = us.distance_centimeters

# Start robot moving forwards

steer_pair.on(steering=0, speed=50)

# Wait until robot has moved (at least) 11 cm closer

# to the reflecting object in front of it

while us.distance_centimeters > startdistance-11:

sleep(0.01)

steer_pair.off() # Stop moving forwards

sleep(1)

# Reverse at 50% speed

steer_pair.on(steering=0, speed=-50)

# Wait until robot is less than 5 cm from its starting position

while us.distance_centimeters < startdistance-5:

sleep(0.01)

steer_pair.off() # Stop moving backwards

### Notes:

#!/usr/bin/env python3

from ev3dev2.motor import MoveSteering, OUTPUT_B, OUTPUT_C

from ev3dev2.sensor.lego import InfraredSensor

from time import sleep

steer_pair = MoveSteering(OUTPUT_B, OUTPUT_C)

ir = InfraredSensor()

# Since the IR values are very approximate,

# make sure the initial separation is at least 30cm

# Record the approximate initial distance of the object from the sensor in cm

# A 'proximity' value of 100 corresponds to approximately 70cm

# so proximity can be very roughly converted to cm

# by multiplying by 0.7

start_distance = int(ir.proximity*0.7)

# Start robot moving forwards

steer_pair.on(steering=0, speed=50)

# Wait until robot has moved (at least) 11 cm closer

# to the reflecting object in front of it

while ir.proximity*0.7 > start_distance-11:

sleep(0.01)

steer_pair.off() # Stop moving forwards

sleep(1)

# Reverse at 50% speed

steer_pair.on(steering=0, speed=-50)

# Wait until robot is less than 5 cm from its starting position

while ir.proximity*0.7 > start_distance-5:

sleep(0.01)

steer_pair.off() # Stop moving backwards

Now that you have complete the 'Basics' exercises you are ready to tackle the 18 'Beyond Basics' exercises which begin with Beyond Basics exercises 1-6.