/**
   * Initializes the Create by sending the start command over the serial cable from the Qwerk to the
   * Create. Also reads sensor data from the Create to determine the initial configuration of the
   * robot
   */
  public void initialize() {
    // Create a serial service
    final SerialIOService serialIOService = getQwerkController().getSerialIOService();
    if (serialIOService != null) {
      try {
        // Close the serial port if for some reason an earlier program left it open
        serialIOService.getSerialPort(QwerkSerialPortDevice.DEV_TTY_AM1.getName()).close();

        // Open the serial port with our configuration values (baud = 57600, 8n1, no flow control)
        serialIOService.getSerialPort(QwerkSerialPortDevice.DEV_TTY_AM1.getName()).open(config);
        System.out.println("Serial port opened.");

        // Send the start command and change mode to 'safe'
        byte[] data = new byte[2];
        data[0] = (byte) 128; // start command
        data[1] = (byte) 131; // change mode to 'safe' mode

        // Write the data to the Create through the serial port
        serialIOService.getSerialPort(QwerkSerialPortDevice.DEV_TTY_AM1.getName()).write(data);
        System.out.println(dateFormatter.format(new Date()) + "Data written successfully.");
      } catch (SerialIOException e) {
        final String msg = "SerialIOException while opening the serial port";
        System.out.println(dateFormatter.format(new Date()) + msg + e);
      }
    } else {
      System.out.println(dateFormatter.format(new Date()) + "SerialIOService is null!");
    }

    // Update the sensors on initialization - this reads in values for all of the sensor variables
    // defined at the start of this class
    updateSensors();
  }
 /** @return The distance in millimeters the right wheel of the Create has traveled */
 public double rightWheelDistance() {
   updateSensors();
   return rightWheelDistance;
 }
 /** @return The distance in millimeters the left wheel of the Create has traveled */
 public double leftWheelDistance() {
   updateSensors();
   return leftWheelDistance;
 }
 /** @return The angle in degrees that the Create has traveled */
 public int angle() {
   updateSensors();
   return angle;
 }
 /** @return The distance in millimeters that the Create has traveled */
 public int distance() {
   updateSensors();
   return distance;
 }
 /** @return True if the advance button on the Create is pressed, false otherwise */
 public boolean advanceButtonPressed() {
   updateSensors();
   return advanceButtonPressed;
 }
 /** @return True if the left bumper is depressed, false otherwise */
 public boolean bumpLeft() {
   updateSensors();
   return bumpLeft;
 }
 /** @return The charge remaining in the battery pack in milliAmp-hours. */
 public int robotChargeRemaining() {
   updateSensors();
   return batteryCharge;
 }
 /** @return True if a wall is seen on the right side of the robot, false otherwise */
 public boolean wallSeen() {
   updateSensors();
   return wallSeen;
 }
 /** @return True if the front right cliff sensor sees a cliff, false otherwise */
 public boolean cliffFrontRight() {
   updateSensors();
   return cliffFrontRight;
 }
 /** @return True if the front left cliff sensor sees a cliff, false otherwise */
 public boolean cliffFrontLeft() {
   updateSensors();
   return cliffFrontLeft;
 }
 /** @return True if the caster is dropped, false otherwise */
 public boolean wheelDropCaster() {
   updateSensors();
   return wheelDropCaster;
 }
 /** @return True if the right wheel is dropped, false otherwise */
 public boolean wheelDropRight() {
   updateSensors();
   return wheelDropRight;
 }
 /** @return True if the left wheel is dropped, false otherwise */
 public boolean wheelDropLeft() {
   updateSensors();
   return wheelDropLeft;
 }
 /** @return True if the right bumper is depressed, false otherwise */
 public boolean bumpRight() {
   updateSensors();
   return bumpRight;
 }
 /** @return The voltage of the Create's battery pack in millivolts */
 public int robotVoltage() {
   updateSensors();
   return voltage;
 }
 /**
  * @return The current draw on the Create's battery pack in milliAmps - negative numbers imply
  *     current flowing out of the battery
  */
 public int robotCurrent() {
   updateSensors();
   return current;
 }
 /** @return True if an iRobot virtual wall is seen by the central IR sensor, false otherwise */
 public boolean virtualWallSeen() {
   updateSensors();
   return virtualWallSeen;
 }
 /** @return True if the play button on the Create is pressed, false otherwise */
 public boolean playButtonPressed() {
   updateSensors();
   return playButtonPressed;
 }
  /**
   * Cause the Create to rotate by the number of degrees specified by <code>travelAngle</code>
   *
   * @param travelAngle Specifies the number of degrees to rotate - positive values cause counter
   *     clockwise rotation, negative values cause clockwise rotation
   */
  public void moveAngle(int travelAngle) {
    int leftMotor = 0;
    int rightMotor = 0;

    if (travelAngle > 0) {
      leftMotor = 65406;
      rightMotor = 130;
    } else if (travelAngle < 0) {
      leftMotor = 130;
      rightMotor = 65406;
    }

    // Get a serial service
    final SerialIOService serialIOService = getQwerkController().getSerialIOService();
    if (serialIOService != null) {
      try {
        // Convert negative distances to values over 32767 to send the data in two's complement form
        int sleepTime;

        if (travelAngle < 0) {
          sleepTime = -travelAngle * 20;
          travelAngle += 65536;
        } else {
          sleepTime = travelAngle * 20;
        }
        updateSensors();
        // Create the movement packet
        byte[] data = new byte[15];

        data[0] = (byte) 131; // Change mode to 'safe'
        data[1] = (byte) 145; // Send the command for driving the wheels
        data[2] = (byte) (rightMotor / 256); // Send the high 8-bits for right wheel speed
        data[3] = (byte) (rightMotor % 256); // Send the low 8-bits for right wheel speed
        data[4] = (byte) (leftMotor / 256);
        data[5] = (byte) (leftMotor % 256);
        data[6] = (byte) 157; // Change mode to 'safe'
        data[7] = (byte) (travelAngle / 256); // Send the high 8-bits for travel distance
        data[8] = (byte) (travelAngle % 256); // Send the low 8-bits for travel distance
        data[9] = (byte) 131; // Change mode to 'safe'
        data[10] = (byte) 145; // Send the command for driving the wheels
        data[11] = (byte) (0); // Send the high 8-bits for right wheel speed
        data[12] = (byte) (0); // Send the low 8-bits for right wheel speed
        data[13] = (byte) (0);
        data[14] = (byte) (0);

        // Write the data to the Create through the Qwerk's serial port
        serialIOService.getSerialPort(QwerkSerialPortDevice.DEV_TTY_AM1.getName()).write(data);
        System.out.println(dateFormatter.format(new Date()) + "Data written successfully.");
        stopMoving();
        if (travelAngle < 0) {
          travelAngle = -travelAngle;
        }
        sleepUnlessStop(sleepTime);
        updateSensors();
      } catch (SerialIOException e) {
        final String msg = "SerialIOException while writing to the serial port";
        System.out.println(dateFormatter.format(new Date()) + msg);
      }
    } else {
      System.out.println(dateFormatter.format(new Date()) + "SerialIOService is null!");
    }
  }