Category Archives: Programming

Adafruit Bluefruit LE Micro into Wowwee Robosapien

I bought an Arduino Micro for a project a little while ago, found it easy to develop with and wondered where else I could use one. There are two Robosapiens in our house, so one of them went under the knife for a brain transplant. I chose an Adafruit Bluefruit LE Micro this time, so I could disconnect the USB cable and control the Robosapien over Bluetooth.

The Robosapien’s getting on in years and resources explaining what’s inside it are disappearing from the WWW. Markcra’s Robosapien pages are an invaluable starting point, though I never did find a complete list of pinouts for the U2 controller IC. Here’s the list I used while adding the wire extensions for the prototyping board:

U2 pin Connected to
P10 IR
P11 Finger/toe/heel switches left
P12 Grip switch left
P13 Shoulder switch left
P14 Finger/toe/heel switches right
P15 Grip switch right
P16 Shoulder switch right
P17 Microphone
P20 LED
P21 LED
P22 LED
P23 LED
P24 LED
P25 LED
P26 LED
P27 LED
P30 Grip motor open left
P31 Grip motor close left
V01 Speaker
V02 ?
P32 Shoulder motor left
P33 Shoulder motor leftexpecting to be able to
P34 Grip motor open right
P35 Grip motor open right
P36 Shoulder motor right
P37 Shoulder motor right
P40 Waist left
P41 Waist right
P42 Leg motor left
P43 Leg motor left
P44 Leg motor right
P45 Leg motor right
P46 ?
P47 ?

“Left” and “right” are from the Robosapien’s point of view. With 31 lines of I/O before any enhancements might be considered, I had to add some extra I/O in the form of 2 MCP23S17 SPI I/O Expanders. The Bluefruit LE Micro uses SPI to communicate with its Bluetooth module, so adding the MCP23S17s was straightforward. I failed to get a single CS (Chip Select) line to work with HAEN (Hardware Address ENable) set on the MCP23S17s, but one CS pin on the master per MCP23S17 works a treat.

Prototyping board close up

Prototyping board close up

The Arduino code is very simple – it reads a character from either the USB serial port or the Bluetooth UART into a command buffer. ‘Commands’ on the modified Robosapien are trivial – motors and LEDs can be turned on and off,  delays of 0-999ms can be inserted and triggers for low/high on the switches can be waited for. For example, “s+” is “left shoulder up”, “S-” (lower/upper case for left/right!) is “right shoulder down”, “w0” is “waist motor off”. “L=” is right leg motor ‘brake’ (high signal to both sides of motor driver, though the brake effect is very weak). “e000” is all LEDs on. “e255” is all LEDs off. There are 8 LEDs. “W500” inserts a delay of 500ms before the next command is executed. “tb1” is “trigger when left button signal is high”. “q” turns off all motors.

Behaviour Send text string
Funky walk w+W300s+S-l-L+w-W360s-S+l+L-w+W360s+S-l-L+w-W360s-S+l+L-w+W360s+S-l-L+w-W360s-S+l+L-w+W360s+S-l-L+w-W360s-S+l+L-w+W360s+S-l-L+w-W360s-S+l+L-w+W360s+S-l-L+w-W360s-S+l+L-w+W360l0L0s0S0W500q
Turn in place w+l+L-W075l-L+W075w-W075l+L-W150l-L+W075w+W075l+L-W150l-L+W075w-W075l+L-W150l-L+W075w+W075l+L-W150l-L+W075w-W075l+L-W150l-L+W075w+W075l+L-W150l-L+W075w-W075l+L-W150l-L+W075w+W075l+L-W150l-L+W075q
‘High’ kick w+h+H-s+S+W999W600qS-tS1S=l-W999W150L+W150L-W150L+W150L-W150L+W150L-W150L+W150L-W150L+W150q

Source code for Arduino IDE is here: robosapienarduino.tar.gz

While the brain transplant is a success, losing the behavioural repertoire and vocalisations means there’s plenty still to do to return the Robosapien to full health. It being an old (nearly ten years?) toy, I’m wary of physically modding it further – such as adding contact sensors to its feet – and using it more in case I break its mechanisms.

The Robosapien has lived up to its claims of “made to be hackable”, but PCB-hacking is fraught with dangers. I’d like to see “made-to-hack” toys have their toy-behaviour controllers on pluggable daughter boards, exposing well-documented headers for owners who want to try their hand at brain surgery.

Having successfully operated on one patient, I’m looking forward to using the Adafruit Bluefruit LE Micro on new candidates… and there’s an unloved, apparently-hard-of-hearing Zoomer in the toy cupboard downstairs. “Zoomer! Here boy! Whassis? Screwdriver! Roll over!”

