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: 48f2466671bb
Choose a base ref
...
head repository: mockingbirdnest/Principia
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1e25c7314ae5
Choose a head ref
  • 10 commits
  • 14 files changed
  • 1 contributor

Commits on May 10, 2020

  1. Get rid of ApparentBubble

    eggrobin committed May 10, 2020
    Copy the full SHA
    2c51a6f View commit details
  2. fix motions

    eggrobin committed May 10, 2020
    Copy the full SHA
    200c7af View commit details
  3. after pleroy’s review

    eggrobin committed May 10, 2020
    Copy the full SHA
    ab939ec View commit details
  4. typo

    eggrobin committed May 10, 2020
    Copy the full SHA
    83e613e View commit details
  5. formatting

    eggrobin committed May 10, 2020
    Copy the full SHA
    41e3459 View commit details
  6. comment

    eggrobin committed May 10, 2020
    Copy the full SHA
    3e2bcb9 View commit details
  7. * not ()

    eggrobin committed May 10, 2020
    Copy the full SHA
    08140f0 View commit details
  8. long line

    eggrobin committed May 10, 2020
    Copy the full SHA
    f3745ab View commit details
  9. Copy the full SHA
    1df6820 View commit details
  10. Merge pull request #2564 from eggrobin/no-bubble

    Get rid of ApparentBubble
    eggrobin authored May 10, 2020
    Copy the full SHA
    1e25c73 View commit details
2 changes: 2 additions & 0 deletions geometry/frame.hpp
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@ namespace internal_frame {
using base::not_constructible;
using base::not_null;

// The enumerators of |FrameMotion| are ordered from most restrictive to least
// restrictive; m1 <= m2 means that m1 satisfies the requirements of m2.
enum FrameMotion {
Inertial,
NonRotating,
30 changes: 19 additions & 11 deletions ksp_plugin/frames.hpp
Original file line number Diff line number Diff line change
@@ -44,14 +44,21 @@ using Barycentric = Frame<serialization::Frame::PluginTag,
Handedness::Right,
serialization::Frame::BARYCENTRIC>;

// The axes are those of |Barycentric|. The origin is that of |World|. This
// frame is used for degrees of freedom obtained after the physics simulation of
// the game has run, and before we perform our correction: the origin has no
// physical significance.
using ApparentBubble = Frame<serialization::Frame::PluginTag,
NonRotating,
Handedness::Right,
serialization::Frame::APPARENT_BUBBLE>;
// The |Apparent...| frames are used for data obtained after the physics
// simulation of the game has run, and before we perform our correction.

// |World| coordinates from the game, but before the correction.
using ApparentWorld = Frame<serialization::Frame::PluginTag,
Arbitrary,
Handedness::Left,
serialization::Frame::APPARENT_WORLD>;

// The axes are those of |Barycentric|. The origin is that of |ApparentWorld|,
// and should not be depended upon.
using Apparent = Frame<serialization::Frame::PluginTag,
NonRotating,
Handedness::Right,
serialization::Frame::APPARENT>;

// |Barycentric|, with its y and z axes swapped.
using CelestialSphere = Frame<serialization::Frame::PluginTag,
@@ -100,14 +107,14 @@ using CameraReference = Frame<serialization::Frame::PluginTag,
// only be performed between simultaneous quantities, then converted to a
// consistent (frame, basis) pair before use.
using AliceSun = Frame<serialization::Frame::PluginTag,
Arbitrary,
NonRotating,
Handedness::Right,
serialization::Frame::ALICE_SUN>;

// Same as above, but with same axes as |World| instead of those of
// |AliceWorld|. The caveats are the same as for |AliceSun|.
using WorldSun = Frame<serialization::Frame::PluginTag,
Arbitrary,
NonRotating,
Handedness::Left,
serialization::Frame::WORLD_SUN>;

@@ -142,7 +149,8 @@ Permutation<WorldSun, AliceSun> const sun_looking_glass(

using internal_frames::AliceSun;
using internal_frames::AliceWorld;
using internal_frames::ApparentBubble;
using internal_frames::Apparent;
using internal_frames::ApparentWorld;
using internal_frames::Barycentric;
using internal_frames::BodyWorld;
using internal_frames::Camera;
3 changes: 2 additions & 1 deletion ksp_plugin/interface.hpp
Original file line number Diff line number Diff line change
@@ -39,11 +39,12 @@ using geometry::AngularVelocity;
using geometry::Displacement;
using geometry::Instant;
using geometry::Position;
using geometry::R3Element;
using geometry::Quaternion;
using geometry::R3Element;
using geometry::Vector;
using geometry::Velocity;
using ksp_plugin::AliceSun;
using ksp_plugin::ApparentWorld;
using ksp_plugin::Barycentric;
using ksp_plugin::Camera;
using ksp_plugin::Iterator;
12 changes: 12 additions & 0 deletions ksp_plugin/interface_body.hpp
Original file line number Diff line number Diff line change
@@ -545,5 +545,17 @@ inline RigidMotion<RigidPart, World> MakePartRigidMotion(
return part_rigid_motion;
}

// Same as |MakePartRigidMotion|, but uses the separate type |ApparentWorld| to
// avoid mixing uncorrected and corrected data.
inline RigidMotion<RigidPart, ApparentWorld> MakePartApparentRigidMotion(
QP const& part_world_degrees_of_freedom,
WXYZ const& part_rotation,
XYZ const& part_angular_velocity) {
return RigidMotion<World, ApparentWorld>::Identity() *
MakePartRigidMotion(part_world_degrees_of_freedom,
part_rotation,
part_angular_velocity);
}

} // namespace interface
} // namespace principia
3 changes: 2 additions & 1 deletion ksp_plugin/interface_part.cpp
Original file line number Diff line number Diff line change
@@ -122,7 +122,8 @@ void __cdecl principia__PartSetApparentRigidMotion(
CHECK_NOTNULL(plugin);
plugin->SetPartApparentRigidMotion(
part_id,
MakePartRigidMotion(degrees_of_freedom, rotation, angular_velocity));
MakePartApparentRigidMotion(
degrees_of_freedom, rotation, angular_velocity));
return m.Return();
}

