Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 61fc78d86756
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 084a34288aff
Choose a head ref
  • 10 commits
  • 7 files changed
  • 1 contributor

Commits on Oct 17, 2021

  1. Rsegments.

    pleroy committed Oct 17, 2021
    Copy the full SHA
    51b7e3d View commit details
  2. Copy the full SHA
    8456a6b View commit details
  3. Copy the full SHA
    b57b668 View commit details
  4. ForgetBefore.

    pleroy committed Oct 17, 2021
    Copy the full SHA
    66543b0 View commit details
  5. Forgetting and empty segments.

    pleroy committed Oct 17, 2021
    Copy the full SHA
    d7b0374 View commit details
  6. DetachSegments.

    pleroy committed Oct 17, 2021
    Copy the full SHA
    bc9f990 View commit details
  7. AttachSegments.

    pleroy committed Oct 17, 2021
    Copy the full SHA
    319cbb9 View commit details
  8. Copy the full SHA
    aedbe3a View commit details
  9. A comment.

    pleroy committed Oct 17, 2021
    Copy the full SHA
    95335a8 View commit details
  10. Merge pull request #3155 from pleroy/Trajectory2

    DiscreteTrajectory2, second part of the implementation and tests
    pleroy authored Oct 17, 2021
    Copy the full SHA
    084a342 View commit details
