top of page
WFU Robotics

Programming the Diddybot

The Diddybot is fitted with a Raspberry Pi, which means we can upload code scripts to run onboard. I will be introducing a very basic script, which will cause your Diddybot to move in approximately a 1 meter square. This tutorial will introduce you to concepts such as interacting with the motor controller, turning your Diddybot, and beginner techniques for traveling set distances. There will not be much interaction with the Raspberry Pi in this tutorial, as the motor controller takes care of that for us.


First, on Wake Forest Robotics Club issued Raspberry Pis, we create a file called “tutorial.py” in the diddyborgv2 folder. To do so, we open up the terminal, and navigate to the diddyborgv2 folder using:


pi@raspberrypi:~ $ cd diddyborgv2

Next we create tutorial.py in this folder using


pi@raspberrypi:~ $ touch tutorial.py

Now that the python file exists, we need to open it in a code editor. The Raspberry Pis have a few built in code editors, such as Thonny IDE, so you can use those if you’d like. I like to use the code editor which is built into Linux, nano. To access it, we enter from the command line:


pi@raspberrypi:~/diddyborgv2 $ nano tutorial.py

Now that we are into a code editor, we can start writing our sample script.


First, we have to import our packages and set up the motor controller, the ThunderBorg. The ThunderBorg motor controller is a package which already exists in the diddyborgv2 folder inside our Raspberry Pis. If you find that this folder is not included, it is available for download at https://github.com/phopley/thunderborg


Import ThunderBorg
Import time
Import math
Import sys

TB = ThunderBorg.ThunderBorg()

TB.Init()

If not TB.foundChip:
 Boards = ThunderBorg.ScanForThunderBorg()
 If len(boards) == 0:
  print(‘No ThunderBorg found, check you are attached)
 sys.exit()
TB.SetCommsFailSafe(False)
TB.SetLedShowBattery(False)

These lines of code should be run before you use the ThunderBorg motor controller in any program. It will connect your program to the physical ThunderBorg board on the robot, and initialize its values, as well as check whether the board is connected properly.


Next, we will initialize the global variables. These are global constants which we wish to stay the same throughout our program’s execution.


timeForward1m = 5.0
timeSpin360 = 4.0

The two variables timeForward1m and timeSpin360, are important constants that will require some tinkering. They describe how many seconds it takes for your specific robot to move 1 meter forward, or spin in a full circle. These variables will be vital when we decide how long we turn each motor on. If we have accurate values, then we can easily make the robot turn a specific amount of degrees, or move a specific distance forward.


Next, we will create our main movement function. This function will take as arguments the power and direction each motor should output, and for how long. It will interact with the ThunderBorg motor controller package to turn these motors on.


def PerformMove(driveLeft, driveRight, numSeconds):   
    TB.SetMotor1(driveLeft)
    TB.SetMotor2(driveRight)
    time.sleep(numSeconds)
    TB.MotorsOff()

In this case, Motor1 and Motor2 refer to the motors whose wires connect to the M1+, M1-, M2+, and M2- ports on the physical ThunderBorg board. Since we have 3 motors connected to each M1 and M2 port, turning on Motor1 will turn on either the right or left motors, depending on your wiring, and turning on Motor 2 will turn on the others. driveLeft and driveRight are constants. They should have the same magnitude to encourage even driving and turning, but can be different signs (positive or negative) depending on if we want the robot to turn or not. We will see this in more detail later.


After turning on the motors, we wait a certain number of seconds. This sleep function will pause our code, so the motors will continue running at the same rate for the amount of time we tell our program to sleep. Once the sleep is over, we turn off the motors.


This next function will perform a turn, according to an inputted angle. This depends on your robot’s wiring, but in mine, a negative angle corresponds to a left (counterclockwise) turn, and a positive angle corresponds to a right (clockwise) turn.


def PerformSpin(angle):
     if angle < 0.0:
         #Turn left
         driveLeft = -1.0
         driveRight = 1.0
         angle = angle * -1
     else:
         #Turn right
         driveLeft = 1.0
         driveRight = -1.0
 
     numSeconds = (angle / 360.0) * timeSpin360
     PerformMove(driveLeft, driveRight, numSeconds)

First, we determine which direction the robot should turn using the if-else block. As said above, a negative angle corresponds to a left turn, and a positive angle to a right turn in this function. To turn the robot left, we set the motors on the left side to move backwards, and the motors on the right side to move forwards. We also multiply the angle by -1 to make the numSeconds calculation work correctly.


Conversely, for turning right, you would set the left motors to move forwards, and the right motors to move backwards.


To calculate the number of seconds the motors should be set in this configuration to turn our desired angle, we calculate the ratio angle/360.0 and multiply that by the time it takes the robot to spin a full circle. Running the motors for this number of seconds should spin the robot the correct amount, should the timeSpin360 variable be set correctly.


We then perform the move function with our calculated inputs. Note that driveLeft and driveRight both have magnitude 1. This magnitude does not matter much, as long as they are the same for both motors, but if you adjust its value, you may have to adjust the time it takes the robot to spin in a circle. Play around with the constants to see how the robot reacts.


Next, we can create a function which will make the robot drive an inputted number of meters straight ahead, or behind.


def PerformDrive(meters):
    if meters < 0.0:
        #drive backwards
        driveLeft = -1.0
        driveRight = -1.0
        meters = meters * -1
    else:
        driveLeft = 1.0
        driveRight = 1.0
    numSeconds = meters * timeForward1m
    PerformMove(driveLeft, driveRight, numSeconds)

This function takes in a number of meters to drive, and sets the motor values correspondingly. These motors have a channel which allows us to drive them backwards, so we can specify a negative value to have that happen. Notice how the magnitude of the driveLeft and driveRight values are the same. This prevents any turning. However in practice, you may notice some turning due to the physical configuration of the wheels.


We simply multiply the number of meters to travel by the time it takes to move 1 meter to know the amount of time to turn on the motors for. Lastly, we perform the move function.


Now for the code to be executed. The goal of this simple tutorial is to get the robot to drive in a square, with side lengths equal to .5 meters. To do so, we will implement a for loop, which consists of a .5 meter straightaway, and a 90 degree turn.


try:
    print(“RUNNING”)
    for i in range(4):
        PerformDrive(.5)
        PerformSpin(90)

except KeyboardInterrupt:
    TB.MotorsOff()
    print(“stopping”)

We implement a try block here so that if the robot acts erratically, we can use ctrl+c to stop the motors and kill the program.


Now that the code is written, we can use ctrl+O to save, and ctrl+X to exit. Then back out to the terminal, make sure you are in the diddyborgv2 directory, and execute:


pi@raspberrypi:~/diddyborgv2 $ python tutorial.py

You will probably need to run a few test runs to get the constants correct, but eventually your robot should move in a neat square. Here is a little video of mine running:




8 views0 comments

Recent Posts

See All

Kommentare


bottom of page