Skip to content

Commit f4e4462

Browse files
authored
Merge pull request #3174 from pleroy/MoreConsistency
More consistency checks and some fixes in trajectories
2 parents 90e49e6 + 9599904 commit f4e4462

File tree

3 files changed

+60
-29
lines changed

3 files changed

+60
-29
lines changed

base/status_utilities.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ absl::Status const& GetStatus(absl::StatusOr<T> const& s) {
1919
} // namespace internal_status_utilities
2020

2121
#define CHECK_OK(value) CHECK_EQ((value), ::absl::OkStatus())
22+
#define DCHECK_OK(value) DCHECK_EQ((value), ::absl::OkStatus())
2223
#define EXPECT_OK(value) \
2324
EXPECT_THAT((value), ::principia::testing_utilities::IsOk());
2425

physics/discrete_traject0ry.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ class DiscreteTraject0ry : public Trajectory<Frame> {
140140
typename SegmentByLeftEndpoint::const_iterator
141141
FindSegment(Instant const& t) const;
142142

143-
// Checks if this objects is in a consistent state, and returns an error
143+
// Determines if this objects is in a consistent state, and returns an error
144144
// status with a relevant message if it isn't.
145-
absl::Status ValidateConsistency() const;
145+
absl::Status ConsistencyStatus() const;
146146

147147
// Updates the segments self-pointers and the time-to-segment mapping after
148148
// segments have been spliced from |from| to |to|. The iterator indicates the

physics/discrete_traject0ry_body.hpp

+57-27
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ DiscreteTraject0ry<Frame>::NewSegment() {
168168
segment_by_left_endpoint_.end(), last_time, new_segment_sit);
169169
}
170170

171+
DCHECK_OK(ConsistencyStatus());
171172
return new_self;
172173
}
173174

@@ -185,6 +186,7 @@ DiscreteTraject0ry<Frame>::DetachSegments(SegmentIterator const begin) {
185186
/*to=*/detached,
186187
/*to_segments_begin=*/detached.segments_->begin());
187188

189+
DCHECK_OK(ConsistencyStatus());
188190
return detached;
189191
}
190192

@@ -218,12 +220,30 @@ DiscreteTraject0ry<Frame>::AttachSegments(
218220
/*to=*/*this,
219221
/*to_segments_begin=*/end_before_splice);
220222

223+
DCHECK_OK(ConsistencyStatus());
221224
return SegmentIterator(segments_.get(), end_before_splice);
222225
}
223226

224227
template<typename Frame>
225228
void DiscreteTraject0ry<Frame>::DeleteSegments(SegmentIterator const begin) {
226229
segments_->erase(begin.iterator(), segments_->end());
230+
if (segments_->empty()) {
231+
segment_by_left_endpoint_.clear();
232+
} else {
233+
auto const last_segment = --segments_->end();
234+
if (last_segment->empty()) {
235+
segment_by_left_endpoint_.clear();
236+
} else {
237+
// If there remains a non-empty segment, update the time-to-segment map
238+
// with for its time, and delete the rest.
239+
auto const& [leit, _] = segment_by_left_endpoint_.insert_or_assign(
240+
last_segment->front().time, last_segment);
241+
segment_by_left_endpoint_.erase(std::next(leit),
242+
segment_by_left_endpoint_.end());
243+
}
244+
}
245+
246+
DCHECK_OK(ConsistencyStatus());
227247
}
228248

229249
template<typename Frame>
@@ -246,6 +266,8 @@ void DiscreteTraject0ry<Frame>::ForgetAfter(Instant const& t) {
246266
segment_by_left_endpoint_.erase(std::next(leit),
247267
segment_by_left_endpoint_.end());
248268
}
269+
270+
DCHECK_OK(ConsistencyStatus());
249271
}
250272

251273
template<typename Frame>
@@ -277,6 +299,8 @@ void DiscreteTraject0ry<Frame>::ForgetBefore(Instant const& t) {
277299
segment_by_left_endpoint_.insert_or_assign(segment_by_left_endpoint_.begin(),
278300
sit->front().time,
279301
sit);
302+
303+
DCHECK_OK(ConsistencyStatus());
280304
}
281305

282306
template<typename Frame>
@@ -303,6 +327,8 @@ void DiscreteTraject0ry<Frame>::Append(
303327
CHECK(!sit->empty()) << "Empty segment at " << t;
304328
}
305329
sit->Append(t, degrees_of_freedom);
330+
331+
DCHECK_OK(ConsistencyStatus());
306332
}
307333

