<filename>monsterJoy.py
#!/usr/bin/env python
# coding: utf-8

# Load the libraries
import sys
import Gamepad
import time
sys.path.insert(0, "/home/pi/thunderborg")
import ThunderBorg

# Settings for the gamepad
gamepadType = Gamepad.PS4               # Class for the gamepad (e.g. Gamepad.PS3)
joystickSpeed = 'LEFT-Y'                # Joystick axis to read for up / down position
joystickSpeedInverted = True            # Set this to True if up and down appear to be swapped
joystickSteering = 'RIGHT-X'            # Joystick axis to read for left / right position
joystickSteeringInverted = False        # Set this to True if left and right appear to be swapped
buttonSlow = 'L2'                       # Joystick button for driving slowly whilst held
slowFactor = 0.5                        # Speed to slow to when the drive slowly button is held, e.g. 0.5 would be half speed
buttonFastTurn = 'R2'                   # Joystick button for turning fast
buttonExit = 'PS'                       # Joystick button to end the program
buttonFullBeamToggle = 'CROSS'          # Joystick button to toggle the LEDs between battery mode and fully white
interval = 0.05                         # Time between motor updates in seconds, smaller responds faster but uses more processor time

# Power settings
voltageIn = 1.2 * 10                    # Total battery voltage to the ThunderBorg
voltageOut = 12.0 * 0.95                # Maximum motor voltage, we limit it to 95% to allow the RPi to get uninterrupted power

# Setup the power limits
if voltageOut > voltageIn:
    maxPower = 1.0
else:
    maxPower = voltageOut / float(voltageIn)

# Setup the ThunderBorg
TB = ThunderBorg.ThunderBorg()
#TB.i2cAddress = 0x15                  # Uncomment and change the value if you have changed the board address
TB.Init()
if not TB.foundChip:
    boards = ThunderBorg.ScanForThunderBorg()
    if len(boards) == 0:
        print('No ThunderBorg found, check you are attached :)')
    else:
        print('No ThunderBorg at address %02X, but we did find boards:' % (TB.i2cAddress))
        for board in boards:
            print('    %02X (%d)' % (board, board))
        print('If you need to change the I²C address change the setup line so it is correct, e.g.')
        print('TB.i2cAddress = 0x%02X' % (boards[0]))
    sys.exit()
# Ensure the communications failsafe has been enabled!
failsafe = False
for i in range(5):
    TB.SetCommsFailsafe(True)
    failsafe = TB.GetCommsFailsafe()
    if failsafe:
        break
if not failsafe:
    print('Board %02X failed to report in failsafe mode!' % (TB.i2cAddress))
    sys.exit()

# Show battery monitoring settings
battMin, battMax = TB.GetBatteryMonitoringLimits()
battCurrent = TB.GetBatteryReading()
print('Battery monitoring settings:')
print('    Minimum  (red)     %02.2f V' % (battMin))
print('    Half-way (yellow)  %02.2f V' % ((battMin + battMax) / 2))
print('    Maximum  (green)   %02.2f V' % (battMax))
print('')
print('    Current voltage    %02.2f V' % (battCurrent))
print('')

# Setup the state shared with callbacks
global running
global fullBeam
running = True
fullBeam = False

# Create the callback functions
def exitButtonPressed():
    global running
    print('EXIT')
    running = False

def fullBeamButtonPressed():
    global fullBeam
    fullBeam = not fullBeam
    if fullBeam:
        TB.SetLedShowBattery(False)
        TB.SetLeds(1, 1, 1)
    else:
        TB.SetLedShowBattery(True)

# Wait for a connection
TB.MotorsOff()
TB.SetLedShowBattery(False)
TB.SetLeds(0, 0, 1)
waitingToggle = True
if not Gamepad.available():
    print('Please connect your gamepad...')
    while not Gamepad.available():
        time.sleep(interval * 4)
        waitingToggle = not waitingToggle
        if waitingToggle:
            TB.SetLeds(0, 0, 1)
        else:
            TB.SetLeds(0, 0, 0)
print('Gamepad connected')
gamepad = gamepadType()

# Start the background updating
gamepad.startBackgroundUpdates()
TB.SetLedShowBattery(True)

# Register the callback functions
gamepad.addButtonPressedHandler(buttonExit, exitButtonPressed)
gamepad.addButtonPressedHandler(buttonFullBeamToggle, fullBeamButtonPressed)

