Skip to content

Commit efe442e

Browse files
committed
Proper multilinear interpolation for both value and gradient
1 parent 2e0aa84 commit efe442e

File tree

1 file changed

+66
-45
lines changed

1 file changed

+66
-45
lines changed

ros/src/fastrack/include/fastrack/value/matlab_value_function.h

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
*
3333
* Please contact the author(s) of this library if you have any questions.
3434
* Authors: David Fridovich-Keil ( [email protected] )
35+
* Jaime F. Fisac ( [email protected] )
3536
*/
3637

3738
///////////////////////////////////////////////////////////////////////////////
@@ -106,6 +107,9 @@ class MatlabValueFunction : public ValueFunction<TS, TC, TD, PS, PC, PD, B> {
106107
// of the nearest cell (i.e. cell center minus state).
107108
VectorXd DirectionToCenter(const VectorXd& x) const;
108109

110+
// Accessor for precomputed value at the given state.
111+
VectorXd ValueAccessor(const VectorXd& x) const;
112+
109113
// Accessor for precomputed gradient at the given state.
110114
VectorXd GradientAccessor(const VectorXd& x) const;
111115

@@ -115,7 +119,17 @@ class MatlabValueFunction : public ValueFunction<TS, TC, TD, PS, PC, PD, B> {
115119
// Compute center of nearest grid cell to the given state.
116120
VectorXd NearestCenterPoint(const VectorXd& x) const;
117121

118-
// Recursive helper function for gradient multilinear interpolation.
122+
// Recursive helper function for value or gradient multilinear interpolation.
123+
// Takes in a state and index along which to interpolate, and a boolean
124+
// determining whether this is for the gradient or, otherwise, for the value.
125+
VectorXd RecursiveMultilinearInterpolator(const VectorXd& x, size_t idx,
126+
const bool for_gradient) const;
127+
128+
// Recursive helper function wrapper for gradient multilinear interpolation.
129+
// Takes in a state and index along which to interpolate.
130+
VectorXd RecursiveValueInterpolator(const VectorXd& x, size_t idx) const;
131+
132+
// Recursive helper function wrapper for gradient multilinear interpolation.
119133
// Takes in a state and index along which to interpolate.
120134
VectorXd RecursiveGradientInterpolator(const VectorXd& x, size_t idx) const;
121135

@@ -146,35 +160,7 @@ template <typename TS, typename TC, typename TD, typename PS, typename PC,
146160
double MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD, B>::Value(
147161
const TS& tracker_x, const PS& planner_x) const {
148162
const VectorXd relative_x = RS(tracker_x, planner_x).ToVector();
149-
150-
// Get distance from cell center in each dimension.
151-
const VectorXd center_distance = DirectionToCenter(relative_x);
152-
153-
// Interpolate.
154-
const double nn_value = data_[StateToIndex(relative_x)];
155-
double approx_value = nn_value;
156-
157-
VectorXd neighbor = relative_x;
158-
for (size_t ii = 0; ii < relative_x.size(); ii++) {
159-
// Get neighboring value.
160-
if (center_distance(ii) >= 0.0)
161-
neighbor(ii) += cell_size_[ii];
162-
else
163-
neighbor(ii) -= cell_size_[ii];
164-
165-
const double neighbor_value = data_[StateToIndex(neighbor)];
166-
neighbor(ii) = relative_x(ii);
167-
168-
// Compute forward difference.
169-
const double slope = (center_distance(ii) >= 0.0)
170-
? (neighbor_value - nn_value) / cell_size_[ii]
171-
: (nn_value - neighbor_value) / cell_size_[ii];
172-
173-
// Add to the Taylor approximation.
174-
approx_value += slope * center_distance(ii);
175-
}
176-
177-
return approx_value;
163+
return RecursiveValueInterpolator(x, 0, false); // interpolate x in data_
178164
}
179165

180166
// Gradient at the given relative state.
@@ -185,7 +171,7 @@ MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD, B>::Gradient(
185171
const TS& tracker_x, const PS& planner_x) const {
186172
const VectorXd relative_x = RS(tracker_x, planner_x).ToVector();
187173
return std::unique_ptr<RS>(
188-
new RS(RecursiveGradientInterpolator(relative_x, 0)));
174+
new RS(RecursiveMultilinearInterpolator(relative_x, 0)));
189175
}
190176

191177
// Priority of the optimal control at the given tracker and planner states.
@@ -239,7 +225,21 @@ size_t MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD, B>::StateToIndex(
239225
return idx;
240226
}
241227

242-
// Accessor for precomputed gradient at the given state.
228+
// Accessor for precomputed value at the given state's grid cell.
229+
template <typename TS, typename TC, typename TD, typename PS, typename PC,
230+
typename PD, typename RS, typename RD, typename B>
231+
VectorXd MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD, B>::ValueAccessor(
232+
const VectorXd& x) const {
233+
// Convert to index and read value one dimension at a time.
234+
const size_t idx = StateToIndex(x);
235+
236+
VectorXd value(x.size());
237+
for (size_t ii = 0; ii < value.size(); ii++) value(ii) = data_[ii][idx];
238+
239+
return value;
240+
}
241+
242+
// Accessor for precomputed gradient at the given state's grid cell.
243243
template <typename TS, typename TC, typename TD, typename PS, typename PC,
244244
typename PD, typename RS, typename RD, typename B>
245245
VectorXd MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD,
@@ -292,14 +292,14 @@ VectorXd MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD,
292292
return center;
293293
}
294294

