@@ -317,6 +317,84 @@ TEST(RotationShimControllerTest, computeVelocityTests)
317
317
EXPECT_THROW (controller->computeVelocityCommands (pose, velocity, &checker), std::runtime_error);
318
318
}
319
319
320
+ TEST (RotationShimControllerTest, openLoopRotationTests) {
321
+ auto ctrl = std::make_shared<RotationShimShim>();
322
+ auto node = std::make_shared<rclcpp_lifecycle::LifecycleNode>(" ShimControllerTest" );
323
+ std::string name = " PathFollower" ;
324
+ auto tf = std::make_shared<tf2_ros::Buffer>(node->get_clock ());
325
+ auto listener = std::make_shared<tf2_ros::TransformListener>(*tf, node, true );
326
+ auto costmap = std::make_shared<nav2_costmap_2d::Costmap2DROS>(" fake_costmap" );
327
+ rclcpp_lifecycle::State state;
328
+ costmap->on_configure (state);
329
+ auto tf_broadcaster = std::make_shared<tf2_ros::TransformBroadcaster>(node);
330
+
331
+ geometry_msgs::msg::TransformStamped transform;
332
+ transform.header .frame_id = " base_link" ;
333
+ transform.child_frame_id = " odom" ;
334
+ transform.transform .rotation .x = 0.0 ;
335
+ transform.transform .rotation .y = 0.0 ;
336
+ transform.transform .rotation .z = 0.0 ;
337
+ transform.transform .rotation .w = 1.0 ;
338
+ tf_broadcaster->sendTransform (transform);
339
+
340
+ // set a valid primary controller so we can do lifecycle
341
+ node->declare_parameter (
342
+ " PathFollower.primary_controller" ,
343
+ std::string (" nav2_regulated_pure_pursuit_controller::RegulatedPurePursuitController" ));
344
+ node->declare_parameter (
345
+ " controller_frequency" ,
346
+ 20.0 );
347
+ node->declare_parameter (
348
+ " PathFollower.rotate_to_goal_heading" ,
349
+ true );
350
+ node->declare_parameter (
351
+ " PathFollower.closed_loop" ,
352
+ false );
353
+
354
+ auto controller = std::make_shared<RotationShimShim>();
355
+ controller->configure (node, name, tf, costmap);
356
+ controller->activate ();
357
+
358
+ // Test state update and path setting
359
+ nav_msgs::msg::Path path;
360
+ path.header .frame_id = " base_link" ;
361
+ path.poses .resize (4 );
362
+
363
+ geometry_msgs::msg::PoseStamped pose;
364
+ pose.header .frame_id = " base_link" ;
365
+ geometry_msgs::msg::Twist velocity;
366
+ nav2_controller::SimpleGoalChecker checker;
367
+ node->declare_parameter (
368
+ " checker.xy_goal_tolerance" ,
369
+ 1.0 );
370
+ checker.initialize (node, " checker" , costmap);
371
+
372
+ path.header .frame_id = " base_link" ;
373
+ path.poses [0 ].pose .position .x = 0.0 ;
374
+ path.poses [0 ].pose .position .y = 0.0 ;
375
+ path.poses [1 ].pose .position .x = 0.05 ;
376
+ path.poses [1 ].pose .position .y = 0.05 ;
377
+ path.poses [2 ].pose .position .x = 0.10 ;
378
+ path.poses [2 ].pose .position .y = 0.10 ;
379
+ // goal position within checker xy_goal_tolerance
380
+ path.poses [3 ].pose .position .x = 0.20 ;
381
+ path.poses [3 ].pose .position .y = 0.20 ;
382
+ // goal heading 45 degrees to the left
383
+ path.poses [3 ].pose .orientation .z = -0.3826834 ;
384
+ path.poses [3 ].pose .orientation .w = 0.9238795 ;
385
+ path.poses [3 ].header .frame_id = " base_link" ;
386
+
387
+ // Calculate first velocity command
388
+ controller->setPlan (path);
389
+ auto cmd_vel = controller->computeVelocityCommands (pose, velocity, &checker);
390
+ EXPECT_NEAR (cmd_vel.twist .angular .z , -0.16 , 1e-4 );
391
+
392
+ // Test second velocity command with wrong odometry
393
+ velocity.angular .z = 1.8 ;
394
+ cmd_vel = controller->computeVelocityCommands (pose, velocity, &checker);
395
+ EXPECT_NEAR (cmd_vel.twist .angular .z , -0.32 , 1e-4 );
396
+ }
397
+
320
398
TEST (RotationShimControllerTest, computeVelocityGoalRotationTests) {
321
399
auto ctrl = std::make_shared<RotationShimShim>();
322
400
auto node = std::make_shared<rclcpp_lifecycle::LifecycleNode>(" ShimControllerTest" );
@@ -550,7 +628,8 @@ TEST(RotationShimControllerTest, testDynamicParameter)
550
628
rclcpp::Parameter (" test.simulate_ahead_time" , 7.0 ),
551
629
rclcpp::Parameter (" test.primary_controller" , std::string (" HI" )),
552
630
rclcpp::Parameter (" test.rotate_to_goal_heading" , true ),
553
- rclcpp::Parameter (" test.rotate_to_heading_once" , true )});
631
+ rclcpp::Parameter (" test.rotate_to_heading_once" , true ),
632
+ rclcpp::Parameter (" test.closed_loop" , false )});
554
633
555
634
rclcpp::spin_until_future_complete (
556
635
node->get_node_base_interface (),
@@ -563,4 +642,5 @@ TEST(RotationShimControllerTest, testDynamicParameter)
563
642
EXPECT_EQ (node->get_parameter (" test.simulate_ahead_time" ).as_double (), 7.0 );
564
643
EXPECT_EQ (node->get_parameter (" test.rotate_to_goal_heading" ).as_bool (), true );
565
644
EXPECT_EQ (node->get_parameter (" test.rotate_to_heading_once" ).as_bool (), true );
645
+ EXPECT_EQ (node->get_parameter (" test.closed_loop" ).as_bool (), false );
566
646
}
0 commit comments