As an introductory robotics project, we will be constructing a Palm-based mobile robot with a holonomic base and programming it to follow simple, explicit instructions.
The robot comes as a rough kit. Our three-week goals are to construct the robot, to interface the robot to a Palm, and to use (and if necessary to develop) an API for instructing the robot to perform simple actions. For the first week our goal was to construct the kit and make sure its default behavior worked.
Given the hardware involved, this project seems likely to overlap with the robot-insect work of Rodney Brooks. Depending on the direction we take after our initial three weeks, we may or may not employ multi-layered control architectures like those described by Erann Gat. In the imidiate future, though, we will be essentially controling the robot directly. One issue, discussed below, that we are coping with is the limited abilities of the BrainStem® which is the processor directly in control of the robot. In relation to the work of David Duff et. al. with the reconfigurable PolyBot. Whereas our system has just over 1K of available memory, PolyBots are made of many small 1-DOF segments which each have a Motorola PowerPC 555 embedded processor with 1 megabyte of RAM. That was in 2001.
All of the work for the first few weeks involves the setup of the kit, interfacing it with a Palm, and learning the controls to which we have access as programmers. While none of this is particularly original it will introduce us to the platform and allow us to decide what steps we could take next.
As the project has progressed, we have been suprised at just how much this kit leaves undone. This has made it an interesting teaching tool, but so far the teaching has been at a very low level.
Our single most important decision was to e decided to use this platform. This decision was based on many factors including our interest in the physical characteristics of the robot such as the holonomic base and its small size, as well as a desire to program for a platform which all team members use on a daily basis.
Our approach for the first week was simply to attempt to assemble the machine according to its instructions. While the instructions were unclear at times and while we did have to deviate from the them to fix problems, no other approach seemed an appropriate way to approach this new platform.
Progress and Performance ResultsWe successfully constructed the kit. After some initial technical problems relating to faulty kit parts and our own errors, the robot displays the expected default behavior.
The lighter rectangle of the PCB in this image shows the serial number of the BrainStem®, number 00000229. Apparently the company is ambitious with their projected sales.
After construction was complete the instructions said vaguely that a default
behavior would be performed when the robot was turned on. The behavior we
observed was rotating two wheels such that the machine spun about the third
(stationary) wheel. As it turns out, however, the intended behavior is to rotate
all wheels. This was discovered through speculation, a volt meter, and through
noticing that the stationary wheel would turn briefly if it was helped. This
lead us to conclude that the servo was faulty so we removed and disassembled
it. This image shows the wheel side of gear box:
We got a connection cable this week and were able to interface the palm and the robot to some degree.
Stephen and Paul decided that will be splitting software implementation with Paul working on the interface and Stephen working on the hardware level; Ben will be running interference.
Paul and Ben signed up as a Palm developers, downloaded and setup the PalmOS emulators, and grabbed my a ROM image after doing a flash update to run PalmOS4.1. Most of Paul's time was spent reading the documentation on PalmOS development and finding a decent Tutorial. What I ended up with was extending the basic skeleton code into a “Hello World” application, and starting work on UI elements and the actual coding of how these elements interact. We intend to have an interface like this for testing:
+-----------+ | /---\ | | / / \ | | | / | | | \ / | | \___/ | | +-----|-+ | | STOP | +-----------+Clicking in the circle will move the line to point from the center outwards to cross the pen; the slider controls forward/backward movement. The “Emergency Stop” button will allow the user to keep the robot from doing something stupid like run off a cliff.
Writing the circle requires coding a custom “Gadget” in PalmOS terms, which is fairly involved compared to the normal coding. The buttons and slider are fairly easy, and I've almost got then linked such that the Emergency button sets the slider value to zero.
At present, the interface looks like this:
We also spent time planing our strategy for motor control. Because this system has a holonomic base it requires non-trivial control. After lots of messy geometry and algebra we realized that the motors simply need to rotate at a speed proportional to the dot product of their direction and the desired direction. This lead us to a problem: While that is easy to do with constant coefficients when the orientation of the robot is fixed, as soon as it rotates, controlled motion requires some form of trig functions. On a processor where multiplying is something you want to avoid, this is an expensive proposition. However we may get around this by doing more control in the Palm itself, by approximating trig functions, or by using a lookup table within the small amount of RAM available on the BrainStem® itself.
We had serious issues with one Palm, possibly due to psyton flux from the digital camera. While recording this video, a static discharge from a laptop lead to a very fatal exception within the Palm. This leaves the three of us with one HandSpring, and one Palm IIIx. Ben does have an old Palm III with a defunct screen but a working processor. Some effort may be made to incorporate that hardware with a the screen of the recently-deceased unit.
SoftwareFor our purposes, we found the architecture overly somewhat complex. We would have been content with an API consisting of two commands: one to set the speed for a servo, one to read a sensor. While that functionality clearly exists, it is not clear to us how to make it simply work.
The BrainStem® card communicates via serial cable with a Palm. The BrainStem® has direct control over the motors and can theoretically operate on a high level on its own, although it's memory resources are limited to about 1.5K. The BrainStem® runs a virtual machine which in turn runs programs written in the “TEA” programming language.
We found the SDK provided by Acroname to
be lacking in many respects. In particular, although a wonderful example program
is provided which lets a user manually control each motor and read each sensor
in real time, the source code for it is not available. We had the following
exchange with Acroname:
While this first example is somewhat helpful, the problems we have had are with the build environment rather than with the actual coding.
The Pain of an Unsupported PlatformOur development problems were almost exclusively related to getting the project to build.
Building with GCCAcroname's primary development platform appears to be MacOS with Codewarrior. Thus only Codewarrior project files are provided, not Makefiles. The example project came complete with a MacOS resource fork containing the user interface definitions in a proprietary format readable only by CodeWarrior. Unfortunately for us, the UI is built on the GCC platform using a simple textual representation, and compiled using a tool called PilRC. This means that while the given example may work fine we cannot test it.
Even if the example code were to compile, we would not have been able to base our work directly on it. All example source files include th following terms:
This software is the property of Acroname+ Inc. Any distribution, sale, transmission, or re-use of this code is strictly forbidden except with permission from Acroname Inc.
The first problem we had was a long string of warnings like this:
../aInclude/aIO.h:66: warning: possibly bad __callseq__ `trap #15; dc.w aIOGetVersionTrap'Looking at the code around line 66 we see the following:
63 aIO_EXPORT aLIBRETURN aIO_GetVersion(aIOLib ioRef, 64 unsigned long* pVersion, 65 aErr* pErr) 66 aIO_TRAP(aIOGetVersionTrap);After much searching, we found the following mailing list exchange regarding traps on the Palm: http://www.escribe.com/computing/pcpqa/m49808.html. According to this the new OS API for Palms dictates that SYS_TRAP is a preprocessor macro, so arguments to the macro must be understandable by the preprocessor. The old method was using a function, which allowed for the use of enums. Acroname's SDK doesn't work in the new manner; the only straightforward way we saw to remove the compiler warnings was to remove the trap lines from Acroname's Include files. This was after previously deciding on Palm's SDK version 4 due to its improved user interface widgets.
After overcoming that warning, we were left with linking errors which we are still unable to resolve. For reference they look like this:
robotctl.c:57: undefined reference to `aPacket_Create' robotctl.c:64: undefined reference to `aStem_SendPacket'The fact that a Google search for “aPPRK gcc” should be a clue that this is uncharted territory.
ReflexesThe BrainStem® provides a mechanism for “reflexes” which allow it to respond to certain inputs immediately, before any messages are sent to the Palm. The reflexes are written as .leaf files and are then compiled to .bag files. Unfortunately, this compiler appears to only run on the Windows console program. Furthermore, the generated code is faulty and any command using cmdRFLXE_CHK needs to be edited by hand. For example, cmdRFLXE_CHK might produce this code in the bag file:
// message 22 2 12 128 22 2 2 41 1which then needs to be changed to this:
// message 22 2 12 128 22 2 3 41 1 0
The reflex system has some confusing constraints. Reflexes trigger “reflex vectors” which contain exactly 8 instructions. In order to produce more-complex reflex responses, the last instruction in a vector must be an instruction to jump to another vector.
While testing, all of the command vectors individually works properly, but when set it into an automated loop, it would not work any more. The only way we saw to use reflexes, then, would be to move the functionality to the Palm and listen for DEBUG produced by the reflex code.
TEAWhile TEA is supposed to be a C-like language, we found this to be more confusing than helpful. One expects C to behave in certain ways, ways which TEA does not. Had a simple stack-based language been used in place of TEA, we would have expected it to behave in a new way. As it is, we were easily confused.
Battery LifeAlthough the 4 AA batteries providing power to the logic have lasted just fine, the 9V battery which provides motor power is insufficient to run it for any length of time. This forced us to switch to rechargeables.
One Last AttemptWe took another stab at getting things to work. We learned a lot in this processbut failed to make things work.
We had been unable to compile the example headers which include traps like this after the headers:
aPPRK_TRAP(aPPRKSetServoRelTrap);. As it turns out the arguments to those traps are enumerated types. However with recent Palm SDKs, that is an unacceptable way of doing things and it will not compile, as we discovered. To fix this we had originally just removed those lines alltogether.
Looking at this page regarding Shared libraries on the Palm Pilot and at prc-tools-samples/syslib/ which can be found by Googling for prc-tools-samples, we discovered that the traps were actually useful. In fact, that they allow dynamic linking against the Palm binary libraries that Acroname provides. To fix this we had to remove the
enumfrom aInclude/palmos_aPPRKExport.h and replace it with a series of defines, like this:
#define aPPRKGetVersionTrap sysLibTrapCustom; #define aPPRKTimeSliceTrap sysLibTrapCustom+1; #define aPPRKSetServoAbsTrap sysLibTrapCustom+2; #define aPPRKSetServoRelTrap sysLibTrapCustom+3; #define aPPRKGetServoTrap sysLibTrapCustom+4; #define aPPRKGetRangeTrap sysLibTrapCustom+5; #define aPPRKSleepTrap sysLibTrapCustom+6; #define aLastPPRKTrap sysLibTrapCustom+7;
After doing that we had to figure out how acroname had wrappped the aPPRK library. Using the above link about shared libraries as a guide, we eventually figured out something that would compile and run (sortof). We never were able to get the Palm to control the robot with our software, though.
ConclusionsThe serial number of our BrainStem®, 229, appears to be indicative of the early stage of development of the technology. While the provided binaries clearly show that a Palm can control the robot, the provided code and documentation were remarkably unhelpful. If we did have access to simple commands to control and monitor the robot, further development would all be software-based and should be relatively trouble-free.
“I want to pick this up and throw it against the wall right now”Paul