2 changes: 1 addition & 1 deletion ksp_plugin/interface_vessel.cpp
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ using geometry::Sign;
using geometry::Vector;
using geometry::Velocity;
using ksp_plugin::AliceSun;
using ksp_plugin::ApparentBubble;
using ksp_plugin::Apparent;
using physics::DegreesOfFreedom;
using physics::RelativeDegreesOfFreedom;
using physics::RigidMotion;
18 changes: 8 additions & 10 deletions ksp_plugin/pile_up.cpp
Original file line number Diff line number Diff line change
@@ -132,7 +132,7 @@ std::list<not_null<Part*>> const& PileUp::parts() const {

void PileUp::SetPartApparentRigidMotion(
not_null<Part*> const part,
RigidMotion<RigidPart, ApparentBubble> const& rigid_motion) {
RigidMotion<RigidPart, Apparent> const& rigid_motion) {
auto const [_, inserted] =
apparent_part_rigid_motion_.emplace(part, rigid_motion);
CHECK(inserted) << "Duplicate part " << part->ShortDebugString() << " at "
@@ -325,9 +325,8 @@ not_null<std::unique_ptr<PileUp>> PileUp::ReadFromMessage(
message.apparent_part_degrees_of_freedom()) {
pile_up->apparent_part_rigid_motion_.emplace(
part_id_to_part(part_id),
RigidMotion<RigidPart, ApparentBubble>::MakeNonRotatingMotion(
DegreesOfFreedom<ApparentBubble>::ReadFromMessage(
degrees_of_freedom)));
RigidMotion<RigidPart, Apparent>::MakeNonRotatingMotion(
DegreesOfFreedom<Apparent>::ReadFromMessage(degrees_of_freedom)));
}
} else {
for (auto const& [part_id, rigid_motion] :
@@ -341,8 +340,7 @@ not_null<std::unique_ptr<PileUp>> PileUp::ReadFromMessage(
message.apparent_part_rigid_motion()) {
pile_up->apparent_part_rigid_motion_.emplace(
part_id_to_part(part_id),
RigidMotion<RigidPart, ApparentBubble>::ReadFromMessage(
rigid_motion));
RigidMotion<RigidPart, Apparent>::ReadFromMessage(rigid_motion));
}
}

