★ wanayoo — archive 1999 http://howtoandroid.com/ComputingActivities-April1999.htmlNouvelle recherche | Portail wanayoo

Robot Max Computing Activities


Computing Activites for April, 1999

There's been lots of computing activities in the last month.  This is all happening during the time I'm looking for a job.
 

X11, XDM, GNOME

    X11 on Linux is working fine.  Last month's solution of pulling the very latest XFree86 3.3.3 server (XF86_svga) fixed the problem.  I pulled more of the XF86 3.3.3 software and installed it.  However, I'm really waiting for RedHat to provide the RPM for 3.3.3.  Then I'll know for certain I've got everything.  For now, it is working fine.

    I have XDM configured to launch in Run Level 3 in the /etc/inittab.  This way upon bootup, Linux boots and shows the text login prompt for about 5 seconds, and then XDM kicks in and the screen turns into GUI login mode.  I can login as root or myself.  For root, I've configured the FVWM window manager because it's simpler and less chance of anything going wrong.  For myself I've configured GNOME by making my ~/.xsession file contain this:
 

#!/bin/bash

#exec /usr/X11R6/bin/RunWM --AfterStep
#exec /usr/X11R6/bin/RunWM --WindowMaker
#exec /usr/X11R6/bin/RunWM --FvwmMWM
#exec /usr/X11R6/bin/RunWM --Fvwm95
exec gnome-session
 

    My .xsession looks awfully bare.  That's because gnome and Enlightenment make it pretty easy to launch applications and remember configurations on startup.  For example, I use a background image of stars on my desktop, and it properly remembers to paint it that way every time I login.  The old way I'd have to add the command into my .xsession startup script.  I don't mind configuring it either way.

    I pulled the latest GTK+ toolkit.   I'm beginning to like this Graphics toolkit from the experimenting I did.  I'm a knowledgable X11/Motif programmer, having designed and coded a Hydrologic Graphical Time-Series curve editor named Hydra for the U.S. Geological Survey.  BTW, Hydra has been deployed nationally throughout the USGS to about 67 offices.  One of the minor drawbacks to X11/Motif is that many of the names of things are very long and terse.   In GTK+ the same names of things are much smaller.

    GTK+ is architecturally very similar to X11/Motif.   The XLib component is called GDK.   The Xt/Motif component is called GTK+.  In very little code I was able to implement the scribble, mouse-tracks application.  The code actually came with GTK+ but it's useful to re-write it line-by-line to understand in a detailed fashion what's happening.  I also took the opportunity to add many more comments to it.   Low-level things like background pixmaps which I made significant use of in Hydra are present in GTK+.  Exposure event-handling is also present.  If you know Xlib/Motif, you'll find GTK+ a breeze.
 

C++

    I've also made progress on learning C++.  I had moved straight from C to Java and skipped over C++ entirely.  Now that I'm going back and learning C++ I'm glad I skipped it.  The language is more terse than Java.  Also, the historical features of C are also present, including "&".  I know how to use "&", but this one single operator may be  the root of a large percentage (double-digit?) of all bugs in C/C++ code.    "&" is the pointer and address reference literal.

    I'm including here 4 Classes I've designed in C++.  They are what I'll call "OO Hello World".  There is one generic Class called Greeting.  From this I extended 3 more classes that perform greetings slightly differently, yet reuse the variables and functions from the generic Greeting class.  I'm even included the main.cpp file to drive it.  Compiling is as simple as g++ *.cpp.  Running is then simply executing the a.out file: a.out.

    In creating this I've decided I like Java more than C++.   C++ inherits many syntactic and semantic features from C which I don't particularly like.  Since the "Hello World" is the quintessential example to begin learning a new language, I decided it was time to program an OO Hello World program that actually made some significant use of Class Extension and Reuse.  Modeling the Greeting behaviour over several languages and hollywood characters is one simple way to do that.  Thus, the default Greeting class outputs English, the SpanishGreeting class says hello and goodbye differently, the Borg definitely says hello and goodbye differently, and of course Terminator2 says hello and goodbye very uniquely too.

    Now it can be argued that I've introduced far too much complexity for this particular example:  Perhaps.  But this example is intended to be representative of an evolving system of software which in it's life-cycle will need to be maintained and updated for new and unforeseen features.  For example:  I'd like to extend this system to produce Audio output.  And I don't want to have to change any of this code.  I want to extend it to have Classes that know Audio output (likely using Java Sound or /dev/audio) without changing a single line of this code; afterall this code is working fine.



