@@ -522,6 +522,133 @@ TEST_F(PidControllerTest, receive_message_and_publish_updated_status)
522522  }
523523}
524524
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 (), controller_interface::return_type::OK);
578+ 
579+   //  run update
580+   ASSERT_EQ (
581+     controller_->update (rclcpp::Time (0 ), rclcpp::Duration::from_seconds (0.01 )),
582+     controller_interface::return_type::OK);
583+ 
584+   //  check on result from update
585+   ASSERT_EQ (controller_->command_interfaces_ [0 ].get_value (), expected_command_value);
586+ }
587+ 
588+ /* *
589+  * @brief check chained pid controller with feedforward OFF and gain as non-zero, single interface 
590+  */  
591+ TEST_F (PidControllerTest, test_update_chained_feedforward_off_with_gain)
592+ {
593+   //  state interface value is 1.1 as defined in test fixture
594+   //  given target value 5.0
595+   //  with p gain 0.5, the command value should be 0.5 * (5.0 - 1.1) = 1.95
596+   //  with feedforward off, the command value should be still 1.95 even though feedforward gain
597+   //  is 1.0
598+   const  double  target_value = 5.0 ;
599+   const  double  expected_command_value = 1.95 ;
600+ 
601+   SetUpController (" test_pid_controller_with_feedforward_gain" 
602+   ASSERT_EQ (controller_->on_configure (rclcpp_lifecycle::State ()), NODE_SUCCESS);
603+ 
604+   //  check on interfaces & pid gain parameters
605+   for  (const  auto  & dof_name : dof_names_)
606+   {
607+     ASSERT_EQ (controller_->params_ .gains .dof_names_map [dof_name].p , 0.5 );
608+     ASSERT_EQ (controller_->params_ .gains .dof_names_map [dof_name].feedforward_gain , 1.0 );
609+   }
610+   ASSERT_EQ (controller_->params_ .command_interface , command_interface_);
611+   EXPECT_THAT (
612+     controller_->params_ .reference_and_state_interfaces ,
613+     testing::ElementsAreArray (state_interfaces_));
614+   ASSERT_FALSE (controller_->params_ .use_external_measured_states );
615+ 
616+   //  setup executor
617+   rclcpp::executors::MultiThreadedExecutor executor;
618+   executor.add_node (controller_->get_node ()->get_node_base_interface ());
619+   executor.add_node (service_caller_node_->get_node_base_interface ());
620+ 
621+   controller_->set_chained_mode (true );
622+ 
623+   //  activate controller
624+   ASSERT_EQ (controller_->on_activate (rclcpp_lifecycle::State ()), NODE_SUCCESS);
625+   ASSERT_TRUE (controller_->is_in_chained_mode ());
626+ 
627+   //  feedforward by default is OFF
628+   ASSERT_EQ (*(controller_->control_mode_ .readFromRT ()), feedforward_mode_type::OFF);
629+ 
630+   //  send a message to update reference interface
631+   std::shared_ptr<ControllerCommandMsg> msg = std::make_shared<ControllerCommandMsg>();
632+   msg->dof_names  = controller_->params_ .dof_names ;
633+   msg->values .resize (msg->dof_names .size (), 0.0 );
634+   for  (size_t  i = 0 ; i < msg->dof_names .size (); ++i)
635+   {
636+     msg->values [i] = target_value;
637+   }
638+   msg->values_dot .resize (msg->dof_names .size (), std::numeric_limits<double >::quiet_NaN ());
639+   controller_->input_ref_ .writeFromNonRT (msg);
640+   ASSERT_EQ (
641+     controller_->update_reference_from_subscribers (), controller_interface::return_type::OK);
642+ 
643+   //  run update
644+   ASSERT_EQ (
645+     controller_->update (rclcpp::Time (0 ), rclcpp::Duration::from_seconds (0.01 )),
646+     controller_interface::return_type::OK);
647+ 
648+   //  check on result from update
649+   ASSERT_EQ (controller_->command_interfaces_ [0 ].get_value (), expected_command_value);
650+ }
651+ 
525652int  main (int  argc, char  ** argv)
526653{
527654  ::testing::InitGoogleTest (&argc, argv);
0 commit comments