Page 139 - Hacking Roomba
P. 139
120 Part I — Interfacing
Bit Fields
A bit holds a single on/off (Boolean or binary) value. In many computer languages, Java
included, the concept of a Boolean value is distinct from a numeric value with the value of 0 or
1. To convert a bit in a bit field to a Boolean requires two steps. First, you get out the bit you
want, and then you convert the bit to a Boolean value.
The pattern for getting out a bit in a bit field is:
boolean bit = somebyte & (bit_position << 1)
By using the logical AND operator (&), you mask off all the other bits to leave only the one you
want. In practice you don’t usually do the left-shift of a bit position but just use the numeric
value it represents. For example, a bit in position 2 has a value of 0x04, because (2<<1) == 0x04.
You can remember these bit masks by making them usefully named constants, for example
BUMPLEFT_MASK to get the bump left bit.
To help in remembering which byte of the array to work on, also define constants for the posi-
tions in the array, like BUMPWHEELDROPS for the first byte in the array. These constant defini-
tions aren’t necessary, but they do cut down on the typos.
The preceding equation is actually a little wrong, especially for Java. The masking returns the
byte value of the bit set. So if it were the left-most bit, the value after masking would be either
zero or 127 (0x80). This can lead to all sorts of nasty, hard-to-find bugs. Java tries to help you
out with this by forcing you to convert a number to a Boolean value. In Java, the preceding
would really be written as:
boolean bit = (somebyte & (bit_position << 1)) != 0;
The test against zero results in a Boolean value, effectively doing a conversion. With this cor-
rection and using defines, the test for left and right bumps become Listing 6-4.
Listing 6-4: RoombaComm.bumpLeft() and .bumpRight()
public boolean bumpLeft() {
return (sensor_bytes[BUMPSWHEELDROPS] & BUMPLEFT_MASK) !=0;
}
public boolean bumpRight() {
return (sensor_bytes[BUMPSWHEELDROPS] & BUMPRIGHT_MASK) !=0;
}
All binary sensor values in RoombaComm are implemented the same way. They are too
numerous to list here; check the code or the Javadocs. As you might expect, they are
cliffFrontLeft() and wheelDropCenter().
Chapter 2 and the ROI specification show the various bit values available in the sensor
data. Chapter 2 also mentions briefly in a Tip how to test single bits. The converse of reading
bits, writing them, is discussed in the sidebar “Setting and Clearing Bits” in the same chapter.
Many of the same techniques are used to either read or write bits.