@@ -456,7 +454,7 @@ void PileUp::DeformPileUpIfNeeded(Instant const& t) {
auto const angular_momentum_in_apparent_pile_up =
Identity<NonRotatingPileUp, ApparentPileUp>()(angular_momentum_);

MechanicalSystem<ApparentBubble, ApparentPileUp> apparent_system;
MechanicalSystem<Apparent, ApparentPileUp> apparent_system;
for (auto const& [part, apparent_part_rigid_motion] :
apparent_part_rigid_motion_) {
apparent_system.AddRigidBody(
@@ -635,8 +633,8 @@ void PileUp::DeformPileUpIfNeeded(Instant const& t) {
correct_angular_velocity ? actual_equivalent_angular_velocity
: NonRotatingPileUp::nonrotating,
NonRotatingPileUp::unmoving);
RigidMotion<ApparentBubble, NonRotatingPileUp> const
apparent_bubble_to_pile_up_motion =
RigidMotion<Apparent, NonRotatingPileUp> const
apparent_to_pile_up_motion =
actual_pile_up_equivalent_motion.Inverse() *
apparent_pile_up_equivalent_motion *
apparent_system.LinearMotion().Inverse();
@@ -647,7 +645,7 @@ void PileUp::DeformPileUpIfNeeded(Instant const& t) {
auto const part = pair.first;
auto const& apparent_part_rigid_motion = pair.second;
actual_part_rigid_motion_.emplace(
part, apparent_bubble_to_pile_up_motion * apparent_part_rigid_motion);
part, apparent_to_pile_up_motion * apparent_part_rigid_motion);
}
apparent_part_rigid_motion_.clear();

6 changes: 3 additions & 3 deletions ksp_plugin/pile_up.hpp
Original file line number Diff line number Diff line change
@@ -112,7 +112,7 @@ class PileUp {
// are doing science.
void SetPartApparentRigidMotion(
not_null<Part*> part,
RigidMotion<RigidPart, ApparentBubble> const& rigid_motion);
RigidMotion<RigidPart, Apparent> const& rigid_motion);

// Deforms the pile-up, advances the time, and nudges the parts, in sequence.
// Does nothing if the psychohistory is already advanced beyond |t|. Several
@@ -148,7 +148,7 @@ class PileUp {
// The axes are those of Barycentric. The origin is the centre of mass of the
// pile up. This frame is distinguished from NonRotatingPileUp in that it is
// used to hold uncorrected (apparent) coordinates given by the game, before
// the enforcement of conservation laws; see also ApparentBubble.
// the enforcement of conservation laws; see also Apparent.
using ApparentPileUp = Frame<enum class ApparentPileUpTag, NonRotating>;

// For deserialization.
@@ -235,7 +235,7 @@ class PileUp {
fixed_instance_;

PartTo<RigidMotion<RigidPart, NonRotatingPileUp>> actual_part_rigid_motion_;
PartTo<RigidMotion<RigidPart, ApparentBubble>> apparent_part_rigid_motion_;
PartTo<RigidMotion<RigidPart, Apparent>> apparent_part_rigid_motion_;

PartTo<RigidTransformation<RigidPart, PileUpPrincipalAxes>> rigid_pile_up_;
std::optional<EulerSolver<NonRotatingPileUp, PileUpPrincipalAxes>>
26 changes: 13 additions & 13 deletions ksp_plugin/plugin.cpp
Original file line number Diff line number Diff line change
@@ -656,32 +656,32 @@ void Plugin::FreeVesselsAndPartsAndCollectPileUps(Time const& Δt) {

void Plugin::SetPartApparentRigidMotion(
PartId const part_id,
RigidMotion<RigidPart, World> const& rigid_motion) {
// As a reference frame, |ApparentBubble| differs from |World| only by having
// the same axes as |Barycentric| and being nonrotating. However, there is
RigidMotion<RigidPart, ApparentWorld> const& rigid_motion) {
// As a reference frame, |Apparent| differs from |World| only by having the
// same axes as |Barycentric| and being nonrotating. However, there is
// another semantic distinction: |Apparent...| coordinates are uncorrected
// data from the game, given immediately after its physics step; before using
// them, we must correct them in accordance with the data computed by the pile
// up. This correction overrides the origin of position and velocity, so we
// need not worry about the current definition of
// |{World::origin, World::unmoving}| as we do when getting the actual degrees
// of freedom (via |Plugin::BarycentricToWorld|).
RigidMotion<World, ApparentBubble> world_to_apparent_bubble{
RigidTransformation<World, ApparentBubble>{
World::origin,
ApparentBubble::origin,
OrthogonalMap<Barycentric, ApparentBubble>::Identity() *
renderer_->WorldToBarycentric(PlanetariumRotation())},
renderer_->BarycentricToWorld(PlanetariumRotation())(
-angular_velocity_of_world_),
World::unmoving};
RigidMotion<ApparentWorld, Apparent> world_to_apparent{
RigidTransformation<ApparentWorld, Apparent>{
ApparentWorld::origin,
Apparent::origin,
OrthogonalMap<Barycentric, Apparent>::Identity() *
renderer_->WorldToBarycentric(PlanetariumRotation()) *
OrthogonalMap<ApparentWorld, World>::Identity()},
Identity<Barycentric, Apparent>()(angular_velocity_of_world_),
Apparent::unmoving};

not_null<Vessel*> vessel = FindOrDie(part_id_to_vessel_, part_id);
CHECK(is_loaded(vessel));
not_null<Part*> const part = vessel->part(part_id);
CHECK(part->is_piled_up());
part->containing_pile_up()->SetPartApparentRigidMotion(
part, world_to_apparent_bubble * rigid_motion);
part, world_to_apparent * rigid_motion);
}

RigidMotion<RigidPart, World> Plugin::GetPartActualMotion(
2 changes: 1 addition & 1 deletion ksp_plugin/plugin.hpp
Original file line number Diff line number Diff line change
@@ -254,7 +254,7 @@ class Plugin {
// part. This part must be in a loaded vessel.
virtual void SetPartApparentRigidMotion(
PartId part_id,
RigidMotion<RigidPart, World> const& rigid_motion);
RigidMotion<RigidPart, ApparentWorld> const& rigid_motion);

// Returns the motion of the given part in |World|, assuming that
// the origin of |World| is fixed at the centre of mass of the
85 changes: 41 additions & 44 deletions ksp_plugin_test/pile_up_test.cpp
Original file line number Diff line number Diff line change
@@ -97,7 +97,7 @@ class TestablePileUp : public PileUp {
return actual_part_rigid_motion_;
}

PartTo<RigidMotion<RigidPart, ApparentBubble>> const&
PartTo<RigidMotion<RigidPart, Apparent>> const&
apparent_part_rigid_motion() const {
return apparent_part_rigid_motion_;
}
@@ -161,55 +161,52 @@ class PileUpTest : public testing::Test {
10.0 * Metre / Second,
10.0 / 3.0 * Metre / Second}), 17)));

// Centre of mass of |p1_| and |p2_| in |ApparentBubble|, in SI units:
// Centre of mass of |p1_| and |p2_| in |Apparent|, in SI units:
// {1 / 9, -1 / 3, -2 / 9} {10 / 9, -10 / 3, -20 / 9}
DegreesOfFreedom<ApparentBubble> const p1_dof(
ApparentBubble::origin +
Displacement<ApparentBubble>({-11.0 / 3.0 * Metre,
-1.0 * Metre,
2.0 / 3.0 * Metre}),
Velocity<ApparentBubble>({-110.0 / 3.0 * Metre / Second,
-10.0 * Metre / Second,
20.0 / 3.0 * Metre / Second}));
DegreesOfFreedom<ApparentBubble> const p2_dof(
ApparentBubble::origin +
Displacement<ApparentBubble>({2.0 * Metre,
0.0 * Metre,
-2.0 / 3.0 * Metre}),
Velocity<ApparentBubble>({20.0 * Metre / Second,
0.0 * Metre / Second,
-20.0 / 3.0 * Metre / Second}));
DegreesOfFreedom<Apparent> const p1_dof(
Apparent::origin +
Displacement<Apparent>(
{-11.0 / 3.0 * Metre, -1.0 * Metre, 2.0 / 3.0 * Metre}),
Velocity<Apparent>({-110.0 / 3.0 * Metre / Second,
-10.0 * Metre / Second,
20.0 / 3.0 * Metre / Second}));
DegreesOfFreedom<Apparent> const p2_dof(
Apparent::origin + Displacement<Apparent>(
{2.0 * Metre, 0.0 * Metre, -2.0 / 3.0 * Metre}),
Velocity<Apparent>({20.0 * Metre / Second,
0.0 * Metre / Second,
-20.0 / 3.0 * Metre / Second}));
pile_up.SetPartApparentRigidMotion(
&p1_,
RigidMotion<RigidPart, ApparentBubble>::MakeNonRotatingMotion(p1_dof));
&p1_, RigidMotion<RigidPart, Apparent>::MakeNonRotatingMotion(p1_dof));
pile_up.SetPartApparentRigidMotion(
&p2_,
RigidMotion<RigidPart, ApparentBubble>::MakeNonRotatingMotion(p2_dof));
&p2_, RigidMotion<RigidPart, Apparent>::MakeNonRotatingMotion(p2_dof));

