@@ -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