SPIKE™ Prime with Python

Make It Move

Investigate how an automobile-like model can move forward and change directions using mathematical functions

45 min
Beginner
Years 7-9 OR Key Stage 3

Questions to investigate

• How can use mathematical functions to change directions?

Prepare

• Ensure SPIKE Prime hubs are charged, especially if connecting through Bluetooth.

Engage

(Group Discussion, 5 minutes)

Engage students in a conversation about how the driver causes an automobile to move.

Guide students in a discussion on the different ways a driver controls the movement of an automobile. For example, the driver can make the automobile move forward and in reverse. The driver can stop the vehicle. The driver can also turn left and right at a variety of degrees.

Show students a video of the driving base model they will work with in the explore moving to see how it can move similar to an automobile. The engage video from the Training Camp 1 lesson can be used. The video is available at
https://education.lego.com/en-us/lessons/prime-competition-ready/training-camp-1-driving-around#ignite-a-discussion.

Discuss the video with the students.

Explore

(Small Groups, 20 minutes)

Students will investigate an automobile-like model as a type of transportation.

Direct students to the BUILD section in the SPIKE App. Here students can access the building instructions for the Driving Base model. Ask students to build the driving base model. The building instructions are also available at https://education.lego.com/en-us/support/spike-prime/building-instructions.

Direct students to open a new project in the Python programming canvas. Ask students to erase any code that is already in the programming area. Students should connect their hub.  

Prompt students to think about how they program their driving base to move. Students should write a program that allows the vehicle to move forward, backward and turn by programming the motors. If students need inspiration for their program, suggest they look at the sample program from the Bike Riding for Data lesson. Similar to this program, students should include a method for adding (speeding up) and subtracting (slowing down) speed.

Remind students that when driving a vehicle like a car there is a speed limit restriction that must be followed. In addition to driving forward, challenge students to display the speed of their driving base on the hub of the model to act as a speedometer.

Sample Program:

from hub import port, light_matrix, button
import runloop
import motor_pair

async def main():
    driving_velocity = 250

    # pair motors
    motor_pair.pair(motor_pair.PAIR_1, port.C, port.D)

    # define the ride function
    async def ride():
        await light_matrix.write(str(driving_velocity))
        await motor_pair.move_for_degrees(motor_pair.PAIR_1, 720, 0, velocity = driving_velocity)
        
    # set conditions for moving forward and setting velocity
    while True:
        if button.pressed(button.LEFT):
            driving_velocity -= 50
            await ride()
            await runloop.sleep_ms(3000)
        elif button.pressed(button.RIGHT):
            driving_velocity += 50
            await ride()
            await runloop.sleep_ms(3000)

runloop.run(main())

Allow students time to explore the program. Prompt them to continue pushing the right and/or left buttons while running the program to see how the driving base will continue to move adding or subtracting 50. Students will be able to see the new speed each time on the hub.

Driving Around
Since automobiles do not often drive in a straight line only, challenge students to modify their program to include moving in different directions. Encourage students to use their math functions to help set how they make turns.

Sample Program:

from hub import port, light_matrix, button
import runloop
import motor_pair
import motor

async def main():
    # define the initial driving velocity
    driving_velocity = 250
    # defining the turn distance
    turning_left = -360
    turning_right = 360

    # pair motors
    motor_pair.pair(motor_pair.PAIR_1, port.C, port.D)

    # define the ride and turn functions
    async def ride():
        await light_matrix.write(str(driving_velocity))
        await motor_pair.move_for_degrees(motor_pair.PAIR_1, 720, 0, velocity = driving_velocity)

    async def turn_left():
        await light_matrix.write(str(turning_left/4))
        await motor.run_for_degrees(port.C, turning_left, 250)

    async def turn_right():
        await light_matrix.write(str(turning_right/4))
        await motor.run_for_degrees(port.D, turning_right, 250)

    # set conditions for moving forward and setting velocity
    while True:
        await ride()
        if button.pressed(button.LEFT):
            driving_velocity -= 50
            turning_left -= 360
            await turn_left()
            await runloop.sleep_ms(3000)

        elif button.pressed(button.RIGHT):
            driving_velocity += 50
            turning_right += 360
            await turn_right()
            await runloop.sleep_ms(3000)

runloop.run(main())

Explain

(Whole Group, 5 minutes)

Discuss with students how the program worked. Ask students questions like:
• Why did the program allow you to continue to add or subtract speeds?
• How were you able to modify your program to include turning and moving in different directions?
• Why did the drive base continue to drive when the buttons were not pressed?

