CS 444 - Week 4 Lab - 2015-02-13 * lejos.robotics.navigation lejos.robotics.subsumption * packages we are working our way towards...! * discussed the types a given Java object is considered to be; * can be a pretty big set of types! * includes the class it is an instance of, AND all of its ancestor classes; * in lejos.robotics.navigation, there is class CompassPilot which is a subclass of DifferentialPilot which is a subclass of Object CompassPilot compy = new ... uh oh its deprecated, don't use it BUT... what are compy's types? CompassPilot, DifferentialPilot, and Object * NOW -- Java does NOT permit multiple inheritance -- a class can only extend 1 other class (can only be a subclass of 1 other class) BUT: Java has another option, called INTERFACES -- an interface is not a class, but a set of requirements for classes that want to be known as conforming to that interface. * a class can IMPLEMENTS 0 or more interfaces public class Blah implements A, B, C ...then Blah is expected to IMPLEMENT every one of the requirements for all the interfaces it is implementing; * and then an instance of this class is ALSO considered to have as additional types those interfaces -- an instance of Blah is of considered to be of type Blah, type Object, *and* type A, type B, and type C (see the beauty of it? Any method that expects an argument of type A, can also now handle an argument of my new type Blah... ...it KNOWS that object has the methods that A requires... ...enter in Java events and event listeners... * Java 1.1 event handling model * an action like clicking a button is an event -- Java will tend to have classes for events * we have event SOURCES --like a button, a motor, etc. * we have event LISTENERS -- objects interested in receiving events (or receiving notice of events, if you will) * an event source maintains a list of listeners that want to be notified when an event occurs; when they are notified, they can DO something based on that event. * to put it another way: do you want something to happen when a button is clicked? IF SO, you register an event listener with that button, and each time the user clicks that button, control is passed to EACH of its registered listeners, and its appropriate methods will be called * attempt an example... * package lejos.nxt has class Button * Button has an addButtonListener method -- I can add a specified ButtonListener to a button, and then when that button is clicked, the APPROPRIATE method of EACH registered buttonlistener will be called * OK, what is a ButtonListener? an interface, with 2 methods that are expected to be implemented: public void buttonPressed(Button b) public void buttonReleased(Button b) * AFTER CLASS: *did* get a version of ButtonEventPlay running! * includes a main method that creates an instance of the class itself (using its default constructor, in this case), and then calls a local non-static method that adds a listener instance to each button * why are there *5* versions posted? Because I went overboard checking something out...! * if you only look at one, look at ButtonEventPlay.java! * uses a single private inner class, within the public class ButtonEventPlay, to create the four button listeners for the four buttons on the NXT brick * this private inner class implements ButtonListener -- so it indeed implements the required buttonPressed and buttonReleased methods; ...since it implements interface ButtonListener, an instance of this class if considered to be of type ButtonListener, and so CAN be the argument to the addButtonListener method, ...which can be called on a Button instance to make it sensitive as desired to user actions; * its ButtonEventPlay.nxj's size on NXT brick: 9100 bytes * ButtonEventPlay2.java: uses *anonymous* inner classes for the ButtonListener arguments of the addButtonListener calls; * its ButtonEventPlay2.nxj's size on NXT brick: 9356 bytes * ButtonEventPlay3.java: uses *4* private inner classes, an instance of each being used for one of the addButtonListener calls; * its ButtonEventPlay3.nxj's size on NXT brick: 9432 bytes * ButtonEventPlay4.java and ButtonEventPlay5.java: UH-GLY versions of ButtonEventPlay3.java to test something about nxjc-and-nxjlink resulting file sizes * their .nxj's sizes on NXT brick: also 9432 bytes each * fair to ask: was there a POINT to all those versions? * readability usually should trump minor memory savings, in MANY settings (for example, personal computers, workstations) ...BUT with small memory-challenged devices like NXT bricks, memory needs to be considered more than one typically would nowadays, I *think*; * IF, with some abstraction, an "only useful for THIS class" listener can be shared by MORE than one object, I think a private inner class, as in ButtonEventPlay.java, is the better course (and it does turn out the be the smallest here -- BUT the water might get considerably muddier if the 4 button's actions weren't identical, I think.) * I'd still go with the reused private inner class if it can be used by more than 1 object in the same class (and even go PUBLIC if more than one *class* might actually be able to use...!) ...this seems more robust and more readable; * IF a listener is SHORT -- so readability really isn't impacted TOO much -- and only one object can use it, this little experiment I think provides some supporting evidence that the anonymous inner class may take less memory, and since it is short, readability should not take TOO big a hit -- BUT I *do* think you have to be CAREFUL how you indent it, to improve readability; * but if complex/long -- I'd still consider the private inner class over the anonymous inner class, I think. * easier to write, to read, to debug, to maintain, etc. * (and, by the way? The UH-GLY ButtonEventPlay4.java and ButtonEventPlay5.java suggest what I suspected -- nxjc does indeed strip out comments in the compiled result, and the original source code's spacing, indentation, white space matter NOT A WHIT in the resulting bytecode. So, DON'T go thinking that omitting comments or good indentation and use of white space in your source code is buying you ANYTHING with regard to space on your brick...!) * ButtonEventPlay3.java -> ButtonEventPlay3.nxj, size: 9432 * ButtonEventPlay4.java -> ButtonEventPlay4.nxj, size: 9432 (all comments removed) * ButtonEventPlay5.java -> ButtonEventPlay5.nxj, size: 9432 (all indentation removed, { and } moved to previous lines) ...try it if you doubt it... 8-) ******** moving on! ******** * different types of robots can be controlled by different higher-level classes as well; * consider a 2-wheeled robot, where the 2 wheels are each controlled by an independent motor; This can be controlled using the DifferentialPilot class these higher-level classes work at several levels of abstraction: * at bottom, there are motors that turn the wheels, controlled by the NXTRegulatedMotor class * The DifferentialPilot class uses the motors for elementary moves: rotate in place travel in a straight line travel in an arc * at the NEXT level, the Navigator class uses DifferentialPilot to MOVE the robot through a path in a plane ...to do navigaton, the robot needs the robot location, and direction it is heading * it uses OdometryPoseProvider to keep this information up to date. * the control is top down: the navigator controls the pilot whch controls the motors. the flow of information is from the bottom up: pilot uses info from the motors to control them, the pose provider uses odometry info from the pilot to update its current estimate of the robot pose, (the pose consists of the robot's coordinates and its heading angle -- the direction it is facing) the navigator uses this data to calculate the distance and direction of the destination. * guess what this flow of info uses? events and listeners!! * DifferentialPilot * expects to control a vehicle with two driving wheels, each with its own motor * this object needs to know the wiring diagram of the robot, e.g., which ports the motors are connected to, and whether rotating the motors forward makes the robot go forward * it needs know the diameter of the wheels * and the width of the track (the distance between the centers of the tracks of the two wheels ...TravelTest.java