22 changes: 17 additions & 5 deletions physics/discrete_trajectory2.hpp
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
#include "absl/container/btree_map.h"
#include "base/macros.hpp"
#include "base/not_null.hpp"
#include "base/tags.hpp"
#include "geometry/named_quantities.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "physics/discrete_trajectory_iterator.hpp"
@@ -28,6 +29,7 @@ FORWARD_DECLARE_FROM(discrete_trajectory_segment,
namespace internal_discrete_trajectory2 {

using base::not_null;
using base::uninitialized_t;
using geometry::Instant;
using geometry::Position;
using geometry::Velocity;
@@ -77,15 +79,12 @@ class DiscreteTrajectory2 : public Trajectory<Frame> {

SegmentIterator NewSegment();

DiscreteTrajectory2 DetachSegments(iterator begin);
DiscreteTrajectory2 DetachSegments(SegmentIterator begin);
SegmentIterator AttachSegments(DiscreteTrajectory2&& trajectory);
void DeleteSegments(iterator begin);
void DeleteSegments(SegmentIterator begin);

void ForgetAfter(Instant const& t);
void ForgetAfter(iterator begin);

void ForgetBefore(Instant const& t);
void ForgetBefore(iterator end);

void Append(Instant const& t,
DegreesOfFreedom<Frame> const& degrees_of_freedom);
@@ -117,9 +116,22 @@ class DiscreteTrajectory2 : public Trajectory<Frame> {
private:
using Segments = internal_discrete_trajectory_types::Segments<Frame>;

// This constructor leaves the list of segments empty (but allocated) as well
// as the time-to-segment mapping.
explicit DiscreteTrajectory2(uninitialized_t);

typename Segments::iterator FindSegment(Instant const& t);
typename Segments::const_iterator FindSegment(Instant const& t) const;

// Updates the segments self-pointers and the time-to-segment mapping after
// segments have been spliced from |from| to |to|. The iterators indicate the
// segments to fix-up.
static void AdjustAfterSplicing(
DiscreteTrajectory2& from,
DiscreteTrajectory2& to,
typename Segments::iterator to_segments_begin,
std::reverse_iterator<typename Segments::iterator> to_segments_rend);

// We need a level of indirection here to make sure that the pointer to
// Segments in the DiscreteTrajectorySegmentIterator remain valid when the
// DiscreteTrajectory moves. This field is never null and never empty.
112 changes: 92 additions & 20 deletions physics/discrete_trajectory2_body.hpp
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ namespace internal_discrete_trajectory2 {

using astronomy::InfinitePast;
using base::make_not_null_unique;
using base::uninitialized;

template<typename Frame>
DiscreteTrajectory2<Frame>::DiscreteTrajectory2()
@@ -114,7 +115,10 @@ DiscreteTrajectory2<Frame>::segments() const {
template<typename Frame>
typename DiscreteTrajectory2<Frame>::ReverseSegmentRange
DiscreteTrajectory2<Frame>::rsegments() const {
// TODO(phl): Implement.
return ReverseSegmentRange(std::reverse_iterator(SegmentIterator(
segments_.get(), segments_->end())),
std::reverse_iterator(SegmentIterator(
segments_.get(), segments_->begin())));
}

template<typename Frame>
@@ -139,42 +143,84 @@ DiscreteTrajectory2<Frame>::NewSegment() {

template<typename Frame>
typename DiscreteTrajectory2<Frame>::DiscreteTrajectory2
DiscreteTrajectory2<Frame>::DetachSegments(iterator begin) {
// TODO(phl): Implement.
DiscreteTrajectory2<Frame>::DetachSegments(SegmentIterator const begin) {
DiscreteTrajectory2 detached(uninitialized);

// Move the detached segments to the new trajectory.
detached.segments_->splice(detached.segments_->end(),
*segments_,
begin.iterator(), segments_->end());

AdjustAfterSplicing(/*from=*/*this,
/*to=*/detached,
/*to_segments_begin=*/detached.segments_->begin(),
/*to_segments_rend=*/detached.segments_->rend());

return detached;
}

template<typename Frame>
typename DiscreteTrajectory2<Frame>::SegmentIterator
DiscreteTrajectory2<Frame>::AttachSegments(
DiscreteTrajectory2&& trajectory) {
// TODO(phl): Implement.
}
CHECK(!trajectory.empty());
// NOTE(phl): This check might be too strict, we might want to allow LT as the
// time comparison, and to adjust the first point of trajectory as needed.
// We'll see if the clients need that.
CHECK_EQ(rbegin()->first, trajectory.begin()->first)
<< "Mismatching times when attaching segments";
CHECK_EQ(rbegin()->second, trajectory.begin()->second)
<< "Mismatching degrees of freedom when attaching segments";

template<typename Frame>
void DiscreteTrajectory2<Frame>::DeleteSegments(iterator begin) {
// TODO(phl): Implement.
}
if (empty()) {
*this = DiscreteTrajectory2(uninitialized);
}

template<typename Frame>
void DiscreteTrajectory2<Frame>::ForgetAfter(Instant const& t) {
// TODO(phl): Drop segments as needed.
return FindSegment(t)->ForgetAfter(t);
// The |end| iterator keeps pointing at the end after the splice. Instead,
// we track the iterator to the last segment.
auto const last_before_splice = --segments_->end();

// Move the attached segments to the end of this trajectory.
segments_->splice(segments_->end(),
*trajectory.segments_);

auto const end_before_splice = std::next(last_before_splice);
auto const rbegin_before_splice = std::reverse_iterator(end_before_splice);

AdjustAfterSplicing(/*from=*/trajectory,
/*to=*/*this,
/*to_segments_begin=*/end_before_splice,
/*to_segments_rend=*/rbegin_before_splice);

return SegmentIterator(segments_.get(), end_before_splice);
}

template<typename Frame>
void DiscreteTrajectory2<Frame>::ForgetAfter(iterator begin) {
// TODO(phl): Implement.
void DiscreteTrajectory2<Frame>::DeleteSegments(SegmentIterator const begin) {
segments_->erase(begin.iterator(), segments_->end());
}

template<typename Frame>
void DiscreteTrajectory2<Frame>::ForgetBefore(Instant const& t) {
// TODO(phl): Drop segments as needed.
return FindSegment(t)->ForgetBefore(t);
void DiscreteTrajectory2<Frame>::ForgetAfter(Instant const& t) {
auto const sit = FindSegment(t);
sit->ForgetAfter(t);
// Here |sit| designates a segment starting at or after |t|. If |t| is
// exactly at the beginning of the segment, |ForgetAfter| above will leave it
// empty. In that case we drop the segment entirely. Note that this
// situation doesn't arise for |ForgetBefore| because of the way |FindSegment|
// works.
if (sit->empty()) {
segments_->erase(sit, segments_->end());
} else {
segments_->erase(std::next(sit), segments_->end());
}
}

template<typename Frame>
void DiscreteTrajectory2<Frame>::ForgetBefore(iterator end) {
// TODO(phl): Implement.
void DiscreteTrajectory2<Frame>::ForgetBefore(Instant const& t) {
auto const sit = FindSegment(t);
sit->ForgetBefore(t);
segments_->erase(segments_->begin(), sit);
}

template<typename Frame>
@@ -247,6 +293,10 @@ DiscreteTrajectory2<Frame>::ReadFromMessage(
// TODO(phl): Implement.
}

template<typename Frame>
DiscreteTrajectory2<Frame>::DiscreteTrajectory2(uninitialized_t)
: segments_(make_not_null_unique<Segments>()) {}

template<typename Frame>
typename DiscreteTrajectory2<Frame>::Segments::iterator
DiscreteTrajectory2<Frame>::FindSegment(
@@ -265,6 +315,28 @@ DiscreteTrajectory2<Frame>::FindSegment(
return (--it)->second;
}

template<typename Frame>
void DiscreteTrajectory2<Frame>::AdjustAfterSplicing(
DiscreteTrajectory2& from,
DiscreteTrajectory2& to,
typename Segments::iterator to_segments_begin,
std::reverse_iterator<typename Segments::iterator> to_segments_rend) {

// Iterate through the target segments to move the time-to-segment mapping
// from |from| to |to|.
auto endpoint_it = from.segment_by_left_endpoint_.end();
for (auto sit = to.segments_->rbegin(); sit != to_segments_rend; ++sit) {
--endpoint_it;
to.segment_by_left_endpoint_.insert(
from.segment_by_left_endpoint_.extract(endpoint_it));
}

// Reset the self pointers of the new segments.
for (auto sit = to_segments_begin; sit != to.segments_->end(); ++sit) {
sit->SetSelf(SegmentIterator(to.segments_.get(), sit));
}
}

} // namespace internal_discrete_trajectory2
} // namespace physics
} // namespace principia
Loading