36
36
#include < ur_client_library/ur/ur_driver.h>
37
37
#include < ur_client_library/types.h>
38
38
39
+ #include < chrono>
39
40
#include < iostream>
40
41
#include < memory>
41
42
#include < math.h>
@@ -56,10 +57,15 @@ bool g_HEADLESS = true;
56
57
std::unique_ptr<ExampleRobotWrapper> g_my_robot;
57
58
58
59
bool g_trajectory_running;
60
+ std::condition_variable g_trajectory_result_cv;
61
+ std::mutex g_trajectory_result_mutex;
59
62
control::TrajectoryResult g_trajectory_result;
60
63
void handleTrajectoryState (control::TrajectoryResult state)
61
64
{
65
+ std::lock_guard<std::mutex> lk (g_trajectory_result_mutex);
66
+ g_trajectory_result_cv.notify_one ();
62
67
g_trajectory_result = state;
68
+ URCL_LOG_INFO (" Received trajectory result %s" , control::trajectoryResultToString (state).c_str ());
63
69
g_trajectory_running = false ;
64
70
}
65
71
@@ -74,6 +80,12 @@ bool nearlyEqual(double a, double b, double eps = 1e-15)
74
80
return c < eps || -c < eps;
75
81
}
76
82
83
+ bool waitForTrajectoryResult (std::chrono::milliseconds timeout)
84
+ {
85
+ std::unique_lock<std::mutex> lk (g_trajectory_result_mutex);
86
+ return g_trajectory_result_cv.wait_for (lk, timeout) == std::cv_status::no_timeout;
87
+ }
88
+
77
89
class SplineInterpolationTest : public ::testing::Test
78
90
{
79
91
protected:
@@ -1094,6 +1106,52 @@ TEST_F(SplineInterpolationTest, physically_unfeasible_trajectory_quintic_spline)
1094
1106
}
1095
1107
}
1096
1108
1109
+ TEST_F (SplineInterpolationTest, switching_control_mode_without_trajectory_produces_no_result)
1110
+ {
1111
+ // We start by putting the robot into trajectory control mode
1112
+ ASSERT_TRUE (
1113
+ g_my_robot->ur_driver_ ->writeTrajectoryControlMessage (urcl::control::TrajectoryControlMessage::TRAJECTORY_NOOP));
1114
+
1115
+ // Then we switch to idle
1116
+ ASSERT_TRUE (g_my_robot->ur_driver_ ->writeKeepalive (RobotReceiveTimeout::sec (2 )));
1117
+
1118
+ EXPECT_FALSE (waitForTrajectoryResult (std::chrono::milliseconds (500 )));
1119
+ }
1120
+
1121
+ TEST_F (SplineInterpolationTest, switching_control_mode_with_trajectory_produces_result)
1122
+ {
1123
+ g_my_robot->stopConsumingRTDEData ();
1124
+ std::unique_ptr<rtde_interface::DataPackage> data_pkg;
1125
+ g_my_robot->readDataPackage (data_pkg);
1126
+
1127
+ urcl::vector6d_t joint_positions_before;
1128
+ ASSERT_TRUE (data_pkg->getData (" target_q" , joint_positions_before));
1129
+
1130
+ // Start consuming rtde packages to avoid pipeline overflows while testing that the control script aborts correctly
1131
+ g_my_robot->startConsumingRTDEData ();
1132
+ // Create a trajectory that cannot be executed within the robots limits
1133
+ std::vector<urcl::vector6d_t > s_pos, s_vel, s_acc;
1134
+ urcl::vector6d_t first_point = {
1135
+ joint_positions_before[0 ], joint_positions_before[1 ], joint_positions_before[2 ],
1136
+ joint_positions_before[3 ], joint_positions_before[4 ], joint_positions_before[5 ] + 0.5
1137
+ };
1138
+ s_pos.push_back (first_point);
1139
+
1140
+ urcl::vector6d_t zeros = { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 };
1141
+ s_vel.push_back (zeros);
1142
+ s_acc.push_back (zeros);
1143
+
1144
+ std::vector<double > s_time = { 0.02 };
1145
+ sendTrajectory (s_pos, s_vel, s_acc, s_time);
1146
+ g_my_robot->ur_driver_ ->writeTrajectoryControlMessage (urcl::control::TrajectoryControlMessage::TRAJECTORY_NOOP, -1 ,
1147
+ RobotReceiveTimeout::off ());
1148
+
1149
+ // Then we switch to idle
1150
+ ASSERT_TRUE (g_my_robot->ur_driver_ ->writeKeepalive (RobotReceiveTimeout::sec (2 )));
1151
+
1152
+ EXPECT_TRUE (waitForTrajectoryResult (std::chrono::milliseconds (500 )));
1153
+ }
1154
+
1097
1155
int main (int argc, char * argv[])
1098
1156
{
1099
1157
::testing::InitGoogleTest (&argc, argv);
0 commit comments