Ebay Finding Service API for Java / Maven

I’ve just finished a project which regularly queries the ebay finding API and does something good with the results. It’s in Java, so I downloaded the “Finding Kit for Java” zip file from the ebay Developer’s Program Finding API page. I struggled at first to integrate it with my Java / Maven / One-JAR project. A look through the code included in the zip revealed stuff that didn’t inspire me with confidence (for example the hard-coded Windows path (“C:/william_dev/eBaySDK/715/findingkit/FindingService.wsdl” in FindingService.java) so I decided to make my own Maven findingkit project.

I’m allergic to XML so no expert on SOAP but it seems that the zip-included com.ebay.services.finding package should be automatically generated by some WSDL. I deleted that directory first. The Developer’s Program zip includes the WSDL to generate the deleted source, but my expectation from a public API is that the WSDL should be publicly hosted by the API-owner, so I deleted that too.

It remained only to specify an URL for the Finding Service WSDL which describes the generated source and a maven plugin (I used JAX-WS) to generate the sources (with the maven goal jaxws:wsimport) and I was good to go to generate the Finding java sources. The first time you do this, there’s a package naming issue in the zip-included com.ebay.services.client.FindingServiceClientFactory. Replace the import lines with ones including package names that match the generated code. In NetBeans IDE, I just delete the imports and choose the default suggestions in the ‘Cannot find symbol’ tooltips. The generated package I have to import from is “com.ebay.marketplace.search.v1.services”.

One last clean and build should give you a com.ebay.findingkit artefact in your local maven repository.

Here’s a zip file of the maven project I use in my ebay Finding Service projects. The usual caveats regarding gifts from strangers should apply. At least it has no Windows file path string literals in it.

findingkit.zip

My one remaining concern is the ‘v1’ in the package names. I’d be happier if I had a ‘v1’ URL for the WSDL. A ‘latest’ URL that generates ‘v1’ names seems wrong.

JBullet concurrent/parallel simulations, the ObjectPool problem

I’ve been using JBullet for some simulations recently and wanted to run several concurrently to make the most of my PC’s multiprocessing capabilities. It seems that the stock JBullet jar from jbullet.advel.cz contains code that cannot be used concurrently by more than one thread. You’ll see Exceptions like ArrayIndexOutOfBoundsException, IndexOutOfBoundsException and NullPointerException as your threads modify each other’s objects.

The problem is caused by the com.bulletphysics.util.ObjectPool class which is obviously intended for use by several threads but not properly synchronized. There are two ways to get around the problem – you can remove ObjectPool from the source code, replace all uses of its “get” method by direct (and not reusable) instantiation of the desired object and comment out or delete references to ObjectPool’s release method.

The alternative is to properly synchronize ObjectPool so that it is thread-safe. The code below works for me when it replaces the content of com/bulletphysics/util/ObjectPool.java, the jbullet jar is rebuilt and moved to the place your build tools find it (I replace the jbullet-20101010-1.jar in my local maven repository):

package com.bulletphysics.util;

import java.util.*;

/**
 * Object pool.
 *
 * @author sean
 */
public class ObjectPool<T> {

	private final Class<T> cls;
  private final Queue<T> list = new LinkedList<T>();
  private final static Map<Class, ObjectPool> MAP_CLASS_POOL = new HashMap<Class, ObjectPool>();

	private ObjectPool(Class<T> cls) { this.cls = cls; }

	/**
	 * Returns instance from pool, or create one if pool is empty.
	 *
	 * @return instance
	 */
	public synchronized T get() {
      if (!list.isEmpty())
        return list.remove();
    try { return cls.newInstance(); }
    catch (Exception e) { throw new IllegalStateException("Couldn't create a " + cls.getCanonicalName(), e); }
	}

	/**
	 * Release instance into pool.
	 *
	 * @param obj previously obtained instance from pool
	 */
	public synchronized void release(T obj) {
		list.add(obj);
	}

	/**
	 * Returns per-class object pool for given type, or create one if it doesn't exist.
	 *
	 * @param cls type
	 * @return object pool
	 */
	public synchronized static <T> ObjectPool<T> get(Class<T> cls)
	{
		ObjectPool<T> pool = (ObjectPool<T>)MAP_CLASS_POOL.get(cls);
		if (pool == null) {
			pool = new ObjectPool<T>(cls);
			MAP_CLASS_POOL.put(cls, pool);
		}

		return pool;
	}
	public static void cleanCurrentThread() { /* does nothing */ }
}

In my tests the synchronized ObjectPool executes about 5% faster than plain old object creation and garbage collection. Whatever benefit ObjectPool brings for the objects it reuses seems to be dwarfed by the amount of int[]s created (and not pooled) by JBullet.

Update 2014 August 17th

Spoke too soon – as soon as I extended my very trivial simulation I got similar Exceptions from the ArrayPool class. Applying similar edits to that class yields the following code and simulations that seem to work reasonably (see later update – synchronization in this code is slow) well:

package com.bulletphysics.util;

import java.lang.reflect.Array;
import java.util.*;

/**
 * Object pool for arrays.
 *
 * @author sean
 */
public class ArrayPool<T> {

  private final static HashMap<Class, ArrayPool> MAP_CLASS_QUEUE = new HashMap<Class, ArrayPool>();
	private final Class componentType;
	private final ObjectArrayList list = new ObjectArrayList();
	private final Comparator comparator;
	private final IntValue key = new IntValue();

	/**
	 * Creates object pool.
	 *
	 * @param componentType
	 */
	public ArrayPool(Class componentType) {
		this.componentType = componentType;

		if (componentType == float.class) {
			comparator = floatComparator;
		}
		else if (componentType == int.class) {
			comparator = intComparator;
		}
		else if (!componentType.isPrimitive()) {
			comparator = objectComparator;
		}
		else {
			throw new UnsupportedOperationException("unsupported type "+componentType);
		}
	}

	@SuppressWarnings("unchecked")
	private T create(int length) {
		return (T)Array.newInstance(componentType, length);
	}

	/**
	 * Returns array of exactly the same length as demanded, or create one if not
	 * present in the pool.
	 *
	 * @param length
	 * @return array
	 */
	@SuppressWarnings("unchecked")
	public synchronized T getFixed(int length) {
		key.value = length;
		int index = Collections.binarySearch(list, key, comparator);
		if (index < 0) {
			return create(length);
		}
		return (T)list.remove(index);
	}

	/**
	 * Returns array that has same or greater length, or create one if not present
	 * in the pool.
	 *
	 * @param length the minimum length required
	 * @return array
	 */
	@SuppressWarnings("unchecked")
	public synchronized T getAtLeast(int length) {
		key.value = length;
		int index = Collections.binarySearch(list, key, comparator);
		if (index < 0) {
			index = -index - 1;
			if (index < list.size()) {
				return (T)list.remove(index);
			}
			else {
				return create(length);
			}
		}
		return (T)list.remove(index);
	}

	/**
	 * Releases array into object pool.
	 *
	 * @param array previously obtained array from this pool
	 */
	@SuppressWarnings("unchecked")
	public synchronized void release(T array) {
		int index = Collections.binarySearch(list, array, comparator);
		if (index < 0) index = -index - 1;
		list.add(index, array);

		// remove references from object arrays:
		if (comparator == objectComparator) {
			Object[] objArray = (Object[])array;
			for (int i=0; i<objArray.length; i++) {
				objArray[i] = null;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////

	private static Comparator floatComparator = new Comparator() {
		public int compare(Object o1, Object o2) {
			int len1 = (o1 instanceof IntValue)? ((IntValue)o1).value : ((float[])o1).length;
			int len2 = (o2 instanceof IntValue)? ((IntValue)o2).value : ((float[])o2).length;
			return len1 > len2? 1 : len1 < len2 ? -1 : 0;
		}
	};

	private static Comparator intComparator = new Comparator() {
		public int compare(Object o1, Object o2) {
			int len1 = (o1 instanceof IntValue)? ((IntValue)o1).value : ((int[])o1).length;
			int len2 = (o2 instanceof IntValue)? ((IntValue)o2).value : ((int[])o2).length;
			return len1 > len2? 1 : len1 < len2 ? -1 : 0;
		}
	};

	private static Comparator objectComparator = new Comparator() {
		public int compare(Object o1, Object o2) {
			int len1 = (o1 instanceof IntValue)? ((IntValue)o1).value : ((Object[])o1).length;
			int len2 = (o2 instanceof IntValue)? ((IntValue)o2).value : ((Object[])o2).length;
			return len1 > len2? 1 : len1 < len2 ? -1 : 0;
		}
	};

	private static class IntValue
  {
		public int value;
	}

	/**
	 * Returns per-class array pool for given type, or create one if it doesn't exist.
	 *
	 * @param cls type
	 * @return object pool
	 */
	@SuppressWarnings("unchecked")
	public synchronized static <T> ArrayPool<T> get(Class cls)
  {
    ArrayPool<T> pool = MAP_CLASS_QUEUE.get(cls);
		if (pool == null)
    {
			pool = new ArrayPool<T>(cls);
			MAP_CLASS_QUEUE.put(cls, pool);
    }
		return pool;
	}

	public static void cleanCurrentThread() { /* does nothing */	}

}

Update 2014 September 26th

I’d got reasonable behaviour from my simulation and set about running it on my ‘low performance cluster’ – a collection of random PCs on my desk. It was obvious something was wrong when some old dual-core PCs ran my parallel simulations faster than my recent 8-core workstation! VisualVM made the problem obvious: my worker threads were blocked on the synchronization I’d added in ArrayPool. Using ThreadLocal and paring the class down to the 2 cases for which it’s used in JBullet (int[]s and float[]s) resulted in several times faster concurrent DynamicWorlds.

There’s an obvious kludge at “12 elements should be enough for anyone” – a guess at the maximum length of pooled arrays.

package com.bulletphysics.util;

import java.util.*;


/**
 * Object pool for arrays.
 * 
 * @author sean
 */
public abstract class ArrayPool<T>
{
	private final static ThreadLocal<ArrayPool<int[]>> INT_ARRAY_POOL = new ThreadLocal<ArrayPool<int[]>>()
	{
		@Override
		protected ArrayPool<int[]> initialValue()
		{
			return new ArrayPool<int[]>()
			{
				@Override
				protected int getLength(int[] array)
				{
					return array.length;
				}
				@Override
				protected int[] makeTypedArray(int length)
				{
					return new int[length];
				}
			};
		}
	};
	private final static ThreadLocal<ArrayPool<float[]>> FLOAT_ARRAY_POOL = new ThreadLocal<ArrayPool<float[]>>()
	{
		@Override
		protected ArrayPool<float[]> initialValue()
		{
			return new ArrayPool<float[]>()
			{
				@Override
				protected int getLength(float[] array)
				{
					return array.length;
				}
				@Override
				protected float[] makeTypedArray(int length)
				{
					return new float[length];
				}
			};
		}
	};
	private final Queue[] recyclingQueues = new Queue[12]; // 12 elements should be enough for anyone
	protected abstract T makeTypedArray(int length);
	protected abstract int getLength(T array);
	public ArrayPool()
	{
		for (int i = 0; i < recyclingQueues.length; i++)
			recyclingQueues[i] = new LinkedList<T>();
	}
	/**
	 * Returns array of exactly the same length as demanded, or create one if not
	 * present in the pool.
	 * 
	 * @param length
	 * @return array
	 */
	public T getFixed(int length)
	{
		Queue<T> recyclingQueue = recyclingQueues[length];
		T reusableArray;
		if (recyclingQueue.isEmpty())
			reusableArray = makeTypedArray(length);
		else
			reusableArray = recyclingQueue.remove();
		return reusableArray;
	}

	/**
	 * Releases array into object pool.
	 * 
	 * @param array previously obtained array from this pool
	 */
	public void release(T array)
	{
		Queue<T> recycledArrays = recyclingQueues[getLength(array)];
		recycledArrays.add(array);
	}
	
	/**
	 * Returns per-class array pool for given type, or create one if it doesn't exist.
	 * 
	 * @param cls type
	 * @return object pool
	 */
	public static <T> ArrayPool<T> get(Class cls)
  {
		if (cls == int.class)
			return (ArrayPool<T>)INT_ARRAY_POOL.get();
		else if (cls == float.class)
			return (ArrayPool<T>)FLOAT_ARRAY_POOL.get();
		else
			throw new IllegalArgumentException("No ArrayPool for " + cls.getCanonicalName());
	}

	public static void cleanCurrentThread() { /* does nothing */	}

}

As a side-note, another source of concurrent slow-down was careless use of java.lang.Math.random() to add bit-flipping noise to simulations. The API docs say

This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.

Using a non-shared, fast random number generator made a huge difference to the speed of my simulations.

LWJGL: No Keyboard events in Ubuntu / Linux

Running the jbullet demo just now, I noticed mouse events were handled but none of the keyboard events were handled. Stepping through the code it seemed no events were captured by LWJGL’s Keyboard class. Spotted this “Keyboard does not respond on Linux” discussion on LWJGL’s forum which has the answer (ibus isn’t handled correctly) but doesn’t provide a copy-paste solution for “do you haz teh codez” visitors (as I was just now) who just want to overcome the immediate hurdle of the non-functioning LWJGL Keyboard.

This works for me:

XMODIFIERS="@im=none"; java -Djava.library.path=../lib/lwjgl/linux/ -jar jbullet.jar

Measuring tube homework worksheet

Similar to the clock face worksheet, here’s a simple generator for a measuring tube homework worksheet. Every time you click on the link below, you will download a new randomly-generated measuring tube worksheet with 6 questions on it. The measuring tubes are drawn with vector graphics to make sure they look good when printed.

Download a PDF measuring tubes worksheet ready to print.