Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Headers for the new-style DiscreteTrajectory #3137

Merged
merged 4 commits into from
Oct 3, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions physics/discrete_trajectory2.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#pragma once

#include <list>
#include <memory>

#include "absl/container/btree_map.h"
#include "base/not_null.hpp"
#include "geometry/named_quantities.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "physics/discrete_trajectory_iterator.hpp"
#include "physics/discrete_trajectory_segment_iterator.hpp"
#include "physics/discrete_trajectory_segment_range.hpp"
#include "physics/discrete_trajectory_types.hpp"
#include "physics/trajectory.hpp"
#include "serialization/physics.pb.h"

namespace principia {
namespace physics {

template<typename Frame>
class DiscreteTrajectorySegment;

namespace internal_discrete_trajectory {

using base::not_null;
using geometry::Instant;
using geometry::Position;
using geometry::Velocity;
using physics::DegreesOfFreedom;

template<typename Frame>
class DiscreteTrajectory2 : public Trajectory<Frame> {
public:
using iterator = DiscreteTrajectoryIterator<Frame>;
using reverse_iterator = std::reverse_iterator<iterator>;
using SegmentIterator = DiscreteTrajectorySegmentIterator<Frame>;
using ReverseSegmentIterator = std::reverse_iterator<SegmentIterator>;
using SegmentRange = DiscreteTrajectorySegmentRange<SegmentIterator>;
using ReverseSegmentRange =
DiscreteTrajectorySegmentRange<ReverseSegmentIterator>;

DiscreteTrajectory2() = default;

// Moveable.
DiscreteTrajectory2(DiscreteTrajectory2&&) = default;
DiscreteTrajectory2& operator=(DiscreteTrajectory2&&) = default;
DiscreteTrajectory2(const DiscreteTrajectory2&) = delete;
DiscreteTrajectory2& operator=(const DiscreteTrajectory2&) = delete;

iterator begin() const;
iterator end() const;

reverse_iterator rbegin() const;
reverse_iterator rend() const;

iterator find(Instant const& t) const;

iterator lower_bound(Instant const& t) const;
iterator upper_bound(Instant const& t) const;

SegmentRange segments() const;
ReverseSegmentRange rsegments() const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the Right Thing to do is to have only segments and use an adapter to iterate backward (in C++20 that would be https://en.cppreference.com/w/cpp/ranges/reverse_view, maybe absl has a thing in the meantime, or we can write one in base, we should have make_reverse_iterator).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a TODO to fix this once we have C++20.


SegmentIterator NewSegment();

DiscreteTrajectory DetachSegments(iterator begin);
SegmentIterator AttachSegments(DiscreteTrajectory&& trajectory);
void DeleteSegments(iterator 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);

Position<Frame> EvaluatePosition(Instant const& time) const override;
Velocity<Frame> EvaluateVelocity(Instant const& time) const override;
DegreesOfFreedom<Frame> EvaluateDegreesOfFreedom(
Instant const& time) const override;

void WriteToMessage(
not_null<serialization::DiscreteTrajectory*> message,
std::vector<SegmentIterator> const& tracked,
std::vector<iterator> const& exact) const;
void WriteToMessage(
not_null<serialization::DiscreteTrajectory*> message,
iterator begin, iterator end,
std::vector<SegmentIterator> const& tracked,
std::vector<iterator> const& exact) const;

template<typename F = Frame,
typename = std::enable_if_t<base::is_serializable_v<F>>>
static not_null<std::unique_ptr<DiscreteTrajectory>> ReadFromMessage(
serialization::DiscreteTrajectory const& message,
std::vector<DiscreteTrajectory<Frame>**> const& tracked);

private:
using Segments = internal_discrete_trajectory_types::Segments<Frame>;

Segments segments_;
};

} // namespace internal_discrete_trajectory

template<typename Frame>
using DiscreteTrajectory2 = internal_discrete_trajectory::DiscreteTrajectory2;

} // namespace physics
} // namespace principia
47 changes: 47 additions & 0 deletions physics/discrete_trajectory_iterator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once

#include "absl/container/btree_map.h"
#include "geometry/named_quantities.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "physics/discrete_trajectory_segment_iterator.hpp"
#include "physics/discrete_trajectory_types.hpp"

namespace principia {
namespace physics {

template<typename Frame>
class DiscreteTrajectory;

namespace internal_discrete_trajectory_iterator {

using geometry::Instant;
using physics::DegreesOfFreedom;

template<typename Frame>
class DiscreteTrajectoryIterator {
public:
DiscreteTrajectoryIterator() = default;

DiscreteTrajectoryIterator& operator++();
DiscreteTrajectoryIterator& operator--();
DiscreteTrajectoryIterator operator++(int);
DiscreteTrajectoryIterator operator--(int);

typename DiscreteTrajectory<Frame>::value_type const& operator*() const;
typename DiscreteTrajectory<Frame>::value_type const* operator->() const;

private:
using Timeline = internal_discrete_trajectory_types::Timeline<Frame>;

DiscreteTrajectorySegmentIterator segment_;
Timeline::const_iterator point_;
};

} // namespace internal_discrete_trajectory_iterator

template<typename Frame>
using DiscreteTrajectoryIterator =
internal_discrete_trajectory_iterator::DiscreteTrajectoryIterator;

} // namespace principia
} // namespace physics
66 changes: 66 additions & 0 deletions physics/discrete_trajectory_segment.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once

#include "absl/container/btree_map.h"
#include "absl/container/btree_set.h"
#include "geometry/named_quantities.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "physics/discrete_trajectory_iterator.hpp"
#include "physics/discrete_trajectory_segment_iterator.hpp"
#include "physics/discrete_trajectory_types.hpp"

namespace principia {
namespace physics {
namespace internal_discrete_trajectory_segment {

using geometry::Instant;
using physics::DegreesOfFreedom;

template<typename Frame>
class DiscreteTrajectorySegment {
public:
DiscreteTrajectorySegment() = default;

// Moveable.
DiscreteTrajectorySegment(DiscreteTrajectorySegment&&) = default;
DiscreteTrajectorySegment& operator=(DiscreteTrajectorySegment&&) = default;
DiscreteTrajectorySegment(const DiscreteTrajectorySegment&) = delete;
DiscreteTrajectorySegment& operator=(const DiscreteTrajectorySegment&) =
delete;

DiscreteTrajectoryIterator<Frame> begin() const;
DiscreteTrajectoryIterator<Frame> end() const;

DiscreteTrajectoryIterator<Frame> rbegin() const;
DiscreteTrajectoryIterator<Frame> rend() const;

DiscreteTrajectoryIterator<Frame> find(Instant const& t) const;

DiscreteTrajectoryIterator<Frame> lower_bound(Instant const& t) const;
DiscreteTrajectoryIterator<Frame> upper_bound(Instant const& t) const;

private:
using Timeline = internal_discrete_trajectory_types::Timeline<Frame>;

void Append(Instant const& t,
DegreesOfFreedom<Frame> const& degrees_of_freedom);

void ForgetAfter(Instant const& t);
void ForgetAfter(Timeline::const_iterator begin);

void ForgetBefore(Instant const& t);
void ForgetBefore(Timeline::const_iterator end);

DiscreteTrajectorySegmentIterator<Frame> that_;

Timeline timeline_;
absl::btree_set<Instant> dense_points_;
};

} // namespace internal_discrete_trajectory_segment

template<typename Frame>
using DiscreteTrajectorySegment =
internal_discrete_trajectory_segment::DiscreteTrajectorySegment;

} // namespace physics
} // namespace principia
49 changes: 49 additions & 0 deletions physics/discrete_trajectory_segment_iterator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

#include <list>
#include <memory>

#include "absl/container/btree_map.h"
#include "geometry/named_quantities.hpp"
#include "physics/degrees_of_freedom.hpp"
#include "physics/discrete_trajectory_types.hpp"

namespace principia {
namespace physics {

template<typename Frame>
class DiscreteTrajectorySegment;

namespace internal_discrete_trajectory_segment_iterator {

using geometry::Instant;
using physics::DegreesOfFreedom;

template<typename Frame>
class DiscreteTrajectorySegmentIterator {
public:
DiscreteTrajectorySegmentIterator() = default;

DiscreteTrajectorySegmentIterator& operator++();
DiscreteTrajectorySegmentIterator& operator--();
DiscreteTrajectorySegmentIterator operator++(int);
DiscreteTrajectorySegmentIterator operator--(int);

DiscreteTrajectorySegment<Frame> const& operator*() const;
DiscreteTrajectorySegment<Frame> const* operator->() const;

private:
using Segments = internal_discrete_trajectory_types::Segments<Frame>;

Segments::const_iterator segment_;
};

} // namespace internal_discrete_trajectory_segment_iterator

template<typename Frame>
using DiscreteTrajectorySegmentIterator =
internal_discrete_trajectory_segment_iterator::
DiscreteTrajectorySegmentIterator;

} // namespace physics
} // namespace principia
37 changes: 37 additions & 0 deletions physics/discrete_trajectory_segment_range.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <list>
#include <memory>

#include "absl/container/btree_map.h"
#include "geometry/named_quantities.hpp"
#include "physics/degrees_of_freedom.hpp"

namespace principia {
namespace physics {
namespace internal_discrete_trajectory_segment_range {

using geometry::Instant;
using physics::DegreesOfFreedom;

template<typename Iterator>
class DiscreteTrajectorySegmentRange {
public:
DiscreteTrajectorySegmentRange() = default;

Iterator begin() const;
Iterator end() const;

private:
Iterator begin_;
Iterator end_;
};

} // namespace internal_discrete_trajectory_segment_range

template<typename Iterator>
using DiscreteTrajectorySegmentRange =
internal_discrete_trajectory_segment_range::DiscreteTrajectorySegmentRange;

} // namespace physics
} // namespace principia
33 changes: 33 additions & 0 deletions physics/discrete_trajectory_types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include <list>
#include <memory>

#include "absl/container/btree_map.h"
#include "geometry/named_quantities.hpp"
#include "physics/degrees_of_freedom.hpp"

// An internal header to avoid replicating data structures in multiple places.
// Doesn't export anything outside of its internal namespace.
namespace principia {
namespace physics {

template<typename Frame>
class DiscreteTrajectorySegment;

namespace internal_discrete_trajectory_types {

using geometry::Instant;
using physics::DegreesOfFreedom;

// The use of an unique_ptr here makes it possible to only depend on a forward
// declaration of DiscreteTrajectorySegment.
template<typename Frame>
using Segments = std::list<std::unique_ptr<DiscreteTrajectorySegment<Frame>>>;

template<typename Frame>
using Timeline = absl::btree_map<Instant, DegreesOfFreedom<Frame>>;

} // namespace internal_discrete_trajectory_types
} // namespace physics
} // namespace principia
6 changes: 6 additions & 0 deletions physics/physics.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
<ClInclude Include="body_surface_frame_field_body.hpp" />
<ClInclude Include="checkpointer.hpp" />
<ClInclude Include="checkpointer_body.hpp" />
<ClInclude Include="discrete_trajectory2.hpp" />
<ClInclude Include="discrete_trajectory_iterator.hpp" />
<ClInclude Include="discrete_trajectory_segment.hpp" />
<ClInclude Include="discrete_trajectory_segment_iterator.hpp" />
<ClInclude Include="discrete_trajectory_segment_range.hpp" />
<ClInclude Include="discrete_trajectory_types.hpp" />
<ClInclude Include="mechanical_system.hpp" />
<ClInclude Include="mechanical_system_body.hpp" />
<ClInclude Include="continuous_trajectory_body.hpp" />
Expand Down
18 changes: 18 additions & 0 deletions physics/physics.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,24 @@
<ClInclude Include="mechanical_system_body.hpp">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="discrete_trajectory_segment.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="discrete_trajectory_iterator.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="discrete_trajectory_segment_iterator.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="discrete_trajectory2.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="discrete_trajectory_types.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="discrete_trajectory_segment_range.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="degrees_of_freedom_test.cpp">
Expand Down