Archive for the ‘python’ Category

Award Winning FIRST Robotics Robot Control Interface

Monday, April 8th, 2013

KwarqsDashboard is an award-winning control system developed in 2013 for FIRST Robotics Team 2423, The Kwarqs. For the second year in a row, Team 2423 won the Innovation in Control award at the 2013 Boston Regional. The judges cited this control system as the primary reason for the award.

It is designed to be used with a touchscreen, and robot operators use it to select targets and fire frisbees at the targets. Check out the shiny screenshot below:

Kwarqs Dashboard ScreenshotThere are a lot of really useful features that we built into this control interface, and once we got our mechanical and electrical bugs ironed out the robot was performing quite well. We’re looking forward to competing with it at WPI Battle Cry 2013 in May!  Here’s a list of some of the many features it has:

  • Written entirely in Python
    • Image processing using OpenCV python bindings, GUI written using PyGTK
    • Cross platform, fully functional in Linux and Windows 7/8
  • All control/feedback features use NetworkTables, so the same robot can be controlled using the SmartDashboard instead if needed
    • SendableChooser compatible implementation for mode switching
  • Animated robot drawing that shows how many frisbees are present, and tilts the shooter platform according to the current angle the platform is actually at.
  • Allows operators to select different modes of operation for the robot using brightly lit toggle switches
  • Operators can choose an autonomous mode on the dashboard, and set which target the robot should aim for in modes that use target tracking
  • Switches operator perspective when robot switches modes
  • Simulated lighted rocker switches to activate robot systems
  • Logfiles written to disk with errors when they occur

Target acquisition image processing features:

  • Tracks the selected targets in a live camera stream, and determines adjustments the robot should make to aim at the target
  • User can click on targets to tell the robot what to aim at
  • Differentiates between top/middle/low targets
  • Partially obscured targets can be identified
  • Target changes colors when the robot is aimed properly

Fully integrated realtime analysis support for target acquisition:

  •  Adjustable thresholding, saves settings to file
  • Enable/disable drawing features and labels on detected targets
  • Show extra threshold images
  • Can log captured images to file, once per second
  • Can load a directory of images for analysis, instead of connecting to a live camera

So, as you can see, lots of useful things. We’re releasing the full source code for it under a GPL license, so go ahead, download it, play with it, and let me know what you think! Hope you find this useful.

A lot of people made this project possible:

  • Some code structuring ideas and PyGTK widget ideas were derived from my work with Exaile
  • Team 341 graciously open sourced their image processing code in 2012, and the image processing is heavily derived from a port of that code to python.
  • Sam Rosenblum helped develop the idea for the dashboard, and helped refine some of the operating concepts.
  • Stephen Rawls helped refine the image processing code and distance calculations.
  • Youssef Barhomi created image processing stuff for the Kwarqs in 2012, and some of the ideas from that code were copied.

The included images were obtained from various places:

  • Linda Donoghue created the robot image
  • The fantastic lighted rocker switches were created by Keith Sereby, and are distributed with permission.
  • The green buttons were obtained via google image search, I don’t recall where

Download it on my FRC resources page!

Problems with file descriptors being inherited by default in Python

Wednesday, February 6th, 2013

Have you ever run into a traceback that ends with something like this?

  File "C:\Python27\lib\logging\handlers.py", line 141, in doRollover
    os.rename(self.baseFilename, dfn)
WindowsError: [Error 32] The process cannot access the file because it is being used by another process

I certainly have, in a few places. The basic problem is that when python creates file objects on Windows (and I think on *nix as well), by default Python will mark the handle as being inheritable (I’m sure there’s a reason why… but, doesn’t make a whole lot of sense for this to be the default behavior to me). So if your script spawns a new process, that new process will inherit all the file handles from your script — and of course since it doesn’t realize that it even has those handles, it’ll never close them. A great example of this is launching a process, then exiting. When you launch your script again and try to open that handle… the other process still has it open, and depending on how the file was opened, you may not be able to open it due to a sharing violation.

It looks like they’re trying to provide ways to fix the problem in PEP 433 for Python 3.3, but that doesn’t help those of us still using Python 2.7. Here’s a snippet that you can put at the very beginning of your script to fix this problem on Windows:

