Skip to content

Commit

Permalink
feat: StateBuilder operators, reduction and expansion
Browse files Browse the repository at this point in the history
  • Loading branch information
Pau Hebrero committed Oct 12, 2023
1 parent 250ed7a commit 5abe6fd
Show file tree
Hide file tree
Showing 11 changed files with 541 additions and 351 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_StateBuilder(pybind11::mo
using ostk::astro::trajectory::State;
using ostk::astro::trajectory::StateBuilder;
using ostk::astro::trajectory::state::CoordinatesBroker;
using ostk::astro::trajectory::state::CoordinatesSubset;

class_<StateBuilder>(aModule, "StateBuilder")

Expand All @@ -27,23 +28,39 @@ inline void OpenSpaceToolkitAstrodynamicsPy_Trajectory_StateBuilder(pybind11::mo
arg("frame"),
arg("coordinates_broker")
)
.def(init<const State&>(), arg("state"))

.def(self == self)
.def(self != self)
.def(
"__add__",
[](const StateBuilder& aStateBuilder, const Shared<const CoordinatesSubset>& aCoordinatesSubsetSPtr)
{
return aStateBuilder + aCoordinatesSubsetSPtr;
},
is_operator()
)
.def(
"__sub__",
[](const StateBuilder& aStateBuilder, const Shared<const CoordinatesSubset>& aCoordinatesSubsetSPtr)
{
return aStateBuilder - aCoordinatesSubsetSPtr;
},
is_operator()
)

.def("__str__", &(shiftToString<StateBuilder>))
.def("__repr__", &(shiftToString<StateBuilder>))

.def("is_defined", &StateBuilder::isDefined)

.def("build_state", &StateBuilder::buildState)
.def("build", &StateBuilder::build)
.def("reduce", &StateBuilder::reduce)
.def("expand", &StateBuilder::expand)

.def("get_coordinates_subsets", &StateBuilder::getCoordinatesSubsets)
.def("get_frame", &StateBuilder::getFrame)

.def("expand", &StateBuilder::expand)
.def("contract", &StateBuilder::contract)

.def_static("undefined", &StateBuilder::Undefined)

;
Expand Down
143 changes: 67 additions & 76 deletions bindings/python/test/trajectory/test_state_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,28 @@ def coordinates_subsets() -> list[CoordinatesSubset]:


@pytest.fixture
def coordinates_broker(coordinates_subsets: list[CoordinatesSubset]) -> CoordinatesBroker:
return CoordinatesBroker(coordinates_subsets)
def coordinates() -> list[float]:
return [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]


@pytest.fixture
def state_builder(frame: Frame, coordinates_broker: CoordinatesBroker) -> State:
return StateBuilder(frame, coordinates_broker)
def coordinates_broker(coordinates_subsets: list[CoordinatesSubset]) -> CoordinatesBroker:
return CoordinatesBroker(coordinates_subsets)


@pytest.fixture
def coordinates_subsets_with_mass() -> list[CoordinatesSubset]:
return [
CartesianPosition.default(),
CartesianVelocity.default(),
CoordinatesSubset.mass(),
]
def state(
instant: Instant,
coordinates: list[float],
frame: Frame,
coordinates_broker: CoordinatesBroker,
) -> State:
return State(instant, coordinates, frame, coordinates_broker)


@pytest.fixture
def state_builder_with_mass(
frame: Frame, coordinates_subsets_with_mass: list[CoordinatesSubset]
) -> State:
return StateBuilder(frame, CoordinatesBroker(coordinates_subsets_with_mass))
def state_builder(frame: Frame, coordinates_broker: CoordinatesBroker) -> State:
return StateBuilder(frame, coordinates_broker)


class TestStateBuilder:
Expand All @@ -85,17 +84,38 @@ def test_subsets_constructor(
assert isinstance(builder, StateBuilder)
assert builder.is_defined()

def test_state_constructor(
self,
state: State,
):
builder = StateBuilder(state)
assert builder is not None
assert isinstance(builder, StateBuilder)
assert builder.is_defined()

def test_comparators(self, state_builder: StateBuilder):
assert (state_builder == state_builder) is True
assert (state_builder != state_builder) is False

def test_build_state(
def test_operators(
self,
state_builder: StateBuilder,
):
added_builder: StateBuilder = state_builder + CoordinatesSubset.mass()
assert isinstance(added_builder, StateBuilder)
assert state_builder != added_builder

subtracted_builder: StateBuilder = state_builder - CartesianPosition.default()
assert isinstance(subtracted_builder, StateBuilder)
assert state_builder != subtracted_builder

def test_build(
self,
instant: Instant,
state_builder: StateBuilder,
):
coordinates = [1, 2, 3, 1, 2, 3]
state: State = state_builder.build_state(instant, coordinates)
state: State = state_builder.build(instant, coordinates)

assert state is not None
assert isinstance(state, State)
Expand All @@ -105,74 +125,45 @@ def test_build_state(
assert state.get_frame() == state_builder.get_frame()
assert state.get_coordinates_subsets() == state_builder.get_coordinates_subsets()

def test_getters(
def test_reduce(
self,
state_builder: StateBuilder,
frame: Frame,
coordinates_broker: CoordinatesBroker,
state: State,
):
assert state_builder.get_frame() == frame
assert state_builder.get_coordinates_subsets() == coordinates_broker.get_subsets()
builder = StateBuilder(state.get_frame(), [CartesianPosition.default()])
reduced_state: State = builder.reduce(state)

assert isinstance(reduced_state, State)
assert state != reduced_state

def test_expand(
self,
state_builder: StateBuilder,
state: State,
):
expaned_state_builder: StateBuilder = state_builder.expand(
CoordinatesSubset.mass()
builder = StateBuilder(
state.get_frame(),
[
CartesianPosition.default(),
CartesianVelocity.default(),
CoordinatesSubset.mass(),
],
)

assert (state_builder == expaned_state_builder) is False
assert (state_builder != expaned_state_builder) is True

assert 2 == len(state_builder.get_coordinates_subsets())
assert CartesianPosition.default() == state_builder.get_coordinates_subsets()[0]
assert CartesianVelocity.default() == state_builder.get_coordinates_subsets()[1]

assert 3 == len(expaned_state_builder.get_coordinates_subsets())
assert (
CartesianPosition.default()
== expaned_state_builder.get_coordinates_subsets()[0]
)
assert (
CartesianVelocity.default()
== expaned_state_builder.get_coordinates_subsets()[1]
)
assert (
CoordinatesSubset.mass() == expaned_state_builder.get_coordinates_subsets()[2]
default_state: State = State(
state.get_instant(),
[100],
state.get_frame(),
CoordinatesBroker([CoordinatesSubset.mass()]),
)
expanded_state: State = builder.expand(state, default_state)

assert isinstance(expanded_state, State)
assert state != expanded_state
assert default_state != expanded_state

def test_contract(
def test_getters(
self,
state_builder_with_mass: StateBuilder,
state_builder: StateBuilder,
frame: Frame,
coordinates_broker: CoordinatesBroker,
):
contracted_state_builder: StateBuilder = state_builder_with_mass.contract(
CartesianVelocity.default()
)

assert (state_builder_with_mass == contracted_state_builder) is False
assert (state_builder_with_mass != contracted_state_builder) is True

assert 3 == len(state_builder_with_mass.get_coordinates_subsets())
assert (
CartesianPosition.default()
== state_builder_with_mass.get_coordinates_subsets()[0]
)
assert (
CartesianVelocity.default()
== state_builder_with_mass.get_coordinates_subsets()[1]
)
assert (
CoordinatesSubset.mass()
== state_builder_with_mass.get_coordinates_subsets()[2]
)

assert 2 == len(contracted_state_builder.get_coordinates_subsets())
assert (
CartesianPosition.default()
== contracted_state_builder.get_coordinates_subsets()[0]
)
assert (
CoordinatesSubset.mass()
== contracted_state_builder.get_coordinates_subsets()[1]
)
assert state_builder.get_frame() == frame
assert state_builder.get_coordinates_subsets() == coordinates_broker.get_subsets()
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class CoordinatesSubset
/// @brief Constructor
///
/// The default CoordinatesSubset instance is frame-invariant and implements element-wise
/// addition/substraction.
/// addition/subtraction.
/// @code
/// CoordinateSubset coordinateSubset = {aName, aSize};
/// @endcode
Expand Down
Loading

0 comments on commit 5abe6fd

Please sign in to comment.