fix compile error
[bachelor-thesis/roomba_tests.git] / main.cc
diff --git a/main.cc b/main.cc
index 2363146..09bf40b 100644 (file)
--- a/main.cc
+++ b/main.cc
 #include <QApplication>
 #include <QInputDialog>
 
+using namespace std;
+
 #if QT_VERSION < 0x040500
 #define getInt QInputDialog::getInteger
 #else // QT_VERSION > 0x040500
 #define getInt QInputDialog::getInt
 #endif // QT_VERSION
-
-using namespace std;
-
 // UART port on which we communicate with the Roomba
 char uart[] = "/dev/ttyUSB0";
 
@@ -58,23 +57,54 @@ OsModel::Timer::self_t timer;
 Roomba roomba;
 RoombaUart roomba_uart(os);
 ControlledMotion ctrl_motion;
+char * roomba_id;
+char * ground_type;
 
 /**
  * Sensor data we need, filled in callback
  */
 struct SensorData {
+
+  SensorData() :
+    capacity(0), charge(0), charging(0), current(0), temperature(0),
+      voltage(0), abs_left_encoder_counts(0), abs_right_encoder_counts(0) {
+  }
+
   uint16_t capacity, charge;
   uint8_t charging;
   int16_t current;
   int8_t temperature;
   uint16_t voltage;
-  int16_t left_encoder_counts, right_encoder_counts;
+  /** absolute encoder counts; i.e. not overflown, but consecutive */
+  int abs_left_encoder_counts, abs_right_encoder_counts;
 } sensor_data;
 
