Page 136 - Hacking Roomba
P. 136

Chapter 6 — Reading the Roomba Sensors                 117



                             buffer, is the staging area for incoming data. There is no guarantee that you’ll  receive all
                             26 bytes of sensor data at once, so what is received is buffered up. To keep track of progress, the
                             bufferLast variable is a count of how many bytes received so far.
                             The data received does not contain start- or end-markers; so you have to assume that every 26
                             bytes is a whole sensor packet. This presents some interesting synchronization problems if the
                             SENSORS command is used a lot and you need a guaranteed response time. Just trust that things
                             are okay. If you were building a robot for industrial use, this would be entirely unacceptable, but
                             for hacking it’s okay and rarely messes up.
                             In the serialEvent method itself, first make sure the event is the right type (DATA_AVAILABLE)
                             and then loop while data is available() and read data from the input into buffer. If it
                             gets 26 bytes, reset the counter and copy the finished data into sensor_bytes. Finally, report
                             that there’s data with sensorsValid and update the internal state of the RoombaComm
                             object with computeSensors(). The computeSensors() method encapsulates any process-
                             ing of a newly received sensor packet. Right now, computeSensors() does nothing. If you
                             wanted to add functionality to RoombaComm that acts on sensor data, the place to add it would
                             be computeSensors().
                             So as far as the code goes, it’s straightforward. What is difficult to deal with is the multi-
                             threaded nature of this setup. The serialEvent() method may be called at any time, like
                             when your code may be in the middle of driving the Roomba or updating a user interface.
                             You mitigate this problem with the buffer[] holding area and communicating through the
                             sensorsValid flag. When you want to update your sensors info, set sensorsValid=false,
                             send the SENSORS command to the Roomba, and then watch for sensorsValid to become
                             true again.

                             Making Serial Events Invisible
                             By decoupling the sending of the SENSORS command and when sensor_bytes gets updated,
                             you can have your code go about doing other things like dealing with a user interface. This
                             makes the code more responsive to the user. But, if you don’t mind sitting and waiting, you can
                             do what updateSensors() does in RoombaCommSerial, as in Listing 6-2:


                               Listing 6-2: RoombaCommSerial.updateSensors()
                               public boolean updateSensors() {
                                 sensorsValid = false;
                                 sensors();
                                 for(int i=0; i < 20; i++) {
                                   if( sensorsValid ) {
                                     break;
                                   }
                                   pause(50);
                                 }
                                 return sensorsValid;
                               }
   131   132   133   134   135   136   137   138   139   140   141