Skip to content

Commit 1ed6576

Browse files
urmahpFelix Exner
andauthored
Added tests for the rtde interface clasess (#125)
* Added tests for the rtde interface clasess This adds tests for * control package pause * control package start * control package setup outputs * control package setup inputs * get urcontrol version * request protocol version * rtde writer Added more tests to * test_rtde_data_package * test_rtde_parser * test_rtde_client Added functionality to rtde_client * get_target_frequency function and warning when it is not possible to set target frequency * Read timeout in isRobotBooted is now based on target frequency * Added a wait on 5 seconds to receive answer from pause request. This will prevent the driver from crashing once in a while when pausing the rtde client Added functionality for rtde_writer * Added checks for values and pins before sending to the robot * Removed unnecessary sleep in desctructor Added pipeline changes, so that the test output is shown in the pipeline in case of failure Co-authored-by: Felix Exner <[email protected]>
1 parent 1d9b975 commit 1ed6576

16 files changed

+1636
-66
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
- name: build
3636
run: cmake --build build --config Debug
3737
- name: test
38-
run: cd build && make test
38+
run: cd build && ctest --output-on-failure
3939
- name: install gcovr
4040
run: sudo apt-get install -y gcovr
4141
- name: gcovr

include/ur_client_library/rtde/rtde_client.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class RTDEClient
122122
/*!
123123
* \brief Pauses RTDE data package communication
124124
*
125-
* \returns Wheter the RTDE data package communication was paussed succesfully
125+
* \returns Whether the RTDE data package communication was paused successfully
126126
*/
127127
bool pause();
128128
/*!
@@ -135,15 +135,25 @@ class RTDEClient
135135
std::unique_ptr<rtde_interface::DataPackage> getDataPackage(std::chrono::milliseconds timeout);
136136

137137
/*!
138-
* \brief Getter for the frequency the robot will publish RTDE data packages with.
138+
* \brief Getter for the maximum frequency the robot can publish RTDE data packages with.
139139
*
140-
* \returns The used frequency
140+
* \returns The maximum frequency
141141
*/
142142
double getMaxFrequency() const
143143
{
144144
return max_frequency_;
145145
}
146146

147+
/*!
148+
* \brief Getter for the target frequency that the robot will publish RTDE data packages with.
149+
*
150+
* \returns The target frequency
151+
*/
152+
double getTargetFrequency() const
153+
{
154+
return target_frequency_;
155+
}
156+
147157
/*!
148158
* \brief Getter for the UR control version received from the robot.
149159
*
@@ -208,7 +218,7 @@ class RTDEClient
208218
void disconnect();
209219

210220
/*!
211-
* \brief Checks wheter the robot is booted, this is done by looking at the timestamp from the robot controller, this
221+
* \brief Checks whether the robot is booted, this is done by looking at the timestamp from the robot controller, this
212222
* will show the time in seconds since the controller was started. If the timestamp is below 40, we will read from
213223
* the stream for approximately 1 second to ensure that the RTDE interface is up and running. This will ensure that we
214224
* don't finalize setting up communication, before the controller is up and running. Else we could end up connecting

include/ur_client_library/rtde/rtde_writer.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ class RTDEWriter
6161
~RTDEWriter()
6262
{
6363
running_ = false;
64-
std::this_thread::sleep_for(std::chrono::seconds(5));
6564
if (writer_thread_.joinable())
6665
{
6766
writer_thread_.join();
@@ -118,7 +117,7 @@ class RTDEWriter
118117
* \brief Creates a package to request setting a new value for one of the standard analog output pins.
119118
*
120119
* \param output_pin The pin to change
121-
* \param value The new value
120+
* \param value The new value, it should be between 0 and 1, where 0 is 4mA and 1 is 20mA.
122121
*
123122
* \returns Success of the package creation
124123
*/

src/rtde/rtde_client.cpp

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,11 @@ void RTDEClient::setupOutputs(const uint16_t protocol_version)
254254
}
255255
else
256256
{
257+
if (target_frequency_ != max_frequency_)
258+
{
259+
URCL_LOG_WARN("It is not possible to set a target frequency when using protocol version 1. A frequency "
260+
"equivalent to the maximum frequency will be used instead.");
261+
}
257262
size = ControlPackageSetupOutputsRequest::generateSerializedRequest(buffer, output_recipe_);
258263
}
259264

@@ -403,7 +408,9 @@ bool RTDEClient::isRobotBooted()
403408

