Skip to content

Commit f05351e

Browse files
committed
One class for all interpolate methods
1 parent 9f413a1 commit f05351e

File tree

6 files changed

+84
-124
lines changed

6 files changed

+84
-124
lines changed

bindings/expose-interpolate.cpp

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,29 @@ namespace simple_mpc
1717
{
1818
namespace bp = boost::python;
1919

20-
Eigen::VectorXd stateInterpolateProxy(
21-
StateInterpolator & self, const double delay, const double timestep, const std::vector<Eigen::VectorXd> xs)
20+
Eigen::VectorXd interpolateConfigurationProxy(
21+
Interpolator & self, const double delay, const double timestep, const std::vector<Eigen::VectorXd> & qs)
2222
{
23-
Eigen::VectorXd x_interp(xs[0].size());
24-
self.interpolate(delay, timestep, xs, x_interp);
23+
Eigen::VectorXd q_interp(qs[0].size());
24+
self.interpolateConfiguration(delay, timestep, qs, q_interp);
2525

26-
return x_interp;
26+
return q_interp;
2727
}
2828

29-
Eigen::VectorXd linearInterpolateProxy(
30-
LinearInterpolator & self, const double delay, const double timestep, const std::vector<Eigen::VectorXd> xs)
29+
Eigen::VectorXd interpolateLinearProxy(
30+
Interpolator & self, const double delay, const double timestep, const std::vector<Eigen::VectorXd> & vs)
3131
{
32-
Eigen::VectorXd x_interp(xs[0].size());
33-
self.interpolate(delay, timestep, xs, x_interp);
32+
Eigen::VectorXd v_interp(vs[0].size());
33+
self.interpolateLinear(delay, timestep, vs, v_interp);
3434

35-
return x_interp;
35+
return v_interp;
3636
}
3737

38-
void exposeStateInterpolator()
38+
void exposeInterpolator()
3939
{
40-
bp::class_<StateInterpolator>("StateInterpolator", bp::init<const Model &>(bp::args("self", "model")))
41-
.def("interpolate", &stateInterpolateProxy);
40+
bp::class_<Interpolator>("Interpolator", bp::init<const Model &>(bp::args("self", "model")))
41+
.def("interpolateConfiguration", &interpolateConfigurationProxy)
42+
.def("interpolateLinear", &interpolateLinearProxy);
4243
}
43-
44-
void exposeLinearInterpolator()
45-
{
46-
bp::class_<LinearInterpolator>("LinearInterpolator", bp::init<const size_t>(bp::args("self", "vec_size")))
47-
.def("interpolate", &linearInterpolateProxy);
48-
}
49-
5044
} // namespace python
5145
} // namespace simple_mpc

bindings/module.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ namespace simple_mpc::python
1717
void exposeMPC();
1818
void exposeIDSolver();
1919
void exposeIKIDSolver();
20-
void exposeStateInterpolator();
21-
void exposeLinearInterpolator();
20+
void exposeInterpolator();
2221
void exposeFrictionCompensation();
2322

2423
/* PYTHON MODULE */
@@ -38,8 +37,7 @@ namespace simple_mpc::python
3837
exposeMPC();
3938
exposeIDSolver();
4039
exposeIKIDSolver();
41-
exposeStateInterpolator();
42-
exposeLinearInterpolator();
40+
exposeInterpolator();
4341
exposeFrictionCompensation();
4442
}
4543

examples/go2_fulldynamics.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
FullDynamicsOCP,
77
MPC,
88
IDSolver,
9-
StateInterpolator,
10-
LinearInterpolator,
9+
Interpolator,
1110
FrictionCompensation
1211
)
1312
import example_robot_data as erd
@@ -156,10 +155,7 @@
156155
""" Friction """
157156
fcompensation = FrictionCompensation(model_handler.getModel(), True)
158157
""" Interpolation """
159-
state_interpolator = StateInterpolator(model_handler.getModel())
160-
acc_interpolator = LinearInterpolator(model_handler.getModel().nv)
161-
u_interpolator = LinearInterpolator(nu)
162-
force_interpolator = LinearInterpolator(nf)
158+
interpolator = Interpolator(model_handler.getModel())
163159

