Beyond Basics Ex 7-11

Exercise 7: 'Sensor Blocks'

I have kept the original title for this exercise, 'Sensor Blocks', even though EV3 Python doesn't use programming blocks like the Lego software does. 

Objective:

When the touch sensor is NOT pressed the robot will turn on the spot to the right at a speed that is proportional to the ambient light intensity. When the touch sensor IS pressed then the robot will stop moving for as long as the switch is pressed, and the status light will glow red. This program will not stop by itself so you must force the program to stop by pressing the Back button on the EV3 or the stop button in VS Code if you launched the script from there.

Solution:

#!/usr/bin/env python3

from ev3dev2.motor import MoveSteering, OUTPUT_B, OUTPUT_C

from ev3dev2.sensor.lego import TouchSensor, ColorSensor

from ev3dev2.led import Leds

from time import sleep

steer_pair = MoveSteering(OUTPUT_B, OUTPUT_C)

cl = ColorSensor()

ts = TouchSensor()

leds = Leds()

while True:     # forever

    if ts.is_pressed==0:    # touch sensor NOT pressed

        leds.all_off()   # turn off LEDs

        # turn motors at opposite speeds to turn on the spot

        steer_pair.on(steering=100, speed=cl.ambient_light_intensity)

    else:   #  touch sensor is pressed

        steer_pair.off()

        leds.set_color('LEFT', 'RED')

        leds.set_color('RIGHT', 'RED')

Notes:

1. My solution is very different to the official EV3-G solution, shown below:

The official solution uses two threads which run simultaneously since they are both attached to a Start block. When the lower loop detects that the touch sensor has been pressed it issues a Stop Motor command but this seems to be in conflict with the Motor command in the top loop, which tells the motors to move. Presumably the Stop Motor command takes precedence, but how can it, since the stop motor command and the start motor command are in different loops and will be executed at different times? So this solution may work but is hard to understand and unnecessarily complex - why use two threads for this solution? 

Exercise 8: Text

This exercise is like exercise 5, but simpler. 

Objective:

The ultrasonic sensor will measure distance. The distance value will be displayed in centimeters on the LCD screen followed by the string ' cm'. The text will be displayed in the font courB24. The display will be continuously updated with the current distance reading of the sensor.

Solution:

#!/usr/bin/env python3

from ev3dev2.sensor.lego import UltrasonicSensor

from ev3dev2.display import Display

from time import sleep

lcd = Display()

us = UltrasonicSensor()

while True: # forever

    distance = us.distance_centimeters # a float

    lcd.text_pixels(str(distance) +' cm', x=40, y=50, font='courB24')

    lcd.update()

    sleep(0.1) # so the display doesn't change too frequently

Notes:

Exercise 9: Range

Objective:

Make the robot follow an object that is moving away from it - it should move forwards towards the object as long as the object is between 10 and 20 cm in front of the robot but will stop moving if it gets closer than 10 cm, thereby avoiding a collision. It will also stop moving (give up) if the leading object is more than 20 cm in front of the robot.

Solution:

#!/usr/bin/env python3

from ev3dev2.motor import MoveTank, OUTPUT_B, OUTPUT_C

from ev3dev2.sensor.lego import UltrasonicSensor

from time import sleep

tank_pair = MoveTank(OUTPUT_B, OUTPUT_C)

us = UltrasonicSensor()

while True:    # forever

    distance = us.distance_centimeters

    if distance > 10 and distance < 20:

        tank_pair.on(left_speed=50, right_speed=50)

    else:

        tank_pair.off()

    sleep(0.1)

Notes:

Exercise 10: Math - Basic

Objective:

This program will calculate how many wheel rotations are necessary to make the robot move forward 50 cm, then it will make the robot move, then it will calculate the speed of the robot during the motion.

Solution:

Each time a robot wheel turns through one rotation the entire circumference of the wheel rolls along the ground.

To find the number of rotations necessary to move the robot forward 50 cm we must divide 50 cm by the distance moved in each rotation of the wheel (equal to the circumference of the wheel).

We will use the function time() which is part of the time library - don't confuse the function with the library of the same name. time() returns (as a float) the number of seconds that have elapsed since the 'epoch'. We don't need to know when the 'epoch' was (it may be the very beginning of 1970?) because all we are interested in is the increase in time between the start of the movement and the end of the movement. In this script I use from time import time so in the script I only need to use time() to invoke the function. If I had used import time then in the script I would have had to use time.time() to invoke the function.

#!/usr/bin/env python3

from ev3dev2.motor import MoveSteering, OUTPUT_B, OUTPUT_C

from ev3dev2.display import Display

from time import sleep, time

steer_pair = MoveSteering(OUTPUT_B, OUTPUT_C)

lcd = Display()

# num_rots is number of wheel rotations needed for robot to advance 50 cm

num_rots = 50/17.6 # wheel circumference = 17.6 cm for education version

# num_rots = 50/13.6 # wheel circumference = 13.6 cm for home version

start_time = time() # time() returns seconds since the 'epoch'

steer_pair.on_for_rotations(steering=0, speed=40, rotations=num_rots)

travel_time = time() - start_time # calculate how long the movement took

speed = 50/travel_time # speed = distance in cm / time in s

lcd.text_pixels(str(round(speed)) + ' cm/s', x=40, y=50, font='helvB24')

lcd.update()

sleep(5) # Give enough time for the screen to be read

Notes:

Exercise 11: Gyro - rate

Objective:

The program should continuously (every 0.5 seconds) display the rate of turn of the gyro sensor in degrees per second. In EV3 Python v2 the rate of turn is given by the rate property of the gyro sensor.

Solution:

Recall that whenever you use the gyro sensor it is vitally important to keep the sensor absolutely stationary when the EV3 brick is powered up or the gyro sensor is plugged in, otherwise the gyro reading will continually wander away from the correct value.

#!/usr/bin/env python3

from ev3dev2.sensor.lego import GyroSensor

from ev3dev2.display import Display

import ev3dev2.fonts as fonts

from time import sleep

gyro = GyroSensor()

lcd = Display()

while True:

    lcd.text_pixels(str(gyro.rate)+' deg/s', x=40, y=50, font='helvB24')

    lcd.update()

    sleep(0.4) # so the display doesn't change too frequently

Notes:

You are now ready to tackle Beyond Basics exercises 12-18.