404409
while (timestamp < 40 && reading_count < target_frequency_ * 2)
405410
{
406-
if (pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
411+
// Set timeout based on target frequency, to make sure that reading doesn't timeout
412+
int timeout = static_cast<int>((1 / target_frequency_) * 1000) * 10;
413+
if (pipeline_.getLatestProduct(package, std::chrono::milliseconds(timeout)))
407414
{
408415
rtde_interface::DataPackage* tmp_input = dynamic_cast<rtde_interface::DataPackage*>(package.get());
409416
tmp_input->getData("timestamp", timestamp);
@@ -520,35 +527,24 @@ bool RTDEClient::sendPause()
520527
URCL_LOG_ERROR("Sending RTDE pause command failed!");
521528
return false;
522529
}
523-
static unsigned num_retries = 0;
524-
while (num_retries < MAX_REQUEST_RETRIES)
530+
std::unique_ptr<RTDEPackage> package;
531+
std::chrono::time_point start = std::chrono::steady_clock::now();
532+
int seconds = 5;
533+
while (std::chrono::steady_clock::now() - start < std::chrono::seconds(seconds))
525534
{
526-
std::unique_ptr<RTDEPackage> package;
527-
528535
if (!pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
529536
{
530537
URCL_LOG_ERROR("Could not get response to RTDE communication pause request from robot");
531538
return false;
532539
}
533-
534540
if (rtde_interface::ControlPackagePause* tmp = dynamic_cast<rtde_interface::ControlPackagePause*>(package.get()))
535541
{
536542
client_state_ = ClientState::PAUSED;
537543
return tmp->accepted_;
538544
}
539-
else
540-
{
541-
std::stringstream ss;
542-
ss << "Did not receive answer to RTDE pause request. Message received instead: " << std::endl
543-
<< package->toString();
544-
URCL_LOG_WARN("%s", ss.str().c_str());
545-
num_retries++;
546-
}
547545
}
548546
std::stringstream ss;
549-
ss << "Could not pause RTDE communication after " << MAX_REQUEST_RETRIES
550-
<< " tries. Please check the output of the "
551-
"negotiation attempts above to get a hint what could be wrong.";
547+
ss << "Could not receive answer to pause RTDE communication after " << seconds << " seconds.";
552548
throw UrException(ss.str());
553549
}
554550

src/rtde/rtde_writer.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ void RTDEWriter::run()
6565

6666
bool RTDEWriter::sendSpeedSlider(double speed_slider_fraction)
6767
{
68+
if (speed_slider_fraction > 1.0 || speed_slider_fraction < 0.0)
69+
{
70+
std::stringstream ss;
71+
ss << "Speed slider fraction should be between 0 and 1. The speed slider fraction is "
72+
<< static_cast<int>(speed_slider_fraction);
73+
URCL_LOG_ERROR(ss.str().c_str());
74+
return false;
75+
}
76+
6877
std::lock_guard<std::mutex> guard(package_mutex_);
6978
uint32_t mask = 1;
7079
bool success = true;
@@ -85,6 +94,14 @@ bool RTDEWriter::sendSpeedSlider(double speed_slider_fraction)
8594

8695
bool RTDEWriter::sendStandardDigitalOutput(uint8_t output_pin, bool value)
8796
{
97+
if (output_pin > 7)
98+
{
99+
std::stringstream ss;
100+
ss << "Standard digital output pins goes from 0 to 7. The output pin to change is " << static_cast<int>(output_pin);
101+
URCL_LOG_ERROR(ss.str().c_str());
102+
return false;
103+
}
104+
88105
std::lock_guard<std::mutex> guard(package_mutex_);
89106
uint8_t mask = pinToMask(output_pin);
90107
bool success = true;
@@ -114,6 +131,15 @@ bool RTDEWriter::sendStandardDigitalOutput(uint8_t output_pin, bool value)
114131

115132
bool RTDEWriter::sendConfigurableDigitalOutput(uint8_t output_pin, bool value)
116133
{
134+
if (output_pin > 7)
135+
{
136+
std::stringstream ss;
137+
ss << "Configurable digital output pins goes from 0 to 7. The output pin to change is "
138+
<< static_cast<int>(output_pin);
139+
URCL_LOG_ERROR(ss.str().c_str());
140+
return false;
141+
}
142+
117143
std::lock_guard<std::mutex> guard(package_mutex_);
118144
uint8_t mask = pinToMask(output_pin);
119145
bool success = true;
@@ -143,6 +169,14 @@ bool RTDEWriter::sendConfigurableDigitalOutput(uint8_t output_pin, bool value)
143169

144170
bool RTDEWriter::sendToolDigitalOutput(uint8_t output_pin, bool value)
145171
{
172+
if (output_pin > 1)
173+
{
174+
std::stringstream ss;
175+
ss << "Tool digital output pins goes from 0 to 1. The output pin to change is " << static_cast<int>(output_pin);
176+
URCL_LOG_ERROR(ss.str().c_str());
177+
return false;
178+
}
179+
146180
std::lock_guard<std::mutex> guard(package_mutex_);
147181
uint8_t mask = pinToMask(output_pin);
148182
bool success = true;
@@ -172,6 +206,21 @@ bool RTDEWriter::sendToolDigitalOutput(uint8_t output_pin, bool value)
172206

173207
bool RTDEWriter::sendStandardAnalogOutput(uint8_t output_pin, double value)
174208
{
209+
if (output_pin > 1)
210+
{
211+
std::stringstream ss;
212+
ss << "Standard analog output goes from 0 to 1. The output pin to change is " << static_cast<int>(output_pin);
213+
URCL_LOG_ERROR(ss.str().c_str());
214+
return false;
215+
}
216+
if (value > 1.0 || value < 0.0)
217+
{
218+
std::stringstream ss;
219+
ss << "Analog output value should be between 0 and 1. The value is " << static_cast<int>(value);
220+
URCL_LOG_ERROR(ss.str().c_str());
221+
return false;
222+
}
223+
175224
std::lock_guard<std::mutex> guard(package_mutex_);
176225
uint8_t mask = pinToMask(output_pin);
177226
// default to current for now, as no functionality to choose included in set io service
@@ -206,6 +255,14 @@ uint8_t RTDEWriter::pinToMask(uint8_t pin)
206255

207256
bool RTDEWriter::sendInputBitRegister(uint32_t register_id, bool value)
208257
{
258+
if (register_id < 64 || register_id > 127)
259+
{
260+
std::stringstream ss;
261+
ss << "Input bit register goes from 64 to 127. The register id to change is " << static_cast<int>(register_id);
262+
URCL_LOG_ERROR(ss.str().c_str());
263+
return false;
264+
}
265+
209266
std::lock_guard<std::mutex> guard(package_mutex_);
210267
std::stringstream ss;
211268
ss << "input_bit_register_" << register_id;
@@ -224,6 +281,14 @@ bool RTDEWriter::sendInputBitRegister(uint32_t register_id, bool value)
224281

225282
bool RTDEWriter::sendInputIntRegister(uint32_t register_id, int32_t value)
226283
{
284+
if (register_id < 24 || register_id > 47)
285+
{
286+
std::stringstream ss;
287+
ss << "Input int register goes from 24 to 47. The register id to change is " << static_cast<int>(register_id);
288+
URCL_LOG_ERROR(ss.str().c_str());
289+
return false;
290+
}
291+
227292
std::lock_guard<std::mutex> guard(package_mutex_);
228293
std::stringstream ss;
229294
ss << "input_int_register_" << register_id;
@@ -242,6 +307,14 @@ bool RTDEWriter::sendInputIntRegister(uint32_t register_id, int32_t value)
242307

243308
bool RTDEWriter::sendInputDoubleRegister(uint32_t register_id, double value)
244309
{
310+
if (register_id < 24 || register_id > 47)
311+
{
312+
std::stringstream ss;
313+
ss << "Input double register goes from 24 to 47. The register id to change is " << static_cast<int>(register_id);
314+
URCL_LOG_ERROR(ss.str().c_str());
315+
return false;
316+
}
317+
245318
std::lock_guard<std::mutex> guard(package_mutex_);
246319
std::stringstream ss;
247320
ss << "input_double_register_" << register_id;

tests/CMakeLists.txt

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ target_link_libraries(primary_parser_tests PRIVATE ur_client_library::urcl ${GTE
4848
gtest_add_tests(TARGET primary_parser_tests
4949
)
5050

51-
add_executable(rtde_data_package test_rtde_data_package.cpp)
52-
target_compile_options(rtde_data_package PRIVATE ${CXX17_FLAG})
53-
target_include_directories(rtde_data_package PRIVATE ${GTEST_INCLUDE_DIRS})
54-
target_link_libraries(rtde_data_package PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
55-
gtest_add_tests(TARGET rtde_data_package
51+
add_executable(rtde_data_package_tests test_rtde_data_package.cpp)
52+
target_compile_options(rtde_data_package_tests PRIVATE ${CXX17_FLAG})
53+
target_include_directories(rtde_data_package_tests PRIVATE ${GTEST_INCLUDE_DIRS})
54+
target_link_libraries(rtde_data_package_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
55+
gtest_add_tests(TARGET rtde_data_package_tests
5656
)
5757

5858
add_executable(rtde_parser_tests test_rtde_parser.cpp)
@@ -89,3 +89,53 @@ target_include_directories(trajectory_point_interface_tests PRIVATE ${GTEST_INCL
8989
target_link_libraries(trajectory_point_interface_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
9090
gtest_add_tests(TARGET trajectory_point_interface_tests
9191
)
92+
93+
add_executable(rtde_control_package_pause_tests test_rtde_control_package_pause.cpp)
94+
target_compile_options(rtde_control_package_pause_tests PRIVATE ${CXX17_FLAG})
95+
target_include_directories(rtde_control_package_pause_tests PRIVATE ${GTEST_INCLUDE_DIRS})
96+
target_link_libraries(rtde_control_package_pause_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
97+
gtest_add_tests(TARGET rtde_control_package_pause_tests
98+
)
99+
100+
add_executable(rtde_control_package_start_tests test_rtde_control_package_start.cpp)
101+
target_compile_options(rtde_control_package_start_tests PRIVATE ${CXX17_FLAG})
102+
target_include_directories(rtde_control_package_start_tests PRIVATE ${GTEST_INCLUDE_DIRS})
103+
target_link_libraries(rtde_control_package_start_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
104+
gtest_add_tests(TARGET rtde_control_package_start_tests
105+
)
106+
107+
add_executable(rtde_control_package_setup_outputs_tests test_rtde_control_package_setup_outputs.cpp)
108+
target_compile_options(rtde_control_package_setup_outputs_tests PRIVATE ${CXX17_FLAG})
109+
target_include_directories(rtde_control_package_setup_outputs_tests PRIVATE ${GTEST_INCLUDE_DIRS})
110+
target_link_libraries(rtde_control_package_setup_outputs_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
111+
gtest_add_tests(TARGET rtde_control_package_setup_outputs_tests
112+
)
113+
114+
add_executable(rtde_control_package_setup_inputs_tests test_rtde_control_package_setup_inputs.cpp)
115+
target_compile_options(rtde_control_package_setup_inputs_tests PRIVATE ${CXX17_FLAG})
116+
target_include_directories(rtde_control_package_setup_inputs_tests PRIVATE ${GTEST_INCLUDE_DIRS})
117+
target_link_libraries(rtde_control_package_setup_inputs_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
118+
gtest_add_tests(TARGET rtde_control_package_setup_inputs_tests
119+
)
120+
121+
add_executable(rtde_get_urcontrol_version_tests test_rtde_get_urcontrol_version.cpp)
122+
target_compile_options(rtde_get_urcontrol_version_tests PRIVATE ${CXX17_FLAG})
123+
target_include_directories(rtde_get_urcontrol_version_tests PRIVATE ${GTEST_INCLUDE_DIRS})
124+
target_link_libraries(rtde_get_urcontrol_version_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
125+
gtest_add_tests(TARGET rtde_get_urcontrol_version_tests
126+
)
127+
128+
add_executable(rtde_request_protocol_version_tests test_rtde_request_protocol_version.cpp)
129+
target_compile_options(rtde_request_protocol_version_tests PRIVATE ${CXX17_FLAG})
130+
target_include_directories(rtde_request_protocol_version_tests PRIVATE ${GTEST_INCLUDE_DIRS})
131+
target_link_libraries(rtde_request_protocol_version_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
132+
gtest_add_tests(TARGET rtde_request_protocol_version_tests
133+
)
134+
135+
add_executable(rtde_writer_tests test_rtde_writer.cpp)
136+
target_compile_options(rtde_writer_tests PRIVATE ${CXX17_FLAG})
137+
target_include_directories(rtde_writer_tests PRIVATE ${GTEST_INCLUDE_DIRS})
138+
target_link_libraries(rtde_writer_tests PRIVATE ur_client_library::urcl ${GTEST_LIBRARIES})
139+
gtest_add_tests(TARGET rtde_writer_tests
140+
)
141+

0 commit comments

Comments
 (0)