Skip to content

Commit 26cedc3

Browse files
authored
Merge pull request #3248 from pleroy/Merge1Point
Proper management of the time-to-segment map when merging trajectories with 1-point segments
2 parents c53a6fd + fc5bca0 commit 26cedc3

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

physics/discrete_trajectory_body.hpp

+22-10
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ DiscreteTrajectory<Frame>::NewSegment() {
187187
segment_by_left_endpoint_.end(), last_time, new_segment_sit);
188188
}
189189

190-
DCHECK_OK(ConsistencyStatus());
190+
CHECK_OK(ConsistencyStatus());
191191
return new_self;
192192
}
193193

@@ -205,7 +205,7 @@ DiscreteTrajectory<Frame>::DetachSegments(SegmentIterator const begin) {
205205
/*to=*/detached,
206206
/*to_segments_begin=*/detached.segments_->begin());
207207

208-
DCHECK_OK(ConsistencyStatus());
208+
CHECK_OK(ConsistencyStatus());
209209
return detached;
210210
}
211211

@@ -245,7 +245,7 @@ DiscreteTrajectory<Frame>::AttachSegments(DiscreteTrajectory trajectory) {
245245
/*to=*/*this,
246246
/*to_segments_begin=*/end_before_splice);
247247

248-
DCHECK_OK(ConsistencyStatus());
248+
CHECK_OK(ConsistencyStatus());
249249
return SegmentIterator(segments_.get(), end_before_splice);
250250
}
251251

@@ -270,7 +270,7 @@ void DiscreteTrajectory<Frame>::DeleteSegments(SegmentIterator& begin) {
270270
// Make sure that the client doesn't try to use the invalid iterator.
271271
begin = segments().end();
272272

273-
DCHECK_OK(ConsistencyStatus());
273+
CHECK_OK(ConsistencyStatus());
274274
}
275275

276276
template<typename Frame>
@@ -300,7 +300,7 @@ void DiscreteTrajectory<Frame>::ForgetAfter(Instant const& t) {
300300
segment_by_left_endpoint_.end());
301301
}
302302

303-
DCHECK_OK(ConsistencyStatus());
303+
CHECK_OK(ConsistencyStatus());
304304
}
305305

306306
template<typename Frame>
@@ -342,7 +342,7 @@ void DiscreteTrajectory<Frame>::ForgetBefore(Instant const& t) {
342342
sit);
343343
}
344344

345-
DCHECK_OK(ConsistencyStatus());
345+
CHECK_OK(ConsistencyStatus());
346346
}
347347

348348
template<typename Frame>
@@ -396,12 +396,18 @@ void DiscreteTrajectory<Frame>::Merge(DiscreteTrajectory<Frame> trajectory) {
396396
// Merge corresponding segments.
397397
sit_t->Merge(std::move(*sit_s));
398398

399-
// If the left endpoint has changed, remove its entry from the time-to-
400-
// segment map. Insert a new entry if the segment is not empty.
399+
// If the left endpoint of |sit_t| has changed, remove its entry from the
400+
// time-to-segment map, if any.
401401
if (left_endpoint.has_value() &&
402402
sit_t->front().time < left_endpoint.value()) {
403-
segment_by_left_endpoint_.erase(left_endpoint.value());
403+
auto const it = segment_by_left_endpoint_.find(left_endpoint.value());
404+
if (it != segment_by_left_endpoint_.end() && it->second == sit_t) {
405+
segment_by_left_endpoint_.erase(left_endpoint.value());
406+
}
404407
}
408+
// Insert a new entry in the time-to-segment map if the segment is not
409+
// empty. This entry will be overwritten by any future entry at the same
410+
// time, thereby enforcing the invariants of the time-to-segment map.
405411
if (!sit_t->empty()) {
406412
segment_by_left_endpoint_.insert_or_assign(sit_t->front().time, sit_t);
407413
}
@@ -431,7 +437,7 @@ void DiscreteTrajectory<Frame>::Merge(DiscreteTrajectory<Frame> trajectory) {
431437
}
432438
}
433439

434-
DCHECK_OK(ConsistencyStatus());
440+
CHECK_OK(ConsistencyStatus());
435441
}
436442

437443
template<typename Frame>
@@ -726,6 +732,12 @@ absl::Status DiscreteTrajectory<Frame>::ConsistencyStatus() const {
726732
" and ", DebugString(sit2->front().time)));
727733
}
728734
}
735+
if (sit1 != segments_->cend() && !sit1->empty()) {
736+
return absl::InternalError(
737+
absl::StrCat("Segment at time ", DebugString(sit1->front().time),
738+
" missing in the time-to-segment map of size ",
739+
segment_by_left_endpoint_.size()));
740+
}
729741
}
730742
if (!segments_->empty()) {
731743
int i = 0;

physics/discrete_trajectory_test.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,17 @@ TEST_F(DiscreteTrajectoryTest, Merge) {
628628
EXPECT_EQ(t0_ + 9 * Second, sit->front().time);
629629
EXPECT_EQ(t0_ + 14 * Second, sit->back().time);
630630
}
631+
{
632+
auto trajectory1 = MakeTrajectory();
633+
auto trajectory2 = MakeTrajectory();
634+
635+
trajectory1.ForgetAfter(t0_ + 9 * Second);
636+
// This trajectory starts with a 1-point segment. Merge used to fail the
637+
// consistency check because the time-to-segment map was losing an entry.
638+
trajectory2.ForgetBefore(t0_ + 9 * Second);
639+
640+
trajectory2.Merge(std::move(trajectory1));
641+
}
631642
}
632643

633644
TEST_F(DiscreteTrajectoryTest, TMinTMaxEvaluate) {

0 commit comments

Comments
 (0)