33 namespace rtde_interface
36 const std::string& input_recipe_file)
38 , output_recipe_(readRecipe(output_recipe_file))
39 , input_recipe_(readRecipe(input_recipe_file))
40 , parser_(output_recipe_)
41 , prod_(stream_, parser_)
43 , writer_(&stream_, input_recipe_)
44 , max_frequency_(URE_MAX_FREQUENCY)
62 URCL_LOG_INFO(
"Robot did not accept RTDE protocol version '%hu'. Trying lower protocol version", protocol_version);
64 if (protocol_version == 0)
66 throw UrException(
"Protocol version for RTDE communication could not be established. Robot didn't accept any of " 67 "the suggested versions.");
70 URCL_LOG_INFO(
"Negotiated RTDE protocol version to %hu.", protocol_version);
91 static unsigned num_retries = 0;
96 if (!
stream_.write(buffer, size, written))
97 throw UrException(
"Sending protocol version query to robot failed.");
99 std::unique_ptr<RTDEPackage> package;
102 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
104 throw UrException(
"No answer to RTDE protocol version negotiation request was received from robot. This should " 110 dynamic_cast<rtde_interface::RequestProtocolVersion*>(package.get()))
114 return tmp_version->accepted_;
118 std::stringstream ss;
119 ss <<
"Did not receive protocol negotiation answer from robot. Message received instead: " << std::endl
120 << package->toString() <<
". Retrying...";
125 std::stringstream ss;
127 <<
" tries. Please check the output of the " 128 "negotiation attempts above to get a hint what could be wrong.";
134 static unsigned num_retries = 0;
135 uint8_t buffer[4096];
139 if (!
stream_.write(buffer, size, written))
140 throw UrException(
"Sending urcontrol version query request to robot failed.");
142 std::unique_ptr<RTDEPackage> package;
145 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
146 throw UrException(
"No answer to urcontrol version query was received from robot. This should not happen!");
149 dynamic_cast<rtde_interface::GetUrcontrolVersion*>(package.get()))
156 std::stringstream ss;
157 ss <<
"Did not receive protocol negotiation answer from robot. Message received instead: " << std::endl
158 << package->toString() <<
". Retrying...";
163 std::stringstream ss;
165 <<
" tries. Please check the output of the " 166 "negotiation attempts above to get a hint what could be wrong.";
172 static unsigned num_retries = 0;
175 uint8_t buffer[4096];
177 if (protocol_version == 2)
187 if (!
stream_.write(buffer, size, written))
188 throw UrException(
"Could not send RTDE output recipe to robot.");
190 std::unique_ptr<RTDEPackage> package;
193 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
195 throw UrException(
"Did not receive confirmation on RTDE output recipe.");
199 dynamic_cast<rtde_interface::ControlPackageSetupOutputs*>(package.get()))
202 std::vector<std::string> variable_types =
splitVariableTypes(tmp_output->variable_types_);
204 for (std::size_t i = 0; i < variable_types.size(); ++i)
207 if (variable_types[i] ==
"NOT_FOUND")
210 "' not recognized by the robot. Probably your output recipe contains errors";
218 std::stringstream ss;
219 ss <<
"Did not receive answer to RTDE output setup. Message received instead: " << std::endl
220 << package->toString() <<
". Retrying...";
225 std::stringstream ss;
227 <<
" tries. Please check the output of the " 228 "negotiation attempts above to get a hint what could be wrong.";
234 static unsigned num_retries = 0;
237 uint8_t buffer[4096];
239 if (!
stream_.write(buffer, size, written))
240 throw UrException(
"Could not send RTDE input recipe to robot.");
242 std::unique_ptr<RTDEPackage> package;
245 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
246 throw UrException(
"Did not receive confirmation on RTDE input recipe.");
249 dynamic_cast<rtde_interface::ControlPackageSetupInputs*>(package.get()))
252 std::vector<std::string> variable_types =
splitVariableTypes(tmp_input->variable_types_);
254 for (std::size_t i = 0; i < variable_types.size(); ++i)
257 if (variable_types[i] ==
"NOT_FOUND")
260 "' not recognized by the robot. Probably your input recipe contains errors";
263 else if (variable_types[i] ==
"IN_USE")
266 "' is currently controlled by another RTDE client. The input recipe can't be used as " 278 std::stringstream ss;
279 ss <<
"Did not receive answer to RTDE input setup. Message received instead: " << std::endl
280 << package->toString() <<
". Retrying...";
285 std::stringstream ss;
287 <<
" tries. Please check the output of the " 288 "negotiation attempts above to get a hint what could be wrong.";
294 static unsigned num_retries = 0;
295 uint8_t buffer[4096];
300 std::unique_ptr<RTDEPackage> package;
301 if (!
stream_.write(buffer, size, written))
302 throw UrException(
"Sending RTDE start command failed!");
305 if (!
pipeline_.getLatestProduct(package, std::chrono::milliseconds(1000)))
306 throw UrException(
"Could not get response to RTDE communication start request from robot. This should not " 310 return tmp->accepted_;
314 std::stringstream ss;
315 ss <<
"Did not receive answer to RTDE start request. Message received instead: " << std::endl
316 << package->toString() <<
". Retrying...";
320 std::stringstream ss;
322 <<
" tries. Please check the output of the " 323 "negotiation attempts above to get a hint what could be wrong.";
329 std::vector<std::string> recipe;
330 std::ifstream file(recipe_file);
333 std::stringstream msg;
334 msg <<
"Opening file '" << recipe_file <<
"' failed with error: " << strerror(errno);
339 while (std::getline(file, line))
341 recipe.push_back(line);
348 std::unique_ptr<RTDEPackage> urpackage;
349 if (
pipeline_.getLatestProduct(urpackage, timeout))
355 return std::unique_ptr<rtde_interface::DataPackage>(tmp);
358 return std::unique_ptr<rtde_interface::DataPackage>(
nullptr);
373 std::vector<std::string> result;
374 std::stringstream ss(variable_types);
375 std::string substr =
"";
376 while (getline(ss, substr,
','))
378 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...
#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::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.
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...
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
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.
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 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(...)
bool negotiateProtocolVersion(const uint16_t protocol_version)
std::string getIP() const
Returns the IP address (of the machine running this driver) used for the socket connection.
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(...)
Our base class for exceptions. Specialized exceptions should inherit from those.
VersionInformation urcontrol_version_
void setupOutputs(const uint16_t protocol_version)
static const int UR_RTDE_PORT