test_rtde_client.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // Copyright 2020 FZI Forschungszentrum Informatik
5 // Created on behalf of Universal Robots A/S
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 // -- END LICENSE BLOCK ------------------------------------------------
19 
20 //----------------------------------------------------------------------
27 //----------------------------------------------------------------------
28 
29 #include <gtest/gtest.h>
30 #include <cmath>
31 
33 
34 using namespace urcl;
35 
36 std::string ROBOT_IP = "192.168.56.101";
37 
38 class RTDEClientTest : public ::testing::Test
39 {
40 protected:
41  void SetUp()
42  {
43  client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_, output_recipe_, input_recipe_));
44  }
45 
46  void TearDown()
47  {
48  client_.reset();
49  // If we don't sleep we can get a conflict between two tests controlling the same rtde inputs
50  std::this_thread::sleep_for(std::chrono::seconds(1));
51  }
52 
53  std::string output_recipe_ = "resources/rtde_output_recipe.txt";
54  std::string input_recipe_ = "resources/rtde_input_recipe.txt";
56  std::unique_ptr<rtde_interface::RTDEClient> client_;
57 };
58 
59 TEST_F(RTDEClientTest, rtde_handshake)
60 {
61  EXPECT_TRUE(client_->init());
62 }
63 
65 {
66  std::string output_recipe = "";
67  std::string input_recipe = "";
68  EXPECT_THROW(client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_, output_recipe, input_recipe)),
69  UrException);
70 
71  // Only input recipe is unconfigured
72  EXPECT_THROW(client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_, output_recipe_, input_recipe)),
73  UrException);
74 }
75 
76 TEST_F(RTDEClientTest, empty_recipe)
77 {
78  std::string output_recipe = "resources/empty.txt";
79  std::string input_recipe = "resources/empty.txt";
80  client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_, output_recipe, input_recipe));
81 
82  EXPECT_THROW(client_->init(), UrException);
83 
84  // Only input recipe is empty
85  client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_, output_recipe_, input_recipe));
86 
87  EXPECT_THROW(client_->init(), UrException);
88 }
89 
90 TEST_F(RTDEClientTest, invalid_target_frequency)
91 {
92  // Setting target frequency below 0 or above 500, should throw an exception
93  client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_, output_recipe_, input_recipe_, -1.0));
94 
95  EXPECT_THROW(client_->init(), UrException);
96 
97  client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_, output_recipe_, input_recipe_, 1000));
98 
99  EXPECT_THROW(client_->init(), UrException);
100 }
101 
102 TEST_F(RTDEClientTest, unconfigured_target_frequency)
103 {
104  // When the target frequency is unconfigured, it should be zero before the client has been initialized
105  double expected_target_frequency = 0.0;
106  EXPECT_EQ(client_->getTargetFrequency(), expected_target_frequency);
107 
108  client_->init();
109 
110  // When the target frequency is unconfigured, it should be equal to the maximum frequency after initialization
111  EXPECT_EQ(client_->getTargetFrequency(), client_->getMaxFrequency());
112 }
113 
114 TEST_F(RTDEClientTest, set_target_frequency)
115 {
116  client_.reset(new rtde_interface::RTDEClient(ROBOT_IP, notifier_, output_recipe_, input_recipe_, 1));
117  client_->init();
118 
119  // Maximum frequency should still be equal to the robot's maximum frequency
120  if (client_->getVersion().major >= 5)
121  {
122  double expected_max_frequency = 500;
123  EXPECT_EQ(client_->getMaxFrequency(), expected_max_frequency);
124  }
125  else
126  {
127  double expected_max_frequency = 125;
128  EXPECT_EQ(client_->getMaxFrequency(), expected_max_frequency);
129  }
130 
131  double expected_target_frequency = 1;
132  EXPECT_EQ(client_->getTargetFrequency(), expected_target_frequency);
133 
134  EXPECT_TRUE(client_->start());
135 
136  // Test that we receive packages with a frequency of 2 Hz
137  const std::chrono::milliseconds read_timeout{ 10000 };
138  std::unique_ptr<rtde_interface::DataPackage> data_pkg = client_->getDataPackage(read_timeout);
139  if (data_pkg == nullptr)
140  {
141  std::cout << "Failed to get data package from robot" << std::endl;
142  GTEST_FAIL();
143  }
144 
145  double first_time_stamp = 0.0;
146  data_pkg->getData("timestamp", first_time_stamp);
147 
148  data_pkg = client_->getDataPackage(read_timeout);
149  if (data_pkg == nullptr)
150  {
151  std::cout << "Failed to get data package from robot" << std::endl;
152  GTEST_FAIL();
153  }
154 
155  double second_time_stamp = 0.0;
156  data_pkg->getData("timestamp", second_time_stamp);
157 
158  // There should be 1 second between each timestamp
159  EXPECT_EQ(second_time_stamp - first_time_stamp, 1);
160 
161  client_->pause();
162 }
163 
164 TEST_F(RTDEClientTest, start_uninitialized_client)
165 {
166  // It shouldn't be possible to start an uninitialized client
167  EXPECT_FALSE(client_->start());
168 }
169 
170 TEST_F(RTDEClientTest, start_client)
171 {
172  client_->init();
173  EXPECT_TRUE(client_->start());
174 
175  client_->pause();
176 
177  // We should be able to start the client again after it has been paused
178  EXPECT_TRUE(client_->start());
179 
180  client_->pause();
181 }
182 
183 TEST_F(RTDEClientTest, pause_client_before_it_was_started)
184 {
185  // We shouldn't be able to pause the client before it has been initialized
186  EXPECT_FALSE(client_->pause());
187 
188  // We shouldn't be able to pause the client after it has been initialized
189  client_->init();
190  EXPECT_FALSE(client_->pause());
191 }
192 
193 TEST_F(RTDEClientTest, pause_client)
194 {
195  client_->init();
196  client_->start();
197 
198  EXPECT_TRUE(client_->pause());
199 }
200 
201 TEST_F(RTDEClientTest, output_recipe)
202 {
203  std::vector<std::string> expected_output_recipe = { "timestamp",
204  "actual_q",
205  "actual_qd",
206  "speed_scaling",
207  "target_speed_fraction",
208  "runtime_state",
209  "actual_TCP_force",
210  "actual_TCP_pose",
211  "actual_digital_input_bits",
212  "actual_digital_output_bits",
213  "standard_analog_input0",
214  "standard_analog_input1",
215  "standard_analog_output0",
216  "standard_analog_output1",
217  "analog_io_types",
218  "tool_mode",
219  "tool_analog_input_types",
220  "tool_analog_input0",
221  "tool_analog_input1",
222  "tool_output_voltage",
223  "tool_output_current",
224  "tool_temperature",
225  "robot_mode",
226  "safety_mode",
227  "robot_status_bits",
228  "safety_status_bits",
229  "actual_current",
230  "tcp_offset" };
231 
232  std::vector<std::string> actual_output_recipe = client_->getOutputRecipe();
233  for (unsigned int i = 0; i < expected_output_recipe.size(); ++i)
234  {
235  EXPECT_EQ(expected_output_recipe[i], actual_output_recipe[i]);
236  }
237 }
238 
239 TEST_F(RTDEClientTest, get_data_package)
240 {
241  client_->init();
242  client_->start();
243 
244  // Test that we can receive a package and extract data from the received package
245  const std::chrono::milliseconds read_timeout{ 100 };
246  std::unique_ptr<rtde_interface::DataPackage> data_pkg = client_->getDataPackage(read_timeout);
247  if (data_pkg == nullptr)
248  {
249  std::cout << "Failed to get data package from robot" << std::endl;
250  GTEST_FAIL();
251  }
252 
253  urcl::vector6d_t actual_q;
254  EXPECT_TRUE(data_pkg->getData("actual_q", actual_q));
255 
256  client_->pause();
257 }
258 
259 TEST_F(RTDEClientTest, write_rtde_data)
260 {
261  client_->init();
262  client_->start();
263 
264  bool send_digital_output = true;
265  EXPECT_TRUE(client_->getWriter().sendStandardDigitalOutput(0, send_digital_output));
266 
267  // Make sure that the data has been written to the robot
268  const std::chrono::milliseconds read_timeout{ 100 };
269  std::unique_ptr<rtde_interface::DataPackage> data_pkg = client_->getDataPackage(read_timeout);
270  if (data_pkg == nullptr)
271  {
272  std::cout << "Failed to get data package from robot" << std::endl;
273  GTEST_FAIL();
274  }
275 
276  std::bitset<18> actual_dig_out_bits;
277  data_pkg->getData<uint64_t>("actual_digital_output_bits", actual_dig_out_bits);
278 
279  // If we get the data package to soon the digital output might not have been updated, therefore we get the package a
280  // couple of times
281  int max_tries = 100;
282  int counter = 0;
283  while (actual_dig_out_bits[0] != send_digital_output)
284  {
285  data_pkg = client_->getDataPackage(read_timeout);
286  data_pkg->getData<uint64_t>("actual_digital_output_bits", actual_dig_out_bits);
287  if (counter == max_tries)
288  {
289  break;
290  }
291  counter++;
292  }
293 
294  EXPECT_EQ(send_digital_output, actual_dig_out_bits[0]);
295 
296  client_->pause();
297 }
298 
299 int main(int argc, char* argv[])
300 {
301  ::testing::InitGoogleTest(&argc, argv);
302 
303  for (int i = 0; i < argc; i++)
304  {
305  if (std::string(argv[i]) == "--robot_ip" && i + 1 < argc)
306  {
307  ROBOT_IP = argv[i + 1];
308  break;
309  }
310  }
311 
312  return RUN_ALL_TESTS();
313 }
TEST_F(RTDEClientTest, rtde_handshake)
comm::INotifier notifier_
Parent class for notifiers.
Definition: pipeline.h:210
int main(int argc, char *argv[])
The RTDEClient class manages communication over the RTDE interface. It contains the RTDE handshake an...
Definition: rtde_client.h:92
std::array< double, 6 > vector6d_t
Definition: types.h:30
std::string ROBOT_IP
std::unique_ptr< rtde_interface::RTDEClient > client_
Our base class for exceptions. Specialized exceptions should inherit from those.
Definition: exceptions.h:41


ur_client_library
Author(s): Thomas Timm Andersen, Simon Rasmussen, Felix Exner, Lea Steffen, Tristan Schnell
autogenerated on Tue Jul 4 2023 02:09:47