164160
""" Initialize simulation"""
165161
device = BulletRobot(
@@ -253,7 +249,8 @@
253249

254250
forces = [total_forces, total_forces]
255251
ddqs = [a0, a1]
256-
xss = [mpc.xs[0], mpc.xs[1]]
252+
qss = [mpc.xs[0][:model_handler.getModel().nq], mpc.xs[1][:model_handler.getModel().nq]]
253+
vss = [mpc.xs[0][model_handler.getModel().nq:], mpc.xs[1][model_handler.getModel().nq:]]
257254
uss = [mpc.us[0], mpc.us[1]]
258255

259256
FL_measured.append(mpc.getDataHandler().getFootPose("FL_foot").translation)
@@ -272,10 +269,13 @@
272269
# time.sleep(0.01)
273270
delay = j / float(N_simu) * dt
274271

275-
x_interp = state_interpolator.interpolate(delay, dt, xss)
276-
u_interp = u_interpolator.interpolate(delay, dt, uss)
277-
acc_interp = acc_interpolator.interpolate(delay, dt, ddqs)
278-
force_interp = force_interpolator.interpolate(delay, dt, forces)
272+
q_interp = interpolator.interpolateConfiguration(delay, dt, qss)
273+
v_interp = interpolator.interpolateLinear(delay, dt, vss)
274+
u_interp = interpolator.interpolateLinear(delay, dt, uss)
275+
acc_interp = interpolator.interpolateLinear(delay, dt, ddqs)
276+
force_interp = interpolator.interpolateLinear(delay, dt, forces)
277+
278+
x_interp = np.concatenate((q_interp, v_interp))
279279

280280
q_meas, v_meas = device.measureState()
281281
x_measured = np.concatenate([q_meas, v_meas])

include/simple-mpc/interpolator.hpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,42 +13,34 @@
1313
#ifndef SIMPLE_MPC_INTERPOLATOR_HPP_
1414
#define SIMPLE_MPC_INTERPOLATOR_HPP_
1515

16+
#include <pinocchio/algorithm/joint-configuration.hpp>
17+
1618
#include "simple-mpc/fwd.hpp"
1719
#include "simple-mpc/model-utils.hpp"
1820

1921
namespace simple_mpc
2022
{
21-
class StateInterpolator
23+
class Interpolator
2224
{
2325
public:
24-
explicit StateInterpolator(const Model & model);
26+
explicit Interpolator(const Model & model);
2527

26-
void interpolate(
28+
void interpolateConfiguration(
2729
const double delay,
2830
const double timestep,
29-
const std::vector<Eigen::VectorXd> xs,
30-
Eigen::Ref<Eigen::VectorXd> x_interp);
31+
const std::vector<Eigen::VectorXd> & qs,
32+
Eigen::Ref<Eigen::VectorXd> q_interp);
3133

32-
// Intermediate differential configuration
33-
Eigen::VectorXd diff_q_;
34+
void interpolateLinear(
35+
const double delay,
36+
const double timestep,
37+
const std::vector<Eigen::VectorXd> & vs,
38+
Eigen::Ref<Eigen::VectorXd> v_interp);
3439

3540
// Pinocchio model
3641
Model model_;
3742
};
3843

39-
class LinearInterpolator
40-
{
41-
public:
42-
explicit LinearInterpolator(const size_t vec_size);
43-
44-
void interpolate(
45-
const double delay,
46-
const double timestep,
47-
const std::vector<Eigen::VectorXd> vecs,
48-
Eigen::Ref<Eigen::VectorXd> vec_interp);
49-
50-
size_t vec_size_;
51-
};
5244
} // namespace simple_mpc
5345

5446
/* --- Details -------------------------------------------------------------- */

src/interpolator.cpp

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,64 +6,52 @@
66
// All rights reserved.
77
///////////////////////////////////////////////////////////////////////////////
88
#include "simple-mpc/interpolator.hpp"
9-
#include <pinocchio/algorithm/joint-configuration.hpp>
109

1110
namespace simple_mpc
1211
{
1312

14-
StateInterpolator::StateInterpolator(const Model & model)
13+
Interpolator::Interpolator(const Model & model)
1514
{
1615
model_ = model;
17-
diff_q_.resize(model_.nv);
1816
}
1917

20-
void StateInterpolator::interpolate(
18+
void Interpolator::interpolateConfiguration(
2119
const double delay,
2220
const double timestep,
23-
const std::vector<Eigen::VectorXd> xs,
24-
Eigen::Ref<Eigen::VectorXd> x_interp)
21+
const std::vector<Eigen::VectorXd> & qs,
22+
Eigen::Ref<Eigen::VectorXd> q_interp)
2523
{
24+
assert(("Configuration is not of the right size", qs[0].size() == model_.nq));
25+
2626
// Compute the time knot corresponding to the current delay
2727
size_t step_nb = static_cast<size_t>(delay / timestep);
2828
double step_progress = (delay - (double)step_nb * timestep) / timestep;
2929

30-
// Interpolate state and command trajectories
31-
if (step_nb >= xs.size() - 1)
32-
x_interp = xs.back();
30+
// Interpolate configuration trajectory
31+
if (step_nb >= qs.size() - 1)
32+
q_interp = qs.back();
3333
else
3434
{
35-
// Compute the differential between configuration
36-
diff_q_ = pinocchio::difference(model_, xs[step_nb].head(model_.nq), xs[step_nb + 1].head(model_.nq));
37-
38-
pinocchio::integrate(model_, xs[step_nb].head(model_.nq), diff_q_ * step_progress, x_interp.head(model_.nq));
39-
40-
// Compute velocity interpolation
41-
x_interp.tail(model_.nv) =
42-
xs[step_nb + 1].tail(model_.nv) * step_progress + xs[step_nb].tail(model_.nv) * (1. - step_progress);
35+
q_interp = pinocchio::interpolate(model_, qs[step_nb], qs[step_nb + 1], step_progress);
4336
}
4437
}
4538

46-
LinearInterpolator::LinearInterpolator(const size_t vec_size)
47-
{
48-
vec_size_ = vec_size;
49-
}
50-
51-
void LinearInterpolator::interpolate(
39+
void Interpolator::interpolateLinear(
5240
const double delay,
5341
const double timestep,
54-
const std::vector<Eigen::VectorXd> vecs,
55-
Eigen::Ref<Eigen::VectorXd> vec_interp)
42+
const std::vector<Eigen::VectorXd> & vs,
43+
Eigen::Ref<Eigen::VectorXd> v_interp)
5644
{
5745
// Compute the time knot corresponding to the current delay
5846
size_t step_nb = static_cast<size_t>(delay / timestep);
5947
double step_progress = (delay - (double)step_nb * timestep) / timestep;
6048

61-
// Interpolate state and command trajectories
62-
if (step_nb >= vecs.size() - 1)
63-
vec_interp = vecs.back();
49+
// Interpolate configuration trajectory
50+
if (step_nb >= vs.size() - 1)
51+
v_interp = vs.back();
6452
else
6553
{
66-
vec_interp = vecs[step_nb + 1] * step_progress + vecs[step_nb] * (1. - step_progress);
54+
v_interp = vs[step_nb + 1] * step_progress + vs[step_nb] * (1. - step_progress);
6755
}
6856
}
6957

tests/interpolator.cpp

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,61 +17,50 @@ BOOST_AUTO_TEST_CASE(interpolate)
1717

1818
pinocchio::urdf::buildModel(urdf_path, JointModelFreeFlyer(), model);
1919
double timestep = 0.01;
20-
StateInterpolator interpolator = StateInterpolator(model);
20+
Interpolator interpolator = Interpolator(model);
2121

22-
std::vector<Eigen::VectorXd> xs;
22+
// Test configuration interpolation method
23+
std::vector<Eigen::VectorXd> qs;
2324
for (std::size_t i = 0; i < 4; i++)
2425
{
25-
Eigen::VectorXd x0(model.nq + model.nv);
26-
x0.tail(model.nv).setRandom();
27-
x0.head(model.nq) = pinocchio::neutral(model);
26+
Eigen::VectorXd q0(model.nq);
27+
Eigen::VectorXd q1(model.nq);
28+
q0 = pinocchio::neutral(model);
2829
Eigen::VectorXd dq(model.nv);
2930
dq.setRandom();
30-
pinocchio::integrate(model, x0.head(model.nq), dq, x0.head(model.nq));
31+
pinocchio::integrate(model, q0, dq, q1);
3132

32-
xs.push_back(x0);
33+
qs.push_back(q1);
3334
}
3435
double delay = 0.02;
3536

36-
Eigen::VectorXd x_interp(model.nq + model.nv);
37-
interpolator.interpolate(delay, timestep, xs, x_interp);
37+
Eigen::VectorXd q_interp(model.nq);
38+
interpolator.interpolateConfiguration(delay, timestep, qs, q_interp);
3839

39-
BOOST_CHECK(xs[2].isApprox(x_interp));
40+
BOOST_CHECK(qs[2].isApprox(q_interp));
4041

4142
delay = 0.5;
42-
interpolator.interpolate(delay, timestep, xs, x_interp);
43-
BOOST_CHECK(xs.back().isApprox(x_interp));
43+
interpolator.interpolateConfiguration(delay, timestep, qs, q_interp);
44+
BOOST_CHECK(qs.back().isApprox(q_interp));
4445

4546
delay = 0.005;
46-
interpolator.interpolate(delay, timestep, xs, x_interp);
47-
Eigen::VectorXd x_interp2(model.nq + model.nv);
47+
interpolator.interpolateConfiguration(delay, timestep, qs, q_interp);
48+
Eigen::VectorXd q_interp2(model.nq);
4849
Eigen::VectorXd dq(model.nv);
49-
pinocchio::difference(model, xs[0].head(model.nq), xs[1].head(model.nq), dq);
50-
pinocchio::integrate(model, xs[0].head(model.nq), dq * 0.5, x_interp2.head(model.nq));
51-
x_interp2.tail(model.nv) = (xs[0].tail(model.nv) + xs[1].tail(model.nv)) * 0.5;
50+
pinocchio::difference(model, qs[0], qs[1], dq);
51+
pinocchio::integrate(model, qs[0], dq * 0.5, q_interp2);
5252

53-
BOOST_CHECK(x_interp2.isApprox(x_interp));
53+
BOOST_CHECK(q_interp2.isApprox(q_interp));
5454

55-
std::vector<Eigen::VectorXd> xs2;
55+
std::vector<Eigen::VectorXd> qs2;
5656
for (std::size_t i = 0; i < 2; i++)
5757
{
58-
xs2.push_back(xs[0]);
58+
qs2.push_back(qs[0]);
5959
}
60-
interpolator.interpolate(delay, timestep, xs2, x_interp);
61-
BOOST_CHECK(xs2[0].isApprox(x_interp));
62-
}
63-
64-
BOOST_AUTO_TEST_CASE(linear_interpolate)
65-
{
66-
Model model;
67-
// Load pinocchio model from example robot data
68-
const std::string urdf_path = EXAMPLE_ROBOT_DATA_MODEL_DIR "/solo_description/robots/solo12.urdf";
69-
const std::string srdf_path = EXAMPLE_ROBOT_DATA_MODEL_DIR "/solo_description/srdf/solo.srdf";
70-
71-
pinocchio::urdf::buildModel(urdf_path, JointModelFreeFlyer(), model);
72-
double timestep = 0.01;
73-
LinearInterpolator interpolator = LinearInterpolator((size_t)model.nv);
60+
interpolator.interpolateConfiguration(delay, timestep, qs2, q_interp);
61+
BOOST_CHECK(qs2[0].isApprox(q_interp));
7462

63+
// Test linear interpolation method
7564
std::vector<Eigen::VectorXd> vs;
7665
for (std::size_t i = 0; i < 4; i++)
7766
{
@@ -80,18 +69,17 @@ BOOST_AUTO_TEST_CASE(linear_interpolate)
8069

8170
vs.push_back(v0);
8271
}
83-
double delay = 0.02;
84-
72+
delay = 0.02;
8573
Eigen::VectorXd v_interp(model.nv);
86-
interpolator.interpolate(delay, timestep, vs, v_interp);
74+
interpolator.interpolateLinear(delay, timestep, vs, v_interp);
8775
BOOST_CHECK(vs[2].isApprox(v_interp));
8876

8977
delay = 0.5;
90-
interpolator.interpolate(delay, timestep, vs, v_interp);
78+
interpolator.interpolateLinear(delay, timestep, vs, v_interp);
9179
BOOST_CHECK(vs.back().isApprox(v_interp));
9280

9381
delay = 0.005;
94-
interpolator.interpolate(delay, timestep, vs, v_interp);
82+
interpolator.interpolateLinear(delay, timestep, vs, v_interp);
9583
Eigen::VectorXd v_interp2(model.nv);
9684
v_interp2 = (vs[0] + vs[1]) * 0.5;
9785

@@ -102,7 +90,7 @@ BOOST_AUTO_TEST_CASE(linear_interpolate)
10290
{
10391
vs2.push_back(vs[0]);
10492
}
105-
interpolator.interpolate(delay, timestep, vs2, v_interp);
93+
interpolator.interpolateLinear(delay, timestep, vs2, v_interp);
10694
BOOST_CHECK(vs2[0].isApprox(v_interp));
10795
}
10896

0 commit comments

Comments
 (0)