@@ -554,6 +554,95 @@ TEST_F(JointSaturationLimiterTest, check_desired_jerk_only_cases)
554
554
test_limit_enforcing (-1.5 , -0.5 , true );
555
555
}
556
556
557
+ TEST_F (JointSaturationLimiterTest, check_all_desired_references_limiting)
558
+ {
559
+ SetupNode (" joint_saturation_limiter" );
560
+ ASSERT_TRUE (Load ());
561
+
562
+ joint_limits::JointLimits limits;
563
+ limits.has_position_limits = true ;
564
+ limits.min_position = -5.0 ;
565
+ limits.max_position = 5.0 ;
566
+ limits.has_velocity_limits = true ;
567
+ limits.max_velocity = 1.0 ;
568
+ limits.has_acceleration_limits = true ;
569
+ limits.max_acceleration = 0.5 ;
570
+ limits.has_deceleration_limits = true ;
571
+ limits.max_deceleration = 0.25 ;
572
+ limits.has_jerk_limits = true ;
573
+ limits.max_jerk = 2.0 ;
574
+ ASSERT_TRUE (Init (limits));
575
+ ASSERT_TRUE (joint_limiter_->configure (last_commanded_state_));
576
+
577
+ rclcpp::Duration period (1 , 0 ); // 1 second
578
+ auto test_limit_enforcing =
579
+ [&](
580
+ const std::optional<double > & actual_position, const std::optional<double > & actual_velocity,
581
+ double desired_position, double desired_velocity, double desired_acceleration,
582
+ double desired_jerk, double expected_position, double expected_velocity,
583
+ double expected_acceleration, double expected_jerk, bool is_clamped)
584
+ {
585
+ // Reset the desired and actual states
586
+ desired_state_ = {};
587
+ actual_state_ = {};
588
+ const double act_pos = actual_position.has_value () ? actual_position.value ()
589
+ : std::numeric_limits<double >::quiet_NaN ();
590
+ const double act_vel = actual_velocity.has_value () ? actual_velocity.value ()
591
+ : std::numeric_limits<double >::quiet_NaN ();
592
+ SCOPED_TRACE (
593
+ " Testing for actual position: " + std::to_string (act_pos) + " , actual velocity: " +
594
+ std::to_string (act_vel) + " , desired position: " + std::to_string (desired_position) +
595
+ " , desired velocity: " + std::to_string (desired_velocity) + " , desired acceleration: " +
596
+ std::to_string (desired_acceleration) + " , desired jerk: " + std::to_string (desired_jerk) +
597
+ " , expected position: " + std::to_string (expected_position) +
598
+ " , expected velocity: " + std::to_string (expected_velocity) + " , expected acceleration: " +
599
+ std::to_string (expected_acceleration) + " , expected jerk: " + std::to_string (expected_jerk) +
600
+ " , is clamped: " + std::to_string (is_clamped) +
601
+ " for the joint limits : " + limits.to_string ());
602
+ if (actual_position.has_value ())
603
+ {
604
+ actual_state_.position = actual_position.value ();
605
+ }
606
+ if (actual_velocity.has_value ())
607
+ {
608
+ actual_state_.velocity = actual_velocity.value ();
609
+ }
610
+ desired_state_.position = desired_position;
611
+ desired_state_.velocity = desired_velocity;
612
+ desired_state_.acceleration = desired_acceleration;
613
+ desired_state_.jerk = desired_jerk;
614
+ ASSERT_EQ (is_clamped, joint_limiter_->enforce (actual_state_, desired_state_, period));
615
+ EXPECT_NEAR (desired_state_.position .value (), expected_position, COMMON_THRESHOLD);
616
+ EXPECT_NEAR (desired_state_.velocity .value (), expected_velocity, COMMON_THRESHOLD);
617
+ EXPECT_NEAR (desired_state_.acceleration .value (), expected_acceleration, COMMON_THRESHOLD);
618
+ EXPECT_NEAR (desired_state_.jerk .value (), expected_jerk, COMMON_THRESHOLD);
619
+ };
620
+
621
+ // Test cases when there is no actual position and velocity
622
+ // Desired position and velocity affected due to the acceleration limits
623
+ test_limit_enforcing (std::nullopt, std::nullopt, 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , false );
624
+ test_limit_enforcing (std::nullopt, std::nullopt, 6.0 , 2.0 , 1.0 , 0.5 , 0.5 , 0.5 , 0.5 , 0.5 , true );
625
+ test_limit_enforcing (std::nullopt, std::nullopt, 6.0 , 2.0 , 1.0 , 0.5 , 1.0 , 1.0 , 0.5 , 0.5 , true );
626
+ test_limit_enforcing (std::nullopt, std::nullopt, 6.0 , 2.0 , 1.0 , 0.5 , 1.5 , 1.0 , 0.5 , 0.5 , true );
627
+ test_limit_enforcing (std::nullopt, std::nullopt, 6.0 , 2.0 , 1.0 , 0.5 , 2.0 , 1.0 , 0.5 , 0.5 , true );
628
+ test_limit_enforcing (std::nullopt, std::nullopt, 3.0 , 2.0 , 1.0 , 0.5 , 2.5 , 1.0 , 0.5 , 0.5 , true );
629
+ test_limit_enforcing (std::nullopt, std::nullopt, 3.0 , 2.0 , 1.0 , 0.5 , 3.0 , 1.0 , 0.5 , 0.5 , true );
630
+ test_limit_enforcing (std::nullopt, std::nullopt, 3.0 , 1.0 , 0.5 , 0.5 , 3.0 , 1.0 , 0.5 , 0.5 , false );
631
+
632
+ // Now enforce the limits with actual position and velocity
633
+ ASSERT_TRUE (Init (limits));
634
+ // Desired position and velocity affected due to the acceleration limits
635
+ test_limit_enforcing (0.5 , 0.0 , 6.0 , 0.0 , 0.0 , 0.0 , 1.0 , 0.0 , 0.0 , 0.0 , true );
636
+ test_limit_enforcing (1.0 , 0.0 , 6.0 , 0.0 , 0.0 , 0.0 , 1.5 , 0.0 , 0.0 , 0.0 , true );
637
+ test_limit_enforcing (1.0 , 0.0 , 6.0 , 0.0 , 0.0 , 0.0 , 2.0 , 0.0 , 0.0 , 0.0 , true );
638
+ test_limit_enforcing (1.0 , 0.0 , -6.0 , 0.0 , 0.0 , 0.0 , 1.5 , 0.0 , 0.0 , 0.0 , true );
639
+ test_limit_enforcing (2.0 , 0.0 , 6.0 , 2.0 , 1.0 , 0.5 , 2.0 , 0.5 , 0.5 , 0.5 , true );
640
+ test_limit_enforcing (2.0 , 0.5 , 6.0 , 2.0 , 1.0 , 0.5 , 3.0 , 1.0 , 0.5 , 0.5 , true );
641
+ test_limit_enforcing (3.0 , 0.5 , 6.0 , 2.0 , 1.0 , 0.5 , 4.0 , 1.0 , 0.5 , 0.5 , true );
642
+ test_limit_enforcing (4.0 , 0.5 , 6.0 , 2.0 , 1.0 , 0.5 , 5.0 , 1.0 , 0.5 , 0.5 , true );
643
+ test_limit_enforcing (5.0 , 0.5 , 6.0 , 2.0 , 1.0 , 0.5 , 5.0 , 0.0 , 0.5 , 0.5 , true );
644
+ }
645
+
557
646
int main (int argc, char ** argv)
558
647
{
559
648
::testing::InitGoogleTest (&argc, argv);
0 commit comments