//
// File - Greeting.h
//
#ifndef _GREETING_H_
#define _GREETING_H_

class Greeting {
    private:
        char* greetMessage;
        char* byeMessage;
    public:
        Greeting();
        void greet();
        void bye();
        void setGreeting(char *);
        char* getGreeting();
        void setBye(char *);
        char* getBye();
};

#endif
----------------------
//
// File - Greeting.cpp
//
#include <iostream>
#include "Greeting.h"

Greeting::Greeting() {
     greetMessage = "Hello World";
     byeMessage   = "Bye-bye";
}

void Greeting::greet() {
  std::cout << getGreeting() << '\n';
}

void Greeting::bye() {
  std::cout << getBye() << '\n';
}

void Greeting::setGreeting(char* msg) {
  greetMessage = msg;
}

char* Greeting::getGreeting() {
  return greetMessage;
}

void Greeting::setBye(char* msg) {
  byeMessage = msg;
}

char* Greeting::getBye() {
  return byeMessage;
}
=======================================================================
//
// File - SpanishGreeting.h
//
#include "Greeting.h"

class SpanishGreeting : public Greeting {
    public:
        SpanishGreeting(); // Constructor
};
-----------------------------------
//
// File - SpanishGreeting.cpp
//
#include "SpanishGreeting.h"

//
// Constructor
//
SpanishGreeting::SpanishGreeting() {
    setGreeting("Hola Mundo!");
    setBye("Hasta la Vista, baby!");
}
====================================================================
//
// File - BorgGreeting.h
//
#include "Greeting.h"

class BorgGreeting : public Greeting {
    public:
        BorgGreeting(); // Constructor
};
------------------------------------
//
// File - BorgGreeting.cpp
//
#include "BorgGreeting.h"

