Skip to content

Commit 92f171d

Browse files
authored
Merge pull request #205 from Simple-Robotics/topic/more-casting-shortcuts
[core | modelling] Add templated getters for cost and dynamics
2 parents b1ec455 + ec926aa commit 92f171d

File tree

5 files changed

+50
-1
lines changed

5 files changed

+50
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Templated getters `getCost<U>()` and `getDynamics<U>()` in the StageModel class, and another `getDynamics<U>()` for integrator classes, to get the concrete types ([##205](https://github.com/Simple-Robotics/aligator/pull/205))
13+
1014
### Changed
1115

1216
- All map types are now `boost::unordered_map` ([#203](https://github.com/Simple-Robotics/aligator/pull/203))

include/aligator/core/stage-model.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
namespace aligator {
1212

13+
#define ALIGATOR_CHECK_DERIVED_CLASS(Base, Derived) \
14+
static_assert((std::is_base_of_v<Base, Derived>), \
15+
"Failed check for derived class.")
16+
1317
/** @brief A stage in the control problem.
1418
*
1519
* @details Each stage containts cost functions, dynamical
@@ -46,6 +50,30 @@ template <typename _Scalar> struct StageModelTpl {
4650
/// Dynamics model
4751
PolyDynamics dynamics_;
4852

53+
/// @brief Get a pointer to an expected concrete type for the cost function.
54+
template <typename U> U *getCost() {
55+
ALIGATOR_CHECK_DERIVED_CLASS(Cost, U);
56+
return dynamic_cast<U *>(&*cost_);
57+
}
58+
59+
/// @copybrief castCost()
60+
template <typename U> const U *getCost() const {
61+
ALIGATOR_CHECK_DERIVED_CLASS(Cost, U);
62+
return dynamic_cast<const U *>(&*cost_);
63+
}
64+
65+
/// @brief Get a pointer to an expected concrete type for the dynamics class.
66+
template <typename U> U *getDynamics() {
67+
ALIGATOR_CHECK_DERIVED_CLASS(Dynamics, U);
68+
return dynamic_cast<U *>(&*dynamics_);
69+
}
70+
71+
/// @copybrief castDynamics()
72+
template <typename U> const U *getDynamics() const {
73+
ALIGATOR_CHECK_DERIVED_CLASS(Dynamics, U);
74+
return dynamic_cast<const U *>(&*dynamics_);
75+
}
76+
4977
/// Constructor assumes the control space is a Euclidean space of
5078
/// dimension @p nu.
5179
StageModelTpl(const PolyCost &cost, const PolyDynamics &dynamics);

include/aligator/modelling/dynamics/integrator-abstract.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ struct IntegratorAbstractTpl : DynamicsModelTpl<_Scalar> {
3131
/// The underlying continuous dynamics.
3232
xyz::polymorphic<ContinuousDynamics> continuous_dynamics_;
3333

34+
template <typename U> U *getDynamics() {
35+
return dynamic_cast<U *>(&*continuous_dynamics_);
36+
}
37+
template <typename U> const U *getDynamics() const {
38+
return dynamic_cast<const U *>(&*continuous_dynamics_);
39+
}
40+
3441
/// Constructor from instances of DynamicsType.
3542
explicit IntegratorAbstractTpl(
3643
const xyz::polymorphic<ContinuousDynamics> &cont_dynamics);

include/aligator/modelling/dynamics/integrator-explicit.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ struct ExplicitIntegratorAbstractTpl : ExplicitDynamicsModelTpl<_Scalar> {
3232

3333
xyz::polymorphic<ODEType> ode_;
3434

35+
template <typename U> U *getDynamics() { return dynamic_cast<U *>(&*ode_); }
36+
template <typename U> const U *getDynamics() const {
37+
return dynamic_cast<const U *>(&*ode_);
38+
}
39+
3540
explicit ExplicitIntegratorAbstractTpl(
3641
const xyz::polymorphic<ODEType> &cont_dynamics);
3742
virtual ~ExplicitIntegratorAbstractTpl() = default;

tests/problem.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,15 @@ BOOST_AUTO_TEST_CASE(test_problem) {
8686

8787
auto nu = f.nu;
8888
auto &space = f.space;
89-
auto &stage = *f.problem.stages_[0];
89+
const auto &stage = *f.problem.stages_[0];
9090
BOOST_CHECK_EQUAL(stage.numPrimal(), space.ndx() + nu);
9191
BOOST_CHECK_EQUAL(stage.numDual(), space.ndx());
9292

93+
auto *p_dyn = stage.getDynamics<MyModel>();
94+
BOOST_CHECK(p_dyn);
95+
auto *p_cost = stage.getCost<MyCost>();
96+
BOOST_CHECK(p_cost);
97+
9398
Eigen::VectorXd u0(nu);
9499
u0.setZero();
95100
auto x0 = stage.xspace_->rand();

0 commit comments

Comments
 (0)