35 namespace rtde_interface
38 const std::string& input_recipe_file,
double target_frequency)
40 , output_recipe_(readRecipe(output_recipe_file))
41 , input_recipe_(readRecipe(input_recipe_file))
42 , parser_(output_recipe_)
43 , prod_(stream_, parser_)
45 , writer_(&stream_, input_recipe_)
46 , max_frequency_(URE_MAX_FREQUENCY)
47 , target_frequency_(target_frequency)
64 unsigned int attempts = 0;
71 URCL_LOG_ERROR(
"Failed to initialize RTDE client, retrying in 10 seconds");
72 std::this_thread::sleep_for(std::chrono::seconds(10));
90 URCL_LOG_INFO(
"Robot did not accept RTDE protocol version '%hu'. Trying lower protocol version", protocol_version);
92 if (protocol_version == 0)
94 throw UrException(
"Protocol version for RTDE communication could not be established. Robot didn't accept any of " 95 "the suggested versions.");
101 URCL_LOG_INFO(
"Negotiated RTDE protocol version to %hu.", protocol_version);
118 else if (target_frequency_ <= 0.0 || target_frequency_ >
max_frequency_)
121 throw UrException(
"Invalid target frequency of RTDE connection");
147 unsigned int num_retries = 0;
148 uint8_t buffer[4096];
152 if (!
stream_.write(buffer, size, written))
154 URCL_LOG_ERROR(
"Sending protocol version query to robot failed, disconnecting");
161 std::unique_ptr<RTDEPackage> package;
162 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
164 URCL_LOG_ERROR(
"failed to get package from rtde interface, disconnecting");
169 dynamic_cast<rtde_interface::RequestProtocolVersion*>(package.get()))
173 return tmp_version->accepted_;
177 std::stringstream ss;
178 ss <<
"Did not receive protocol negotiation answer from robot. Message received instead: " << std::endl
179 << package->toString() <<
". Retrying...";
184 std::stringstream ss;
186 <<
" tries. Please check the output of the " 187 "negotiation attempts above to get a hint what could be wrong.";
193 unsigned int num_retries = 0;
194 uint8_t buffer[4096];
198 if (!
stream_.write(buffer, size, written))
200 URCL_LOG_ERROR(
"Sending urcontrol version query request to robot failed, disconnecting");
205 std::unique_ptr<RTDEPackage> package;
208 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
210 URCL_LOG_ERROR(
"No answer to urcontrol version query was received from robot, disconnecting");
216 dynamic_cast<rtde_interface::GetUrcontrolVersion*>(package.get()))
223 std::stringstream ss;
224 ss <<
"Did not receive protocol negotiation answer from robot. Message received instead: " << std::endl
225 << package->toString() <<
". Retrying...";
230 std::stringstream ss;
232 <<
" tries. Please check the output of the " 233 "negotiation attempts above to get a hint what could be wrong.";
239 unsigned int num_retries = 0;
242 uint8_t buffer[4096];
245 const std::string timestamp =
"timestamp";
251 if (protocol_version == 2)
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.");
266 if (!
stream_.write(buffer, size, written))
268 URCL_LOG_ERROR(
"Could not send RTDE output recipe to robot, disconnecting");
275 std::unique_ptr<RTDEPackage> package;
276 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
278 URCL_LOG_ERROR(
"Did not receive confirmation on RTDE output recipe, disconnecting");
284 dynamic_cast<rtde_interface::ControlPackageSetupOutputs*>(package.get()))
287 std::vector<std::string> variable_types =
splitVariableTypes(tmp_output->variable_types_);
289 for (std::size_t i = 0; i < variable_types.size(); ++i)
292 if (variable_types[i] ==
"NOT_FOUND")
295 "' not recognized by the robot. Probably your output recipe contains errors";
303 std::stringstream ss;
304 ss <<
"Did not receive answer to RTDE output setup. Message received instead: " << std::endl
305 << package->toString() <<
". Retrying...";
310 std::stringstream ss;
312 <<
" tries. Please check the output of the " 313 "negotiation attempts above to get a hint what could be wrong.";
319 unsigned int num_retries = 0;
322 uint8_t buffer[4096];
324 if (!
stream_.write(buffer, size, written))
326 URCL_LOG_ERROR(
"Could not send RTDE input recipe to robot, disconnecting");
333 std::unique_ptr<RTDEPackage> package;
334 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
336 URCL_LOG_ERROR(
"Did not receive confirmation on RTDE input recipe, disconnecting");
342 dynamic_cast<rtde_interface::ControlPackageSetupInputs*>(package.get()))
345 std::vector<std::string> variable_types =
splitVariableTypes(tmp_input->variable_types_);
347 for (std::size_t i = 0; i < variable_types.size(); ++i)
350 if (variable_types[i] ==
"NOT_FOUND")
353 "' not recognized by the robot. Probably your input recipe contains errors";
356 else if (variable_types[i] ==
"IN_USE")
359 "' is currently controlled by another RTDE client. The input recipe can't be used as " 370 std::stringstream ss;
371 ss <<
"Did not receive answer to RTDE input setup. Message received instead: " << std::endl
372 << package->toString() <<
". Retrying...";
377 std::stringstream ss;
379 <<
" tries. Please check the output of the " 380 "negotiation attempts above to get a hint what could be wrong.";
400 std::unique_ptr<RTDEPackage> package;
401 double timestamp = 0;
402 int reading_count = 0;
413 if (
pipeline_.getLatestProduct(package, std::chrono::milliseconds(timeout)))
416 tmp_input->
getData(
"timestamp", timestamp);
439 URCL_LOG_ERROR(
"Cannot start an unitialized client, please initialize it first");
462 URCL_LOG_ERROR(
"Can't pause the client, as it hasn't been started");
479 uint8_t buffer[4096];
483 if (!
stream_.write(buffer, size, written))
489 std::unique_ptr<RTDEPackage> package;
490 unsigned int num_retries = 0;
493 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
495 URCL_LOG_ERROR(
"Could not get response to RTDE communication start request from robot");
501 return tmp->accepted_;
505 std::stringstream ss;
506 ss <<
"Did not receive answer to RTDE start request. Message received instead: " << std::endl
507 << package->toString();
512 std::stringstream ss;
514 <<
" tries. Please check the output of the " 515 "negotiation attempts above to get a hint what could be wrong.";
521 uint8_t buffer[4096];
525 if (!
stream_.write(buffer, size, written))
530 std::unique_ptr<RTDEPackage> package;
531 std::chrono::time_point
start = std::chrono::steady_clock::now();
533 while (std::chrono::steady_clock::now() - start < std::chrono::seconds(seconds))
535 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
537 URCL_LOG_ERROR(
"Could not get response to RTDE communication pause request from robot");
543 return tmp->accepted_;
546 std::stringstream ss;
547 ss <<
"Could not receive answer to pause RTDE communication after " << seconds <<
" seconds.";
553 std::vector<std::string> recipe;
554 std::ifstream file(recipe_file);
557 std::stringstream msg;
558 msg <<
"Opening file '" << recipe_file <<
"' failed with error: " << strerror(errno);
563 while (std::getline(file, line))
565 recipe.push_back(line);
572 std::unique_ptr<RTDEPackage> urpackage;
573 if (
pipeline_.getLatestProduct(urpackage, timeout))
579 return std::unique_ptr<rtde_interface::DataPackage>(tmp);
582 return std::unique_ptr<rtde_interface::DataPackage>(
nullptr);
597 std::vector<std::string> result;
598 std::stringstream ss(variable_types);
599 std::string substr =
"";
600 while (getline(ss, substr,
','))
602 result.push_back(substr);
static const unsigned MAX_REQUEST_RETRIES
void setProtocolVersion(uint16_t protocol_version)
static size_t generateSerializedRequest(uint8_t *buffer, double output_frequency, std::vector< std::string > variable_names)
Generates a serialized package.
void init(uint8_t recipe_id)
Starts the writer thread, which periodically clears the queue to write packages to the robot...
std::vector< std::string > splitVariableTypes(const std::string &variable_types) const
Splits a variable_types string as reported from the robot into single variable type strings...
#define URCL_LOG_ERROR(...)
This class handles the robot's response to a requested start in RTDE data package communication...
RTDEWriter & getWriter()
Getter for the RTDE writer, which is used to send data via the RTDE interface to the robot...
std::string getIP() const
Returns the IP address (of the machine running this driver) used for the socket connection.
std::vector< std::string > output_recipe_
static constexpr const double CB3_MAX_FREQUENCY
std::vector< std::string > readRecipe(const std::string &recipe_file)
bool start()
Triggers the robot to start sending RTDE data packages in the negotiated format.
bool getData(const std::string &name, T &val)
Get a data field from the DataPackage.
ClientState client_state_
static size_t generateSerializedRequest(uint8_t *buffer, uint16_t version)
Generates a serialized package.
std::vector< std::string > input_recipe_
static const std::string PIPELINE_NAME
bool isRobotBooted()
Checks whether the robot is booted, this is done by looking at the timestamp from the robot controlle...
The RTDEWriter class offers an abstraction layer to send data to the robot via the RTDE interface...
void queryURControlVersion()
std::unique_ptr< rtde_interface::DataPackage > getDataPackage(std::chrono::milliseconds timeout)
Reads the pipeline to fetch the next data package.
This class handles the package detailing the UR control version sent by the robot.
static size_t generateSerializedRequest(uint8_t *buffer)
Generates a serialized package.
comm::Pipeline< RTDEPackage > pipeline_
Parent class for notifiers.
static size_t generateSerializedRequest(uint8_t *buffer)
Generates a serialized package.
#define URCL_LOG_DEBUG(...)
This class handles the robot's response to a requested stop in RTDE data package communication.
This class handles the robot's response to a requested output recipe setup.
static size_t generateSerializedRequest(uint8_t *buffer)
Generates a serialized package.
This class handles the robot's response after trying to set the used RTDE protocol version...
comm::URStream< RTDEPackage > stream_
#define URCL_LOG_WARN(...)
static const unsigned MAX_INITIALIZE_ATTEMPTS
bool negotiateProtocolVersion(const uint16_t protocol_version)
The DataPackage class handles communication in the form of RTDE data packages both to and from the ro...
bool init()
Sets up RTDE communication with the robot. The handshake includes negotiation of the used protocol ve...
static const uint16_t MAX_RTDE_PROTOCOL_VERSION
#define URCL_LOG_INFO(...)
void setupCommunication()
Our base class for exceptions. Specialized exceptions should inherit from those.
VersionInformation urcontrol_version_
bool pause()
Pauses RTDE data package communication.
void setupOutputs(const uint16_t protocol_version)
static const int UR_RTDE_PORT