RemoteJoyBorg - Control a PicoBorg robot from a remote joystick
So you have seen RemoteKeyBorg and you have seen JoyBorg and wondered if you could put the two together, making a gamepad or joystick on another computer control a PicoBorg based robot using WiFi (or any other network connection).
Well it would seem a shame not to be able to, so we have made RemoteJoyBorgC.py, a replacement for RemoteKeyBorgC.py which reads a joystick or gamepad instead of the keyboard.
Since this script replaces the functionality of RemoteKeyBorgC.py, you will need to have RemoteKeyBorgS.py running on the Pi connected to your picoBorg.
Here's the code, you can download the RemoteKeyBorgS script file as text here.
Save the text file on your Raspberry Pi as RemoteKeyBorgS.py
Make the script executable using
and run on the Raspberry Pi with the PicoBorg using
This may also help if you are running Linux on another machine.
First plug the joystick into Raspberry Pi, this will be into a USB port from either the joysticks cable, or the wireless receiver.
You will now need to run the following to ensure the joystick drivers are installed:
Then you will want to run jstest as follows:
If you wiggle one of the analogue sticks up and down you should see output like:
In this case we can see axis 1 is moving, so that is our up/down axis, do the same thing for a left/right movement (they can be the same stick or different, which ever you prefer) and make a note of both numbers.
For those of you trying to get a PS3 controller to work, you will need a bluetooth dongle that the Raspberry Pi is happy with, and the process is a bit more involved.
We followed the guide here to get the PS3 controller to work properly, the axis numbers for the joysticks are:
First plug the joystick into your computer, making sure you install any necessary drivers.
You may need to guess which axis numbers correspond to which movements on the joystick, try numbers in sequential order starting from 0 and 1 if in doubt.
You will also need to install Python and pygame so the script can be run.
Now we have a working joystick, we need to download the script code:
However we will also need to change the settings (those numbers you remembered earlier).
Open RemoteJoyBorgC.py in a text editor, e.g.
On line 16,
If up / down seems to be swapped, change line 17 to read
On line 18,
If left / right seems to be swapped, change line 19 to read
Finally on line 10 make sure
Now we are all ready, run the script using:
on Linux or you favoured method under Windows.
You can download RemoteJoyBorgC.py as text here.
Well it would seem a shame not to be able to, so we have made RemoteJoyBorgC.py, a replacement for RemoteKeyBorgC.py which reads a joystick or gamepad instead of the keyboard.
Setting up the Raspberry Pi
Since this script replaces the functionality of RemoteKeyBorgC.py, you will need to have RemoteKeyBorgS.py running on the Pi connected to your picoBorg.
Here's the code, you can download the RemoteKeyBorgS script file as text here.
Save the text file on your Raspberry Pi as RemoteKeyBorgS.py
Make the script executable using
chmod +x RemoteKeyBorgS.py
and run on the Raspberry Pi with the PicoBorg using
sudo ./RemoteKeyBorgS.py
Connecting the joystick to a Raspberry Pi
This may also help if you are running Linux on another machine.
First plug the joystick into Raspberry Pi, this will be into a USB port from either the joysticks cable, or the wireless receiver.
You will now need to run the following to ensure the joystick drivers are installed:
sudo apt-get -y install joystick
Then you will want to run jstest as follows:
jstest /dev/input/js0
If you wiggle one of the analogue sticks up and down you should see output like:
In this case we can see axis 1 is moving, so that is our up/down axis, do the same thing for a left/right movement (they can be the same stick or different, which ever you prefer) and make a note of both numbers.
For those of you trying to get a PS3 controller to work, you will need a bluetooth dongle that the Raspberry Pi is happy with, and the process is a bit more involved.
We followed the guide here to get the PS3 controller to work properly, the axis numbers for the joysticks are:
- Left stick left/right: 0
- Left stick up/down: 1
- Right stick left/right: 2
- Right stick up/down: 3
Connecting the joystick to a Windows based machine
First plug the joystick into your computer, making sure you install any necessary drivers.
You may need to guess which axis numbers correspond to which movements on the joystick, try numbers in sequential order starting from 0 and 1 if in doubt.
You will also need to install Python and pygame so the script can be run.
Get the script running
Now we have a working joystick, we need to download the script code:
cd ~ wget -O RemoteJoyBorgC.py http://www.piborg.org/downloads/RemoteJoyBorgC.txt chmod +x RemoteJoyBorgC.pyAlternatively download the code here, and save the file as RemoteJoyBorgC.py, on Linux you will also need to make the script executable
However we will also need to change the settings (those numbers you remembered earlier).
Open RemoteJoyBorgC.py in a text editor, e.g.
nano RemoteJoyBorgC.py
On line 16,
axisUpDown
should be changed to the first number you noted earlier, e.g. axisUpDown = 0
if 0 is the axis which changed when moving up and down.If up / down seems to be swapped, change line 17 to read
axisUpDownInverted = True
instead.On line 18,
axisLeftRight
should be changed to the second number you noted earlier, e.g. axisLeftRight = 1
if 1 is the axis which changed when moving left and right.If left / right seems to be swapped, change line 19 to read
axisLeftRightInverted = True
instead.Finally on line 10 make sure
broadcastIP
is set to the correct IP address for the Raspberry Pi running RemoteKeyBorgS.py, e.g. broadcastIP = '192.168.0.15'
, you can use '255' for the last number to make it talk to any address that matches the first 3 numbers, assuming your network permits broadcasting.Now we are all ready, run the script using:
~/RemoteJoyBorgC.py
on Linux or you favoured method under Windows.
The source
You can download RemoteJoyBorgC.py as text here.
#!/usr/bin/env python # coding: Latin-1 # Load library functions we want import socket import time import pygame # Settings for the RemoteJoyBorg client broadcastIP = '192.168.0.255' # IP address to send to, 255 in one or more positions is a broadcast / wild-card broadcastPort = 9038 # What message number to send with leftDrive = 1 # Drive number for left motor rightDrive = 4 # Drive number for right motor interval = 0.1 # Time between updates in seconds, smaller responds faster but uses more processor time regularUpdate = True # If True we send a command at a regular interval, if False we only send commands when keys are pressed or released axisUpDown = 1 # Joystick axis to read for up / down position axisUpDownInverted = False # Set this to True if up and down appear to be swapped axisLeftRight = 3 # Joystick axis to read for left / right position axisLeftRightInverted = False # Set this to True if left and right appear to be swapped # Setup the connection for sending on sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # Create the socket sender.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Enable broadcasting (sending to many IPs based on wild-cards) sender.bind(('0.0.0.0', 0)) # Set the IP and port number to use locally, IP 0.0.0.0 means all connections and port 0 means assign a number for us (do not care) # Setup pygame and key states global hadEvent global moveUp global moveDown global moveLeft global moveRighte global moveQuit hadEvent = True moveUp = False moveDown = False moveLeft = False moveRight = False moveQuit = False pygame.init() pygame.joystick.init() joystick = pygame.joystick.Joystick(0) joystick.init() screen = pygame.display.set_mode([300,300]) pygame.display.set_caption("RemoteKeyBorg - Press [ESC] to quit") # Function to handle pygame events def PygameHandler(events): # Variables accessible outside this function global hadEvent global moveUp global moveDown global moveLeft global moveRight global moveQuit # Handle each event individually for event in events: if event.type == pygame.QUIT: # User exit hadEvent = True moveQuit = True elif event.type == pygame.KEYDOWN: # A key has been pressed, see if it is one we want hadEvent = True if event.key == pygame.K_ESCAPE: moveQuit = True elif event.type == pygame.KEYUP: # A key has been released, see if it is one we want hadEvent = True if event.key == pygame.K_ESCAPE: moveQuit = False elif event.type == pygame.JOYAXISMOTION: # A joystick has been moved, read axis positions (-1 to +1) hadEvent = True upDown = joystick.get_axis(axisUpDown) leftRight = joystick.get_axis(axisLeftRight) # Invert any axes which are incorrect if axisUpDownInverted: upDown = -upDown if axisLeftRightInverted: leftRight = -leftRight # Determine Up / Down values if upDown < -0.1: moveUp = True moveDown = False elif upDown > 0.1: moveUp = False moveDown = True else: moveUp = False moveDown = False # Determine Left / Right values if leftRight < -0.1: moveLeft = True moveRight = False elif leftRight > 0.1: moveLeft = False moveRight = True else: moveLeft = False moveRight = False try: print 'Press [ESC] to quit' # Loop indefinitely while True: # Get the currently pressed keys on the keyboard PygameHandler(pygame.event.get()) if hadEvent or regularUpdate: # Keys have changed, generate the command list based on keys hadEvent = False driveCommands = ['X', 'X', 'X', 'X'] # Default to do not change if moveQuit: break elif moveLeft: driveCommands[leftDrive - 1] = 'OFF' driveCommands[rightDrive - 1] = 'ON' elif moveRight: driveCommands[leftDrive - 1] = 'ON' driveCommands[rightDrive - 1] = 'OFF' elif moveUp: driveCommands[leftDrive - 1] = 'ON' driveCommands[rightDrive - 1] = 'ON' else: # None of our expected keys, stop driveCommands[leftDrive - 1] = 'OFF' driveCommands[rightDrive - 1] = 'OFF' # Send the drive commands command = '' for driveCommand in driveCommands: command += driveCommand + ',' command = command[:-1] # Strip the trailing comma sender.sendto(command, (broadcastIP, broadcastPort)) # Wait for the interval period time.sleep(interval) # Inform the server to stop sender.sendto('ALLOFF', (broadcastIP, broadcastPort)) except KeyboardInterrupt: # CTRL+C exit, inform the server to stop sender.sendto('ALLOFF', (broadcastIP, broadcastPort))