RemoteTiltBorg - Control a PicoBorg robot using an XLoBorg

If you have two Raspberry Pis, and you like both PicoBorg and XLoBorg then we have something special for you today.
We have turned the XLoBorg into a remote tilt style controller for a PicoBorg based robot (such as PiCy), offering yet another way to control your robots.
To do this we have made RemoteTiltBorgC.py, a replacement for RemoteKeyBorgC.py which reads an XLoBorg instead of the keyboard.

Setting up the Raspberry Pi robot


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

Get the script running


Now we need to download the new script code onto the Raspberry Pi with the XLoBorg:
cd ~/xloborg
wget -O RemoteTiltBorgC.py http://www.piborg.org/downloads/RemoteTiltBorgC.txt
chmod +x RemoteTiltBorgC.py
Alternatively download the code here, and save the file as RemoteTiltBorgC.py in the ~/xloborg directory, on Linux you will also need to make the script executable
On line 11 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:
cd ~/xloborg
./RemoteTiltBorgC.py
You can download RemoteTiltBorgC.py as text here.
#!/usr/bin/env python
# coding: Latin-1

# Load library functions we want
import socket
import time
import XLoBorg
XLoBorg.Init()

# Settings for the RemoteTiltBorg 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.05                         # 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
thresholdOn = 0.4                       # Tilt level above which an axis is read as active
thresholdOff = 0.2                      # Tilt level below which an axis is read as inactive
filterLength = 5                        # Filter size, larger is smoother but slower to update

# Function used to provide a simple averaging window on a value
def BoxFilter(value, filterStorage):
    if len(filterStorage) == 0:
        # Setup the filter for first use
        for i in range(filterLength):
            filterStorage.append(value)
    else:
        # Insert the new value into the filter and remove the oldest
        filterStorage.pop()
        filterStorage.insert(0, value)
        # Generate a new average value
        value = 0.0
        divisor = float(len(filterStorage))
        for raw in filterStorage:
            value += raw / divisor
    return value

# 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)

try:
    # Set-up states
    moveLeft = False
    moveRight = False
    moveUp = False
    hadEvent = True
    filterX = []
    filterY = []
    filterZ = []
    print 'Press CTRL+C to quit'
    # Loop indefinitely
    while True:
        # Read the accelerometer and filter the results
        x, y, z = XLoBorg.ReadAccelerometer()
        x = BoxFilter(x, filterX)
        y = BoxFilter(y, filterY)
        z = BoxFilter(z, filterZ)
        # Check for movement
        if moveUp:
            if y < thresholdOff:
                hadEvent = True
                moveUp = False
        else:
            if y > thresholdOn:
                hadEvent = True
                moveUp = True
        if moveLeft:
            if x > -thresholdOff:
                hadEvent = True
                moveLeft = False
        else:
            if x < -thresholdOn:
                hadEvent = True
                moveLeft = True
        if moveRight:
            if x < thresholdOff:
                hadEvent = True
                moveRight = False
        else:
            if x > thresholdOn:
                hadEvent = True
                moveRight = True
        # Send an update if needed
        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 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))
Subscribe to Comments for &quot;RemoteTiltBorg - Control a PicoBorg robot using an XLoBorg&quot;