Hey, I’ve been playing with RobotPy quite a bit lately, and one thing you’ll probably note is that debugging scripts is a bit annoying. Ok, more than just a bit annoying… haha. Anyways, here’s a great solution to solve that problem! Winpdbis a GPL remote debugger that works pretty well from what I can see so far, and gives you full source debugging over the network. I’ve modified it a bit so that it works on RobotPy. Check it out:
Speaking of debugging, have you found a way to compile and check your scripts before running on the robot?
In Java NetBeans would compile our code locally and show where we had syntax errors or improper API calls, but with Python we don’t find this out until runtime. This makes it hard to work on code when there is no robot access, since someone’s usually working on it mechanically.
So far I can check syntax with:
python3.1 -c “import py_compile; py_compile.compile(‘robot.py’)”
However that does not seem to catch many of the problems we’ll run into, like misspelling function names and other common errors.
Indeed that’s the downside of using a dynamic language… static analysis is pretty much impossible (look up the halting problem). The long term solution will be a robot simulator (written in Python?) that provides an emulated Python wpilib so you can test your code offline. I’ve started looking at this but it’s a pretty large project (the simulator is hard enough but there’s also a LOT of wpilib classes to write emulated versions of).
#This file should emulate enough of wpilib to make it usable for testing
#DONE: use pygame to get joystick inputs from actual joysticks
print("="*40)
print("TESTING.PY LOADED, IF THIS IS ON THE ROBOT CALL SAM *NOW*")
print("NNN NNN NNNN")
print("="*40)
try:
import pygame
import pygame.joystick
pygame.init()
print(str(pygame.joystick.get_count()) + " Joysticks attatched")
new = True
except:
new = False
print ("NO PYGAME FOUND")
def limit(n):
if n > 1.0:
return 1.0
elif n < -1.0:
return -1.0
else:
return n
class Victor:
def __init__(self, port):
self.port = port
print("Virtual Victor set up on port " + str(port))
self.speed = float()
def Set(self, speed):
"""***FOR TESTING PURPOSES ONLY***
This "sets" the virtual Victor to any arbitrary speed"""
speed = limit(speed)
print("on port " + str(self.port) + " the speed is now " + str(speed))
self.speed = speed
def Get(self):
"""***FOR TESTING PURPOSES ONLY***
This emulates the wpilib.Victor.Get function"""
return self.speed
class Joystick_old:
def __init__(self, port):
self.port = port
print("New FAKE joystick set up at port "+str(port))
def GetRawAxis(self, n):
return float()
def GetRawButton(self, n):
return False
class Joystick_pygame:
def __init__(self, port):
self.port = port -1
self.joy = pygame.joystick.Joystick(port-1)
self.joy.init()
print("made new pygame joystick on port " + str(port))
print(self.joy.get_name())
def GetRawAxis(self, n):
pygame.event.pump()
return self.joy.get_axis(n-1)
def GetRawButton(self, n):
pygame.event.pump()
r = self.joy.get_button(n-1)
if r == 1:
return True
else:
return False
def Joystick(port):
if new:
print("trying to use awesomesauce new features")
try:
print ("can use awesome features")
return Joystick_pygame(port)
except:
print ("cannot use awesome new features")
return Joystick_old(port)
else:
print ("cannot use awesome new features")
return Joystick_old(port)
def speedReport(list_obj):
"""Use this for the driver object"""
for n in list_obj:
n.Get()
def IsDisabled():
return False
def IsAutonomous():
return False
def IsOperatorControl():
return True
def IsEnabled():
return True
class dummyDog:
def SetEnabled(self, var):
pass
def SetExpiration(self, var):
pass
def Feed(self):
pass
def Kill(self):
pass
def GetWatchdog():
return dummyDog()
def Wait(n):
pass
class Solenoid:
def __init__(self, slot, port):
self.slot = slot
self.port = port
print("Solenoid set up on slot " + str(slot) + " port " + str(port))
def Get(self):
return self.state
def Set(self, state):
self.state = state
if state:
print("port " + str(self.port) + " active")
else:
print("port " + str(self.port) + " inactive")
class Relay:
def __init__(self, port):
self.port = port
print("Relay set up on port " + str(port))
self.kForward = 1
self.kOff = 2
self.kReverse = 3
def Get(self):
pass
def Set(self, value):
if value == self.kForward:
print("relay forward")
elif value == self.kOff:
print ("relay off")
elif value == self.kReverse:
print ("relay backwards")
class Compressor:
def __init__(self, port1, port2):
pass
def Start(self):
print ("compressor on")
def Stop(self):
print ("compressor off")
class SimpleRobot():
def StartCompetition():
run_old()
edit:
Wow, i was high when i wrote this, pasted wrong file