Sunday, November 25, 2007

ZeroBUGS on PowerPC


Happy Thanksgiving! (Yes, we do celebrate Thanksgiving in Seattle in spite of what the Liberal Turkeys want you to believe).

And what a great long weekend this was. We took advantage of the great weather and hiked in the Lincoln and Discovery Parks and walked around Alki Beach, with our son in the backpack.

I have been looking for a solid block of free time from my daytime job in order to look into porting ZeroBUGS to the PowerPC.

I have an old PowerMac that I bought used from a company in Oregon this past summer, for this specific purpose (and promptly installed Ubuntu on it).

But I did not have the time to look into it seriously until now. The main motivation was to see how far I can push the envelope, with the existing design holding up. In other words, I wanted to see how portable my overall design of ZeroBUGS was. And porting prompts one to revisit, re-test and refactor old code.

Of course, I did not expect the outcome of three or four nights of hacking to be perfect.

But the result, while very rough, is quite usable (at least usable enough for me to bootstrap the debugging of the debugger with itself) and I am quite happy with it.

So what's so hard about porting the debugger to the Power architecture? you may ask. Shouldn't it be quite a straightforward task, given it is written in portable C++?

A debugger interacts with the target program (and the OS) at a low level, and hence parts of it depend on the low-level architecture details. Take stack unwinding for example. The layout of stack frames (or links, in PPC parlance) is different than on the Intel chips. And so is the mapping of DWARF register numbers onto the CPU general purpose registers.

Linux runs on PowerPC in big endian mode (as opposed to Intel chips which are little-endian systems) and thus the binary representation of C and C++ bit fields differs.

The hardware support for debugging (special debug CPU registers) also varies across processors.

Well-thought abstractions should isolate these idiosyncrasies. I found out that I have done a good job designing the stack unwinding mechanism (a "driver", template method that delegates to platform-specific bits) but totally blew the model for hardware debug registers.

Oh well. Back to the drawing board. Luckily it is not a heavily-used feature...

Sunday, November 18, 2007

The Pros and Cons of Hitch Hacking... Ubuntu 7.10


After fubar-ing one of my systems last week with Fedora Core 8, I switched to Ubuntu 7.10 Ballsy Baboon as my main development system and I just love it.

I cannot care less about the over-hyped desktop effects, I am interested in software development, and in this context the eye candy is irrelevant.

Ubuntu 7.10 allows you to install all major GCC/G++ versions from 2.95 to 4.2 which is so cool! I can test with older GCC versions without having to boot up an older distro! Excellent.

So that is the Good. Now for The Bad and The Ugly: the PowerPC is not officially supported.

This is hardly any news, 7.4 is not supported either but it worked great on my second-hand G4. Upgrading from 7.4 to 7.10 on the other hand is a terrible mistake. I repeat: if running on PowerPC, do not upgrade from Ubuntu 7.4 to 7.10!

If you do, your machine may not reboot properly. It is very likely that you will find yourself stuck at BusyBox, and then you will have to type:

modprobe ide_core
exit

to bring the system up.

Then you may also see an error box popping up, about HAL not starting. You will have to start it manually:

sudo /etc/init.d/hal start

The network interface may not start either, and there is no sound. But then again, I am only using the G4 for porting ZeroBUGS to PowerPC (which I devote very very little time to, so not a biggie).

As a bonus point: on the AMD64 (my main system) nspluginwrapper and flash are installed auto-magically.

So overall this Manly Monkey distro is great! Oh wait. I got the name wrong again... I think they call it Goofy Gorilla. Or Ghastly Gnome.

Sunday, November 11, 2007

Fedora 8 Headaches

I should have known better: if it ain't broken, don't fix it. My main system is a 64 bit machine which, until yesterday, ran Fedora Core 5. On top of that I ran several 32-bit distros in VMWare.

The system was just fine, yet I decided to get adventurous and upgrade to the new Fedora 8. Big friggin' mistake. First of all, the installation DVD got consistently stuck at about 30% of Checking dependencies in packages selected for installation...

So I grabbed a Fedora 7 DVD which I burnt a while back and never got around to play with, and tried it out. The upgrade worked (I could not afford a fresh install, since I needed to keep my data). And I should have stopped here. But no, I got greedy and retried the FC8 DVD. No more hanging at checking dependencies... hurray! But wait.

After rebooting the system, pirut (the front end to YUM) does not work anymore (crashes every time), the Gnome desktop forgets to repaint after a while and looks like a Windows 3.1 desktop back when an application leaking GDI resources messed up the entire machine.

Oh, and because of the new 2.6.23 kernel, I had to recompile VMWare's kernel module, which would have been ok, had it worked. But in the good old tradition of kernel developers who don't give fudge about backwards compatibility the kernel source is now incompatible with VMWare Server 1.0.4.

I always thought that it would be easier to test my software if I limited myself to fewer distributions. So thank you RedHat, you are out.

Friday, November 09, 2007

Detecting Motor Stalls in NBC/NXC

So I stayed up all night again playing with the Mindstorms kit. I re-built my car model with a shorter, sturdier frame and a more precise steering. I kept the brick in the back and the differential transmission.