EXPECT_THAT(
pile_up.apparent_part_rigid_motion().at(&p1_)({RigidPart::origin,
RigidPart::unmoving}),
Componentwise(AlmostEquals(ApparentBubble::origin +
Displacement<ApparentBubble>(
{-11.0 / 3.0 * Metre,
-1.0 * Metre,
2.0 / 3.0 * Metre}), 0),
AlmostEquals(Velocity<ApparentBubble>(
{-110.0 / 3.0 * Metre / Second,
-10.0 * Metre / Second,
20.0 / 3.0 * Metre / Second}), 4)));
pile_up.apparent_part_rigid_motion().at(&p1_)(
{RigidPart::origin, RigidPart::unmoving}),
Componentwise(
AlmostEquals(
Apparent::origin +
Displacement<Apparent>(
{-11.0 / 3.0 * Metre, -1.0 * Metre, 2.0 / 3.0 * Metre}),
0),
AlmostEquals(Velocity<Apparent>({-110.0 / 3.0 * Metre / Second,
-10.0 * Metre / Second,
20.0 / 3.0 * Metre / Second}),
4)));
EXPECT_THAT(
pile_up.apparent_part_rigid_motion().at(&p2_)({RigidPart::origin,
RigidPart::unmoving}),
Componentwise(AlmostEquals(ApparentBubble::origin +
Displacement<ApparentBubble>(
{2.0 * Metre,
0.0 * Metre,
-2.0 / 3.0 * Metre}), 0),
AlmostEquals(Velocity<ApparentBubble>(
{20.0 * Metre / Second,
0.0 * Metre / Second,
-20.0 / 3.0 * Metre / Second}), 4)));
pile_up.apparent_part_rigid_motion().at(&p2_)(
{RigidPart::origin, RigidPart::unmoving}),
Componentwise(
AlmostEquals(
Apparent::origin +
Displacement<Apparent>(
{2.0 * Metre, 0.0 * Metre, -2.0 / 3.0 * Metre}),
0),
AlmostEquals(Velocity<Apparent>({20.0 * Metre / Second,
0.0 * Metre / Second,
-20.0 / 3.0 * Metre / Second}),
4)));
}

