@@ -56,15 +56,16 @@ class TestKinoID
5656 check_joint_limits ();
5757 }
5858
59- void check_decreasing_error (std::string name, double error)
59+ bool is_error_decreasing (std::string name, double error)
6060 {
6161 if (errors.count (name) == 0 )
6262 {
6363 errors.insert ({name, error});
64- return ; // no further check
64+ return true ; // no further check
6565 }
66- BOOST_CHECK_LE (error, errors.at (name)); // Perform check
67- errors.at (name) = error; // Update value
66+ const bool res{error <= errors.at (name)};
67+ errors.at (name) = error; // Update value
68+ return res;
6869 }
6970
7071protected:
@@ -127,177 +128,133 @@ BOOST_AUTO_TEST_CASE(KinodynamicsID_postureTask)
127128 // Check error is decreasing
128129 Eigen::VectorXd delta_q = pinocchio::difference (model_handler.getModel (), test.q , q_target);
129130 const double error = delta_q.tail (nv - 6 ).norm (); // Consider only the posture not the free flyer
130- test.check_decreasing_error (" posture" , error);
131+ BOOST_CHECK ( test.is_error_decreasing (" posture" , error) );
131132 }
132133}
133134
134135BOOST_AUTO_TEST_CASE (KinodynamicsID_contact)
135136{
136- RobotModelHandler model_handler = getSoloHandler ();
137- RobotDataHandler data_handler (model_handler);
138- const double dt = 1e-3 ;
139-
140- KinodynamicsID solver (
141- model_handler, dt,
142- KinodynamicsID::Settings ()
143- .set_kp_base (10 .)
144- .set_kp_posture (10.0 )
145- .set_kp_contact (10.0 )
146- .set_w_base (10 .)
147- .set_w_posture (1.0 )
148- .set_w_contact_motion (1.0 )
149- .set_w_contact_force (1.0 ));
150-
151- const Eigen::VectorXd q_target = model_handler.getReferenceState ().head (model_handler.getModel ().nq );
152- std::vector<KinodynamicsID::TargetContactForce> f_target;
153- for (int i = 0 ; i < 4 ; i++)
154- {
155- f_target.push_back (KinodynamicsID::TargetContactForce::Zero (3 ));
156- f_target[i][2 ] = model_handler.getMass () * 9.81 / 4 ;
157- }
158- solver.setTarget (
159- q_target, Eigen::VectorXd::Zero (model_handler.getModel ().nv ), Eigen::VectorXd::Zero (model_handler.getModel ().nv ),
160- {true , true , true , true }, f_target);
137+ TestKinoID test (
138+ getSoloHandler (), KinodynamicsID::Settings ()
139+ .set_kp_posture (10.0 )
140+ .set_kp_contact (10.0 )
141+ .set_w_base (10 .)
142+ .set_w_contact_motion (1.0 )
143+ .set_w_contact_force (1.0 ));
144+
145+ // Easy access
146+ const RobotModelHandler & model_handler = test.model_handler ;
147+ const size_t nq = model_handler.getModel ().nq ;
148+ const size_t nv = model_handler.getModel ().nv ;
161149
162- double t = 0 ;
163- Eigen::VectorXd q = solo_q_start ( model_handler);
164- Eigen::VectorXd v = Eigen::VectorXd::Random (model_handler. getModel (). nv );
165- Eigen::VectorXd a = Eigen::VectorXd::Random (model_handler. getModel (). nv );
166- Eigen::VectorXd tau = Eigen::VectorXd::Zero (model_handler. getModel (). nv - 6 );
150+ // No need to set target as KinodynamicsID sets it by default to reference state
151+ const Eigen::VectorXd q_target = model_handler. getReferenceState (). head (nq );
152+
153+ // Change initial state
154+ test. q = solo_q_start (model_handler);
167155
168156 // Let the robot stabilize
169157 const int N_STEP_ON_GROUND = 6000 ;
170158 const int N_STEP_FREE_FALL = 2000 ;
171159 for (int i = 0 ; i < N_STEP_ON_GROUND + N_STEP_FREE_FALL; i++)
172160 {
173- // Solve and get solution
174- solver.solve (t, q, v, tau);
175- solver.getAccelerations (a);
161+ // Solve
162+ test.step ();
176163
177- // Integrate
178- t += dt;
179- q = pinocchio::integrate (model_handler.getModel (), q, (v + a / 2 . * dt) * dt);
180- v += a * dt;
181164 if (i == N_STEP_ON_GROUND)
182165 {
183166 // Robot had time to reach permanent regime, is it stable on ground ?
184- BOOST_CHECK_SMALL (a .head (3 ).norm (), 1e-4 );
185- BOOST_CHECK_SMALL (v .head (3 ).norm (), 1e-4 );
167+ BOOST_CHECK_SMALL (test. dq .head (3 ).norm (), 1e-4 );
168+ BOOST_CHECK_SMALL (test. ddq .head (3 ).norm (), 1e-4 );
186169
187170 // Remove contacts
188- solver.setTarget (
189- q_target, Eigen::VectorXd::Zero (model_handler.getModel ().nv ),
190- Eigen::VectorXd::Zero (model_handler.getModel ().nv ), {false , false , false , false }, f_target);
171+ test.solver .setTarget (
172+ q_target, Eigen::VectorXd::Zero (nv), Eigen::VectorXd::Zero (nv), {false , false , false , false }, {});
191173 }
192174 if (i == N_STEP_ON_GROUND + N_STEP_FREE_FALL - 1 )
193175 {
194176 // Robot had time to reach permanent regime, is it robot free falling ?
195- BOOST_CHECK_SMALL (a .head (3 ).norm () - model_handler.getModel ().gravity .linear ().norm (), 0.01 );
177+ BOOST_CHECK_SMALL (test. ddq .head (3 ).norm () - model_handler.getModel ().gravity .linear ().norm (), 0.01 );
196178 }
197179 }
198180}
199181
200182BOOST_AUTO_TEST_CASE (KinodynamicsID_baseTask)
201183{
202- RobotModelHandler model_handler = getSoloHandler ();
203- RobotDataHandler data_handler (model_handler);
204- const double dt = 1e-3 ;
205-
206- KinodynamicsID solver (
207- model_handler, dt,
208- KinodynamicsID::Settings ()
209- .set_kp_base (7 .)
210- .set_kp_contact (10.0 )
211- .set_w_base (100.0 )
212- .set_w_contact_force (1.0 )
213- .set_w_contact_motion (1.0 ));
184+ TestKinoID test (
185+ getSoloHandler (), KinodynamicsID::Settings ()
186+ .set_kp_base (7 .)
187+ .set_kp_contact (10.0 )
188+ .set_w_base (100.0 )
189+ .set_w_contact_force (1.0 )
190+ .set_w_contact_motion (1.0 ));
191+
192+ // Easy access
193+ const RobotModelHandler & model_handler = test.model_handler ;
194+ const size_t nq = model_handler.getModel ().nq ;
214195
215196 // No need to set target as KinodynamicsID sets it by default to reference state
216- const Eigen::VectorXd q_target = model_handler.getReferenceState ().head (model_handler. getModel (). nq );
197+ const Eigen::VectorXd q_target = model_handler.getReferenceState ().head (nq);
217198
218- double t = 0 ;
219- Eigen::VectorXd q = solo_q_start (model_handler);
220- Eigen::VectorXd v = Eigen::VectorXd::Random (model_handler.getModel ().nv );
221- Eigen::VectorXd a = Eigen::VectorXd::Random (model_handler.getModel ().nv );
222- Eigen::VectorXd tau = Eigen::VectorXd::Zero (model_handler.getModel ().nv - 6 );
199+ // Change initial state
200+ test.q = solo_q_start (model_handler);
223201
224- Eigen::VectorXd error = 1e12 * Eigen::VectorXd::Ones (6 );
225202 const int N_STEP = 10000 ;
226203 for (int i = 0 ; i < N_STEP; i++)
227204 {
228- // Solve and get solution
229- solver.solve (t, q, v, tau);
230- solver.getAccelerations (a);
205+ // Solve
206+ test.step ();
231207
232- // Integrate
233- t += dt;
234- q = pinocchio::integrate (model_handler.getModel (), q, (v + a / 2 . * dt) * dt);
235- v += a * dt;
208+ // Compute error
209+ const Eigen::VectorXd delta_pose = pinocchio::difference (model_handler.getModel (), test.q , q_target).head <6 >();
210+ const double error = delta_pose.norm ();
236211
237- // Check error is decreasing
238- Eigen::VectorXd new_error = pinocchio::difference (model_handler.getModel (), q, q_target).head (6 );
239- if (i > N_STEP / 10 ) // Weird transitional phenomenon at first ...
240- BOOST_CHECK (
241- new_error.norm () < error.norm () || new_error.norm () < 2e-2 ); // Either strictly decreasing or close to target
242- if (i > 9 * N_STEP / 10 )
243- BOOST_CHECK (new_error.norm () < 2e-2 ); // Should have converged by now
244-
245- error = new_error;
212+ // Checks
213+ if (error > 2e-2 ) // If haven't converged yet, should be strictly decreasing
214+ BOOST_CHECK (test.is_error_decreasing (" base" , error));
215+ if (i > 9 * N_STEP / 10 ) // Should have converged by now
216+ BOOST_CHECK (error < 2e-2 );
246217 }
247218}
248219
249220BOOST_AUTO_TEST_CASE (KinodynamicsID_allTasks)
250221{
251- RobotModelHandler model_handler = getTalosModelHandler ();
252- RobotDataHandler data_handler (model_handler);
253- const double dt = 1e-3 ;
254-
255- KinodynamicsID solver (
256- model_handler, dt,
257- KinodynamicsID::Settings ()
258- .set_kp_base (7 .)
259- .set_kp_posture (10 .)
260- .set_kp_contact (1.0 )
261- .set_w_base (10.0 )
262- .set_w_posture (10.0 )
263- .set_w_contact_force (.1 )
264- .set_w_contact_motion (1.0 ));
265-
266- const Eigen::VectorXd q_target = model_handler.getReferenceState ().head (model_handler.getModel ().nq );
222+ TestKinoID test (
223+ getTalosModelHandler (), KinodynamicsID::Settings ()
224+ .set_kp_base (7 .)
225+ .set_kp_posture (10 .)
226+ .set_kp_contact (1.0 )
227+ .set_w_base (10.0 )
228+ .set_w_posture (10.0 )
229+ .set_w_contact_force (.1 )
230+ .set_w_contact_motion (1.0 ));
231+
232+ // Easy access
233+ const RobotModelHandler & model_handler = test.model_handler ;
234+ const size_t nq = model_handler.getModel ().nq ;
235+ const size_t nv = model_handler.getModel ().nv ;
236+
237+ // Set target
238+ const Eigen::VectorXd q_target = model_handler.getReferenceState ().head (nq);
267239 std::vector<KinodynamicsID::TargetContactForce> f_target;
268240 for (int i = 0 ; i < 2 ; i++)
269241 {
270242 f_target.push_back (KinodynamicsID::TargetContactForce::Zero (6 ));
271243 f_target[i][2 ] = model_handler.getMass () * 9.81 / 4 ;
272244 }
273- solver.setTarget (
274- q_target, Eigen::VectorXd::Zero (model_handler.getModel ().nv ), Eigen::VectorXd::Zero (model_handler.getModel ().nv ),
275- {true , true , true , true }, f_target);
276-
277- double t = 0 ;
278- Eigen::VectorXd q = model_handler.getReferenceState ().head (model_handler.getModel ().nq );
279- Eigen::VectorXd v = Eigen::VectorXd::Random (model_handler.getModel ().nv );
280- Eigen::VectorXd a = Eigen::VectorXd::Random (model_handler.getModel ().nv );
281- Eigen::VectorXd tau = Eigen::VectorXd::Zero (model_handler.getModel ().nv - 6 );
282-
283- Eigen::VectorXd error = 1e12 * Eigen::VectorXd::Ones (model_handler.getModel ().nv );
245+ test.solver .setTarget (
246+ q_target, Eigen::VectorXd::Zero (nv), Eigen::VectorXd::Zero (nv), {true , true , true , true }, f_target);
284247
285248 const int N_STEP = 10000 ;
286249 for (int i = 0 ; i < N_STEP; i++)
287250 {
288- // Solve and get solution
289- solver.solve (t, q, v, tau);
290- solver.getAccelerations (a);
291-
292- // Integrate
293- t += dt;
294- q = pinocchio::integrate (model_handler.getModel (), q, (v + a / 2 . * dt) * dt);
295- v += a * dt;
251+ // Solve
252+ test.step ();
296253
297254 // Check error is decreasing
298- Eigen::VectorXd new_error = pinocchio::difference (model_handler.getModel (), q, q_target);
299- BOOST_CHECK_LE (new_error. norm (), error.norm () );
300- error = new_error ;
255+ const Eigen::VectorXd delta_q = pinocchio::difference (model_handler.getModel (), test. q , q_target);
256+ const double error = delta_q .norm ();
257+ BOOST_CHECK (test. is_error_decreasing ( " q " , error)) ;
301258 }
302259}
303260
0 commit comments