CS 444 - Week 6 Lecture 2 - 2015-02-26

*   a few final points re: leJOS object detection

*   feature - in the world of leJOS,
    feature is meant to be a more neutral term
    for something a sensor can detect

    ...not NECESSARILY an obstacle (although it might be)
    ...not NECESSARILY its desired goal (")
    ...avoiding the word "object" because TOO easy to
       confuse with OBJECT-oriented programming...

*   in leJOS, then,
    a FeatureDetector detects objects using a sensor

    leJOS includes 2 implementations of this interface:
    *   RangeFeatureDetector
    *   TouchFeatureDetector

    *   a RangeFeatureDetector instance, then,
        can call its scan method,
	
	which returns a Feature object

	...usually.

        ...what if it doesn't detect anything?
	...scan might return null!

        *   leJOS object-detection tutorial notes:
	    "Warning: make sure to check for a null
	    object before trying to read data from the
	    returned Feature object,
	    otherwise your code might throw a null pointer
	    exception."

            Feature result = myFeatureDetector.scan();

	    // it is WISE to follow this with SOME kind
	    //   of assurance that result is NOT null
	    //   before attempting to call a Feature 
	    //   method using it!

            if (result != null)
            {
                ... it is safe to call 
                    result.getRangeReading() etc. ...
            }

************
ASIDE
...or you could try using a try-catch ...
************
*   we know that some methods in Java can throw
    so-called exceptions

*   there is a superclass called Exception
    and I *believe* all *Exception classes
    are either children or descendants of this
    class;

*   mention: the Java (and hopefully leJOS)
    APIs should note when a method MIGHT throw
    an exception

    ...IF you know a statement MIGHT cause an
    exception to be thrown, you can place it 
    in a try block:

    try
    {
        ...statement(s) some of which MIGHT cause
           an exception to be thrown...
    }
    catch(NullPointerException e)
    {
        ...
    }
    catch(ArrayIndexOutOfBoundsException e)
    {
        ...
    }

    // note that if you don't know WHAT exception
    // might be thrown, you can catch Exception,
    //    which being an ancestor of all of them
    //    should catch ANY of them...!

    finally
    {
        // optional!
        // means do this ALWAYS, whether an exception
        //    is thrown or not
    }
 
*   semantics:
    *   statements are done in the try block.
        IF an exception is thrown, control
	immediately passes FROM the try-block
	TO the first catch block whose type
	matches the type of the thrown expection
        and do THAT catch block's actions

        ...then proceed either to the finally
	block OR to the next statement after
	the last catch

        if NO exception is thrown in the try
	block, either the finally block's
	actions will be done, or if no
	finally block is there,
	continue with the next statement after
	the last catch block

Welcome to DrJava.  Working directory is /Users/smtuttle/humboldt/s15cs444/444lectures-and-labs/444week04-2
> String name;
> name.length()
java.lang.NullPointerException

[edited for more-proper formatting/readability!]

> try
  {
       System.out.println("" + name.length());
  } 
  catch(NullPointerException e)
  {
        System.out.println("cannot follow a null, my dear person!");
  }
cannot follow a null, my dear person!

> try
  {
      System.out.println("" + name.length());
      System.out.println("AHA!");
  } 
  catch(ArrayIndexOutOfBoundsException e)
  {
        System.out.println("NOOOOOOOO");
  } 
  catch(NullPointerException e)
  {
        System.out.println("can't follow a null pointer, still!");
  } 
  catch(Exception e)
  {
        System.out.println("BETTER not get here!");
  }
can't follow a null pointer, still!
> 

*   ...
    I think this might be possible:

    try
    {
        System.out.println("Range: " + 
            result.getRangeReading().getRange());
    }
    catch (NullPointerException null_exc)
    {
        System.out.println("NO feature detected");
    }

*   END OF try-catch ASIDE *****

*   ...and with your FeatureDetector,
    you can automatically notify other classes
    when an object is detected
    with the help of LISTENERS

    ...can add one or more FeatureListeners to a 
       FeatureDetector,
       and when a feature is detected,
       each listener's featureDetected() method
       will be called!

*   aside: you can combine several feature detectors
    into ONE feature detector instance
    using the FusorDetector class...! sounds cool!

***************************************************
*   BUT... moving on now to
    SUBSUMPTION architecture, and Behavior-Based Robotics

    *   chapter 14! which you are to read by next
        Tuesday, remember!

    *   first defined by Rodney Brooks - while at
        MIT AI Lab

        *   insects: do pretty well, in spite of what	
            seems to be a SMALL memory model, small
	    data model;

	    ...seem to rely on a strategy of MANY simple
	    BEHAVIORS, that, when combined and
	    alternated, APPEAR as complex behavior;

        *   out of this strategy comes
            a practical implementation of
	    behavior-based robotics,
	    called subsumption architecture;

            ...architecture decomposes complex behaviors
	    into several smaller, simpler behaviors

            two discrete structures build up a
	    behavior:
	    sensors/inputs and actuators/outputs/actions

	    think of "flyswatter behavior"
	    ...SENSE a movement,
	    ...take the ACTION of flying away from that
	       movement

        *   there's a hierarchy or ordering to
	    these behaviors --
	    such that all "lower" level behaviors
	    are supposed to be SUPPRESSED when a
	    higher-level behavior takes over

    *   this is implemented in the lejos.robotics.subsumption
        package!