295-
// Recursive helper function for gradient multilinear interpolation.
296-
// Takes in a state and index along which to interpolate.
295+
// Recursive helper function for value or gradient multilinear interpolation.
296+
// Takes in a state and index along which to interpolate, and a boolean
297+
// determining whether this is for the gradient or, otherwise, for the value.
297298
template <typename TS, typename TC, typename TD, typename PS, typename PC,
298299
typename PD, typename RS, typename RD, typename B>
299-
VectorXd
300-
MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD,
301-
B>::RecursiveGradientInterpolator(const VectorXd& x,
302-
size_t idx) const {
300+
VectorXd MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD, B>::
301+
RecursiveMultilinearInterpolator(const VectorXd& x, size_t idx,
302+
const bool for_gradient) const {
303303
// Assume x's entries prior to idx are equal to the upper/lower bounds of
304304
// the cell containing x.
305305
// Begin by computing the lower and upper bounds of the cell containing x
@@ -319,23 +319,44 @@ MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD,
319319

320320
// Base case.
321321
if (idx == x.size() - 1) {
322-
return GradientAccessor(x_upper) * fractional_dist +
323-
GradientAccessor(x_lower) * (1.0 - fractional_dist);
322+
return for_gradient
323+
? GradientAccessor(x_upper) * fractional_dist +
324+
GradientAccessor(x_lower) * (1.0 - fractional_dist)
325+
: ValueAccessor(x_upper) * fractional_dist +
326+
ValueAccessor(x_lower) * (1.0 - fractional_dist);
324327
}
325328

326329
// Recursive step.
327-
return RecursiveGradientInterpolator(x_upper, idx + 1) * fractional_dist +
328-
RecursiveGradientInterpolator(x_lower, idx + 1) *
330+
return RecursiveMultilinearInterpolator(x_upper, idx + 1, for_gradient) *
331+
fractional_dist +
332+
RecursiveMultilinearInterpolator(x_lower, idx + 1, for_gradient) *
329333
(1.0 - fractional_dist);
330334
}
331335

336+
// Recursive helper function wrapper for value multilinear interpolation.
337+
// Takes in a state and index along which to interpolate.
338+
template <typename TS, typename TC, typename TD, typename PS, typename PC,
339+
typename PD, typename RS, typename RD, typename B>
340+
VectorXd MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD, B>::
341+
RecursiveGradientInterpolator(const VectorXd& x, size_t idx) const {
342+
return RecursiveMultilinearInterpolator(x idx, false);
343+
}
344+
345+
// Recursive helper function wrapper for gradient multilinear interpolation.
346+
// Takes in a state and index along which to interpolate.
347+
template <typename TS, typename TC, typename TD, typename PS, typename PC,
348+
typename PD, typename RS, typename RD, typename B>
349+
VectorXd MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD, B>::
350+
RecursiveGradientInterpolator(const VectorXd& x, size_t idx) const {
351+
return RecursiveMultilinearInterpolator(x idx, true);
352+
}
353+
332354
// Initialize from file. Returns whether or not loading was successful.
333355
// Can be used as an alternative to intialization from a NodeHandle.
334356
template <typename TS, typename TC, typename TD, typename PS, typename PC,
335357
typename PD, typename RS, typename RD, typename B>
336-
bool MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD,
337-
B>::InitializeFromMatFile(const std::string&
338-
file_name) {
358+
bool MatlabValueFunction<TS, TC, TD, PS, PC, PD, RS, RD, B>::
359+
InitializeFromMatFile(const std::string& file_name) {
339360
// Open up this file.
340361
MatlabFileReader reader(file_name);
341362
if (!reader.IsOpen()) return false;

0 commit comments

Comments
 (0)