Merge "Prevent aos_send from sending invalid messages"
diff --git a/aos/mutex/mutex_test.cc b/aos/mutex/mutex_test.cc
index 54e9201..8d10b26 100644
--- a/aos/mutex/mutex_test.cc
+++ b/aos/mutex/mutex_test.cc
@@ -241,10 +241,11 @@
static_cast<Mutex *>(shm_malloc_aligned(sizeof(Mutex), alignof(Mutex)));
new (mutex) Mutex();
- std::thread thread([&]() { ASSERT_FALSE(mutex->Lock()); });
- thread.join();
EXPECT_DEATH(
{
+ std::thread thread([&]() { ASSERT_FALSE(mutex->Lock()); });
+ thread.join();
+
logging::SetImplementation(
std::make_shared<util::DeathTestLogImplementation>());
MutexLocker locker(mutex);
diff --git a/aos/network/multinode_timestamp_filter.cc b/aos/network/multinode_timestamp_filter.cc
index cae9e1f..1869ffb 100644
--- a/aos/network/multinode_timestamp_filter.cc
+++ b/aos/network/multinode_timestamp_filter.cc
@@ -399,7 +399,11 @@
<< a_solution_index << ") -> "
<< filter.filter->node_b()->name()->string_view() << "("
<< b_solution_index << "): " << std::setprecision(12)
- << error.first.count() << " + " << error.second;
+ << error.first.count() << " + " << error.second << " "
+ << filter.filter->DebugOffsetErrorPoints(
+ filter.b_filter, filter.pointer, base_clock_[i],
+ time_offsets(a_solution_index), base_clock_[filter.b_index],
+ time_offsets(b_solution_index));
}
// Reminder, our cost function has the following form.
diff --git a/aos/network/timestamp_filter.cc b/aos/network/timestamp_filter.cc
index f3aea62..b2e7294 100644
--- a/aos/network/timestamp_filter.cc
+++ b/aos/network/timestamp_filter.cc
@@ -1141,6 +1141,44 @@
rise, run, std::get<1>(points.first).count());
}
+std::string NoncausalTimestampFilter::DebugOffsetErrorPoints(
+ const NoncausalTimestampFilter *other, Pointer pointer,
+ BootTimestamp ta_base, double ta, BootTimestamp tb_base, double tb) const {
+ NormalizeTimestamps(&ta_base, &ta);
+ NormalizeTimestamps(&tb_base, &tb);
+
+ const BootFilter *f = maybe_filter(pointer, ta_base.boot, tb_base.boot);
+ if (f == nullptr || f->filter.timestamps_size() == 0u) {
+ return "0";
+ }
+
+ if (f->filter.IsOutsideSamples(ta_base.time, ta)) {
+ auto reference_timestamp =
+ f->filter.GetReferenceTimestamp(ta_base.time, ta);
+
+ return std::string("Extrapolating using ") +
+ TimeString(reference_timestamp.second);
+ }
+
+ // FindTimestamps expects nullptr if we don't have the other direction. But,
+ // any of the indirections to go get it might also be nullptr. So keep
+ // checking if it's safe to continue, or give up and return nullptr.
+ const BootFilter *other_boot_filter =
+ other == nullptr ? nullptr : maybe_filter(tb_base.boot, ta_base.boot);
+ const SingleFilter *other_filter =
+ other_boot_filter == nullptr ? nullptr : &other_boot_filter->filter;
+
+ std::pair<std::tuple<monotonic_clock::time_point, chrono::nanoseconds>,
+ std::tuple<monotonic_clock::time_point, chrono::nanoseconds>>
+ points =
+ f->filter
+ .FindTimestamps(other_filter, true, pointer, ta_base.time, ta)
+ .second;
+
+ return std::string("Interpolating using ") + TimeString(points.first) + " " +
+ TimeString(points.second);
+}
+
std::string NoncausalTimestampFilter::NodeNames() const {
return absl::StrCat(node_a_->name()->string_view(), " -> ",
node_b_->name()->string_view());
diff --git a/aos/network/timestamp_filter.h b/aos/network/timestamp_filter.h
index 2361797..04ee605 100644
--- a/aos/network/timestamp_filter.h
+++ b/aos/network/timestamp_filter.h
@@ -361,6 +361,13 @@
Pointer pointer, logger::BootTimestamp ta_base,
double ta, logger::BootTimestamp tb_base,
double tb, size_t node_a, size_t node_b) const;
+ // Returns the string representation of the offset error at the provided
+ // point.
+ std::string DebugOffsetErrorPoints(const NoncausalTimestampFilter *other,
+ Pointer pointer,
+ logger::BootTimestamp ta_base, double ta,
+ logger::BootTimestamp tb_base,
+ double tb) const;
// Confirms that the solution meets the constraints. Returns true on success.
bool ValidateSolution(const NoncausalTimestampFilter *other, Pointer pointer,