When displaying the turns a math function was used to convert the actual degrees of wheel rotation to how much the drive base turned. In this case, when the single motor rotates 360 degrees it makes a full wheel rotation which turns the drive base 90 degrees. Using math you can determine the answer to 360/n=90. In this case n=4. Thus, you see this math function used in the line light_matrix.write(str(turning_left/4)) and light_matrix.write(str(turning_right/4)).

Elaborate

(Small Groups, 10 minutes)

Challenge students to recognize bugs in their programs.

Show students each program below and its error message. Have students discuss what needs to change in each code to fix the bug or add the missing code. Students can type in the program or review together as a whole class. Consider making the changes as a class and ensuring the program runs correctly after each change.

Debug Activity 1:
Find the error in the program. Remind students sometimes that error is not found until the program is running and an action is taken to read that part of the program.

from hub import port, light_matrix, button
import runloop
import motor_pair

async def main():
    driving_velocity = 250

    # pair motors
    motor_pair.pair(motor_pair.PAIR_1, port.C, port.D)

    # define the ride function
    async def ride():
        await light_matrix.write(str(driving_velocity))
        await motor_pair.move_for_degrees(motor_pair.PAIR_1, 0, velocity = driving_velocity)

    # set conditions for moving forward and setting velocity
    while True:
        if button.pressed(button.LEFT):
            driving_velocity -= 50
            await ride()
            await runloop.sleep_ms(3000)

        elif button.pressed(button.RIGHT):
            driving_velocity += 50
            await ride()
            await runloop.sleep_ms(3000)

runloop.run(main())


Error Message: 

Traceback (most recent call last):
File "drive base 1", line 27, in <module>
File "drive base 1", line 19, in main
File "drive base 1", line 13, in ride
TypeError: function missing 1 required positional arguments

The error message references several lines that are incorrect. However, it does not actually point to the one line that has the error. In line 13, the amount of degrees were removed that tell the driving base how far to move forward. This line of code should read await motor_pair.move_for_degrees(motor_pair.PAIR_1, 720, 0, velocity = driving_velocity)

Debug Activity 2:
Find the error in the program. Remind students sometimes that error is not found until the program is running and an action is taken to read that part of the program.

from hub import port, light_matrix, button
import runloop
import motor_pair

driving_velocity = 250

async def main():
    # pair motors
    motor_pair.pair(motor_pair.PAIR_1, port.C, port.D)

    # define the ride function
    async def ride():
        await light_matrix.write(str(driving_velocity))
        await motor_pair.move_for_degrees(motor_pair.PAIR_1, 720, 0, velocity = driving_velocity)

    # set conditions for moving forward and setting velocity
    while True:
        if button.pressed(button.LEFT):
            driving_velocity -= 50
            await ride()
            await runloop.sleep_ms(3000)

        elif button.pressed(button.RIGHT):
            driving_velocity += 50
            await ride()
            await runloop.sleep_ms(3000)

runloop.run(main())

Error Message: 
Traceback (most recent call last):
File "drive base 1", line 29, in <module>
File "drive base 1", line 25, in main
NameError: local variable referenced before assignment

The error message will not appear until students press one of the buttons. Students should recognize that the error is occurring in line 20. The error message indicates that local variable is referenced before the assignment. This is a typo in the program where the program is trying to reference a variable that is set in the wrong place. The variable should be defined in the main function.

Evaluate

(Group Exercise, 5 minutes)

Teacher Observation:
Discuss the program with students.
Ask students questions like:
• How were you able to use math functions to change how the driving base moved both in straight lines and when turning?
• What errors can occur when creating complex programs? What are strategies to debug these errors?
• How could you use the drive base to turn instead of a single motor?

Self-Assessment:
Have students answer the following in their journals:
• What did you learn today about using multiple math functions in one program?
• What characteristics of a good teammate did I display today?
• Ask students to rate themselves on a scale of 1-3, on their time management today.
• Ask students to rate themselves on a scale of 1-3, on their materials (parts) management today.

Teacher Support

Students will:
• Program a driving base to move forward and change directions
• Create a program with mathematical functions

• SPIKE Prime sets ready for student use
• Devices with the SPIKE App installed
• Student journals

CSTA
2-CS-02 Design projects that combine hardware and software components to collect and exchange data.
2-AP-10 Use flowcharts and/or pseudocode to address complex problems as algorithms
2-AP-13 Decompose problems and subproblems into parts to facilitate the design, implementation, and review of programs.
2-AP-16 Incorporate existing code, media, and libraries into original programs, and give attribution.
2-AP-17 Systematically test and refine programs using a range of test cases.
2-AP-19 Document programs in order to make them easier to follow, test, and debug.