# Keep running while joystick updates are handled by the callbacks
try:
    while running and gamepad.isConnected():
        # Read the latest speed and steering
        if joystickSpeedInverted:
            speed = -gamepad.axis(joystickSpeed)
        else:
            speed = +gamepad.axis(joystickSpeed)
        if joystickSteeringInverted:
            steering = -gamepad.axis(joystickSteering)
        else:
            steering = +gamepad.axis(joystickSteering)

        # Work out the adjusted speed and steering
        if gamepad.isPressed(buttonSlow):
            finalSpeed = speed * slowFactor
        else:
            finalSpeed = speed
        if gamepad.isPressed(buttonFastTurn):
            finalSteering = steering * 2.0
        else:
            finalSteering = steering

        # Determine the drive power levels
        driveLeft = finalSpeed
        driveRight = finalSpeed
        if finalSteering < -0.05:
            # Turning left
            driveLeft *= 1.0 + finalSteering
        elif finalSteering > +0.05:
            # Turning right
            driveRight *= 1.0 - finalSteering

        # Set the motors to the new speeds
        TB.SetMotor1(driveRight * maxPower)
        TB.SetMotor2(driveLeft * maxPower)

        # Sleep for our motor change interval
        time.sleep(interval)
finally:
    # Ensure the background thread is always terminated when we are done
    gamepad.disconnect()

    # Turn the motors off
    TB.MotorsOff()

    # Set the LED to a dim red to indicate we have finished
    TB.SetCommsFailsafe(False)
    TB.SetLedShowBattery(False)
    TB.SetLeds(0.2, 0, 0)

<filename>monsterJoy.py
#!/usr/bin/env python
# coding: utf-8

# Load the libraries
import sys
import Gamepad
import time
sys.path.insert(0, "/home/pi/thunderborg")
import ThunderBorg

# Settings for the gamepad
gamepadType = Gamepad.PS4               # Class for the gamepad (e.g. Gamepad.PS3)
joystickSpeed = 'LEFT-Y'                # Joystick axis to read for up / down position
joystickSpeedInverted = True            # Set this to True if up and down appear to be swapped
joystickSteering = 'RIGHT-X'            # Joystick axis to read for left / right position
joystickSteeringInverted = False        # Set this to True if left and right appear to be swapped
buttonSlow = 'L2'                       # Joystick button for driving slowly whilst held
slowFactor = 0.5                        # Speed to slow to when the drive slowly button is held, e.g. 0.5 would be half speed
buttonFastTurn = 'R2'                   # Joystick button for turning fast
buttonExit = 'PS'                       # Joystick button to end the program
buttonFullBeamToggle = 'CROSS'          # Joystick button to toggle the LEDs between battery mode and fully white
interval = 0.05                         # Time between motor updates in seconds, smaller responds faster but uses more processor time

# Power settings
voltageIn = 1.2 * 10                    # Total battery voltage to the ThunderBorg
voltageOut = 12.0 * 0.95                # Maximum motor voltage, we limit it to 95% to allow the RPi to get uninterrupted power

# Setup the power limits
if voltageOut > voltageIn:
    maxPower = 1.0
else:
    maxPower = voltageOut / float(voltageIn)

# Setup the ThunderBorg
TB = ThunderBorg.ThunderBorg()
#TB.i2cAddress = 0x15                  # Uncomment and change the value if you have changed the board address
TB.Init()
if not TB.foundChip:
    boards = ThunderBorg.ScanForThunderBorg()
    if len(boards) == 0:
        print('No ThunderBorg found, check you are attached :)')
    else:
        print('No ThunderBorg at address %02X, but we did find boards:' % (TB.i2cAddress))
        for board in boards:
            print('    %02X (%d)' % (board, board))
        print('If you need to change the I²C address change the setup line so it is correct, e.g.')
        print('TB.i2cAddress = 0x%02X' % (boards[0]))
    sys.exit()
# Ensure the communications failsafe has been enabled!
failsafe = False
for i in range(5):
    TB.SetCommsFailsafe(True)
    failsafe = TB.GetCommsFailsafe()
    if failsafe:
        break
if not failsafe:
    print('Board %02X failed to report in failsafe mode!' % (TB.i2cAddress))
    sys.exit()

# Show battery monitoring settings
battMin, battMax = TB.GetBatteryMonitoringLimits()
battCurrent = TB.GetBatteryReading()
print('Battery monitoring settings:')
print('    Minimum  (red)     %02.2f V' % (battMin))
print('    Half-way (yellow)  %02.2f V' % ((battMin + battMax) / 2))
print('    Maximum  (green)   %02.2f V' % (battMax))
print('')
print('    Current voltage    %02.2f V' % (battCurrent))
print('')