import sys

if sys.platform == 'win32':
    from ctypes import *
    import msvcrt
    
    __builtins__open = __builtins__.open
    
    def __open_inheritance_hack(*args, **kwargs):
        result = __builtins__open(*args, **kwargs)
        handle = msvcrt.get_osfhandle(result.fileno())
        windll.kernel32.SetHandleInformation(handle, 1, 0)
        return result
        
    __builtins__.open = __open_inheritance_hack

Now, I admit, this is a bit of a hack… but it solves the problem for me. Hope you find this useful!

Drawing in color in PyGTK

Monday, October 15th, 2012

I’ve been playing with drawing on your own widgets in PyGTK on Windows, and I found it incredibly difficult to figure out how to draw something in color on a gtk.gdk.Drawable object using draw_line, draw_rectangle, etc. You can’t just set the color using the semi-obvious mechanism:

    gc = widget.window.new_gc()
    gc.set_foreground(gtk.gdk.Color(255,0,0))

I think the reason it doesn’t work is because if the color isn’t in the device-specific colormap, then GTK will ignore whatever color you set without bothering to warn you that something is wrong. However, I’ve finally hit on something that works. In your expose event (or elsewhere), you can put in something like the following:

    def on_expose_event(self, widget, event):

        gc = widget.window.new_gc()
        colormap = self.gc.get_colormap()
        color = colormap.alloc_color('yellow')
        gc.set_foreground(color)

        # whatever gtk.gdk.Drawable draw_* functions you call here
        # will use that color

Hope you find this useful!

BPM Counter Plugin for Exaile 0.3.2

Monday, October 3rd, 2011

I’ve been starting to use my desktop machine at home a lot lately, so I’ve been looking for a cross-platform audio player that I can use that doesn’t annoy me. After a long search (and discarding most of the linux audio players: amarok, banshee, etc as too annoying or not the right features or whatever) I finally stumbled across Exaile, which not only doesn’t annoy me greatly, but it’s written in python so its way easy to modify and figure out what it does :)

I’ve been doing a bit of swing dancing lately (in particular Lindy Hop), so I’ve been gathering music together to listen to, and I need BPM for the music… one thing Exaile did not already have was a BPM counter, so I wrote a manual beat counter for it. You can write plugins for Exaile, though the documentation is rather sparse. I must say though, using the GLADE widget editor thing has to be the most annoying GUI design tool ever…


Download it at my usual software site.

PS: In case anyone asks, I’m not interested in writing an automated beat counter… this works well enough for me :)

Winpdb Remote Debugger for Python ported to RobotPy on vxWorks

Tuesday, January 11th, 2011

I’m really excited about the idea of using python on our FIRST Robotics Team’s Robot this year, and one of the first things that got really annoying was the lack of debugging capability, since vxWorks doesn’t really have a console (I mean it does, but in the way that FRC has it setup, its not really a console in the traditional sense of the word). So I searched around and found Winpdb, a pretty neat remote debugger for python. So after playing with it for a bit, I’ve got it working on RobotPy and it seems to do the trick so far. :)

I’ll be creating some other tools as needed, so watch for more python in the future!

Download: http://www.virtualroadside.com/FRC/

cRio Netconsole implemented in Python

Friday, November 12th, 2010

The FIRST Robotics Competition uses the NI-cRio platform for the controller for the robots in the competition. There is a bit of functionality called ‘NetConsole’ which sends the stdout from vxWorks out to a waiting client (refer to the WPI FIRST website for instructions to enable this). It turns out that the protocol used to implement the NetConsole for the cRio is incredibly simple… it just sends the raw output data as a bunch of UDP packets out to the broadcast address on port 6666 (which I suppose is slightly amusing). Here’s a dirt-simple python script that catches the output (TODO: need to send it input… haven’t gotten around to looking at that yet).

#!/usr/bin/env python

import socket
import select

UDP_PORT=6666

sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP )

sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind( ('',UDP_PORT) )
sock.setblocking(0)

while True:
    result = select.select( [sock], [], [] )
    msg = result[0][0].recv( 8196 )
    print msg