Page 118 - Hacking Roomba
P. 118
Chapter 5 — Driving Roomba 99
Listing 5-1: RoombaComm.drive()
public void drive(int velocity, int radius) {
byte cmd[] = {(byte)DRIVE,
(byte)(velocity>>>8),(byte)(velocity&0xff),
(byte)(radius >>>8),(byte)(radius &0xff)};
send(cmd);
}
Using it to replace the DRIVE command created before results in the following:
roombacomm.drive(500,-1);
This command is much easier to read and understand.
The internals of the drive() method may look a little strange if you are not familiar with
bit-manipulation. The situation is this: There’s a 16-bit number (say, velocity) and you need
to break it up into two 8-bit bytes. In Java, as in most computer languages, the high byte (the
most significant byte) of a two-byte value is thought of as being on the left and the low byte
(the least significant byte) is thought of as being on the right. The statement velocity >>> 8
says “Shift velocity’s high byte to the right 8 bits” which results in the low byte being discarded,
moves the high byte into the low byte’s place, and fills the high byte with zero. Any 16-bit
number’s value without a high byte is the value of the low byte.
Knowing how to do bit manipulations is key to programming with robotics and microcon-
trollers. It’s easy to forget exactly how to form proper bit-manipulation code, so the first thing
you do is create a function to remember it for you, which is what drive() does.
The drive() command is what the Drive example program is based around. In fact, the
entirety of Drive, except the parsing of the command-line arguments, is in Listing 5-2.
Controlling Roomba is getting easier.
Listing 5-2: A Condensed Drive.java
String portname = “/dev/cu.KeySerial1”;
int velocity = 500, radius = -1, waittime = 2000;
RoombaCommSerial roombacomm = new RoombaCommSerial();
if( !roombacomm.connect(portname) )
System.exit(1);
roombacomm.startup();
roombacomm.control();
roombacomm.pause(100);
roombacomm.drive(velocity, radius);
roombacomm.pause(waittime);
roombacomm.stop();
roombacomm.disconnect();