<!> Totally outdated page <!>


USB toolbox benchmark results

These figures are based on prototypes versions with beta status. They were of course executed on the same machine. Also I tried to make sure that the libraries were already loaded into memory. (29.4.2008)

--- New USB Benchmark (Windows) ---
Playing 400 tones
............done
2.1ms per tone, 471.9 tones per second
Getting 100 light values
............done
4.7ms per reading, 214.5 readings per second
Getting 100 motor values
............done
5.7ms per reading, 174.0 readings per second
Getting 100 ultrasonic values
............done
8.0ms per reading, 124.7 readings per second
--- New USB Benchmark (Linux) ---
Playing 400 tones
............done
4.1ms per tone, 245.2 tones per second
Getting 100 light values
............done
6.7ms per reading, 149.0 readings per second
Getting 100 motor values
............done
7.6ms per reading, 131.9 readings per second
Getting 100 ultrasonic values
............done
18.5ms per reading, 54.1 readings per second


Some USB / Linux related things to read

Latest news (March 29th, 2008)

  • (!) Yeah, first working demo in my branch (see source:branches/atorf/USB_Development changeset [22]). Official LEGO Mindstorms NXT drivers ver 1.02 are needed. So fantom.dll has made the race it seems.
  • Tested only direct command PlayTone?. Performance: ~3ms per call without requesting reply. Sending and collecting answers takes about 6ms. So we got a performance boost factor of 10 right now {OK}

Btw, I couldn't get NXT_Python to work, libusb reported error: (forgot to log, something like this): Error in usb_reap. I had the same problem using libusb in Matlab…:

Old news (March 12th, 2008)

Nothing seems to work, read this first: http://www.beyondlogic.org/usbnutshell/usb4.htm

Try to download USB sniffers, Debuggers, Stacktracers etc. Also have a look at "linxt" and the impressing Delphi-Source of "NXTCntPnl_src".

Both methods use pre-compiled, platform-dependent DLLs and according header-files, to interface to these DLLs with the loadlibrary()-function.

  • Either use the free API "usblib" to interface directly with the USB DLLs from MATLAB and then use bulk_write and bulk_read, similar to Python_NXT's implementation (see below).
    Libusb in MATLAB works now. Enumerating devices and so on. First bulk_write with NXT_PlayTone shouldn't be a big problem now!
  • Or use THIS code, which provides a direct interface to the NXT's installed USB driver / protocol called Fantom. Looks promising, however no easy wrapper can could be used: The ready-compiled binary packages, that we are transferring to BT_SendPacket would have to be unwrapped again and passed to the according function — if no function like "bulk_write" is present in the fantom.dll. See Fantom SDK.
    http://forums.nxtasy.org/index.php?showtopic=2018


Previus ("old") information

  • Calling Python from MATLAB using system() is too slow, about 200ms for each call.
  • We only need USB methods to find devices and send/read data using sendBulkData and readBulkData
  • Under Linux, try to accesss NXT directly as file handle: /dev/usb/NXT?
  • Use C(++) to produce win and linux code (compile using g++), then compile to mex? Fastet and "professional" way
  • For Windows, use USB API
  • For Linux, look inside Python implementation, use same libs
  • For Linux, look here: http://www.linuxforen.de/forums/showthread.php?t=157913
  • Use Java with jUSB, try to interface DIRECTLY with MATLAB? Probably best, if fast enough: 1 Code for all platforms, no binaries
  • Java-USB-Doc for Win: http://jusb.sourceforge.net/apidoc/usb/windows/DeviceImpl.html
  • Try to "rip" code from Instrument Control Toolbox, or use it directly?
  • Create simple USB↔UDP wrapper in Python? Needs open IP ports unfortunately
  • Find a way to compile Perl or Python to .dll or libs, and then (or directly) to .mex?
  • Most tricky / fastest way: Use /dev/usb/NXT in Linux if possible, use virtual comport → NXT in Windows

Read THIS: http://today.java.net/pub/a/today/2006/07/06/java-and-usb.html

Virtual COMPort links:
http://www.ftdichip.com/Drivers/VCP.htm ??
http://members.aol.com/idinnov/idi-00000e.htm ?
http://www.softplatz.com/software/usb-virtual-driver/ ?

Taken from the free Perl::NXT implementation on http://nxt.ivorycity.com :

package LEGO::NXT::USBComm;

use Device::USB;
use LEGO::NXT::Constants;
use strict;

=head1 NAME

LEGO::NXT::USBComm - The USB Communication Module For the NXT 