# Setup the state shared with callbacks
global running
global fullBeam
running = True
fullBeam = False

# Create the callback functions
def exitButtonPressed():
    global running
    print('EXIT')
    running = False

def fullBeamButtonPressed():
    global fullBeam
    fullBeam = not fullBeam
    if fullBeam:
        TB.SetLedShowBattery(False)
        TB.SetLeds(1, 1, 1)
    else:
        TB.SetLedShowBattery(True)

# Wait for a connection
TB.MotorsOff()
TB.SetLedShowBattery(False)
TB.SetLeds(0, 0, 1)
waitingToggle = True
if not Gamepad.available():
    print('Please connect your gamepad...')
    while not Gamepad.available():
        time.sleep(interval * 4)
        waitingToggle = not waitingToggle
        if waitingToggle:
            TB.SetLeds(0, 0, 1)
        else:
            TB.SetLeds(0, 0, 0)
print('Gamepad connected')
gamepad = gamepadType()

# Start the background updating
gamepad.startBackgroundUpdates()
TB.SetLedShowBattery(True)

# Register the callback functions
gamepad.addButtonPressedHandler(buttonExit, exitButtonPressed)
gamepad.addButtonPressedHandler(buttonFullBeamToggle, fullBeamButtonPressed)

# Keep running while joystick updates are handled by the callbacks
try:
    while running and gamepad.isConnected():
        # Read the latest speed and steering
        if joystickSpeedInverted:
            speed = -gamepad.axis(joystickSpeed)
        else:
            speed = +gamepad.axis(joystickSpeed)
        if joystickSteeringInverted:
            steering = -gamepad.axis(joystickSteering)
        else:
            steering = +gamepad.axis(joystickSteering)

        # Work out the adjusted speed and steering
        if gamepad.isPressed(buttonSlow):
            finalSpeed = speed * slowFactor
        else:
            finalSpeed = speed
        if gamepad.isPressed(buttonFastTurn):
            finalSteering = steering * 2.0
        else:
            finalSteering = steering

        # Determine the drive power levels
        driveLeft = finalSpeed
        driveRight = finalSpeed
        if finalSteering < -0.05:
            # Turning left
            driveLeft *= 1.0 + finalSteering
        elif finalSteering > +0.05:
            # Turning right
            driveRight *= 1.0 - finalSteering

        # Set the motors to the new speeds
        TB.SetMotor1(driveRight * maxPower)
        TB.SetMotor2(driveLeft * maxPower)

        # Sleep for our motor change interval
        time.sleep(interval)
finally:
    # Ensure the background thread is always terminated when we are done
    gamepad.disconnect()

    # Turn the motors off
    TB.MotorsOff()

    # Set the LED to a dim red to indicate we have finished
    TB.SetCommsFailsafe(False)
    TB.SetLedShowBattery(False)
    TB.SetLeds(0.2, 0, 0)

#!/usr/bin/env python # coding: utf-8 # Load the libraries # Settings for the gamepad # Class for the gamepad (e.g. Gamepad.PS3) # Joystick axis to read for up / down position # Set this to True if up and down appear to be swapped # Joystick axis to read for left / right position # Set this to True if left and right appear to be swapped # Joystick button for driving slowly whilst held # Speed to slow to when the drive slowly button is held, e.g. 0.5 would be half speed # Joystick button for turning fast # Joystick button to end the program # Joystick button to toggle the LEDs between battery mode and fully white # Time between motor updates in seconds, smaller responds faster but uses more processor time # Power settings # Total battery voltage to the ThunderBorg # Maximum motor voltage, we limit it to 95% to allow the RPi to get uninterrupted power # Setup the power limits # Setup the ThunderBorg #TB.i2cAddress = 0x15                  # Uncomment and change the value if you have changed the board address # Ensure the communications failsafe has been enabled! # Show battery monitoring settings # Setup the state shared with callbacks # Create the callback functions # Wait for a connection # Start the background updating # Register the callback functions # Keep running while joystick updates are handled by the callbacks # Read the latest speed and steering # Work out the adjusted speed and steering # Determine the drive power levels # Turning left # Turning right # Set the motors to the new speeds # Sleep for our motor change interval # Ensure the background thread is always terminated when we are done # Turn the motors off # Set the LED to a dim red to indicate we have finished