Skip to content

Commit c536b1c

Browse files
committed
Fixing SGF in MPPI and Smoother (#4669)
Signed-off-by: Steve Macenski <stevenmacenski@gmail.com>
1 parent e3e8781 commit c536b1c

File tree

2 files changed

+63
-182
lines changed

2 files changed

+63
-182
lines changed

nav2_mppi_controller/include/nav2_mppi_controller/tools/utils.hpp

Lines changed: 33 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,8 @@ inline void savitskyGolayFilter(
461461
xt::xarray<float> filter = {-21.0, 14.0, 39.0, 54.0, 59.0, 54.0, 39.0, 14.0, -21.0};
462462
filter /= 231.0;
463463

464-
const unsigned int num_sequences = control_sequence.vx.shape(0) - 1;
465-
466464
// Too short to smooth meaningfully
465+
const unsigned int num_sequences = control_sequence.vx.shape(0) - 1;
467466
if (num_sequences < 20) {
468467
return;
469468
}
@@ -473,137 +472,49 @@ inline void savitskyGolayFilter(
473472
};
474473

475474
auto applyFilterOverAxis =
476-
[&](xt::xtensor<float, 1> & sequence,
475+
[&](xt::xtensor<float, 1> & sequence, const xt::xtensor<float, 1> & initial_sequence,
477476
const float hist_0, const float hist_1, const float hist_2, const float hist_3) -> void
478477
{
479-
unsigned int idx = 0;
480-
sequence(idx) = applyFilter(
481-
{
482-
hist_0,
483-
hist_1,
484-
hist_2,
485-
hist_3,
486-
sequence(idx),
487-
sequence(idx + 1),
488-
sequence(idx + 2),
489-
sequence(idx + 3),
490-
sequence(idx + 4)});
491-
492-
idx++;
493-
sequence(idx) = applyFilter(
494-
{
495-
hist_1,
496-
hist_2,
497-
hist_3,
498-
sequence(idx - 1),
499-
sequence(idx),
500-
sequence(idx + 1),
501-
sequence(idx + 2),
502-
sequence(idx + 3),
503-
sequence(idx + 4)});
504-
505-
idx++;
506-
sequence(idx) = applyFilter(
507-
{
508-
hist_2,
509-
hist_3,
510-
sequence(idx - 2),
511-
sequence(idx - 1),
512-
sequence(idx),
513-
sequence(idx + 1),
514-
sequence(idx + 2),
515-
sequence(idx + 3),
516-
sequence(idx + 4)});
517-
518-
idx++;
519-
sequence(idx) = applyFilter(
520-
{
521-
hist_3,
522-
sequence(idx - 3),
523-
sequence(idx - 2),
524-
sequence(idx - 1),
525-
sequence(idx),
526-
sequence(idx + 1),
527-
sequence(idx + 2),
528-
sequence(idx + 3),
529-
sequence(idx + 4)});
530-
531-
for (idx = 4; idx != num_sequences - 4; idx++) {
532-
sequence(idx) = applyFilter(
533-
{
534-
sequence(idx - 4),
535-
sequence(idx - 3),
536-
sequence(idx - 2),
537-
sequence(idx - 1),
538-
sequence(idx),
539-
sequence(idx + 1),
540-
sequence(idx + 2),
541-
sequence(idx + 3),
542-
sequence(idx + 4)});
478+
float pt_m4 = hist_0;
479+
float pt_m3 = hist_1;
480+
float pt_m2 = hist_2;
481+
float pt_m1 = hist_3;
482+
float pt = initial_sequence(0);
483+
float pt_p1 = initial_sequence(1);
484+
float pt_p2 = initial_sequence(2);
485+
float pt_p3 = initial_sequence(3);
486+
float pt_p4 = initial_sequence(4);
487+
488+
for (unsigned int idx = 0; idx != num_sequences; idx++) {
489+
sequence(idx) = applyFilter({pt_m4, pt_m3, pt_m2, pt_m1, pt, pt_p1, pt_p2, pt_p3, pt_p4});
490+
pt_m4 = pt_m3;
491+
pt_m3 = pt_m2;
492+
pt_m2 = pt_m1;
493+
pt_m1 = pt;
494+
pt = pt_p1;
495+
pt_p1 = pt_p2;
496+
pt_p2 = pt_p3;
497+
pt_p3 = pt_p4;
498+
499+
if (idx + 5 < num_sequences) {
500+
pt_p4 = initial_sequence(idx + 5);
501+
} else {
502+
// Return the last point
503+
pt_p4 = initial_sequence(num_sequences);
504+
}
543505
}
544-
545-
idx++;
546-
sequence(idx) = applyFilter(
547-
{
548-
sequence(idx - 4),
549-
sequence(idx - 3),
550-
sequence(idx - 2),
551-
sequence(idx - 1),
552-
sequence(idx),
553-
sequence(idx + 1),
554-
sequence(idx + 2),
555-
sequence(idx + 3),
556-
sequence(idx + 3)});
557-
558-
idx++;
559-
sequence(idx) = applyFilter(
560-
{
561-
sequence(idx - 4),
562-
sequence(idx - 3),
563-
sequence(idx - 2),
564-
sequence(idx - 1),
565-
sequence(idx),
566-
sequence(idx + 1),
567-
sequence(idx + 2),
568-
sequence(idx + 2),
569-
sequence(idx + 2)});
570-
571-
idx++;
572-
sequence(idx) = applyFilter(
573-
{
574-
sequence(idx - 4),
575-
sequence(idx - 3),
576-
sequence(idx - 2),
577-
sequence(idx - 1),
578-
sequence(idx),
579-
sequence(idx + 1),
580-
sequence(idx + 1),
581-
sequence(idx + 1),
582-
sequence(idx + 1)});
583-
584-
idx++;
585-
sequence(idx) = applyFilter(
586-
{
587-
sequence(idx - 4),
588-
sequence(idx - 3),
589-
sequence(idx - 2),
590-
sequence(idx - 1),
591-
sequence(idx),
592-
sequence(idx),
593-
sequence(idx),
594-
sequence(idx),
595-
sequence(idx)});
596506
};
597507

598508
// Filter trajectories
509+
const models::ControlSequence initial_control_sequence = control_sequence;
599510
applyFilterOverAxis(
600-
control_sequence.vx, control_history[0].vx,
511+
control_sequence.vx, initial_control_sequence.vx, control_history[0].vx,
601512
control_history[1].vx, control_history[2].vx, control_history[3].vx);
602513
applyFilterOverAxis(
603-
control_sequence.vy, control_history[0].vy,
514+
control_sequence.vy, initial_control_sequence.vy, control_history[0].vy,
604515
control_history[1].vy, control_history[2].vy, control_history[3].vy);
605516
applyFilterOverAxis(
606-
control_sequence.wz, control_history[0].wz,
517+
control_sequence.wz, initial_control_sequence.wz, control_history[0].wz,
607518
control_history[1].wz, control_history[2].wz, control_history[3].wz);
608519

609520
// Update control history

nav2_smoother/src/savitzky_golay_smoother.cpp

Lines changed: 30 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -118,74 +118,44 @@ bool SavitzkyGolaySmoother::smoothImpl(
118118
};
119119

120120
auto applyFilterOverAxes =
121-
[&](std::vector<geometry_msgs::msg::PoseStamped> & plan_pts) -> void
121+
[&](std::vector<geometry_msgs::msg::PoseStamped> & plan_pts,
122+
const std::vector<geometry_msgs::msg::PoseStamped> & init_plan_pts) -> void
122123
{
123-
// Handle initial boundary conditions, first point is fixed
124-
unsigned int idx = 1;
125-
plan_pts[idx].pose.position = applyFilter(
126-
{
127-
plan_pts[idx - 1].pose.position,
128-
plan_pts[idx - 1].pose.position,
129-
plan_pts[idx - 1].pose.position,
130-
plan_pts[idx].pose.position,
131-
plan_pts[idx + 1].pose.position,
132-
plan_pts[idx + 2].pose.position,
133-
plan_pts[idx + 3].pose.position});
134-
135-
idx++;
136-
plan_pts[idx].pose.position = applyFilter(
137-
{
138-
plan_pts[idx - 2].pose.position,
139-
plan_pts[idx - 2].pose.position,
140-
plan_pts[idx - 1].pose.position,
141-
plan_pts[idx].pose.position,
142-
plan_pts[idx + 1].pose.position,
143-
plan_pts[idx + 2].pose.position,
144-
plan_pts[idx + 3].pose.position});
145-
146-
// Apply nominal filter
147-
for (idx = 3; idx < path_size - 4; ++idx) {
148-
plan_pts[idx].pose.position = applyFilter(
149-
{
150-
plan_pts[idx - 3].pose.position,
151-
plan_pts[idx - 2].pose.position,
152-
plan_pts[idx - 1].pose.position,
153-
plan_pts[idx].pose.position,
154-
plan_pts[idx + 1].pose.position,
155-
plan_pts[idx + 2].pose.position,
156-
plan_pts[idx + 3].pose.position});
124+
auto pt_m3 = init_plan_pts[0].pose.position;
125+
auto pt_m2 = init_plan_pts[0].pose.position;
126+
auto pt_m1 = init_plan_pts[0].pose.position;
127+
auto pt = init_plan_pts[1].pose.position;
128+
auto pt_p1 = init_plan_pts[2].pose.position;
129+
auto pt_p2 = init_plan_pts[3].pose.position;
130+
auto pt_p3 = init_plan_pts[4].pose.position;
131+
132+
// First point is fixed
133+
for (unsigned int idx = 1; idx != path_size - 1; idx++) {
134+
plan_pts[idx].pose.position = applyFilter({pt_m3, pt_m2, pt_m1, pt, pt_p1, pt_p2, pt_p3});
135+
pt_m3 = pt_m2;
136+
pt_m2 = pt_m1;
137+
pt_m1 = pt;
138+
pt = pt_p1;
139+
pt_p1 = pt_p2;
140+
pt_p2 = pt_p3;
141+
142+
if (idx + 4 < path_size - 1) {
143+
pt_p3 = init_plan_pts[idx + 4].pose.position;
144+
} else {
145+
// Return the last point
146+
pt_p3 = init_plan_pts[path_size - 1].pose.position;
147+
}
157148
}
158-
159-
// Handle terminal boundary conditions, last point is fixed
160-
idx++;
161-
plan_pts[idx].pose.position = applyFilter(
162-
{
163-
plan_pts[idx - 3].pose.position,
164-
plan_pts[idx - 2].pose.position,
165-
plan_pts[idx - 1].pose.position,
166-
plan_pts[idx].pose.position,
167-
plan_pts[idx + 1].pose.position,
168-
plan_pts[idx + 2].pose.position,
169-
plan_pts[idx + 2].pose.position});
170-
171-
idx++;
172-
plan_pts[idx].pose.position = applyFilter(
173-
{
174-
plan_pts[idx - 3].pose.position,
175-
plan_pts[idx - 2].pose.position,
176-
plan_pts[idx - 1].pose.position,
177-
plan_pts[idx].pose.position,
178-
plan_pts[idx + 1].pose.position,
179-
plan_pts[idx + 1].pose.position,
180-
plan_pts[idx + 1].pose.position});
181149
};
182150

183-
applyFilterOverAxes(path.poses);
151+
const auto initial_path_poses = path.poses;
152+
applyFilterOverAxes(path.poses, initial_path_poses);
184153

185154
// Lets do additional refinement, it shouldn't take more than a couple milliseconds
186155
if (do_refinement_) {
187156
for (int i = 0; i < refinement_num_; i++) {
188-
applyFilterOverAxes(path.poses);
157+
const auto reined_initial_path_poses = path.poses;
158+
applyFilterOverAxes(path.poses, reined_initial_path_poses);
189159
}
190160
}
191161

0 commit comments

Comments
 (0)