Add remote timestamps and queue_index to context
This gives us the knobs to expose the remote timestamps and queue_index
to anything receiving the events. The first use case is the logger. It
can now log forwarded entries *without* having to make the
message_gateway responsible for logging this data.
Change-Id: Ie34dd040d270f4fa90ecd6e463069e1adca1818a
diff --git a/aos/controls/control_loop-tmpl.h b/aos/controls/control_loop-tmpl.h
index f937bb4..349a55c 100644
--- a/aos/controls/control_loop-tmpl.h
+++ b/aos/controls/control_loop-tmpl.h
@@ -58,7 +58,7 @@
// If the driver's station reports being disabled, we're probably not
// actually going to send motor values regardless of what the FPGA
// reports.
- last_pwm_sent_ = robot_state_fetcher_.context().monotonic_sent_time;
+ last_pwm_sent_ = robot_state_fetcher_.context().monotonic_event_time;
}
}
diff --git a/aos/events/event_loop.cc b/aos/events/event_loop.cc
index af5a3e5..ee3365d 100644
--- a/aos/events/event_loop.cc
+++ b/aos/events/event_loop.cc
@@ -23,8 +23,10 @@
: event_loop_(event_loop),
channel_(channel),
timing_(event_loop_->ChannelIndex(channel)) {
- context_.monotonic_sent_time = monotonic_clock::min_time;
- context_.realtime_sent_time = realtime_clock::min_time;
+ context_.monotonic_event_time = monotonic_clock::min_time;
+ context_.monotonic_remote_time = monotonic_clock::min_time;
+ context_.realtime_event_time = realtime_clock::min_time;
+ context_.realtime_remote_time = realtime_clock::min_time;
context_.queue_index = 0xffffffff;
context_.size = 0;
context_.data = nullptr;
diff --git a/aos/events/event_loop.h b/aos/events/event_loop.h
index bd0c4d4..5edecf1 100644
--- a/aos/events/event_loop.h
+++ b/aos/events/event_loop.h
@@ -28,14 +28,25 @@
// Struct available on Watchers, Fetchers, Timers, and PhasedLoops with context
// about the current message.
struct Context {
- // Time that the message was sent, or the timer was triggered.
- monotonic_clock::time_point monotonic_sent_time;
- // Realtime the message was sent. This is set to min_time for Timers and
- // PhasedLoops.
- realtime_clock::time_point realtime_sent_time;
+ // Time that the message was sent on this node, or the timer was triggered.
+ monotonic_clock::time_point monotonic_event_time;
+ // Realtime the message was sent on this node. This is set to min_time for
+ // Timers and PhasedLoops.
+ realtime_clock::time_point realtime_event_time;
+
+ // For a single-node configuration, these two are identical to *_event_time.
+ // In a multinode configuration, these are the times that the message was
+ // sent on the original node.
+ monotonic_clock::time_point monotonic_remote_time;
+ realtime_clock::time_point realtime_remote_time;
+
// The rest are only valid for Watchers and Fetchers.
// Index in the queue.
uint32_t queue_index;
+ // Index into the remote queue. Useful to determine if data was lost. In a
+ // single-node configuration, this will match queue_index.
+ uint32_t remote_queue_index;
+
// Size of the data sent.
size_t size;
// Pointer to the data.
@@ -94,23 +105,60 @@
// Sends a message without copying it. The users starts by copying up to
// size() bytes into the data backed by data(). They then call Send to send.
// Returns true on a successful send.
+ // If provided, monotonic_remote_time, realtime_remote_time, and
+ // remote_queue_index are attached to the message and are available in the
+ // context on the read side. If they are not populated, the read side will
+ // get the sent times instead.
virtual void *data() = 0;
virtual size_t size() = 0;
- bool Send(size_t size);
+ bool Send(size_t size,
+ aos::monotonic_clock::time_point monotonic_remote_time =
+ aos::monotonic_clock::min_time,
+ aos::realtime_clock::time_point realtime_remote_time =
+ aos::realtime_clock::min_time,
+ uint32_t remote_queue_index = 0xffffffffu);
// Sends a single block of data by copying it.
- bool Send(const void *data, size_t size);
+ // The remote arguments have the same meaning as in Send above.
+ bool Send(const void *data, size_t size,
+ aos::monotonic_clock::time_point monotonic_remote_time =
+ aos::monotonic_clock::min_time,
+ aos::realtime_clock::time_point realtime_remote_time =
+ aos::realtime_clock::min_time,
+ uint32_t remote_queue_index = 0xffffffffu);
const Channel *channel() const { return channel_; }
+ // Returns the time_points that the last message was sent at.
+ aos::monotonic_clock::time_point monotonic_sent_time() const {
+ return monotonic_sent_time_;
+ }
+ aos::realtime_clock::time_point realtime_sent_time() const {
+ return realtime_sent_time_;
+ }
+ // Returns the queue index that this was sent with.
+ uint32_t sent_queue_index() const { return sent_queue_index_; }
+
protected:
EventLoop *event_loop() { return event_loop_; }
+ aos::monotonic_clock::time_point monotonic_sent_time_ =
+ aos::monotonic_clock::min_time;
+ aos::realtime_clock::time_point realtime_sent_time_ =
+ aos::realtime_clock::min_time;
+ uint32_t sent_queue_index_ = 0xffffffff;
+
private:
friend class EventLoop;
- virtual bool DoSend(const void *data, size_t size) = 0;
- virtual bool DoSend(size_t size) = 0;
+ virtual bool DoSend(const void *data, size_t size,
+ aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index) = 0;
+ virtual bool DoSend(size_t size,
+ aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index) = 0;
EventLoop *event_loop_;
const Channel *channel_;
diff --git a/aos/events/event_loop_param_test.cc b/aos/events/event_loop_param_test.cc
index c1256f3..e1e05a2 100644
--- a/aos/events/event_loop_param_test.cc
+++ b/aos/events/event_loop_param_test.cc
@@ -59,8 +59,10 @@
EXPECT_FALSE(fetcher.Fetch());
EXPECT_EQ(fetcher.get(), nullptr);
- EXPECT_EQ(fetcher.context().monotonic_sent_time, monotonic_clock::min_time);
- EXPECT_EQ(fetcher.context().realtime_sent_time, realtime_clock::min_time);
+ EXPECT_EQ(fetcher.context().monotonic_event_time, monotonic_clock::min_time);
+ EXPECT_EQ(fetcher.context().monotonic_remote_time, monotonic_clock::min_time);
+ EXPECT_EQ(fetcher.context().realtime_event_time, realtime_clock::min_time);
+ EXPECT_EQ(fetcher.context().realtime_remote_time, realtime_clock::min_time);
EXPECT_EQ(fetcher.context().queue_index, 0xffffffffu);
EXPECT_EQ(fetcher.context().size, 0u);
EXPECT_EQ(fetcher.context().data, nullptr);
@@ -76,14 +78,17 @@
const chrono::milliseconds kEpsilon(100);
- EXPECT_GE(fetcher.context().monotonic_sent_time,
- loop2->monotonic_now() - kEpsilon);
- EXPECT_LE(fetcher.context().monotonic_sent_time,
- loop2->monotonic_now() + kEpsilon);
- EXPECT_GE(fetcher.context().realtime_sent_time,
- loop2->realtime_now() - kEpsilon);
- EXPECT_LE(fetcher.context().realtime_sent_time,
- loop2->realtime_now() + kEpsilon);
+ const aos::monotonic_clock::time_point monotonic_now = loop2->monotonic_now();
+ const aos::realtime_clock::time_point realtime_now = loop2->realtime_now();
+ EXPECT_EQ(fetcher.context().monotonic_event_time,
+ fetcher.context().monotonic_remote_time);
+ EXPECT_EQ(fetcher.context().realtime_event_time,
+ fetcher.context().realtime_remote_time);
+
+ EXPECT_GE(fetcher.context().monotonic_event_time, monotonic_now - kEpsilon);
+ EXPECT_LE(fetcher.context().monotonic_event_time, monotonic_now + kEpsilon);
+ EXPECT_GE(fetcher.context().realtime_event_time, realtime_now - kEpsilon);
+ EXPECT_LE(fetcher.context().realtime_event_time, realtime_now + kEpsilon);
EXPECT_EQ(fetcher.context().queue_index, 0x0u);
EXPECT_EQ(fetcher.context().size, 20u);
EXPECT_NE(fetcher.context().data, nullptr);
@@ -512,12 +517,14 @@
auto test_timer = loop->AddTimer([this, ×, &expected_times, &loop]() {
times.push_back(loop->monotonic_now());
- EXPECT_EQ(loop->context().realtime_sent_time, realtime_clock::min_time);
+ EXPECT_EQ(loop->context().monotonic_remote_time, monotonic_clock::min_time);
+ EXPECT_EQ(loop->context().realtime_event_time, realtime_clock::min_time);
+ EXPECT_EQ(loop->context().realtime_remote_time, realtime_clock::min_time);
EXPECT_EQ(loop->context().queue_index, 0xffffffffu);
EXPECT_EQ(loop->context().size, 0u);
EXPECT_EQ(loop->context().data, nullptr);
- expected_times.push_back(loop->context().monotonic_sent_time);
+ expected_times.push_back(loop->context().monotonic_event_time);
if (times.size() == kCount) {
this->Exit();
}
@@ -684,7 +691,7 @@
TEST_P(AbstractEventLoopTest, MessageSendTime) {
auto loop1 = MakePrimary();
auto loop2 = Make();
- auto sender = loop1->MakeSender<TestMessage>("/test");
+ auto sender = loop2->MakeSender<TestMessage>("/test");
auto fetcher = loop2->MakeFetcher<TestMessage>("/test");
auto test_timer = loop1->AddTimer([&sender]() {
@@ -694,12 +701,32 @@
ASSERT_TRUE(msg.Send(builder.Finish()));
});
- loop2->MakeWatcher("/test", [&loop2](const TestMessage &msg) {
- // Confirm that the data pointer makes sense from a watcher.
- EXPECT_GT(&msg, loop2->context().data);
+ bool triggered = false;
+ loop1->MakeWatcher("/test", [&triggered, &loop1](const TestMessage &msg) {
+ // Confirm that the data pointer makes sense from a watcher, and all the
+ // timestamps look right.
+ EXPECT_GT(&msg, loop1->context().data);
+ EXPECT_EQ(loop1->context().monotonic_remote_time,
+ loop1->context().monotonic_event_time);
+ EXPECT_EQ(loop1->context().realtime_remote_time,
+ loop1->context().realtime_event_time);
+
+ const aos::monotonic_clock::time_point monotonic_now =
+ loop1->monotonic_now();
+ const aos::realtime_clock::time_point realtime_now =
+ loop1->realtime_now();
+
+ EXPECT_LE(loop1->context().monotonic_event_time, monotonic_now);
+ EXPECT_LE(loop1->context().realtime_event_time, realtime_now);
+ EXPECT_GE(loop1->context().monotonic_event_time + chrono::milliseconds(500),
+ monotonic_now);
+ EXPECT_GE(loop1->context().realtime_event_time + chrono::milliseconds(500),
+ realtime_now);
+
EXPECT_LT(&msg, reinterpret_cast<void *>(
- reinterpret_cast<char *>(loop2->context().data) +
- loop2->context().size));
+ reinterpret_cast<char *>(loop1->context().data) +
+ loop1->context().size));
+ triggered = true;
});
test_timer->Setup(loop1->monotonic_now() + ::std::chrono::seconds(1));
@@ -707,18 +734,25 @@
EndEventLoop(loop1.get(), ::std::chrono::seconds(2));
Run();
+ EXPECT_TRUE(triggered);
+
EXPECT_TRUE(fetcher.Fetch());
monotonic_clock::duration monotonic_time_offset =
- fetcher.context().monotonic_sent_time -
+ fetcher.context().monotonic_event_time -
(loop1->monotonic_now() - ::std::chrono::seconds(1));
realtime_clock::duration realtime_time_offset =
- fetcher.context().realtime_sent_time -
+ fetcher.context().realtime_event_time -
(loop1->realtime_now() - ::std::chrono::seconds(1));
+ EXPECT_EQ(fetcher.context().realtime_event_time,
+ fetcher.context().realtime_remote_time);
+ EXPECT_EQ(fetcher.context().monotonic_event_time,
+ fetcher.context().monotonic_remote_time);
+
EXPECT_TRUE(monotonic_time_offset > ::std::chrono::milliseconds(-500))
<< ": Got "
- << fetcher.context().monotonic_sent_time.time_since_epoch().count()
+ << fetcher.context().monotonic_event_time.time_since_epoch().count()
<< " expected " << loop1->monotonic_now().time_since_epoch().count();
// Confirm that the data pointer makes sense.
EXPECT_GT(fetcher.get(), fetcher.context().data);
@@ -728,16 +762,16 @@
fetcher.context().size));
EXPECT_TRUE(monotonic_time_offset < ::std::chrono::milliseconds(500))
<< ": Got "
- << fetcher.context().monotonic_sent_time.time_since_epoch().count()
+ << fetcher.context().monotonic_event_time.time_since_epoch().count()
<< " expected " << loop1->monotonic_now().time_since_epoch().count();
EXPECT_TRUE(realtime_time_offset > ::std::chrono::milliseconds(-500))
<< ": Got "
- << fetcher.context().realtime_sent_time.time_since_epoch().count()
+ << fetcher.context().realtime_event_time.time_since_epoch().count()
<< " expected " << loop1->realtime_now().time_since_epoch().count();
EXPECT_TRUE(realtime_time_offset < ::std::chrono::milliseconds(500))
<< ": Got "
- << fetcher.context().realtime_sent_time.time_since_epoch().count()
+ << fetcher.context().realtime_event_time.time_since_epoch().count()
<< " expected " << loop1->realtime_now().time_since_epoch().count();
}
@@ -768,9 +802,13 @@
[×, &expected_times, &loop1, this](int count) {
EXPECT_EQ(count, 1);
times.push_back(loop1->monotonic_now());
- expected_times.push_back(loop1->context().monotonic_sent_time);
+ expected_times.push_back(loop1->context().monotonic_event_time);
- EXPECT_EQ(loop1->context().realtime_sent_time,
+ EXPECT_EQ(loop1->context().monotonic_remote_time,
+ monotonic_clock::min_time);
+ EXPECT_EQ(loop1->context().realtime_event_time,
+ realtime_clock::min_time);
+ EXPECT_EQ(loop1->context().realtime_remote_time,
realtime_clock::min_time);
EXPECT_EQ(loop1->context().queue_index, 0xffffffffu);
EXPECT_EQ(loop1->context().size, 0u);
@@ -1145,6 +1183,89 @@
EXPECT_TRUE(happened);
}
+// Tests that a raw watcher and raw fetcher can receive messages from a raw
+// sender with remote times filled out.
+TEST_P(AbstractEventLoopTest, RawRemoteTimes) {
+ auto loop1 = Make();
+ auto loop2 = MakePrimary();
+ auto loop3 = Make();
+
+ const std::string kData("971 is the best");
+
+ const aos::monotonic_clock::time_point monotonic_remote_time =
+ aos::monotonic_clock::time_point(chrono::seconds(1501));
+ const aos::realtime_clock::time_point realtime_remote_time =
+ aos::realtime_clock::time_point(chrono::seconds(3132));
+
+ std::unique_ptr<aos::RawSender> sender =
+ loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
+
+ std::unique_ptr<aos::RawFetcher> fetcher =
+ loop3->MakeRawFetcher(loop3->configuration()->channels()->Get(1));
+
+ loop2->OnRun([&]() {
+ EXPECT_TRUE(sender->Send(kData.data(), kData.size(), monotonic_remote_time,
+ realtime_remote_time));
+ });
+
+ bool happened = false;
+ loop2->MakeRawWatcher(
+ loop2->configuration()->channels()->Get(1),
+ [this, monotonic_remote_time, realtime_remote_time, &fetcher, &happened](
+ const Context &context, const void * /*message*/) {
+ happened = true;
+ EXPECT_EQ(monotonic_remote_time, context.monotonic_remote_time);
+ EXPECT_EQ(realtime_remote_time, context.realtime_remote_time);
+
+ ASSERT_TRUE(fetcher->Fetch());
+ EXPECT_EQ(monotonic_remote_time,
+ fetcher->context().monotonic_remote_time);
+ EXPECT_EQ(realtime_remote_time,
+ fetcher->context().realtime_remote_time);
+
+ this->Exit();
+ });
+
+ EXPECT_FALSE(happened);
+ Run();
+ EXPECT_TRUE(happened);
+}
+
+// Tests that a raw sender fills out sent data.
+TEST_P(AbstractEventLoopTest, RawSenderSentData) {
+ auto loop1 = MakePrimary();
+
+ const std::string kData("971 is the best");
+
+ std::unique_ptr<aos::RawSender> sender =
+ loop1->MakeRawSender(loop1->configuration()->channels()->Get(1));
+
+ const aos::monotonic_clock::time_point monotonic_now =
+ loop1->monotonic_now();
+ const aos::realtime_clock::time_point realtime_now =
+ loop1->realtime_now();
+
+ EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
+
+ EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
+ EXPECT_LE(sender->monotonic_sent_time(),
+ monotonic_now + chrono::milliseconds(100));
+ EXPECT_GE(sender->realtime_sent_time(), realtime_now);
+ EXPECT_LE(sender->realtime_sent_time(),
+ realtime_now + chrono::milliseconds(100));
+ EXPECT_EQ(sender->sent_queue_index(), 0u);
+
+ EXPECT_TRUE(sender->Send(kData.data(), kData.size()));
+
+ EXPECT_GE(sender->monotonic_sent_time(), monotonic_now);
+ EXPECT_LE(sender->monotonic_sent_time(),
+ monotonic_now + chrono::milliseconds(100));
+ EXPECT_GE(sender->realtime_sent_time(), realtime_now);
+ EXPECT_LE(sender->realtime_sent_time(),
+ realtime_now + chrono::milliseconds(100));
+ EXPECT_EQ(sender->sent_queue_index(), 1u);
+}
+
// Tests that not setting up nodes results in no node.
TEST_P(AbstractEventLoopTest, NoNode) {
auto loop1 = Make();
diff --git a/aos/events/event_loop_tmpl.h b/aos/events/event_loop_tmpl.h
index 0b485c6..ef223a9 100644
--- a/aos/events/event_loop_tmpl.h
+++ b/aos/events/event_loop_tmpl.h
@@ -59,7 +59,7 @@
const monotonic_clock::time_point monotonic_time = result.second;
const float latency =
std::chrono::duration_cast<std::chrono::duration<float>>(
- monotonic_time - context_.monotonic_sent_time)
+ monotonic_time - context_.monotonic_event_time)
.count();
timing_.latency.Add(latency);
return true;
@@ -74,7 +74,7 @@
const monotonic_clock::time_point monotonic_time = result.second;
const float latency =
std::chrono::duration_cast<std::chrono::duration<float>>(
- monotonic_time - context_.monotonic_sent_time)
+ monotonic_time - context_.monotonic_event_time)
.count();
timing_.latency.Add(latency);
return true;
@@ -82,8 +82,12 @@
return false;
}
-inline bool RawSender::Send(size_t size) {
- if (DoSend(size)) {
+inline bool RawSender::Send(
+ size_t size, aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index) {
+ if (DoSend(size, monotonic_remote_time, realtime_remote_time,
+ remote_queue_index)) {
timing_.size.Add(size);
timing_.sender->mutate_count(timing_.sender->count() + 1);
return true;
@@ -91,8 +95,13 @@
return false;
}
-inline bool RawSender::Send(const void *data, size_t size) {
- if (DoSend(data, size)) {
+inline bool RawSender::Send(
+ const void *data, size_t size,
+ aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index) {
+ if (DoSend(data, size, monotonic_remote_time, realtime_remote_time,
+ remote_queue_index)) {
timing_.size.Add(size);
timing_.sender->mutate_count(timing_.sender->count() + 1);
return true;
@@ -106,8 +115,10 @@
CHECK_NOTNULL(timing_.timer);
const monotonic_clock::time_point monotonic_start_time = get_time();
- event_loop_->context_.monotonic_sent_time = event_time;
- event_loop_->context_.realtime_sent_time = realtime_clock::min_time;
+ event_loop_->context_.monotonic_event_time = event_time;
+ event_loop_->context_.monotonic_remote_time = monotonic_clock::min_time;
+ event_loop_->context_.realtime_remote_time =
+ event_loop_->context_.realtime_event_time = realtime_clock::min_time;
event_loop_->context_.queue_index = 0xffffffffu;
event_loop_->context_.size = 0;
event_loop_->context_.data = nullptr;
@@ -138,8 +149,10 @@
const monotonic_clock::time_point monotonic_start_time = get_time();
// Update the context to hold the desired wakeup time.
- event_loop_->context_.monotonic_sent_time = phased_loop_.sleep_time();
- event_loop_->context_.realtime_sent_time = realtime_clock::min_time;
+ event_loop_->context_.monotonic_event_time = phased_loop_.sleep_time();
+ event_loop_->context_.monotonic_remote_time = monotonic_clock::min_time;
+ event_loop_->context_.realtime_remote_time =
+ event_loop_->context_.realtime_event_time = realtime_clock::min_time;
event_loop_->context_.queue_index = 0xffffffffu;
event_loop_->context_.size = 0;
event_loop_->context_.data = nullptr;
@@ -150,7 +163,7 @@
{
const float start_latency =
std::chrono::duration_cast<std::chrono::duration<float>>(
- monotonic_start_time - event_loop_->context_.monotonic_sent_time)
+ monotonic_start_time - event_loop_->context_.monotonic_event_time)
.count();
timing_.wakeup_latency.Add(start_latency);
}
@@ -193,7 +206,7 @@
{
const float start_latency =
std::chrono::duration_cast<std::chrono::duration<float>>(
- monotonic_start_time - context.monotonic_sent_time)
+ monotonic_start_time - context.monotonic_event_time)
.count();
wakeup_latency_.Add(start_latency);
}
diff --git a/aos/events/logging/log_cat.cc b/aos/events/logging/log_cat.cc
index c146945..9c75076 100644
--- a/aos/events/logging/log_cat.cc
+++ b/aos/events/logging/log_cat.cc
@@ -62,7 +62,7 @@
// replaying it.
std::cout << channel->name()->c_str() << ' '
<< channel->type()->c_str() << " at "
- << context.monotonic_sent_time << ": "
+ << context.monotonic_event_time << ": "
<< aos::FlatbufferToJson(
channel->schema(),
static_cast<const uint8_t *>(message))
diff --git a/aos/events/logging/logger.cc b/aos/events/logging/logger.cc
index 01f75ec..e38c476 100644
--- a/aos/events/logging/logger.cc
+++ b/aos/events/logging/logger.cc
@@ -164,9 +164,9 @@
MessageHeader::Builder message_header_builder(*fbb);
message_header_builder.add_channel_index(channel_index);
message_header_builder.add_monotonic_sent_time(
- context.monotonic_sent_time.time_since_epoch().count());
+ context.monotonic_event_time.time_since_epoch().count());
message_header_builder.add_realtime_sent_time(
- context.realtime_sent_time.time_since_epoch().count());
+ context.realtime_event_time.time_since_epoch().count());
message_header_builder.add_queue_index(context.queue_index);
@@ -212,7 +212,7 @@
CHECK(!f.written);
// TODO(james): Write tests to exercise this logic.
- if (f.fetcher->context().monotonic_sent_time <
+ if (f.fetcher->context().monotonic_event_time <
last_synchronized_time_) {
// Write!
flatbuffers::FlatBufferBuilder fbb(f.fetcher->context().size +
@@ -410,7 +410,7 @@
std::pair<monotonic_clock::time_point, int> oldest_channel_index =
PopOldestChannel();
const monotonic_clock::time_point monotonic_now =
- event_loop_->context().monotonic_sent_time;
+ event_loop_->context().monotonic_event_time;
CHECK(monotonic_now == oldest_channel_index.first)
<< ": Now " << monotonic_now.time_since_epoch().count()
<< " trying to send "
diff --git a/aos/events/shm_event_loop.cc b/aos/events/shm_event_loop.cc
index 0f933f9..0ca713f 100644
--- a/aos/events/shm_event_loop.cc
+++ b/aos/events/shm_event_loop.cc
@@ -35,7 +35,7 @@
}
std::string ShmPath(const Channel *channel) {
CHECK(channel->has_type());
- return ShmFolder(channel) + channel->type()->str() + ".v0";
+ return ShmFolder(channel) + channel->type()->str() + ".v1";
}
class MMapedQueue {
@@ -193,11 +193,21 @@
// TODO(austin): Get behind and make sure it dies both here and with
// Fetch.
ipc_lib::LocklessQueue::ReadResult read_result = lockless_queue_.Read(
- actual_queue_index_.index(), &context_.monotonic_sent_time,
- &context_.realtime_sent_time, &context_.size,
- reinterpret_cast<char *>(data_storage_.get()));
+ actual_queue_index_.index(), &context_.monotonic_event_time,
+ &context_.realtime_event_time, &context_.monotonic_remote_time,
+ &context_.realtime_remote_time, &context_.remote_queue_index,
+ &context_.size, reinterpret_cast<char *>(data_storage_.get()));
if (read_result == ipc_lib::LocklessQueue::ReadResult::GOOD) {
context_.queue_index = actual_queue_index_.index();
+ if (context_.remote_queue_index == 0xffffffffu) {
+ context_.remote_queue_index = context_.queue_index;
+ }
+ if (context_.monotonic_remote_time == aos::monotonic_clock::min_time) {
+ context_.monotonic_remote_time = context_.monotonic_event_time;
+ }
+ if (context_.realtime_remote_time == aos::realtime_clock::min_time) {
+ context_.realtime_remote_time = context_.realtime_event_time;
+ }
context_.data = reinterpret_cast<char *>(data_storage_.get()) +
lockless_queue_.message_data_size() - context_.size;
actual_queue_index_ = actual_queue_index_.Increment();
@@ -231,12 +241,22 @@
return false;
}
- ipc_lib::LocklessQueue::ReadResult read_result =
- lockless_queue_.Read(queue_index.index(), &context_.monotonic_sent_time,
- &context_.realtime_sent_time, &context_.size,
- reinterpret_cast<char *>(data_storage_.get()));
+ ipc_lib::LocklessQueue::ReadResult read_result = lockless_queue_.Read(
+ queue_index.index(), &context_.monotonic_event_time,
+ &context_.realtime_event_time, &context_.monotonic_remote_time,
+ &context_.realtime_remote_time, &context_.remote_queue_index,
+ &context_.size, reinterpret_cast<char *>(data_storage_.get()));
if (read_result == ipc_lib::LocklessQueue::ReadResult::GOOD) {
context_.queue_index = queue_index.index();
+ if (context_.remote_queue_index == 0xffffffffu) {
+ context_.remote_queue_index = context_.queue_index;
+ }
+ if (context_.monotonic_remote_time == aos::monotonic_clock::min_time) {
+ context_.monotonic_remote_time = context_.monotonic_event_time;
+ }
+ if (context_.realtime_remote_time == aos::realtime_clock::min_time) {
+ context_.realtime_remote_time = context_.realtime_event_time;
+ }
context_.data = reinterpret_cast<char *>(data_storage_.get()) +
lockless_queue_.message_data_size() - context_.size;
actual_queue_index_ = queue_index.Increment();
@@ -326,14 +346,25 @@
void *data() override { return lockless_queue_sender_.Data(); }
size_t size() override { return lockless_queue_sender_.size(); }
- bool DoSend(size_t length) override {
- lockless_queue_sender_.Send(length);
+ bool DoSend(size_t length,
+ aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index) override {
+ lockless_queue_sender_.Send(
+ length, monotonic_remote_time, realtime_remote_time, remote_queue_index,
+ &monotonic_sent_time_, &realtime_sent_time_, &sent_queue_index_);
lockless_queue_.Wakeup(event_loop()->priority());
return true;
}
- bool DoSend(const void *msg, size_t length) override {
- lockless_queue_sender_.Send(reinterpret_cast<const char *>(msg), length);
+ bool DoSend(const void *msg, size_t length,
+ aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index) override {
+ lockless_queue_sender_.Send(reinterpret_cast<const char *>(msg), length,
+ monotonic_remote_time, realtime_remote_time,
+ remote_queue_index, &monotonic_sent_time_,
+ &realtime_sent_time_, &sent_queue_index_);
lockless_queue_.Wakeup(event_loop()->priority());
// TODO(austin): Return an error if we send too fast.
return true;
@@ -370,7 +401,7 @@
if (has_new_data_) {
event_.set_event_time(
- simple_shm_fetcher_.context().monotonic_sent_time);
+ simple_shm_fetcher_.context().monotonic_event_time);
event_loop_->AddEvent(&event_);
}
}
diff --git a/aos/events/shm_event_loop_test.cc b/aos/events/shm_event_loop_test.cc
index f2c730b..d33f496 100644
--- a/aos/events/shm_event_loop_test.cc
+++ b/aos/events/shm_event_loop_test.cc
@@ -27,11 +27,11 @@
}
// Clean up anything left there before.
- unlink((FLAGS_shm_base + "/test/aos.TestMessage.v0").c_str());
- unlink((FLAGS_shm_base + "/test1/aos.TestMessage.v0").c_str());
- unlink((FLAGS_shm_base + "/test2/aos.TestMessage.v0").c_str());
- unlink((FLAGS_shm_base + "/test2/aos.TestMessage.v0").c_str());
- unlink((FLAGS_shm_base + "/aos/aos.timing.Report.v0").c_str());
+ unlink((FLAGS_shm_base + "/test/aos.TestMessage.v1").c_str());
+ unlink((FLAGS_shm_base + "/test1/aos.TestMessage.v1").c_str());
+ unlink((FLAGS_shm_base + "/test2/aos.TestMessage.v1").c_str());
+ unlink((FLAGS_shm_base + "/test2/aos.TestMessage.v1").c_str());
+ unlink((FLAGS_shm_base + "/aos/aos.timing.Report.v1").c_str());
}
~ShmEventLoopTestFactory() { FLAGS_override_hostname = ""; }
diff --git a/aos/events/simulated_event_loop.cc b/aos/events/simulated_event_loop.cc
index cd04c9f..578e151 100644
--- a/aos/events/simulated_event_loop.cc
+++ b/aos/events/simulated_event_loop.cc
@@ -86,8 +86,9 @@
watchers_.erase(std::find(watchers_.begin(), watchers_.end(), watcher));
}
- // Sends the message to all the connected receivers and fetchers.
- void Send(std::shared_ptr<SimulatedMessage> message);
+ // Sends the message to all the connected receivers and fetchers. Returns the
+ // sent queue index.
+ uint32_t Send(std::shared_ptr<SimulatedMessage> message);
// Unregisters a fetcher.
void UnregisterFetcher(SimulatedFetcher *fetcher);
@@ -150,15 +151,23 @@
size_t size() override { return simulated_channel_->max_size(); }
- bool DoSend(size_t length) override {
+ bool DoSend(size_t length,
+ aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index) override {
CHECK_LE(length, size()) << ": Attempting to send too big a message.";
- message_->context.monotonic_sent_time = event_loop_->monotonic_now();
- message_->context.realtime_sent_time = event_loop_->realtime_now();
+ message_->context.monotonic_event_time = event_loop_->monotonic_now();
+ message_->context.monotonic_remote_time = monotonic_remote_time;
+ message_->context.remote_queue_index = remote_queue_index;
+ message_->context.realtime_event_time = event_loop_->realtime_now();
+ message_->context.realtime_remote_time = realtime_remote_time;
CHECK_LE(length, message_->context.size);
message_->context.size = length;
// TODO(austin): Track sending too fast.
- simulated_channel_->Send(message_);
+ sent_queue_index_ = simulated_channel_->Send(message_);
+ monotonic_sent_time_ = event_loop_->monotonic_now();
+ realtime_sent_time_ = event_loop_->realtime_now();
// Drop the reference to the message so that we allocate a new message for
// next time. Otherwise we will continue to reuse the same memory for all
@@ -167,7 +176,10 @@
return true;
}
- bool DoSend(const void *msg, size_t size) override {
+ bool DoSend(const void *msg, size_t size,
+ aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index) override {
CHECK_LE(size, this->size()) << ": Attempting to send too big a message.";
// This is wasteful, but since flatbuffers fill from the back end of the
@@ -179,7 +191,8 @@
// data segment.
memcpy(message_->data() + simulated_channel_->max_size() - size, msg, size);
- return Send(size);
+ return Send(size, monotonic_remote_time, realtime_remote_time,
+ remote_queue_index);
}
private:
@@ -232,6 +245,15 @@
void SetMsg(std::shared_ptr<SimulatedMessage> msg) {
msg_ = msg;
context_ = msg_->context;
+ if (context_.remote_queue_index == 0xffffffffu) {
+ context_.remote_queue_index = context_.queue_index;
+ }
+ if (context_.monotonic_remote_time == aos::monotonic_clock::min_time) {
+ context_.monotonic_remote_time = context_.monotonic_event_time;
+ }
+ if (context_.realtime_remote_time == aos::realtime_clock::min_time) {
+ context_.realtime_remote_time = context_.realtime_event_time;
+ }
}
// Internal method for Simulation to add a message to the buffer.
@@ -527,7 +549,7 @@
// Messages are queued in order. If we are the first, add ourselves.
// Otherwise, don't.
if (msgs_.size() == 0) {
- event_.set_event_time(message->context.monotonic_sent_time);
+ event_.set_event_time(message->context.monotonic_event_time);
simulated_event_loop_->AddEvent(&event_);
DoSchedule(event_time);
@@ -541,12 +563,23 @@
const monotonic_clock::time_point monotonic_now =
simulated_event_loop_->monotonic_now();
- DoCallCallback([monotonic_now]() { return monotonic_now; },
- msgs_.front()->context);
+ Context context = msgs_.front()->context;
+
+ if (context.remote_queue_index == 0xffffffffu) {
+ context.remote_queue_index = context.queue_index;
+ }
+ if (context.monotonic_remote_time == aos::monotonic_clock::min_time) {
+ context.monotonic_remote_time = context.monotonic_event_time;
+ }
+ if (context.realtime_remote_time == aos::realtime_clock::min_time) {
+ context.realtime_remote_time = context.realtime_event_time;
+ }
+
+ DoCallCallback([monotonic_now]() { return monotonic_now; }, context);
msgs_.pop_front();
if (msgs_.size() != 0) {
- event_.set_event_time(msgs_.front()->context.monotonic_sent_time);
+ event_.set_event_time(msgs_.front()->context.monotonic_event_time);
simulated_event_loop_->AddEvent(&event_);
DoSchedule(event_.event_time());
@@ -579,8 +612,9 @@
return ::std::move(fetcher);
}
-void SimulatedChannel::Send(std::shared_ptr<SimulatedMessage> message) {
- message->context.queue_index = next_queue_index_.index();
+uint32_t SimulatedChannel::Send(std::shared_ptr<SimulatedMessage> message) {
+ const uint32_t queue_index = next_queue_index_.index();
+ message->context.queue_index = queue_index;
message->context.data =
message->data() + channel()->max_size() - message->context.size;
next_queue_index_ = next_queue_index_.Increment();
@@ -594,6 +628,8 @@
for (auto &fetcher : fetchers_) {
fetcher->Enqueue(message);
}
+
+ return queue_index;
}
void SimulatedChannel::UnregisterFetcher(SimulatedFetcher *fetcher) {
diff --git a/aos/ipc_lib/lockless_queue.cc b/aos/ipc_lib/lockless_queue.cc
index 3fb506b..903150b 100644
--- a/aos/ipc_lib/lockless_queue.cc
+++ b/aos/ipc_lib/lockless_queue.cc
@@ -552,16 +552,30 @@
return &message->data[0];
}
-void LocklessQueue::Sender::Send(const char *data, size_t length) {
+void LocklessQueue::Sender::Send(
+ const char *data, size_t length,
+ aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index,
+ aos::monotonic_clock::time_point *monotonic_sent_time,
+ aos::realtime_clock::time_point *realtime_sent_time,
+ uint32_t *queue_index) {
CHECK_LE(length, size());
// Flatbuffers write from the back of the buffer to the front. If we are
// going to write an explicit chunk of memory into the buffer, we need to
// adhere to this convention and place it at the end.
memcpy((reinterpret_cast<char *>(Data()) + size() - length), data, length);
- Send(length);
+ Send(length, monotonic_remote_time, realtime_remote_time, remote_queue_index,
+ monotonic_sent_time, realtime_sent_time, queue_index);
}
-void LocklessQueue::Sender::Send(size_t length) {
+void LocklessQueue::Sender::Send(
+ size_t length, aos::monotonic_clock::time_point monotonic_remote_time,
+ aos::realtime_clock::time_point realtime_remote_time,
+ uint32_t remote_queue_index,
+ aos::monotonic_clock::time_point *monotonic_sent_time,
+ aos::realtime_clock::time_point *realtime_sent_time,
+ uint32_t *queue_index) {
const size_t queue_size = memory_->queue_size();
CHECK_LE(length, size());
@@ -572,6 +586,11 @@
Message *const message = memory_->GetMessage(scratch_index);
message->header.length = length;
+ // Pass these through. Any alternative behavior can be implemented out a
+ // layer.
+ message->header.remote_queue_index = remote_queue_index;
+ message->header.monotonic_remote_time = monotonic_remote_time;
+ message->header.realtime_remote_time = realtime_remote_time;
while (true) {
const QueueIndex actual_next_queue_index =
@@ -625,6 +644,15 @@
message->header.monotonic_sent_time = ::aos::monotonic_clock::now();
message->header.realtime_sent_time = ::aos::realtime_clock::now();
+ if (monotonic_sent_time != nullptr) {
+ *monotonic_sent_time = message->header.monotonic_sent_time;
+ }
+ if (realtime_sent_time != nullptr) {
+ *realtime_sent_time = message->header.realtime_sent_time;
+ }
+ if (queue_index != nullptr) {
+ *queue_index = next_queue_index.index();
+ }
// Before we are fully done filling out the message, update the Sender state
// with the new index to write. This re-uses the barrier for the
@@ -676,8 +704,10 @@
LocklessQueue::ReadResult LocklessQueue::Read(
uint32_t uint32_queue_index,
::aos::monotonic_clock::time_point *monotonic_sent_time,
- ::aos::realtime_clock::time_point *realtime_sent_time, size_t *length,
- char *data) {
+ ::aos::realtime_clock::time_point *realtime_sent_time,
+ ::aos::monotonic_clock::time_point *monotonic_remote_time,
+ ::aos::realtime_clock::time_point *realtime_remote_time,
+ uint32_t *remote_queue_index, size_t *length, char *data) {
const size_t queue_size = memory_->queue_size();
// Build up the QueueIndex.
@@ -751,6 +781,13 @@
// make length be from either end.
*monotonic_sent_time = m->header.monotonic_sent_time;
*realtime_sent_time = m->header.realtime_sent_time;
+ if (m->header.remote_queue_index == 0xffffffffu) {
+ *remote_queue_index = queue_index.index();
+ } else {
+ *remote_queue_index = m->header.remote_queue_index;
+ }
+ *monotonic_remote_time = m->header.monotonic_remote_time;
+ *realtime_remote_time = m->header.realtime_remote_time;
memcpy(data, &m->data[0], message_data_size());
*length = m->header.length;
diff --git a/aos/ipc_lib/lockless_queue.h b/aos/ipc_lib/lockless_queue.h
index d539386..976f758 100644
--- a/aos/ipc_lib/lockless_queue.h
+++ b/aos/ipc_lib/lockless_queue.h
@@ -65,6 +65,13 @@
// fails.
::aos::monotonic_clock::time_point monotonic_sent_time;
::aos::realtime_clock::time_point realtime_sent_time;
+ // Timestamps of the message from the remote node. These are transparently
+ // passed through.
+ ::aos::monotonic_clock::time_point monotonic_remote_time;
+ ::aos::realtime_clock::time_point realtime_remote_time;
+
+ // Queue index from the remote node.
+ uint32_t remote_queue_index;
size_t length;
} header;
@@ -146,7 +153,9 @@
ReadResult Read(uint32_t queue_index,
::aos::monotonic_clock::time_point *monotonic_sent_time,
::aos::realtime_clock::time_point *realtime_sent_time,
- size_t *length, char *data);
+ ::aos::monotonic_clock::time_point *monotonic_remote_time,
+ ::aos::realtime_clock::time_point *realtime_remote_time,
+ uint32_t *remote_queue_index, size_t *length, char *data);
// Returns the index to the latest queue message. Returns empty_queue_index()
// if there are no messages in the queue. Do note that this index wraps if
@@ -195,10 +204,26 @@
// Note: calls to Data() are expensive enough that you should cache it.
size_t size();
void *Data();
- void Send(size_t length);
+ void Send(size_t length,
+ aos::monotonic_clock::time_point monotonic_remote_time =
+ aos::monotonic_clock::min_time,
+ aos::realtime_clock::time_point realtime_remote_time =
+ aos::realtime_clock::min_time,
+ uint32_t remote_queue_index = 0xffffffff,
+ aos::monotonic_clock::time_point *monotonic_sent_time = nullptr,
+ aos::realtime_clock::time_point *realtime_sent_time = nullptr,
+ uint32_t *queue_index = nullptr);
// Sends up to length data. Does not wakeup the target.
- void Send(const char *data, size_t length);
+ void Send(const char *data, size_t length,
+ aos::monotonic_clock::time_point monotonic_remote_time =
+ aos::monotonic_clock::min_time,
+ aos::realtime_clock::time_point realtime_remote_time =
+ aos::realtime_clock::min_time,
+ uint32_t remote_queue_index = 0xffffffff,
+ aos::monotonic_clock::time_point *monotonic_sent_time = nullptr,
+ aos::realtime_clock::time_point *realtime_sent_time = nullptr,
+ uint32_t *queue_index = nullptr);
private:
friend class LocklessQueue;
diff --git a/aos/ipc_lib/lockless_queue_death_test.cc b/aos/ipc_lib/lockless_queue_death_test.cc
index e3d6c5e..213c9e4 100644
--- a/aos/ipc_lib/lockless_queue_death_test.cc
+++ b/aos/ipc_lib/lockless_queue_death_test.cc
@@ -584,12 +584,16 @@
while (true) {
::aos::monotonic_clock::time_point monotonic_sent_time;
::aos::realtime_clock::time_point realtime_sent_time;
+ ::aos::monotonic_clock::time_point monotonic_remote_time;
+ ::aos::realtime_clock::time_point realtime_remote_time;
+ uint32_t remote_queue_index;
char read_data[1024];
size_t length;
LocklessQueue::ReadResult read_result =
- queue.Read(i, &monotonic_sent_time, &realtime_sent_time, &length,
- &(read_data[0]));
+ queue.Read(i, &monotonic_sent_time, &realtime_sent_time,
+ &monotonic_remote_time, &realtime_remote_time,
+ &remote_queue_index, &length, &(read_data[0]));
if (read_result != LocklessQueue::ReadResult::GOOD) {
break;
diff --git a/aos/ipc_lib/lockless_queue_test.cc b/aos/ipc_lib/lockless_queue_test.cc
index b9cb54d..109c2ea 100644
--- a/aos/ipc_lib/lockless_queue_test.cc
+++ b/aos/ipc_lib/lockless_queue_test.cc
@@ -260,6 +260,9 @@
// Read a result from 5 in the past.
::aos::monotonic_clock::time_point monotonic_sent_time;
::aos::realtime_clock::time_point realtime_sent_time;
+ ::aos::monotonic_clock::time_point monotonic_remote_time;
+ ::aos::realtime_clock::time_point realtime_remote_time;
+ uint32_t remote_queue_index;
char read_data[1024];
size_t length;
@@ -271,7 +274,8 @@
}
LocklessQueue::ReadResult read_result =
queue.Read(index.index(), &monotonic_sent_time, &realtime_sent_time,
- &length, &(read_data[0]));
+ &monotonic_remote_time, &realtime_remote_time,
+ &remote_queue_index, &length, &(read_data[0]));
// This should either return GOOD, or TOO_OLD if it is before the start of
// the queue.
diff --git a/aos/ipc_lib/queue_racer.cc b/aos/ipc_lib/queue_racer.cc
index 350350c..9bb0a70 100644
--- a/aos/ipc_lib/queue_racer.cc
+++ b/aos/ipc_lib/queue_racer.cc
@@ -251,6 +251,9 @@
i < (1 + write_wrap_count) * num_messages_ * num_threads_; ++i) {
::aos::monotonic_clock::time_point monotonic_sent_time;
::aos::realtime_clock::time_point realtime_sent_time;
+ ::aos::monotonic_clock::time_point monotonic_remote_time;
+ ::aos::realtime_clock::time_point realtime_remote_time;
+ uint32_t remote_queue_index;
size_t length;
char read_data[1024];
@@ -259,7 +262,8 @@
0xffffffffu, queue.QueueSize()));
LocklessQueue::ReadResult read_result =
queue.Read(wrapped_i, &monotonic_sent_time, &realtime_sent_time,
- &length, &(read_data[0]));
+ &monotonic_remote_time, &realtime_remote_time,
+ &remote_queue_index, &length, &(read_data[0]));
if (race_reads) {
if (read_result == LocklessQueue::ReadResult::NOTHING_NEW) {
@@ -280,6 +284,9 @@
ASSERT_GT(monotonic_sent_time, last_monotonic_sent_time);
last_monotonic_sent_time = monotonic_sent_time;
+ EXPECT_EQ(monotonic_remote_time, aos::monotonic_clock::min_time);
+ EXPECT_EQ(realtime_remote_time, aos::realtime_clock::min_time);
+
ThreadPlusCount tpc;
ASSERT_EQ(length, sizeof(ThreadPlusCount));
memcpy(&tpc, read_data + queue.message_data_size() - length,
diff --git a/y2016/vision/target_receiver.cc b/y2016/vision/target_receiver.cc
index b946f8b..e9a2e1d 100644
--- a/y2016/vision/target_receiver.cc
+++ b/y2016/vision/target_receiver.cc
@@ -205,7 +205,7 @@
bool CompleteVisionStatus(::y2016::vision::VisionStatusT *status) {
while (drivetrain_status_fetcher_.FetchNext()) {
data_[data_index_].time =
- drivetrain_status_fetcher_.context().monotonic_sent_time;
+ drivetrain_status_fetcher_.context().monotonic_event_time;
data_[data_index_].left =
drivetrain_status_fetcher_->estimated_left_position();
data_[data_index_].right =
diff --git a/y2017/control_loops/superstructure/superstructure.cc b/y2017/control_loops/superstructure/superstructure.cc
index 29886e2..a0448fd 100644
--- a/y2017/control_loops/superstructure/superstructure.cc
+++ b/y2017/control_loops/superstructure/superstructure.cc
@@ -138,7 +138,7 @@
status->fbb());
flatbuffers::Offset<ShooterStatus> shooter_offset = shooter_.Iterate(
unsafe_goal != nullptr ? &shooter_goal : nullptr,
- position->theta_shooter(), position_context().monotonic_sent_time,
+ position->theta_shooter(), position_context().monotonic_event_time,
output != nullptr ? &(output_struct.voltage_shooter) : nullptr,
status->fbb());
diff --git a/y2017/control_loops/superstructure/vision_time_adjuster.cc b/y2017/control_loops/superstructure/vision_time_adjuster.cc
index 7db653e..6684546 100644
--- a/y2017/control_loops/superstructure/vision_time_adjuster.cc
+++ b/y2017/control_loops/superstructure/vision_time_adjuster.cc
@@ -116,7 +116,7 @@
if (drivetrain_status_fetcher_.Fetch()) {
const auto &position = drivetrain_status_fetcher_.get();
DrivetrainAngle new_position{
- .time = drivetrain_status_fetcher_.context().monotonic_sent_time,
+ .time = drivetrain_status_fetcher_.context().monotonic_event_time,
.left = position->estimated_left_position(),
.right = position->estimated_right_position()};
drivetrain_data_.Push(new_position);
diff --git a/y2018/control_loops/superstructure/superstructure.cc b/y2018/control_loops/superstructure/superstructure.cc
index 9f5b9fe..f24da3b 100644
--- a/y2018/control_loops/superstructure/superstructure.cc
+++ b/y2018/control_loops/superstructure/superstructure.cc
@@ -289,7 +289,7 @@
SendColors(0.5, 0.0, 0.0);
} else if (!vision_status_fetcher_.get() ||
monotonic_now >
- vision_status_fetcher_.context().monotonic_sent_time +
+ vision_status_fetcher_.context().monotonic_event_time +
chrono::seconds(1)) {
SendColors(0.5, 0.5, 0.0);
} else if (rotation_state_ == RotationState::ROTATING_LEFT ||
diff --git a/y2018/wpilib_interface.cc b/y2018/wpilib_interface.cc
index 968076d..641a474 100644
--- a/y2018/wpilib_interface.cc
+++ b/y2018/wpilib_interface.cc
@@ -537,7 +537,7 @@
// Flash the red light slowly.
StatusLightT color;
if (!status_light_fetcher_.get() ||
- monotonic_now > status_light_fetcher_.context().monotonic_sent_time +
+ monotonic_now > status_light_fetcher_.context().monotonic_event_time +
chrono::milliseconds(100)) {
color.red = 0.0;
color.green = 0.0;
@@ -549,7 +549,7 @@
color.red = 0.5;
} else if (!vision_status_fetcher_.get() ||
monotonic_now >
- vision_status_fetcher_.context().monotonic_sent_time +
+ vision_status_fetcher_.context().monotonic_event_time +
chrono::seconds(1)) {
color.red = 0.5;
color.green = 0.5;
diff --git a/y2019/vision/server/server.cc b/y2019/vision/server/server.cc
index 99a3727..56aa289 100644
--- a/y2019/vision/server/server.cc
+++ b/y2019/vision/server/server.cc
@@ -165,7 +165,7 @@
&camera_frames) {
while (drivetrain_status_fetcher.FetchNext()) {
DrivetrainPosition drivetrain_position{
- drivetrain_status_fetcher.context().monotonic_sent_time,
+ drivetrain_status_fetcher.context().monotonic_event_time,
drivetrain_status_fetcher->x(), drivetrain_status_fetcher->y(),
drivetrain_status_fetcher->theta()};
diff --git a/y2019/wpilib_interface.cc b/y2019/wpilib_interface.cc
index 097f011..b6d432f 100644
--- a/y2019/wpilib_interface.cc
+++ b/y2019/wpilib_interface.cc
@@ -661,7 +661,7 @@
// Flash the red light slowly.
StatusLightT color;
if (!status_light_fetcher_.get() ||
- status_light_fetcher_.context().monotonic_sent_time +
+ status_light_fetcher_.context().monotonic_event_time +
chrono::milliseconds(100) <
event_loop_->monotonic_now()) {
color.red = 0.0;