Skip to content

Commit 1cd120f

Browse files
tests added for optimal path publication
Signed-off-by: Alyssa Agnissan <alyssa.agnissan@quantillion.io>
1 parent 1a2df95 commit 1cd120f

File tree

5 files changed

+79
-8
lines changed

5 files changed

+79
-8
lines changed

nav2_mppi_controller/include/nav2_mppi_controller/controller.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ class MPPIController : public nav2_core::Controller
106106
* @brief Visualize trajectories
107107
* @param transformed_plan Transformed input plan
108108
*/
109-
void visualize(nav_msgs::msg::Path transformed_plan, const builtin_interfaces::msg::Time & cmd_stamp);
109+
void visualize(
110+
nav_msgs::msg::Path transformed_plan,
111+
const builtin_interfaces::msg::Time & cmd_stamp);
110112

111113
std::string name_;
112114
rclcpp_lifecycle::LifecycleNode::WeakPtr parent_;

nav2_mppi_controller/include/nav2_mppi_controller/tools/trajectory_visualizer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class TrajectoryVisualizer
9797
* @brief Visualize the plan
9898
* @param plan Plan to visualize
9999
*/
100-
void visualize(const nav_msgs::msg::Path & plan,const builtin_interfaces::msg::Time & cmd_stamp);
100+
void visualize(const nav_msgs::msg::Path & plan, const builtin_interfaces::msg::Time & cmd_stamp);
101101