=head1 SYNOPSIS

  use LEGO::NXT::USBComm;

  $comm = new LEGO::NXT::USBComm();

=head1 DESCRIPTION

Presents a USB comm interface to the LEGO NXT for internal use in the L<LEGO::NXT> module.

=cut

my $USB_ID_VENDOR_LEGO = 0x0694;
my $USB_ID_PRODUCT_NXT = 0x0002;
my $USB_OUT_ENDPOINT   = 0x01;
my $USB_IN_ENDPOINT    = 0x82;
my $USB_TIMEOUT        = 1000;
my $USB_READSIZE       = 64;
my $USB_INTERFACE      = 0;

=head1 METHODS

=head2 new

  $interface = 0; 
  $comm = new LEGO::NXT:USBComm($interface) 
  $nxt = LEGO::NXT->new( $comm );

Creates a new USB comm object. $interface will usually be 0 unless you're using more than one NXT. 

=cut

sub new
{
  my ($pkg,$interface) = @_;

  my $this = {
    'interface'   => $interface || $USB_INTERFACE,
    'fh'          => undef ,
    'device_name' => undef ,
    'id'          => undef ,
    'serial'      => undef ,
    'status'    => 0
  };

  bless $this, $pkg;
  $this;
}


sub connect
{ 
  my ($this) = @_;
 
  my $usb = Device::USB->new();

  my $dev = $usb->find_device($USB_ID_VENDOR_LEGO, $USB_ID_PRODUCT_NXT);
     die "Device not found.\n" unless defined $dev;

  $dev->open();
  $dev->reset();

  $this->{device_name} = $dev->filename();
  $this->{id}          = sprintf("%04x:%04x", $dev->idVendor(), $dev->idProduct() );
  $this->{serial}      = $dev->serial_number();

  $dev->claim_interface($USB_INTERFACE);
  $this->{fh} = $dev;
  $|=1; #HOT PIPES
  $dev;
}

sub do_cmd
{
  my ($this,$request,$needsret) = @_;

  $this->connect unless $this->{fh};

  my $dev = $this->{fh};

  $dev->bulk_write($USB_OUT_ENDPOINT, $request, length($request), $USB_TIMEOUT);

  return if( $needsret == $NXT_NORET );

  my $buf = "\0" x $USB_READSIZE;
  my $response ='';
  my $len;
  my $nread;
  $|=1; 

  $dev->bulk_read($USB_IN_ENDPOINT, $buf, $USB_READSIZE, $USB_TIMEOUT);

  $buf;  
}



sub type { 'usb' }

1;

Taken from the free python implementation NXT_Python, http://home.comcast.net/~dplau/nxt_python/index.html

# nxt.usbsock module -- USB socket communication with LEGO Minstorms NXT
# Copyright (C) 2006-2007  Douglas P Lau
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

import usb
from nxt.brick import Brick

ID_VENDOR_LEGO = 0x0694
ID_PRODUCT_NXT = 0x0002

class USBSock(object):

        bsize = 60      # USB socket block size

        def __init__(self, device):
                self.device = device
                self.handle = None
                self.debug = False

        def __str__(self):
                return 'USB (%s)' % (self.device.filename)

        def connect(self):
                config = self.device.configurations[0]
                iface = config.interfaces[0][0]
                self.blk_out, self.blk_in = iface.endpoints
                self.handle = self.device.open()
                self.handle.setConfiguration(1)
                self.handle.claimInterface(0)
                self.handle.reset()
                return Brick(self)

        def close(self):
                self.device = None
                self.handle = None
                self.blk_out = None
                self.blk_in = None

        def send(self, data):
                if self.debug:
                        print 'Send:',
                        print ':'.join('%02x' % ord(c) for c in data)
                self.handle.bulkWrite(self.blk_out.address, data)

        def recv(self):
                data = self.handle.bulkRead(self.blk_in.address, 64)
                if self.debug:
                        print 'Recv:',
                        print ':'.join('%02x' % (c & 0xFF) for c in data)
                # NOTE: bulkRead returns a tuple of ints ... make it sane
                return ''.join(chr(d & 0xFF) for d in data)

def find_bricks(host=None, name=None):
        # FIXME: probably should check host and name
        for bus in usb.busses():
                for device in bus.devices:
                        if device.idVendor == ID_VENDOR_LEGO and \
                           device.idProduct == ID_PRODUCT_NXT:
                                yield USBSock(device)

Last modified 9 years ago Last modified on Dec 7, 2009, 3:57:42 PM