@@ -522,6 +522,137 @@ TEST_F(PidControllerTest, receive_message_and_publish_updated_status)
522
522
}
523
523
}
524
524
525
+ /* *
526
+ * @brief check chained pid controller with feedforward and gain as non-zero, single interface
527
+ */
528
+ TEST_F (PidControllerTest, test_update_chained_feedforward_with_gain)
529
+ {
530
+ // state interface value is 1.1 as defined in test fixture
531
+ // with p gain 0.5, the command value should be 0.5 * (5.0 - 1.1) = 1.95
532
+ // with feedforward gain 1.0, the command value should be 1.95 + 1.0 * 5.0 = 6.95
533
+ const double target_value = 5.0 ;
534
+ const double expected_command_value = 6.95 ;
535
+
536
+ SetUpController (" test_pid_controller_with_feedforward_gain" );
537
+ ASSERT_EQ (controller_->on_configure (rclcpp_lifecycle::State ()), NODE_SUCCESS);
538
+
539
+ // check on interfaces & pid gain parameters
540
+ for (const auto & dof_name : dof_names_)
541
+ {
542
+ ASSERT_EQ (controller_->params_ .gains .dof_names_map [dof_name].p , 0.5 );
543
+ ASSERT_EQ (controller_->params_ .gains .dof_names_map [dof_name].feedforward_gain , 1.0 );
544
+ }
545
+ ASSERT_EQ (controller_->params_ .command_interface , command_interface_);
546
+ EXPECT_THAT (
547
+ controller_->params_ .reference_and_state_interfaces ,
548
+ testing::ElementsAreArray (state_interfaces_));
549
+ ASSERT_FALSE (controller_->params_ .use_external_measured_states );
550
+
551
+ // setup executor
552
+ rclcpp::executors::MultiThreadedExecutor executor;
553
+ executor.add_node (controller_->get_node ()->get_node_base_interface ());
554
+ executor.add_node (service_caller_node_->get_node_base_interface ());
555
+
556
+ controller_->set_chained_mode (true );
557
+
558
+ // activate controller
559
+ ASSERT_EQ (controller_->on_activate (rclcpp_lifecycle::State ()), NODE_SUCCESS);
560
+ ASSERT_TRUE (controller_->is_in_chained_mode ());
561
+
562
+ // turn on feedforward
563
+ controller_->control_mode_ .writeFromNonRT (feedforward_mode_type::ON);
564
+ ASSERT_EQ (*(controller_->control_mode_ .readFromRT ()), feedforward_mode_type::ON);
565
+
566
+ // send a message to update reference interface
567
+ std::shared_ptr<ControllerCommandMsg> msg = std::make_shared<ControllerCommandMsg>();
568
+ msg->dof_names = controller_->params_ .dof_names ;
569
+ msg->values .resize (msg->dof_names .size (), 0.0 );
570
+ for (size_t i = 0 ; i < msg->dof_names .size (); ++i)
571
+ {
572
+ msg->values [i] = target_value;
573
+ }
574
+ msg->values_dot .resize (msg->dof_names .size (), std::numeric_limits<double >::quiet_NaN ());
575
+ controller_->input_ref_ .writeFromNonRT (msg);
576
+ ASSERT_EQ (
577
+ controller_->update_reference_from_subscribers (
578
+ rclcpp::Time (0 ), rclcpp::Duration::from_seconds (0.01 )),
579
+ controller_interface::return_type::OK);
580
+
581
+ // run update
582
+ ASSERT_EQ (
583
+ controller_->update (rclcpp::Time (0 ), rclcpp::Duration::from_seconds (0.01 )),
584
+ controller_interface::return_type::OK);
585
+
586
+ // check on result from update
587
+ ASSERT_EQ (controller_->command_interfaces_ [0 ].get_value (), expected_command_value);
588
+ }
589
+
590
+ /* *
591
+ * @brief check chained pid controller with feedforward OFF and gain as non-zero, single interface
592
+ */
593
+ TEST_F (PidControllerTest, test_update_chained_feedforward_off_with_gain)
594
+ {
595
+ // state interface value is 1.1 as defined in test fixture
596
+ // given target value 5.0
597
+ // with p gain 0.5, the command value should be 0.5 * (5.0 - 1.1) = 1.95
598
+ // with feedforward off, the command value should be still 1.95 even though feedforward gain
599
+ // is 1.0
600
+ const double target_value = 5.0 ;
601
+ const double expected_command_value = 1.95 ;
602
+
603
+ SetUpController (" test_pid_controller_with_feedforward_gain" );
604
+ ASSERT_EQ (controller_->on_configure (rclcpp_lifecycle::State ()), NODE_SUCCESS);
605
+
606
+ // check on interfaces & pid gain parameters
607
+ for (const auto & dof_name : dof_names_)
608
+ {
609
+ ASSERT_EQ (controller_->params_ .gains .dof_names_map [dof_name].p , 0.5 );
610
+ ASSERT_EQ (controller_->params_ .gains .dof_names_map [dof_name].feedforward_gain , 1.0 );
611
+ }
612
+ ASSERT_EQ (controller_->params_ .command_interface , command_interface_);
613
+ EXPECT_THAT (
614
+ controller_->params_ .reference_and_state_interfaces ,
615
+ testing::ElementsAreArray (state_interfaces_));
616
+ ASSERT_FALSE (controller_->params_ .use_external_measured_states );
617
+
618
+ // setup executor
619
+ rclcpp::executors::MultiThreadedExecutor executor;
620
+ executor.add_node (controller_->get_node ()->get_node_base_interface ());
621
+ executor.add_node (service_caller_node_->get_node_base_interface ());
622
+
623
+ controller_->set_chained_mode (true );
624
+
625
+ // activate controller
626
+ ASSERT_EQ (controller_->on_activate (rclcpp_lifecycle::State ()), NODE_SUCCESS);
627
+ ASSERT_TRUE (controller_->is_in_chained_mode ());
628
+
629
+ // feedforward by default is OFF
630
+ ASSERT_EQ (*(controller_->control_mode_ .readFromRT ()), feedforward_mode_type::OFF);
631
+
632
+ // send a message to update reference interface
633
+ std::shared_ptr<ControllerCommandMsg> msg = std::make_shared<ControllerCommandMsg>();
634
+ msg->dof_names = controller_->params_ .dof_names ;
635
+ msg->values .resize (msg->dof_names .size (), 0.0 );
636
+ for (size_t i = 0 ; i < msg->dof_names .size (); ++i)
637
+ {
638
+ msg->values [i] = target_value;
639
+ }
640
+ msg->values_dot .resize (msg->dof_names .size (), std::numeric_limits<double >::quiet_NaN ());
641
+ controller_->input_ref_ .writeFromNonRT (msg);
642
+ ASSERT_EQ (
643
+ controller_->update_reference_from_subscribers (
644
+ rclcpp::Time (0 ), rclcpp::Duration::from_seconds (0.01 )),
645
+ controller_interface::return_type::OK);
646
+
647
+ // run update
648
+ ASSERT_EQ (
649
+ controller_->update (rclcpp::Time (0 ), rclcpp::Duration::from_seconds (0.01 )),
650
+ controller_interface::return_type::OK);
651
+
652
+ // check on result from update
653
+ ASSERT_EQ (controller_->command_interfaces_ [0 ].get_value (), expected_command_value);
654
+ }
655
+
525
656
int main (int argc, char ** argv)
526
657
{
527
658
::testing::InitGoogleTest (&argc, argv);
0 commit comments