102102
/**
103103
* @brief Reset object

nav2_mppi_controller/src/controller.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ geometry_msgs::msg::TwistStamped MPPIController::computeVelocityCommands(
105105
return cmd;
106106
}
107107

108-
void MPPIController::visualize(nav_msgs::msg::Path transformed_plan, const builtin_interfaces::msg::Time & cmd_stamp)
108+
void MPPIController::visualize(
109+
nav_msgs::msg::Path transformed_plan,
110+
const builtin_interfaces::msg::Time & cmd_stamp)
109111
{
110112
trajectory_visualizer_.add(optimizer_.getGeneratedTrajectories(), "Candidate Trajectories");
111113
trajectory_visualizer_.add(optimizer_.getOptimizedTrajectory(), "Optimal Trajectory");

nav2_mppi_controller/src/trajectory_visualizer.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ void TrajectoryVisualizer::reset()
120120
optimal_traj_ = std::make_unique<xt::xtensor<float, 2>>();
121121
}
122122

123-
void TrajectoryVisualizer::visualize(const nav_msgs::msg::Path & plan, const builtin_interfaces::msg::Time & cmd_stamp)
123+
void TrajectoryVisualizer::visualize(
124+
const nav_msgs::msg::Path & plan,
125+
const builtin_interfaces::msg::Time & cmd_stamp)
124126
{
125127
if (trajectories_publisher_->get_subscription_count() > 0) {
126128
trajectories_publisher_->publish(std::move(points_));

nav2_mppi_controller/test/trajectory_visualizer_tests.cpp

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ TEST(TrajectoryVisualizerTests, VisPathRepub)
5959
TrajectoryVisualizer vis;
6060
vis.on_configure(node, "my_name", "map", parameters_handler.get());
6161
vis.on_activate();
62-
vis.visualize(pub_path);
62+
builtin_interfaces::msg::Time bogus_stamp;
63+
vis.visualize(pub_path, bogus_stamp);
6364

6465
rclcpp::spin_some(node->get_node_base_interface());
6566
EXPECT_EQ(recieved_path.poses.size(), 5u);
@@ -83,15 +84,16 @@ TEST(TrajectoryVisualizerTests, VisOptimalTrajectory)
8384
vis.on_activate();
8485
vis.add(optimal_trajectory, "Optimal Trajectory");
8586
nav_msgs::msg::Path bogus_path;
86-
vis.visualize(bogus_path);
87+
builtin_interfaces::msg::Time bogus_stamp;
88+
vis.visualize(bogus_path, bogus_stamp);
8789

8890
rclcpp::spin_some(node->get_node_base_interface());
8991
EXPECT_EQ(recieved_msg.markers.size(), 0u);
9092

9193
// Now populated with content, should publish
9294
optimal_trajectory = xt::ones<float>({20, 2});
9395
vis.add(optimal_trajectory, "Optimal Trajectory");
94-
vis.visualize(bogus_path);
96+
vis.visualize(bogus_path, bogus_stamp);
9597

9698
rclcpp::spin_some(node->get_node_base_interface());
9799

@@ -147,9 +149,72 @@ TEST(TrajectoryVisualizerTests, VisCandidateTrajectories)
147149
vis.on_activate();
148150
vis.add(candidate_trajectories, "Candidate Trajectories");
149151
nav_msgs::msg::Path bogus_path;
150-
vis.visualize(bogus_path);
152+
builtin_interfaces::msg::Time bogus_stamp;
153+
vis.visualize(bogus_path, bogus_stamp);
151154

152155
rclcpp::spin_some(node->get_node_base_interface());
153156
// 40 * 4, for 5 trajectory steps + 3 point steps
154157
EXPECT_EQ(recieved_msg.markers.size(), 160u);
155158
}
159+
160+
TEST(TrajectoryVisualizerTests, VisOptimalPath)
161+
{
162+
auto node = std::make_shared<rclcpp_lifecycle::LifecycleNode>("my_node");
163+
auto parameters_handler = std::make_unique<ParametersHandler>(node);
164+
builtin_interfaces::msg::Time cmd_stamp;
165+
cmd_stamp.sec = 5;
166+
cmd_stamp.nanosec = 10;
167+
168+
nav_msgs::msg::Path recieved_path;
169+
auto my_sub = node->create_subscription<nav_msgs::msg::Path>(
170+
"/local_plan", 10,
171+
[&](const nav_msgs::msg::Path msg) {recieved_path = msg;});
172+
173+
// optimal_trajectory empty, should fail to publish
174+
xt::xtensor<float, 2> optimal_trajectory;
175+
TrajectoryVisualizer vis;
176+
vis.on_configure(node, "my_name", "fkmap", parameters_handler.get());
177+
vis.on_activate();
178+
vis.add(optimal_trajectory, "Optimal Trajectory");
179+
nav_msgs::msg::Path bogus_path;
180+
vis.visualize(bogus_path, cmd_stamp);
181+
182+
rclcpp::spin_some(node->get_node_base_interface());
183+
EXPECT_EQ(recieved_path.poses.size(), 0u);
184+
185+
// Now populated with content, should publish
186+
optimal_trajectory.resize({20, 2});
187+
for (unsigned int i = 0; i != optimal_trajectory.shape()[0] - 1; i++) {
188+
optimal_trajectory(i, 0) = static_cast<float>(i);
189+
optimal_trajectory(i, 1) = static_cast<float>(i);
190+
}
191+
vis.add(optimal_trajectory, "Optimal Trajectory");
192+
vis.visualize(bogus_path, cmd_stamp);
193+
194+
rclcpp::spin_some(node->get_node_base_interface());
195+
196+
// Should have a 20 points path in the map frame and with same stamp than velocity command
197+
EXPECT_EQ(recieved_path.poses.size(), 20u);
198+
EXPECT_EQ(recieved_path.header.frame_id, "fkmap");
199+
EXPECT_EQ(recieved_path.header.stamp.sec, cmd_stamp.sec);
200+
EXPECT_EQ(recieved_path.header.stamp.nanosec, cmd_stamp.nanosec);
201+
202+
tf2::Quaternion quat;
203+
for (unsigned int i = 0; i != recieved_path.poses.size() - 1; i++) {
204+
// Poses should be in map frame too
205+
EXPECT_EQ(recieved_path.poses[i].header.frame_id, "fkmap");
206+
207+
// Check positions are correct
208+
EXPECT_EQ(recieved_path.poses[i].pose.position.x, static_cast<float>(i));
209+
EXPECT_EQ(recieved_path.poses[i].pose.position.y, static_cast<float>(i));
210+
EXPECT_EQ(recieved_path.poses[i].pose.position.z, 0.0);
211+
212+
// Check orientations are correct
213+
quat.setRPY(0., 0., optimal_trajectory(i, 2));
214+
auto expected_orientation = tf2::toMsg(quat);
215+
EXPECT_EQ(recieved_path.poses[i].pose.orientation.x, expected_orientation.x);
216+
EXPECT_EQ(recieved_path.poses[i].pose.orientation.y, expected_orientation.y);
217+
EXPECT_EQ(recieved_path.poses[i].pose.orientation.z, expected_orientation.z);
218+
EXPECT_EQ(recieved_path.poses[i].pose.orientation.w, expected_orientation.w);
219+
}
220+
}

0 commit comments

Comments
 (0)