test_producer.cpp
Go to the documentation of this file.
1 // -- BEGIN LICENSE BLOCK ----------------------------------------------
2 // Copyright 2022 Universal Robots A/S
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 //
14 // * Neither the name of the {copyright_holder} nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 // -- END LICENSE BLOCK ------------------------------------------------
30 
31 #include <gtest/gtest.h>
32 #include <chrono>
33 #include <condition_variable>
34 
39 
40 using namespace urcl;
41 
42 class ProducerTest : public ::testing::Test
43 {
44 protected:
45  void SetUp()
46  {
47  server_.reset(new comm::TCPServer(60002));
48  server_->setConnectCallback(std::bind(&ProducerTest::connectionCallback, this, std::placeholders::_1));
49  server_->start();
50  }
51 
52  void teardown()
53  {
54  // Clean up
55  server_.reset();
56  }
57 
58  void connectionCallback(const socket_t filedescriptor)
59  {
60  std::lock_guard<std::mutex> lk(connect_mutex_);
61  client_fd_ = filedescriptor;
62  connect_cv_.notify_one();
63  connection_callback_ = true;
64  }
65 
66  bool waitForConnectionCallback(int milliseconds = 100)
67  {
68  std::unique_lock<std::mutex> lk(connect_mutex_);
69  if (connect_cv_.wait_for(lk, std::chrono::milliseconds(milliseconds)) == std::cv_status::no_timeout ||
70  connection_callback_ == true)
71  {
72  connection_callback_ = false;
73  return true;
74  }
75  return false;
76  }
77 
78  std::unique_ptr<comm::TCPServer> server_;
80 
81 private:
82  std::condition_variable connect_cv_;
83  std::mutex connect_mutex_;
84 
85  bool connection_callback_ = false;
86 };
87 
88 TEST_F(ProducerTest, get_data_package)
89 {
90  comm::URStream<rtde_interface::RTDEPackage> stream("127.0.0.1", 60002);
91  std::vector<std::string> recipe = { "timestamp" };
92  rtde_interface::RTDEParser parser(recipe);
93  parser.setProtocolVersion(2);
94  comm::URProducer<rtde_interface::RTDEPackage> producer(stream, parser);
95 
96  producer.setupProducer();
97  waitForConnectionCallback();
98  producer.startProducer();
99 
100  // RTDE package with timestamp
101  uint8_t data_package[] = { 0x00, 0x0c, 0x55, 0x01, 0x40, 0xbb, 0xbf, 0xdb, 0xa5, 0xe3, 0x53, 0xf7 };
102  size_t written;
103  server_->write(client_fd_, data_package, sizeof(data_package), written);
104 
105  std::vector<std::unique_ptr<rtde_interface::RTDEPackage>> products;
106  EXPECT_EQ(producer.tryGet(products), true);
107 
108  if (rtde_interface::DataPackage* data = dynamic_cast<rtde_interface::DataPackage*>(products[0].get()))
109  {
110  double timestamp;
111  data->getData("timestamp", timestamp);
112  EXPECT_FLOAT_EQ(timestamp, 7103.86);
113  }
114  else
115  {
116  std::cout << "Failed to get data package" << std::endl;
117  GTEST_FAIL();
118  }
119 
120  producer.stopProducer();
121 }
122 
123 TEST_F(ProducerTest, connect_non_connected_robot)
124 {
125  comm::URStream<rtde_interface::RTDEPackage> stream("127.0.0.1", 12321);
126  std::vector<std::string> recipe = { "timestamp" };
127  rtde_interface::RTDEParser parser(recipe);
128  parser.setProtocolVersion(2);
129  comm::URProducer<rtde_interface::RTDEPackage> producer(stream, parser);
130 
131  auto start = std::chrono::system_clock::now();
132  EXPECT_THROW(producer.setupProducer(2, std::chrono::milliseconds(500)), UrException);
133  auto end = std::chrono::system_clock::now();
134  auto elapsed = end - start;
135  // This is only a rough estimate, obviously
136  EXPECT_LT(elapsed, std::chrono::milliseconds(7500));
137 }
138 
139 int main(int argc, char* argv[])
140 {
141  ::testing::InitGoogleTest(&argc, argv);
142 
143  return RUN_ALL_TESTS();
144 }
urcl::comm::URStream
The stream is an abstraction of the TCPSocket that offers reading a full UR data package out of the s...
Definition: stream.h:40
socket_t
int socket_t
Definition: socket_t.h:57
urcl::rtde_interface::DataPackage
The DataPackage class handles communication in the form of RTDE data packages both to and from the ro...
Definition: data_package.h:60
TEST_F
TEST_F(ProducerTest, get_data_package)
Definition: test_producer.cpp:88
urcl
Definition: bin_parser.h:36
ProducerTest::waitForConnectionCallback
bool waitForConnectionCallback(int milliseconds=100)
Definition: test_producer.cpp:66
urcl::rtde_interface::RTDEParser
The RTDE specific parser. Interprets a given byte stream as serialized RTDE packages and parses it ac...
Definition: rtde_parser.h:45
rtde_parser.h
ProducerTest::connectionCallback
void connectionCallback(const socket_t filedescriptor)
Definition: test_producer.cpp:58
urcl::comm::URProducer::setupProducer
void setupProducer(const size_t max_num_tries=0, const std::chrono::milliseconds reconnection_time=std::chrono::seconds(10)) override
Triggers the stream to connect to the robot.
Definition: producer.h:67
urcl::rtde_interface::RTDEParser::setProtocolVersion
void setProtocolVersion(uint16_t protocol_version)
Definition: rtde_parser.h:119
ProducerTest::teardown
void teardown()
Definition: test_producer.cpp:52
urcl::comm::URProducer
A general producer for URPackages. Implements funcionality to produce packages by reading and parsing...
Definition: producer.h:40
ProducerTest::server_
std::unique_ptr< comm::TCPServer > server_
Definition: test_producer.cpp:78
urcl::UrException
Our base class for exceptions. Specialized exceptions should inherit from those.
Definition: exceptions.h:53
ProducerTest
Definition: test_producer.cpp:42
urcl::comm::URProducer::startProducer
void startProducer() override
Definition: producer.h:94
producer.h
stream.h
urcl::comm::TCPServer
Wrapper class for a TCP socket server.
Definition: tcp_server.h:58
ProducerTest::SetUp
void SetUp()
Definition: test_producer.cpp:45
main
int main(int argc, char *argv[])
Definition: test_producer.cpp:139
urcl::comm::URProducer::tryGet
bool tryGet(std::vector< std::unique_ptr< T >> &products) override
Attempts to read byte stream from the robot and parse it as a URPackage.
Definition: producer.h:106
ProducerTest::connect_mutex_
std::mutex connect_mutex_
Definition: test_producer.cpp:83
ProducerTest::connect_cv_
std::condition_variable connect_cv_
Definition: test_producer.cpp:82
ProducerTest::client_fd_
socket_t client_fd_
Definition: test_producer.cpp:79
urcl::comm::URProducer::stopProducer
void stopProducer() override
Stops the producer. Currently no functionality needed.
Definition: producer.h:89
tcp_server.h


ur_client_library
Author(s): Thomas Timm Andersen, Simon Rasmussen, Felix Exner, Lea Steffen, Tristan Schnell
autogenerated on Mon May 26 2025 02:35:58