Skip to content

Commit cbbcd2c

Browse files
authored
Merge pull request #300 from Simple-Robotics/topic/lqr-problem-is-approx
[gar] Add `LqrProblemTpl::isApprox()` and helper `lqrKnotsSameDim`, check dimensions in `LqrKnotTpl::isApprox()`
2 parents fabdf67 + f641b10 commit cbbcd2c

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- Add CMake macro `aligator_create_python_extension()` to export ([#298](https://github.com/Simple-Robotics/aligator/pull/298))
13+
- Add `LqrProblemTpl::isApprox()` and helper `lqrKnotsSameDim`, check dimensions in `LqrKnotTpl::isApprox()` ([#300](https://github.com/Simple-Robotics/aligator/pull/300))
1314

1415
## [0.13.0] - 2025-04-26
1516

gar/include/aligator/gar/lqr-problem.hpp

+18
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,17 @@ template <typename Scalar> struct LqrProblemTpl {
9494

9595
inline uint ntheta() const { return stages[0].nth; }
9696

97+
inline bool isApprox(const LqrProblemTpl &other) {
98+
if (horizon() != other.horizon() || !G0.isApprox(other.G0) ||
99+
!g0.isApprox(other.g0))
100+
return false;
101+
for (uint i = 0; i < uint(horizon()); i++) {
102+
if (!stages[i].isApprox(other.stages[i]))
103+
return false;
104+
}
105+
return true;
106+
}
107+
97108
/// Evaluate the quadratic objective.
98109
Scalar evaluate(const VectorOfVectors &xs, const VectorOfVectors &us,
99110
const std::optional<ConstVectorRef> &theta_) const;
@@ -106,6 +117,13 @@ template <typename Scalar> struct LqrProblemTpl {
106117
}
107118
};
108119

120+
template <typename Scalar>
121+
bool lqrKnotsSameDim(const LqrKnotTpl<Scalar> &lhs,
122+
const LqrKnotTpl<Scalar> &rhs) {
123+
return (lhs.nx == rhs.nx) && (lhs.nu == rhs.nu) && (lhs.nc == rhs.nc) &&
124+
(lhs.nx2 == rhs.nx2) && (lhs.nth == rhs.nth);
125+
}
126+
109127
template <typename Scalar>
110128
std::ostream &operator<<(std::ostream &oss, const LqrKnotTpl<Scalar> &self) {
111129
oss << "LqrKnot {";

gar/include/aligator/gar/lqr-problem.hxx

+18-11
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,24 @@ void LqrKnotTpl<Scalar>::addParameterization(uint nth) {
4545

4646
template <typename Scalar>
4747
bool LqrKnotTpl<Scalar>::isApprox(const LqrKnotTpl &other, Scalar prec) const {
48-
bool cost = Q.isApprox(other.Q, prec) && S.isApprox(other.S, prec) &&
49-
R.isApprox(other.R, prec) && q.isApprox(other.q, prec) &&
50-
r.isApprox(other.r, prec);
51-
bool dyn = A.isApprox(other.A, prec) && B.isApprox(other.B, prec) &&
52-
E.isApprox(other.E, prec) && f.isApprox(other.f, prec);
53-
bool cstr = C.isApprox(other.C, prec) && D.isApprox(other.D, prec) &&
54-
d.isApprox(other.d, prec);
55-
bool th = Gth.isApprox(other.Gth, prec) && Gx.isApprox(other.Gx, prec) &&
56-
Gu.isApprox(other.Gu, prec) && Gv.isApprox(other.Gv, prec) &&
57-
gamma.isApprox(other.gamma, prec);
58-
return cost && dyn && cstr && th;
48+
if (!lqrKnotsSameDim(*this, other))
49+
return false;
50+
if (!(Q.isApprox(other.Q, prec) && S.isApprox(other.S, prec) &&
51+
R.isApprox(other.R, prec) && q.isApprox(other.q, prec) &&
52+
r.isApprox(other.r, prec)))
53+
return false;
54+
55+
if (!(A.isApprox(other.A, prec) && B.isApprox(other.B, prec) &&
56+
E.isApprox(other.E, prec) && f.isApprox(other.f, prec)))
57+
return false;
58+
59+
if (!(C.isApprox(other.C, prec) && D.isApprox(other.D, prec) &&
60+
d.isApprox(other.d, prec)))
61+
return false;
62+
63+
return Gth.isApprox(other.Gth, prec) && Gx.isApprox(other.Gx, prec) &&
64+
Gu.isApprox(other.Gu, prec) && Gv.isApprox(other.Gv, prec) &&
65+
gamma.isApprox(other.gamma, prec);
5966
}
6067

6168
template <typename Scalar>

0 commit comments

Comments
 (0)