Since that went well into the wee hours, I had little time left to program the thing before the sunrise (yeah, I had to stretch that Transylvanian connection again).

Anyway, the detection of obstacles and steering around them is quite imperfect, and the vehicle bumps into things more often than I would like. So I have decided to compensate with a hack, and searched the Internet for ways to detect motor stalls. The search turned a couple of solutions, one in RobotC and another one in the graphical NXT-G language.

I could not find any NXC code snippet, but after some experimentation I came up with the code below. It checks whether the rotation count drops under a specified threshold for three consecutive times (to avoid spurious, false positives).


#define OUT_DRIVE OUT_C
#define STALL_THRESHOLD 6 // may depend on battery charge level?


bool is_stalled()
{
for (int i = 0; i != 3; ++i)
{
ResetRotationCount(OUT_DRIVE);
Wait(10);

const int count = MotorRotationCount(OUT_DRIVE);
NumOut(0, LCD_LINE1, count, true);

if (abs(count) >= STALL_THRESHOLD)
{
return false;
}
}
return true;
}


Here is another variation:

bool is_stalled()
{
ResetRotationCount(OUT_DRIVE);

for (int i = 0; i != 3; ++i)
{
Wait(10);

const int count = MotorRotationCount(OUT_DRIVE);
NumOut(0, LCD_LINE1, count, true);

if (abs(count) >= stallThreshold * (i + 1))
{
return false;
}
}
TextOut(0, LCD_LINE1, "stalled", true);
return true;
}

I have yet to build a robot with the motors attached directly to the wheels, and I wonder if the false positive that I get are related to the fact that my wheels are powered through a differential transmission.

And the stall threshold depends on the surface the robot runs on, so I added the following code to read it from the user:

void input_stall_threshold()
{
bool done = false;
int count = 0;

stallThreshold = INIT_STALL_THRESHOLD;
until (done)
{
Wait(300);
ReadButtonEx(BTNCENTER, true, done, count);

bool pressed = false;
int n = 0;

ReadButtonEx(BTNLEFT, true, pressed, n);
if (pressed)
{
if (stallThreshold > 0)
--stallThreshold;
}
pressed = false;
ReadButtonEx(BTNRIGHT, true, pressed, n);
if (pressed)
{
++stallThreshold;
}
TextOut(0, LCD_LINE1, "stall thresh=", true);
NumOut(78, LCD_LINE1, stallThreshold);
}
}

Saturday, November 03, 2007

Mindstorms Roadster Version 1.1

Boy is this Mindstorms thing addictive... I spent last night fixing a bunch of design bugs (I gave up the worm gear steering mechanism shown in the previous post, and adopted a simpler solution).

The chassis is long because my very first intention was to have the brick in the middle of the car (hence the X design, to avoid sagging). But it is more practical to have the brick in the back. And it looks cool, too.





Mechanical issues figured out, I went and downloaded the Bricx Command Center 3.3 and after some tinkering I came up with this code (the car has the touch sensor attached in the back, not shown in the photos).

Although the code is just work in progress, it is already lots of fun to watch to car on the kitchen floor, backing out and steering away to avoid bumping into the furniture!


#include "NXCDefs.h"

#define NEAR 25
#define MIN_BACKOUT 20
#define MAX_BACKOUT 100
#define STEER_ANGLE 20

int angle = STEER_ANGLE;
int backout = MIN_BACKOUT;// backout time


task main()
{
int i;

SetSensorTouch(IN_1);
SetSensorLowspeed(IN_4);

while (true)
{
OnRev(OUT_C, 100); // motor is installed backwards,
// we are going forward

while (SensorUS(IN_4) > NEAR)
;

OnFwd(OUT_C, 100); // back out at full speed
Wait(50); // wait 50 ms

// steer away from obstacle
RotateMotor(OUT_A, 50, angle);

for (i = 0; i < backout; i++)
{
// bumped into something while backing?
if (SENSOR_1)
{
// play sound, then stop
PlayFileEx("! Startup.rso", 1, FALSE);
backout = MIN_BACKOUT;
break;
}
Wait(100);
}
Off(OUT_C); // stop

angle = -angle; // steer the other way

RotateMotor(OUT_A, 50, angle);


backout += 10; // backout increasingly
if (backout >= MAX_BACKOUT)
{
backout = MIN_BACKOUT;
}
}
}

Friday, November 02, 2007

The Roadster


Here is my first Mindstorms NXT project: The Roadster. One servo motor controls the steering (the mechanism is still hacked up, but I have a couple of ideas for making it more solid).


Another motor powers the rear axles through a differential from nxtasy.org. Designing mechanisms is not a strong suit of mine, but I recognize a cool design pattern when I see it. And reuse is an ingredient to successful engineering.

A very simple program receives notifications from the sonar when objects are detected closer than 35 centimeters and commands the front wheels to turn, in order to avoid collision.

I look forward to downloading the NBC/NXC tools (maybe this weekend?) and building a more complex program.

My inner child is so happy.