Guide #2: Autonomous Code

2. Robot.run and autonomous code

Continuing from the last tutorial, we now turn to the question of how to make parts of the system behave autonomously.

This section assumes that you’ve already read part 1.

NOTE: this code is designed to play a game different from this year’s PiE game, and for a robot construction that may be different from yours. This tutorial will explain the tools available for you to program your robot – it is not a library of code you can copy-paste into your robot and run without modifications.

Our robot

First, let’s make a modification to our robot that plays tug-of-war.

It will still have two motors for driving, but let’s add an extra motor for some additional pulling power. The rope the robot is pulling is now going to be attached to a spool, and the extra motor can reel it in to get some additional tug.

Let’s also assume that the rules restrict the robot from coiling up more than 1 foot of rope.

We will be using the following variables, which you should add to the top of your code:

Our goal: fire-and-forget actuation

Before going to full-autonomous operation, let’s first cover semi-autonomous operation.

Imagine we want to have the reeling-in mechanism activate when the driver presses a button. What’s going to happen is that when the driver chooses, the motor will need to wind up a foot of rope and then turn off.

Let’s say we want this winding process to stop automatically 1 second after the driver presses the button.

One might try to implement this by adding some code directly to the loop method:

Consider what would happen if the code paused for 1 second where the “Wait 1 second” comment is placed – then the six lines of driving code at the start of teleop_main would not be running. This means that the robot will be unable to respond to new gamepad commands during that time!

Clearly, this is not what we want. To assist in debugging these sorts of errors, the student API will error if teleop_main (or autonomous_main) takes more than 1/20th of a second to complete.

What we want instead is to start an action that runs independently of the robot, like in the following code:

Autonomous Mode

Now we are ready to move on from semi-autonomous operation to full-autonomous. We will now break with our tug-of-war game metaphor and instead try to design code that makes the robot drive forward, turn, and then drive forward again (all autonomously).

defautonomous_setup():Robot.run(open_loop_drive)defautonomous_main():passasyncdefopen_loop_drive():# Drive forward for one second
Robot.set_value(left_motor,"duty_cycle",1.0)Robot.set_value(right_motor,"duty_cycle",1.0)awaitActions.sleep(1.0)# Turn right for half a second
Robot.set_value(left_motor,"duty_cycle",0.5)Robot.set_value(right_motor,"duty_cycle",-0.5)awaitActions.sleep(0.5)# Drive forward again
Robot.set_value(left_motor,"duty_cycle",1.0)Robot.set_value(right_motor,"duty_cycle",1.0)awaitActions.sleep(0.5)# Stop
Robot.set_value(left_motor,"duty_cycle",0.0)Robot.set_value(right_motor,"duty_cycle",0.0)

NOTE: you will need to use the “Mode” dropdown menu in Dawn to ensure that it is the autonomous code that runs.