void CheckPreAdvanceTimeInvariants(TestablePileUp& pile_up) {
4 changes: 3 additions & 1 deletion physics/massive_body_body.hpp
Original file line number Diff line number Diff line change
@@ -156,7 +156,8 @@ inline not_null<std::unique_ptr<MassiveBody>> MassiveBody::ReadFromMessage(
switch (static_cast<Tag>(enum_value_descriptor->number())) {
ROTATING_BODY_TAG_VALUE_CASE(ALICE_SUN);
ROTATING_BODY_TAG_VALUE_CASE(ALICE_WORLD);
ROTATING_BODY_TAG_VALUE_CASE(APPARENT_BUBBLE);
ROTATING_BODY_TAG_VALUE_CASE(APPARENT);
ROTATING_BODY_TAG_VALUE_CASE(APPARENT_WORLD);
ROTATING_BODY_TAG_VALUE_CASE(BARYCENTRIC);
ROTATING_BODY_TAG_VALUE_CASE(BODY_WORLD);
ROTATING_BODY_TAG_VALUE_CASE(CAMERA);
@@ -166,6 +167,7 @@ inline not_null<std::unique_ptr<MassiveBody>> MassiveBody::ReadFromMessage(
ROTATING_BODY_TAG_VALUE_CASE(NAVBALL);
ROTATING_BODY_TAG_VALUE_CASE(NAVIGATION);
ROTATING_BODY_TAG_VALUE_CASE(NON_ROTATING_PILE_UP);
ROTATING_BODY_TAG_VALUE_CASE(PILE_UP_PRINCIPAL_AXES);
ROTATING_BODY_TAG_VALUE_CASE(RIGID_PART);
ROTATING_BODY_TAG_VALUE_CASE(WORLD);
ROTATING_BODY_TAG_VALUE_CASE(WORLD_SUN);
9 changes: 8 additions & 1 deletion physics/rigid_motion.hpp
Original file line number Diff line number Diff line change
@@ -63,9 +63,16 @@ class RigidMotion final {

RigidMotion<ToFrame, FromFrame> Inverse() const;

// A rigid motion expressing that |FromFrame| and |ToFrame| have the same
// axes, origin, and instantaneous motion.
// This function is enabled only if both frames have the same handedness (this
// is a requirement of OrthogonalMap::Identity) and if the |motion| of
// FromFrame is a special case of that of |ToFrame| (see the comments on
// |FrameMotion|).
template<typename F = FromFrame,
typename T = ToFrame,
typename = std::enable_if_t<std::is_same_v<F, T>>>
typename = std::enable_if_t<(F::handedness == T::handedness &&
F::motion <= T::motion)>>
static RigidMotion Identity();

// A factory that construct a non-rotating motion using the given degrees of
Loading