ReverseJoyBorg - Control a PiCy Type R from a remote joystick
So you have used ReverseKeyBorg to turn your PiCy into a PiCy Type R, but now you want to be able to use a joystick like with RemoteJoyBorg.
Well it looks like another PicoBorg script needs to be upgraded to Type R ^_^.
If you have not already used RemoteJoyBorg you should go through the joystick setup instructions, run through the Setting up the Raspberry Pi and either Connecting the joystick to a Raspberry Pi or Connecting the joystick to a Windows based machine as needed.
If you have already used RemoteJoyBorg, you will want to make a note of your settings (the
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 ReverseJoyBorgC.py in a text editor, e.g.
On line 18,
If up / down seems to be swapped, change line 19 to read
On line 20,
If left / right seems to be swapped, change line 21 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.
The settings in ReverseJoyBorgC.py are similar to RemoteKeyBorgC.py, if the communications are not working you may need to change the network settings as outlined in RemoteKeyBorg, note that some of the line numbers will be close but different.
If motors are turning the wrong way, the following procedure should correct the problem:
If you have problems with the Raspberry Pi restarting when you try and move a motor, you may need to add resistors in series with the motors as shown in the main PiCy article.
You can download ReverseJoyBorgC.py as text here.
If you have not already used RemoteJoyBorg you should go through the joystick setup instructions, run through the Setting up the Raspberry Pi and either Connecting the joystick to a Raspberry Pi or Connecting the joystick to a Windows based machine as needed.
If you have already used RemoteJoyBorg, you will want to make a note of your settings (the
axis*
values) to copy them to this version.Get the script running
Now we have a working joystick, we need to download the script code:
cd ~ wget -O ReverseJoyBorgC.py http://www.piborg.org/downloads/ReverseJoyBorgC.txt chmod +x ReverseJoyBorgC.pyAlternatively download the code here, and save the file as ReverseJoyBorgC.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 ReverseJoyBorgC.py in a text editor, e.g.
nano ReverseJoyBorgC.py
On line 18,
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 19 to read
axisUpDownInverted = True
instead.On line 20,
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 21 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:
~/ReverseJoyBorgC.py
on Linux or you favoured method under Windows.
If your Type R does not work correctly T_T
The settings in ReverseJoyBorgC.py are similar to RemoteKeyBorgC.py, if the communications are not working you may need to change the network settings as outlined in RemoteKeyBorg, note that some of the line numbers will be close but different.
If motors are turning the wrong way, the following procedure should correct the problem:
- Press and hold the joystick up:
- If no motors move the
axisUpDown
andaxisLeftRight
are probably set to the wrong values, run through the joystick procedure listed here. - If the left wheel goes the wrong way, swap the drive numbers for
leftDrivePos
andleftDriveNeg
. - If the right wheel goes the wrong way, swap the drive numbers for
rightDrivePos
andrightDriveNeg
. - If you made any changes, re-run the script and try again, if problems persist swap
leftDrivePos
withrightDrivePos
andleftDriveNeg
withrightDriveNeg
and start from the top of this list again.
- If no motors move the
- Press and hold the joystick left, if the left wheel is going forward (PiCy rotates to the right) swap
leftDrivePos
withrightDrivePos
andleftDriveNeg
withrightDriveNeg
and start from the top of this list again.
If you have problems with the Raspberry Pi restarting when you try and move a motor, you may need to add resistors in series with the motors as shown in the main PiCy article.
The source
You can download ReverseJoyBorgC.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 ReverseJoyBorg 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 leftDrivePos = 1 # Drive number for left motor positive relay leftDriveNeg = 2 # Drive number for left motor negative relay rightDrivePos = 3 # Drive number for right motor positive relay rightDriveNeg = 4 # Drive number for right motor negative relay 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 moveRight 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: # Left in reverse, right in forward driveCommands[leftDrivePos - 1] = 'OFF' driveCommands[leftDriveNeg - 1] = 'ON' driveCommands[rightDrivePos - 1] = 'ON' driveCommands[rightDriveNeg - 1] = 'OFF' elif moveRight: # Left in forward, right in reverse driveCommands[leftDrivePos - 1] = 'ON' driveCommands[leftDriveNeg - 1] = 'OFF' driveCommands[rightDrivePos - 1] = 'OFF' driveCommands[rightDriveNeg - 1] = 'ON' elif moveUp: # Both in forward driveCommands[leftDrivePos - 1] = 'ON' driveCommands[leftDriveNeg - 1] = 'OFF' driveCommands[rightDrivePos - 1] = 'ON' driveCommands[rightDriveNeg - 1] = 'OFF' elif moveDown: # Both in reverse driveCommands[leftDrivePos - 1] = 'OFF' driveCommands[leftDriveNeg - 1] = 'ON' driveCommands[rightDrivePos - 1] = 'OFF' driveCommands[rightDriveNeg - 1] = 'ON' else: # None of our expected keys, stop driveCommands[leftDrivePos - 1] = 'OFF' driveCommands[leftDriveNeg - 1] = 'OFF' driveCommands[rightDrivePos - 1] = 'OFF' driveCommands[rightDriveNeg - 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))