+/**
+ * Returns the difference between two unsigned short values. The calculated
+ * value is always smaller or equal to 0x8000.
+ * This is useful if you have an overflowing counter and you want to determine
+ * when you have to "wrap over" the value.
+ */
+int nearest_diff(unsigned short last, unsigned short current) {
+  int d = current - last;
+  if(d < -0x8000) { // overflow in positive direction
+    d = (0x10000 - last + current);
+  }
+  if(d >= 0x8000) { // overflow in negative direction
+    d = -(0x10000 - current + last);
+  }
+}
+
 /**
  * Callback that fills the sensor data when data is available
  */
 struct DataAvailable {
+  int latest_encoder_left_, latest_encoder_right_;
+
+  DataAvailable() :
+    latest_encoder_left_(0), latest_encoder_right_(0) {
+  }
+
   void cb(int state) {
     if(state != Roomba::DATA_AVAILABLE) {
       return;
@@ -84,8 +114,12 @@ struct DataAvailable {
     sensor_data.charging = roomba().charging;
     sensor_data.current = roomba().current;
     sensor_data.voltage = roomba().voltage;
-    sensor_data.left_encoder_counts = roomba().left_encoder_counts;
-    sensor_data.right_encoder_counts = roomba().right_encoder_counts;
+    sensor_data.abs_left_encoder_counts += nearest_diff(latest_encoder_left_,
+      roomba().left_encoder_counts);
+    latest_encoder_left_ = roomba().left_encoder_counts;
+    sensor_data.abs_right_encoder_counts += nearest_diff(latest_encoder_right_,
+      roomba().right_encoder_counts);
+    latest_encoder_right_ = roomba().right_encoder_counts;
   }
 } data_available;
 
@@ -110,44 +144,45 @@ void drive(Roomba& roomba, ControlledMotion& ctrl_motion) {
     input_distance = getInt(0, "Input distance", chargeText(roomba)
       + "Input new distance in mm:", input_distance,
       numeric_limits<int>::min(), numeric_limits<int>::max(), 1, &ok);
-    if(ok) {
-      // new turn velocity
-      velocity = getInt(0, "Input velocity", chargeText(roomba)
-        + "Input drive velocity in mm/sec:", velocity, -500, 500, 10, &ok);
-      if(ok) {
-        ctrl_motion.move_distance(input_distance, velocity);
-        roomba.wait_for_stop();
-      } else {
-        break;
-      }
-    } else {
+    if(!ok) {
+      break;
+    }
+    // new velocity
+    velocity = getInt(0, "Input velocity", chargeText(roomba)
+      + "Input drive velocity in mm/sec:", velocity, -500, 500, 10, &ok);
+    if(!ok) {
       break;
     }
+    ctrl_motion.move_distance(input_distance, velocity);
+    roomba.wait_for_stop();
 
     // measured deviation
     deviation_x = getInt(0, "Input x deviation", chargeText(roomba)
       + "Input travelled distance on x axis in mm:", deviation_x,
       numeric_limits<int>::min(), numeric_limits<int>::max(), 1, &ok);
-    if(ok) {
-      deviation_y = getInt(0, "Input y deviation", chargeText(roomba)
-        + "Input travelled distance on y axis in mm:", deviation_y,
-        numeric_limits<int>::min(), numeric_limits<int>::max(), 1, &ok);
-      if(ok) {
-        cout << "svn=" << SVNREVISION << " input_distance=" << input_distance
-          << " velocity=" << velocity << " internal_distance="
-          << roomba.distance() << " deviation_x=" << deviation_x
-          << " deviation_y=" << deviation_y << " encoder_ticks_left="
-          << sensor_data.left_encoder_counts << " encoder_ticks_right="
-          << sensor_data.right_encoder_counts << " batt_charge="
-          << sensor_data.charge << " batt_capacity=" << sensor_data.capacity
-          << " batt_voltage=" << sensor_data.voltage << " batt_current="
-          << sensor_data.current << endl;
-      } else {
-        break;
-      }
-    } else {
+    if(!ok) {
       break;
     }
+    deviation_y = getInt(0, "Input y deviation", chargeText(roomba)
+      + "Input travelled distance on y axis in mm:", deviation_y,
+      numeric_limits<int>::min(), numeric_limits<int>::max(), 1, &ok);
+    if(!ok) {
+      break;
+    }
+    cout << "svn=" << SVNREVISION << " roomba_id=" << roomba_id
+      << " move=straight" << " ground_type=" << ground_type
+      << " input_distance=" << input_distance << " velocity=" << velocity
+      << " internal_distance=" << roomba.distance() << " deviation_x="
+      << deviation_x << " deviation_y=" << deviation_y
+      << " abs_encoder_ticks_left=" << sensor_data.abs_left_encoder_counts
+      << " abs_encoder_ticks_right=" << sensor_data.abs_right_encoder_counts
+      << " batt_charge=" << sensor_data.charge << " batt_capacity="
+      << sensor_data.capacity << " batt_voltage=" << sensor_data.voltage
+      << " batt_current=" << sensor_data.current << endl;
+
+    // reset, because we only need the difference between two drive commands
+    sensor_data.abs_left_encoder_counts = 0;
+    sensor_data.abs_right_encoder_counts = 0;
   }
 }
 
@@ -188,23 +223,28 @@ void turn(Roomba& roomba, ControlledMotion& ctrl_motion) {
     // new current angle
     measured_angle = getInt(0, "Input measured angle", chargeText(roomba)
       + QString("Orientation should be %1 degree now.\n\n").arg((cur_angle
-      + turn_angle) % 360) + "Input measured angle in degree the Roomba has "
+        + turn_angle) % 360) + "Input measured angle in degree the Roomba has "
       "turned:", turn_angle, 0, numeric_limits<int>::max(), 1, &ok);
     if(!ok) {
       break;
     }
 
-    cout << "turn_angle=" << turn_angle << " measured_angle=" << measured_angle
-      << " velocity=" << velocity << " internal_angle=" << roomba.angle()
-      << " encoder_ticks_left=" << sensor_data.left_encoder_counts
-      << " encoder_ticks_right=" << sensor_data.right_encoder_counts
+    cout << "svn=" << SVNREVISION << " roomba_id=" << roomba_id
+      << " move=straight" << " ground_type=" << ground_type << "turn_angle="
+      << turn_angle << " measured_angle=" << measured_angle << " velocity="
+      << velocity << " internal_angle=" << roomba.angle()
+      << " abs_encoder_ticks_left=" << sensor_data.abs_left_encoder_counts
+      << " abs_encoder_ticks_right=" << sensor_data.abs_right_encoder_counts
       << " batt_charge=" << sensor_data.charge << " batt_capacity="
       << sensor_data.capacity << " batt_voltage=" << sensor_data.voltage
       << " batt_current=" << sensor_data.current << endl;
 
+    // reset, because we only need the difference between two turns
+    sensor_data.abs_left_encoder_counts = 0;
+    sensor_data.abs_right_encoder_counts = 0;
+
     // new orientation
     cur_angle = (cur_angle + measured_angle) % 360;
-
   }
 }
 
@@ -213,8 +253,9 @@ void turn(Roomba& roomba, ControlledMotion& ctrl_motion) {
  */
 int main(int argc, char ** argv) {
 
-  if(argc < 2) {
-    cerr << "Usage: " << argv[0] << " --turn|-t|--drive|-d" << endl;
+  if(argc < 4) {
+    cerr << "Usage: " << argv[0]
+      << " --turn|-t|--drive|-d roomba-id ground-type" << endl;
     exit(-1);
   }
 
@@ -241,6 +282,8 @@ int main(int argc, char ** argv) {
   roomba.notify_state_receivers(Roomba::DATA_AVAILABLE);
 
   // actual tests
+  roomba_id = argv[2];
+  ground_type = argv[3];
   if(strcmp(argv[1], "--turn") == 0 || strcmp(argv[1], "-t") == 0) {
     turn(roomba, ctrl_motion);
   } else if(strcmp(argv[1], "--drive") == 0 || strcmp(argv[1], "-d") == 0) {
This page took 0.027655 seconds and 4 git commands to generate.