@@ -38,12 +38,8 @@ namespace Variables {
38
38
/* ************** Define helper m-variables. ***************/
39
39
inline constexpr auto NUM_LEGS = 4_idx;
40
40
41
- inline constexpr auto LF = 0_idx;
42
- inline constexpr auto LH = 1_idx;
43
- inline constexpr auto RF = 2_idx;
44
- inline constexpr auto RH = 3_idx;
45
-
46
- inline constexpr auto FOOT_FRAME_IDS = std::array{12UL , 22UL , 32UL , 42UL };
41
+ inline auto FOOT_FRAME_NAMES = std::array{" LF_FOOT" s, " LH_FOOT" s, " RF_FOOT" s, " RH_FOOT" s};
42
+ inline constexpr auto FOOT_FRAME_INDICES = std::array{12_idx, 22_idx, 32_idx, 42_idx};
47
43
48
44
UNGAR_LEAF_MVARIABLE (position, 3 );
49
45
UNGAR_LEAF_MVARIABLE (orientation, Q);
@@ -68,43 +64,103 @@ UNGAR_BRANCH_MVARIABLE(qv, q, v);
68
64
69
65
} // namespace Variables
70
66
67
+ /* ************** Define custom quantity. ***************/
68
+ /* *
69
+ * @brief To compute and get a quantity using \c Ungar::Robot, the following steps must be
70
+ * followed:
71
+ * 1) define the quantity;
72
+ * 2) define a corresponding evaluator;
73
+ * 3) define a corresponding getter.
74
+ */
75
+
76
+ /* ======================================================================================*/
77
+ /* ~~~~~~~~~~~~~| PART I: QUANTITY |~~~~~~~~~~~~~*/
78
+ /* ======================================================================================*/
79
+ // / @brief Ungar provides a convenient macro to simplify the definition of quantities.
71
80
namespace Quantities {
72
81
73
- UNGAR_MAKE_QUANTITY (foot_pose);
82
+ UNGAR_MAKE_QUANTITY (frame_pose); // Quantity corresponding to the pose of a frame.
74
83
75
84
}
76
85
} // namespace ANYmalB
77
86
87
+ /* ======================================================================================*/
88
+ /* ~~~~~~~~~~~~~| PART II: EVALUATOR |~~~~~~~~~~~~~*/
89
+ /* ======================================================================================*/
90
+ // / @brief Evaluators wrap Pinocchio's functionalities and provide the user with a
91
+ // / minimal interface.
78
92
namespace Ungar {
79
93
namespace RBD {
80
94
95
+ /* *
96
+ * @brief Evaluators must implement a (possibly overloaded) function \c At computing
97
+ * the desired quantity and returning \c void.
98
+ */
81
99
template <typename _Scalar>
82
- struct Evaluator <ANYmalB::Quantities::foot_pose , _Scalar> {
100
+ struct Evaluator <ANYmalB::Quantities::frame_pose , _Scalar> {
83
101
void At (const auto & q) {
84
- namespace vs = ANYmalB::Variables;
85
-
102
+ // Compute the pose of each joint frame.
86
103
pinocchio::forwardKinematics (model, data, q);
87
- for (const auto frameID : vs::FOOT_FRAME_IDS) {
88
- pinocchio::updateFramePlacement (model, data, frameID);
89
- }
90
104
}
91
105
92
106
const pinocchio::ModelTpl<_Scalar>& model;
93
107
pinocchio::DataTpl<_Scalar>& data;
94
108
};
95
109
110
+ } // namespace RBD
111
+ } // namespace Ungar
112
+
113
+ /* ======================================================================================*/
114
+ /* ~~~~~~~~~~~~~| PART III: GETTER |~~~~~~~~~~~~~*/
115
+ /* ======================================================================================*/
116
+ // / @brief Getters allow the user to easily retrieve desired quantities.
117
+ namespace Ungar {
118
+ namespace RBD {
119
+
120
+ /* *
121
+ * @brief Getters must implement a (possibly overloaded) function \c Get returning
122
+ * the desired quantity.
123
+ */
96
124
template <typename _Scalar>
97
- struct Getter <ANYmalB::Quantities::foot_pose, _Scalar> {
98
- const auto & Get (const index_t foot) const {
99
- namespace vs = ANYmalB::Variables;
125
+ struct Getter <ANYmalB::Quantities::frame_pose, _Scalar> {
126
+ const auto & Get (const index_t frameIndex) const {
127
+ UNGAR_ASSERT (static_cast <index_t >(frameIndex) < model.nframes );
128
+
129
+ const size_t frameID = static_cast <size_t >(frameIndex);
100
130
101
- return data.oMf [vs::FOOT_FRAME_IDS[static_cast <size_t >(foot)]];
131
+ // Update the pose of the desired frame before returning it.
132
+ pinocchio::updateFramePlacement (model, data, frameID);
133
+ return data.oMf [frameID];
102
134
}
103
135
104
- auto & Get (const index_t foot) {
105
- namespace vs = ANYmalB::Variables;
136
+ const auto & Get (const std::string& frameName) const {
137
+ UNGAR_ASSERT (model.existFrame (frameName));
138
+
139
+ const size_t frameID = model.getFrameId (frameName);
140
+
141
+ // Update the pose of the desired frame before returning it.
142
+ pinocchio::updateFramePlacement (model, data, frameID);
143
+ return data.oMf [frameID];
144
+ }
145
+
146
+ auto & Get (const index_t frameIndex) {
147
+ UNGAR_ASSERT (static_cast <index_t >(frameIndex) < model.nframes );
148
+
149
+ const size_t frameID = static_cast <size_t >(frameIndex);
150
+
151
+ // Update the pose of the desired frame before returning it.
152
+ pinocchio::updateFramePlacement (model, data, frameID);
153
+ return data.oMf [frameID];
154
+ }
155
+
156
+ auto & Get (const std::string& frameName) {
157
+ UNGAR_ASSERT (model.existFrame (frameName));
158
+
159
+ const size_t frameID = model.getFrameId (frameName);
106
160
107
- return data.oMf [vs::FOOT_FRAME_IDS[static_cast <size_t >(foot)]];
161
+ // Update the pose of the desired frame before returning it.
162
+ pinocchio::updateFramePlacement (model, data, frameID);
163
+ return data.oMf [frameID];
108
164
}
109
165
110
166
const pinocchio::ModelTpl<_Scalar>& model;
@@ -136,13 +192,21 @@ int main() {
136
192
q_.Get (vs::position).setRandom ();
137
193
}
138
194
139
- UNGAR_LOG (info, " Computing the pose of feet..." );
140
- robot.Compute (qs::foot_pose ).At (q);
195
+ UNGAR_LOG (info, " Computing the pose of the feet..." );
196
+ robot.Compute (qs::frame_pose ).At (q);
141
197
UNGAR_LOG (info, " Done." );
142
- for (const auto foot : {vs::LF, vs::LH, vs::RF, vs::RH}) {
143
- UNGAR_LOG (info, " Pose of the {}-th foot:\n {}" , foot, robot.Get (qs::foot_pose, foot));
198
+ for (const auto i : enumerate(vs::NUM_LEGS) | cast_to<size_t >) {
199
+ const auto [footFrameIndex, footFrameName] =
200
+ std::pair{vs::FOOT_FRAME_INDICES[i], vs::FOOT_FRAME_NAMES[i]};
201
+ [[maybe_unused]] const pinocchio::SE3 footFramePoseByIndex =
202
+ robot.Get (qs::frame_pose, footFrameIndex);
203
+ [[maybe_unused]] const pinocchio::SE3 footFramePoseByName =
204
+ robot.Get (qs::frame_pose, footFrameName);
205
+
206
+ UNGAR_LOG (info, Utils::DASH_LINE_SEPARATOR);
207
+ UNGAR_LOG (info, " Pose of the foot ('{}'):\n {}" , footFrameName, footFramePoseByIndex);
208
+ UNGAR_ASSERT (footFramePoseByIndex.isEqual (footFramePoseByName));
144
209
}
145
- UNGAR_LOG (info, Utils::DASH_LINE_SEPARATOR);
146
210
147
211
return 0 ;
148
212
}
0 commit comments