added some tests and fixed a few corner case bugs
diff --git a/aos/common/sensors/sensor_receiver-tmpl.h b/aos/common/sensors/sensor_receiver-tmpl.h
index 0c2c177..8faead0 100644
--- a/aos/common/sensors/sensor_receiver-tmpl.h
+++ b/aos/common/sensors/sensor_receiver-tmpl.h
@@ -7,9 +7,11 @@
 template<class Values>
 const time::Time SensorReceiver<Values>::kJitterDelay =
     time::Time::InSeconds(0.002);
+// Not a multiple of kSensorSendFrequency to unwedge ourself if we hit some bug
+// where it needs to get off of that frequency to work.
 template<class Values>
 const time::Time SensorReceiver<Values>::kGiveupTime =
-    time::Time::InSeconds(1.5);
+    time::Time::InSeconds(0.5555);
 
 template<class Values>
 SensorReceiver<Values>::SensorReceiver(
@@ -47,6 +49,8 @@
       synchronized_ = true;
       before_better_cycles_ = after_better_cycles_ = 0;
       last_good_time_ = time::Time::Now();
+    } else {
+      LOG(INFO, "synchronization failed\n");
     }
   }
 }
@@ -98,8 +102,6 @@
       if (before_better_cycles_ > kBadCyclesToSwitch) {
         LOG(INFO, "switching to the packet before\n");
         UpdateStartTime(data_.count - 1);
-        start_count_ = data_.count - 1;
-        start_time_ = last_time;
         before_better_cycles_ = after_better_cycles_ = 0;
       } else {
         ++before_better_cycles_;
@@ -127,13 +129,19 @@
   time::Time old_received_time(0, 0);
   const time::Time start_time = time::Time::Now();
   // When we want to send out the next set of values.
-  const time::Time goal_time = NextLoopTime(start_time) - kJitterDelay;
+  time::Time goal_time = NextLoopTime(start_time) - kJitterDelay;
+  if (goal_time < start_time) {
+    goal_time += kLoopFrequency;
+  }
   while (true) {
     if (ReceiveData()) return false;
     time::Time received_time = time::Time::Now();
-    if (received_time > goal_time) {
+    if (received_time >= goal_time) {
       // If this was the very first one we got, try again.
-      if (old_received_time == time::Time(0, 0)) return false;
+      if (old_received_time == time::Time(0, 0)){
+        LOG(INFO, "first one we got was too late\n");
+        return false;
+      }
 
       assert(old_received_time < goal_time);
 
diff --git a/aos/common/sensors/sensor_receiver.h b/aos/common/sensors/sensor_receiver.h
index eb4fc06..4503351 100644
--- a/aos/common/sensors/sensor_receiver.h
+++ b/aos/common/sensors/sensor_receiver.h
@@ -12,6 +12,8 @@
 namespace testing {
 
 FORWARD_DECLARE_TEST_CASE(SensorReceiverTest, Simple);
+FORWARD_DECLARE_TEST_CASE(SensorReceiverTest, BadStartup2);
+FORWARD_DECLARE_TEST_CASE(SensorReceiverTest, StartTimeAndCountMismatch);
 
 }  // namespace testing
 
@@ -46,6 +48,8 @@
   static const time::Time kGiveupTime;
 
   FRIEND_TEST_NAMESPACE(SensorReceiverTest, Simple, testing);
+  FRIEND_TEST_NAMESPACE(SensorReceiverTest, BadStartup2, testing);
+  FRIEND_TEST_NAMESPACE(SensorReceiverTest, StartTimeAndCountMismatch, testing);
 
   // Subclasses need to implement this to read 1 set of data (blocking until it
   // is available) into data().
diff --git a/aos/common/sensors/sensor_receiver_test.cc b/aos/common/sensors/sensor_receiver_test.cc
index a86b732..3fd19f5 100644
--- a/aos/common/sensors/sensor_receiver_test.cc
+++ b/aos/common/sensors/sensor_receiver_test.cc
@@ -106,6 +106,49 @@
   EXPECT_EQ(50, receiver().unpacks());
 }
 
+TEST_F(SensorReceiverTest, BadStartup1) {
+  time::Time::SetMockTime(NextLoopTime() - Time(0, 100));
+  for (int i = 0; i < 55; ++i) {
+    receiver().RunIteration();
+  }
+  EXPECT_EQ(1, receiver().resets());
+  EXPECT_EQ(5, receiver().unpacks());
+}
+
+TEST_F(SensorReceiverTest, BadStartup2) {
+  time::Time::SetMockTime(NextLoopTime() -
+                          SensorReceiver<TestValues>::kJitterDelay);
+  for (int i = 0; i < 55; ++i) {
+    receiver().RunIteration();
+  }
+  EXPECT_EQ(2, receiver().resets());
+  EXPECT_EQ(5, receiver().unpacks());
+}
+
+TEST_F(SensorReceiverTest, BadStartup3) {
+  time::Time::SetMockTime(NextLoopTime() -
+                          time::Time::InSeconds(0.002) +
+                          kLoopFrequency / 20);
+  for (int i = 0; i < 55; ++i) {
+    receiver().RunIteration();
+  }
+  EXPECT_EQ(1, receiver().resets());
+  EXPECT_EQ(5, receiver().unpacks());
+}
+
+// I think that it somehow got this way once and never recovered.
+// It should never get this way, but if it does, it should recover.
+TEST_F(SensorReceiverTest, StartTimeAndCountMismatch) {
+  for (int i = 0; i < 1005; ++i) {
+    receiver().RunIteration();
+    if (i == 3) {
+      receiver().start_count_ += 10;
+    }
+  }
+  EXPECT_EQ(2, receiver().resets());
+  EXPECT_GT(receiver().unpacks(), 30);
+}
+
 // TODO(brians) finish writing tests and commenting them and the code
 
 }  // namespace testing
diff --git a/aos/common/time.h b/aos/common/time.h
index cb6c24f..14cc19e 100644
--- a/aos/common/time.h
+++ b/aos/common/time.h
@@ -167,6 +167,7 @@
   // Absolute value.
   Time abs() const {
     if (*this > Time(0, 0)) return *this;
+    if (nsec_ == 0) return Time(-sec_, 0);
     return Time(-sec_ - 1, kNSecInSec - nsec_);
   }
 
@@ -178,6 +179,7 @@
   static void SetMockTime(const Time now);
   // Convenience function to just increment the mock time by a certain amount.
   static void IncrementMockTime(const Time amount) {
+    // TODO(brians) make this thread safe so it's more useful?
     SetMockTime(Now() + amount);
   }
   // Disables mocking time.