308334
template<typename Frame>
@@ -403,7 +429,7 @@ DiscreteTraject0ry<Frame>::ReadFromMessage(
403429
LOG_IF(WARNING, is_pre_ζήνων) << "Reading pre-Ζήνων DiscreteTrajectory";
404430
ReadFromPreΖήνωνMessage(
405431
message, tracked, /*fork_point=*/std::nullopt, trajectory);
406-
CHECK_OK(trajectory.ValidateConsistency());
432+
CHECK_OK(trajectory.ConsistencyStatus());
407433
return trajectory;
408434
}
409435

@@ -444,7 +470,7 @@ DiscreteTraject0ry<Frame>::ReadFromMessage(
444470
trajectory.segment_by_left_endpoint_.end(), t, sit);
445471
}
446472

447-
CHECK_OK(trajectory.ValidateConsistency());
473+
CHECK_OK(trajectory.ConsistencyStatus());
448474
return trajectory;
449475
}
450476

@@ -477,7 +503,7 @@ DiscreteTraject0ry<Frame>::FindSegment(
477503
}
478504

479505
template<typename Frame>
480-
absl::Status DiscreteTraject0ry<Frame>::ValidateConsistency() const {
506+
absl::Status DiscreteTraject0ry<Frame>::ConsistencyStatus() const {
481507
if (segments_->size() < segment_by_left_endpoint_.size()) {
482508
return absl::InternalError(absl::StrCat("Size mismatch ",
483509
segments_->size(),
@@ -539,25 +565,27 @@ absl::Status DiscreteTraject0ry<Frame>::ValidateConsistency() const {
539565
// Great care is required here because the DiscreteTrajectoryIterator will
540566
// "helpfully" paper over differences in degrees of freedom as long as the
541567
// times match. We must look at the endpoints of the timeline explicitly.
542-
auto const timeline_rbegin = --sit->timeline_end();
543-
auto const timeline_begin = std::next(sit)->timeline_begin();
544-
if (timeline_rbegin->time != timeline_begin->time) {
545-
return absl::InternalError(
546-
absl::StrCat("Duplicated time mismatch ",
547-
DebugString(timeline_rbegin->time),
548-
" and ",
549-
DebugString(timeline_begin->time),
550-
" for segment #",
551-
i));
552-
} else if (timeline_rbegin->degrees_of_freedom !=
553-
timeline_begin->degrees_of_freedom) {
554-
return absl::InternalError(
555-
absl::StrCat("Duplicated degrees of freedom mismatch ",
556-
DebugString(timeline_rbegin->degrees_of_freedom),
557-
" and ",
558-
DebugString(timeline_begin->degrees_of_freedom),
559-
" for segment #",
560-
i));
568+
if (!sit->timeline_empty()) {
569+
auto const timeline_rbegin = --sit->timeline_end();
570+
auto const timeline_begin = std::next(sit)->timeline_begin();
571+
if (timeline_rbegin->time != timeline_begin->time) {
572+
return absl::InternalError(
573+
absl::StrCat("Duplicated time mismatch ",
574+
DebugString(timeline_rbegin->time),
575+
" and ",
576+
DebugString(timeline_begin->time),
577+
" for segment #",
578+
i));
579+
} else if (timeline_rbegin->degrees_of_freedom !=
580+
timeline_begin->degrees_of_freedom) {
581+
return absl::InternalError(
582+
absl::StrCat("Duplicated degrees of freedom mismatch ",
583+
DebugString(timeline_rbegin->degrees_of_freedom),
584+
" and ",
585+
DebugString(timeline_begin->degrees_of_freedom),
586+
" for segment #",
587+
i));
588+
}
561589
}
562590
}
563591
}
@@ -591,12 +619,14 @@ void DiscreteTraject0ry<Frame>::AdjustAfterSplicing(
591619
// insert it again.
592620
from.segment_by_left_endpoint_.erase(from_leit,
593621
from.segment_by_left_endpoint_.end());
594-
if (!from.empty()) {
622+
if (!from.segments_->empty()) {
595623
auto const last_segment = --from.segments_->end();
596-
from.segment_by_left_endpoint_.insert_or_assign(
597-
from.segment_by_left_endpoint_.end(),
598-
last_segment->front().time,
599-
last_segment);
624+
if (!last_segment->empty()) {
625+
from.segment_by_left_endpoint_.insert_or_assign(
626+
from.segment_by_left_endpoint_.end(),
627+
last_segment->front().time,
628+
last_segment);
629+
}
600630
}
601631
}
602632

0 commit comments

Comments
 (0)