//
// Constructor
//
BorgGreeting::BorgGreeting() {
    setGreeting("YOUR EXISTENCE IS OVER!!!
      YOU WILL BE ASSIMILATED!!!
      RESISTENCE IF FUTILE!!!
      WE'RE REBOOTING YOUR COMPUTER NOW!!!");
    setBye("YOU HAVE BEEN ASSIMILATED!!!
      YOUR SOCIAL AND BIOLOGICAL DISTINCTIVENESS HAS BEEN ADDED TO OURS!!!
      YOU ARE NOW A DRONE!!!");
}
=====================================================================
//
// File - Terminator2.h
//
#include "Greeting.h"

class Terminator2 : public Greeting {
    public:
        Terminator2(); // Constructor
};
-------------------------------------
//
// File - Terminator2.cpp
//
#include "Terminator2.h"

//
// Constructor
//
Terminator2::Terminator2() {
    setGreeting("I need your clothes, your boots and
        your glasses!");
    setBye("I'll be back!");
}
===================================================================
#include <iostream>
#include "Greeting.h"
#include "SpanishGreeting.h"
#include "BorgGreeting.h"
#include "Terminator2.h"

int main() {
    Greeting         english;
    SpanishGreeting  hispano;
    BorgGreeting     seven;
    Terminator2      T2;

    cout << "In English, hello is --> ";
    english.greet();
    cout << " and goodbye is -------> ";
    english.bye();
    cout << "\n";

    cout << "In Spanish, hello is --> ";
    hispano.greet();
    cout << " and goodbye is -------> ";
    hispano.bye();
    cout << "\n";
 

    cout << "In Borg, hello is --> ";
    seven.greet();
    cout << " and goodbye is -------> ";
    seven.bye();
    cout << "\n";
 

    cout << "In Terminator-speak, hello is --> ";
    T2.greet();
    cout << " and goodbye is -------> ";
    T2.bye();
    cout << "\n";
 

} // main()
----------------------------------
[pmrael@localhost]$ g++ *.cpp
[pmrael@localhost]$ a.out
In English, hello is --> Hello World
 and goodbye is -------> Bye-bye

In Spanish, hello is --> Hola Mundo!
 and goodbye is -------> Hasta la Vista, baby!

In Borg, hello is --> YOUR EXISTENCE IS OVER!!!
      YOU WILL BE ASSIMILATED!!!
      RESISTENCE IF FUTILE!!!
      WE'RE REBOOTING YOUR COMPUTER NOW!!!
 and goodbye is -------> YOU HAVE BEEN ASSIMILATED!!!
      YOUR SOCIAL AND BIOLOGICAL DISTINCTIVENESS HAS BEEN ADDED TO OURS!!!
      YOU ARE NOW A DRONE!!!

In Terminator-speak, hello is --> I need your clothes, your boots and
        your glasses!
 and goodbye is -------> I'll be back!
 



 

Java2

    I pulled the Pre-ReleaseJava2 from Blackdown and installed it but something's wrong.   This version is Pre-Release because Blackdown has to officially pass all the certification tests Sun posts in order to stamp their Java2 as being fully compatible and compliant.    The problem is that when I try to run any GUI Java applications, they immediately crash.   Text-only applications seems to run just fine.  Sound like some problem with the AWT or something.  I could revert back to the older JDK 1.1.7 and load in the JFC/Swing APIs.   I may or may not do that.
 

JAI, Image Processing, Edge Detection

    On Windows (my laptop is a dual-boot Linux or Win-98) I pulled Java2 and JAI, the Java Advanced Imaging package.  In very few lines of code I was able to load in a JPEG image of Robot Max and perform Edge-Detection.  This looks real promising.  Last month I was experimenting with GIMP:  This month JAI.    Both look very promising.  However, the architecture for how I'm going to use Edge-Detection is not fully worked out.  Without giving much away, currently it looks like I'm going to need a Triple-Parallel Edge-Detector and comparator: 2 for each robot eye and one for the Minds-Eye!

    I'm cooking up a very interesting pattern-matcher.  I'd like the pattern-matcher to be general-purpose and extendable at the Runtime level.   ie: I'd like it command-line drivable, with the Variability occuring in the command-line arguments/files.  More details will come later.  I'm including the protoypical code for JAI Edge-Detecting here as an example:



[pmrael@localhost]$ more EdgeDetect.java
import java.awt.Frame;
import java.awt.image.renderable.ParameterBlock;
import java.io.IOException;
import javax.media.jai.Interpolation;
import javax.media.jai.JAI;
import javax.media.jai.KernelJAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;
import javax.media.jai.codec.FileSeekableStream;
import javax.media.jai.widget.ScrollingImagePanel;

/**
 * Experimental and prototypical code for testing EdgeDetecting.  Note that all the code below is in
 * a main(), meaning it's not yet decomposed into Object-Oriented classes.
 */
public class EdgeDetect {

    /** The main method */
    public static void main(String[] args) {

        //
        // Validate input
        //
        if (args.length != 1) {
            System.out.println("Usage: java EdgeDetect filename");
            System.exit(-1);
        }
 

        //
        // Create an input stream to load the image file
        //
        FileSeekableStream imageStream = null;
        try {
            imageStream = new FileSeekableStream(args[0]);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(0);
        }
 

        //
        // Create a JAI Operator to decode the image file
        //
        RenderedOp image1 = JAI.create("stream", imageStream);
        //PlanarImage  image1 = (PlanarImage)JAI.create("fileload", args[0]);
 

        //
        // Create the Kernels for Gradient Edge Detection
        //
        float data_h[] = new float[] { 1.0F,   0.0F,   -1.0F,
                                  1.41F,  0.0F,   -1.414F,
                                  1.0F,   0.0F,   -1.0F};
        float data_v[] = new float[] {-1.0F,  -1.414F, -1.0F,
                                  0.0F,   0.0F,    0.0F,
                                  1.0F,   1.414F,  1.0F};

        KernelJAI kern_h = new KernelJAI(3, 3, data_h);
        KernelJAI kern_v = new KernelJAI(3, 3, data_v);
 

        //
        // Create the Gradient edge-detection operation
        //
        PlanarImage image2 = (PlanarImage)JAI.create("gradient", image1,
                                             kern_h, kern_v);
 

        //
        // Get the width and height of the image
        //
        int width  = image1.getWidth();
        int height = image1.getHeight();
 

        //
        // Attach the image to a scrolling panel to be displayed
        //
        ScrollingImagePanel panel = new ScrollingImagePanel(image2,
                                                    width,
                                                    height);
 

        //
        // Create a frame to contain the panel
        //
        Frame window = new Frame("JAI Edge Detector");
        window.add(panel);
        window.pack();
        window.show();

    } // main()
}


 

SQL RDBMS server MySQL

    I needed an SQL server on Linux, so I checked out Ingres's free offer for eval of OpenIngres on Linux.  Unfortunately, the README says before you can pull anything you must agree to become an evaluator of the software and will be required to converse with their engineers at certain intervals.  I wanted zero interaction with them so that I could remain focused on Robotics, so I chose MySql instead.  MySQL is a very simple SQL server.  I have lots of experience with OpenIngres and I know that it's a heavy-duty, Industrial-strength SQL RDBMS server.  MySQL pales in comparison.  BUT, for simple SQL queries that don't need any of the advanced locking features, MySQL will be fine.  I'm considering using an RDBMS as the foundation of the BrainStore.  I haven't decided yet.
 

Sound

    I was trying to get sound working on Linux.  It should be easy.  My ESS card is supposedly SoundBlaster compatible.  It uses something called MPU401, for which I've seen drivers in Linux.  However, my sound system is full-duplex I/O so there may be something incompatible there.  My laptop is a very high-end multimedia system and the card may have features not present on standard audio systems, so that may be the problem.  I need to pull the newer Sound configuring software from the WEB and maybe that will fix it.

    An interesting thing happened as I was manually editing the kernel module definition file /etc/conf.modules by hand.  I messed up one of the I/O addresses, and shortly thereafter Linux loaded the module, and promptly froze solid.  Worse, upon bootup the modules are loaded so the boot process would only get so far and then hang.
So I figured I'd boot into Single user run level and repair the file.  Nope.  Apparently the kernel modules are loaded before any decisions are made about run-levels.  Then I read the RedHat manual which says to resort to the Rescue disk.  It says to boot the floppy rescue disk, then provide special boot parameters and voila I should land directly at a prompt at which point I should be able to fix the problem.  Nope.  Same problem.

    Alas, the solution was to hold down ^C right at the instant in the boot process the kernel was loading the  modules for sound.  This landed me at a shell prompt.  Kind of scary that the boot process can be so easily overpowered.  I need to inform RedHat about this and see if that's been fixed in the newly released RedHat 6 (which is the Linux 2.2 Kernal).
 

M1 Robot Mind Architecture

    I've put in a significant amount of work into the M1 Mind Architecture over the last month.  It's amazing what can be done in a short month.  Actually, many of the ideas that went into M1 have been with me for years.   They finally found a place to reside in the M1 Architecture.  I'm planning on about one or two more months of refining M1 to the point  where coding can begin.

    I think the M1 Architecture is quite an interesting approach toward solving the consciousness, sentience and intelligence processing needs for an Android robot.  It's a very far cry from the old string-based systems of Eliza and similar systems.  However, nothing is functional yet.  The Architecting goes on.
 

QuickCam Internals, and Portability

    I've also discovered something about the Logitech/Connectix QuickCam VC (Video-Conference) video-cameras.  The VC models aren't yet supported on Linux either by Logitech nor the Internet community.  It looks like it may take another month or two according to a person in the know I talked to.

    Also, I found instructions for how to disassemble the QuickCam.  This is good news as I'll be able to mount the ball-joint solidly into the QuickCam instead of just glueing it on.  Also getting to the insides just might enable me to mount a sub-micro servo inside to control the focus from the computer.  This will be quite an achievement if I can control the focus from the computer AND have the servo mounted inside the QuickCam.  I've always been confident I can mount the servo outside; maybe, just maybe I can also package it up nicely too.  Besides, there's lots of wires and cables already on the outside for the eyelids.
 

RMax as a TV Set-Top Robot

    Oh, I also connected RMax and the laptop into our Big Screen TV.  One of the obvious uses of a physical Android Robot Head computer is as a TV Set-Top device.  The idea is simple:   You tell the robot to "Go to Channel 9", "Go to CNN", "Set the VCR Date", "Start playing the video",  "Record NOVA tonight while we're gone, and find out when it comes on and what channel yourself".

    It's been a busy April 1999.