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.