In this part, we want to control the robot remotely with an Xbox 360 controller. Compared to the infrared remote control, the controller has the advantage that it has two joysticks, which are ideal for controlling. In addition, with the second joystick, we can e.g. rotate a camera and the buttons can also be assigned functions.
Even if we have already implemented a controller, I think this type is a lot cooler. Therefore, this video is about setting up the wireless Xbox 360 controller remote control.
Required Hardware Parts
Not much is needed in this tutorial, specifically just the controller and adapter:
If you use a Raspberry Pi Zero, you may have problems with the power supply. Nevertheless, a small USB hub is necessary, as the only USB port on the Zero Model is most likely used for the WiFi adapter.
Preparation & Installation of the Xbox 360 Controllers
Before we connect the controller to the Raspberry Pi and define the functions, the required drivers must be installed. In the tutorial “Control your Raspberry Pi by using a wireless Xbox 360 controller“, the installation and some tests to determine whether the controller was recognized is explained in detail. You can skip the example steps as well as using it as a mouse. The only important thing is that your Xbox controller should be recognized and ready before you continue.
Since the cable of the adapter is quite long, I would not even remove the enclosed rubber or wind the cable up again if necessary. The placement does not matter, since no visual infrared signals but radio signals are sent and received. In the video I hung the adapter over the front of the ultrasonic “eyes”, which may not be the best choice if the automatic obstacle detection is to be retained 😉
Load Module and Expand the Code
To recognize the signals, we use the same library that was used in the previous tutorial. To do this, we first load this file into our robot folder:
cd robot/ wget https://raw.githubusercontent.com/FRC4564/Xbox/2dcc49eb198e57e4dd0af9a15e53fef85c411ea1/xbox.py
We include this (and the math) library in our main file. To do this, we edit them and add the two import
commands to the code at the beginning.
sudo nano robot.py
1 2 |
import math import xbox |
Then you have to expand the code at the end. For this we create two functions, the explanation of which you can find below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
def moveByAxis(self, x, y): if x == 0.0 and y == 0.0: # nowhere to move, stop self.motor.stop() elif x == 0: # only forward / backward if y < 0: self.motor.backward() else: self.motor.forward() else: angle = math.degrees(math.atan(y/x)) angle += 180 if x < 0 else 360 angle = angle % 360 if angle == 0: self.motor.forwardRight() elif angle == 180: self.motor.forwardLeft() if angle > 0 and angle < 90: # forwardRight self.motor.forwardRight() time.sleep(self.motor.SEC_PER_TURN / 360.0 * angle) self.motor.forward() time.sleep(5.0 / self.motor.DIST_PER_SEC) # move 5cm forward elif angle > 90 and angle < 180: # forwardLeft angle -= 90 self.motor.forwardLeft() time.sleep(self.motor.SEC_PER_TURN / 360.0 * angle) self.motor.forward() time.sleep(5.0 / self.motor.DIST_PER_SEC) # move 5cm forward def xboxControl(self): joy = xbox.Joystick() while not joy.Back(): # button A to stop if joy.A(): self.motor.stop() else: # left joystick to move x, y = joy.leftStick() self.moveByAxis(x, y) joy.close() |
Save and exit with CTRL + O and CTRL + X.
The xboxControl
function is used to manage the keystrokes/movements of the joystick from the controller. Here we can call up certain functions if a key has been pressed. In our case, pressing the A button is supposed to stop the robot (even if the joystick is moved). If the button is not pressed, we want to control the robot with the help of the left joystick.
The actual movement takes place in the moveByAxis
function. If the joystick is in the middle (x = y = 0), the robot should stop, otherwise it should move in the specified direction. Since the code is pretty self-describing, I won’t go into it here. If you have a specific question, feel free to post it as a comment.
For the sake of completeness, it must be said that moving the joystick to the rear right or rear left has no associated movement, since I did not need it. If you want to integrate the functionality, you have to look at the angle analogous to the previous queries: This is between 180 and 270 if the stick is at the bottom left and between 270 and 360 in the lower right area.
Code Testing
Finally, of course, we also want to let the robot drive. Make sure the Xbox 360 controller is on and recognized (pressed buttons should appear):
sudo xboxdrv --detach-kernel-driver
If the entry is recognized, cancel with CTRL + C.
Now you open the Python console (sudo python
) and copy the following code into it:
1 2 3 4 5 6 7 8 9 10 |
from robot import Robot import time try: r=Robot() r.xboxControl() except Exception as e: print(e) finally: r.motor.stop() |
If everything works, you can control the robot remotely with the left joystick. In the following video you can see how I navigate my Raspberry Pi robot back and forth with the help of the Xbox 360 controller.
If you only want a short turn, the stick may only be turned briefly in this direction. Since it is sometimes not that easy to control the robot precisely, I designed the A button as a brake.
As an addition, the right controller can now, for example, turn a servo or stepper motor on which a live stream camera is attached.