@@ -40,8 +40,9 @@ RTDEClient::RTDEClient(std::string robot_ip, comm::INotifier& notifier, const st
4040 , output_recipe_(ensureTimestampIsPresent(readRecipe(output_recipe_file)))
4141 , input_recipe_(readRecipe(input_recipe_file))
4242 , parser_(output_recipe_)
43- , prod_(stream_, parser_)
44- , pipeline_(prod_, PIPELINE_NAME, notifier, true )
43+ , prod_(std::make_unique<comm::URProducer<RTDEPackage>>(stream_, parser_))
44+ , notifier_(notifier)
45+ , pipeline_(std::make_unique<comm::Pipeline<RTDEPackage>>(*prod_, PIPELINE_NAME, notifier, true ))
4546 , writer_(&stream_, input_recipe_)
4647 , max_frequency_(URE_MAX_FREQUENCY)
4748 , target_frequency_(target_frequency)
@@ -55,8 +56,9 @@ RTDEClient::RTDEClient(std::string robot_ip, comm::INotifier& notifier, const st
5556 , output_recipe_(ensureTimestampIsPresent(output_recipe))
5657 , input_recipe_(input_recipe)
5758 , parser_(output_recipe_)
58- , prod_(stream_, parser_)
59- , pipeline_(prod_, PIPELINE_NAME, notifier, true )
59+ , prod_(std::make_unique<comm::URProducer<RTDEPackage>>(stream_, parser_))
60+ , notifier_(notifier)
61+ , pipeline_(std::make_unique<comm::Pipeline<RTDEPackage>>(*prod_, PIPELINE_NAME, notifier, true ))
6062 , writer_(&stream_, input_recipe_)
6163 , max_frequency_(URE_MAX_FREQUENCY)
6264 , target_frequency_(target_frequency)
@@ -83,8 +85,8 @@ bool RTDEClient::init(const size_t max_num_tries, const std::chrono::millisecond
8385 if (client_state_ == ClientState::INITIALIZED)
8486 return true ;
8587
86- URCL_LOG_ERROR (" Failed to initialize RTDE client, retrying in 10 seconds" );
87- std::this_thread::sleep_for (std::chrono::seconds (10 ));
88+ URCL_LOG_ERROR (" Failed to initialize RTDE client, retrying in 1 seconds" );
89+ std::this_thread::sleep_for (std::chrono::seconds (1 ));
8890 attempts++;
8991 }
9092 std::stringstream ss;
@@ -96,8 +98,8 @@ void RTDEClient::setupCommunication(const size_t max_num_tries, const std::chron
9698{
9799 client_state_ = ClientState::INITIALIZING;
98100 // A running pipeline is needed inside setup
99- pipeline_. init (max_num_tries, reconnection_time);
100- pipeline_. run ();
101+ pipeline_-> init (max_num_tries, reconnection_time);
102+ pipeline_-> run ();
101103
102104 uint16_t protocol_version = MAX_RTDE_PROTOCOL_VERSION;
103105 while (!negotiateProtocolVersion (protocol_version) && client_state_ == ClientState::INITIALIZING)
@@ -151,7 +153,7 @@ void RTDEClient::setupCommunication(const size_t max_num_tries, const std::chron
151153 return ;
152154
153155 // We finished communication for now
154- pipeline_. stop ();
156+ pipeline_-> stop ();
155157 client_state_ = ClientState::INITIALIZED;
156158}
157159
@@ -174,7 +176,7 @@ bool RTDEClient::negotiateProtocolVersion(const uint16_t protocol_version)
174176 while (num_retries < MAX_REQUEST_RETRIES)
175177 {
176178 std::unique_ptr<RTDEPackage> package;
177- if (!pipeline_. getLatestProduct (package, std::chrono::milliseconds (1000 )))
179+ if (!pipeline_-> getLatestProduct (package, std::chrono::milliseconds (1000 )))
178180 {
179181 URCL_LOG_ERROR (" failed to get package from rtde interface, disconnecting" );
180182 disconnect ();
@@ -220,7 +222,7 @@ void RTDEClient::queryURControlVersion()
220222 std::unique_ptr<RTDEPackage> package;
221223 while (num_retries < MAX_REQUEST_RETRIES)
222224 {
223- if (!pipeline_. getLatestProduct (package, std::chrono::milliseconds (1000 )))
225+ if (!pipeline_-> getLatestProduct (package, std::chrono::milliseconds (1000 )))
224226 {
225227 URCL_LOG_ERROR (" No answer to urcontrol version query was received from robot, disconnecting" );
226228 disconnect ();
@@ -249,39 +251,51 @@ void RTDEClient::queryURControlVersion()
249251 throw UrException (ss.str ());
250252}
251253
254+ void RTDEClient::resetOutputRecipe (const std::vector<std::string> new_recipe) {
255+ prod_->teardownProducer ();
256+ disconnect ();
257+
258+ output_recipe_.assign (new_recipe.begin (), new_recipe.end ());
259+ parser_ = RTDEParser (output_recipe_);
260+ prod_ = std::make_unique<comm::URProducer<RTDEPackage>>(stream_, parser_);
261+ pipeline_ = std::make_unique<comm::Pipeline<RTDEPackage>>(*prod_, PIPELINE_NAME, notifier_, true );
262+ }
263+
252264void RTDEClient::setupOutputs (const uint16_t protocol_version)
253265{
254266 unsigned int num_retries = 0 ;
255267 size_t size;
256268 size_t written;
257269 uint8_t buffer[8192 ];
258270 URCL_LOG_INFO (" Setting up RTDE communication with frequency %f" , target_frequency_);
259- if (protocol_version == 2 )
260- {
261- size = ControlPackageSetupOutputsRequest::generateSerializedRequest (buffer, target_frequency_, output_recipe_);
262- }
263- else
271+
272+ while (num_retries < MAX_REQUEST_RETRIES)
264273 {
265- if (target_frequency_ != max_frequency_)
274+ URCL_LOG_INFO (" Sending output recipe" );
275+ if (protocol_version == 2 )
266276 {
267- URCL_LOG_WARN (" It is not possible to set a target frequency when using protocol version 1. A frequency "
268- " equivalent to the maximum frequency will be used instead." );
277+ size = ControlPackageSetupOutputsRequest::generateSerializedRequest (buffer, target_frequency_, output_recipe_);
278+ }
279+ else
280+ {
281+ if (target_frequency_ != max_frequency_)
282+ {
283+ URCL_LOG_WARN (" It is not possible to set a target frequency when using protocol version 1. A frequency "
284+ " equivalent to the maximum frequency will be used instead." );
285+ }
286+ size = ControlPackageSetupOutputsRequest::generateSerializedRequest (buffer, output_recipe_);
269287 }
270- size = ControlPackageSetupOutputsRequest::generateSerializedRequest (buffer, output_recipe_);
271- }
272288
273- // Send output recipe to robot
274- if (!stream_.write (buffer, size, written))
275- {
276- URCL_LOG_ERROR (" Could not send RTDE output recipe to robot, disconnecting" );
277- disconnect ();
278- return ;
279- }
289+ // Send output recipe to robot
290+ if (!stream_.write (buffer, size, written))
291+ {
292+ URCL_LOG_ERROR (" Could not send RTDE output recipe to robot, disconnecting" );
293+ disconnect ();
294+ return ;
295+ }
280296
281- while (num_retries < MAX_REQUEST_RETRIES)
282- {
283297 std::unique_ptr<RTDEPackage> package;
284- if (!pipeline_. getLatestProduct (package, std::chrono::milliseconds (1000 )))
298+ if (!pipeline_-> getLatestProduct (package, std::chrono::milliseconds (1000 )))
285299 {
286300 URCL_LOG_ERROR (" Did not receive confirmation on RTDE output recipe, disconnecting" );
287301 disconnect ();
@@ -293,17 +307,33 @@ void RTDEClient::setupOutputs(const uint16_t protocol_version)
293307
294308 {
295309 std::vector<std::string> variable_types = splitVariableTypes (tmp_output->variable_types_ );
310+ std::vector<std::string> available_variables;
296311 assert (output_recipe_.size () == variable_types.size ());
297312 for (std::size_t i = 0 ; i < variable_types.size (); ++i)
298313 {
299- URCL_LOG_DEBUG (" %s confirmed as datatype: %s" , output_recipe_[i].c_str (), variable_types[i].c_str ());
314+ const std::string variable_name = output_recipe_[i];
315+ URCL_LOG_DEBUG (" %s confirmed as datatype: %s" , variable_name.c_str (), variable_types[i].c_str ());
316+
300317 if (variable_types[i] == " NOT_FOUND" )
301318 {
302- std::string message = " Variable '" + output_recipe_[i] +
303- " ' not recognized by the robot. Probably your output recipe contains errors" ;
304- throw UrException (message);
319+ const std::string message = " Variable '" + variable_name + " ' not recognized by the robot. "
320+ " Either your output recipe contains errors or the urcontrol version "
321+ " does not support it. It will be removed from the output recipe." ;
322+ URCL_LOG_WARN (" %s" , message.c_str ());
323+ }
324+ else
325+ {
326+ available_variables.push_back (variable_name);
305327 }
306328 }
329+
330+ if (available_variables.size () == output_recipe_.size ()) {
331+ // All variables are accounted for in the RTDE package
332+ return ;
333+ }
334+
335+ // Some variables are not available so retry setting up the communication with a stripped-down output recipe
336+ resetOutputRecipe (available_variables);
307337 return ;
308338 }
309339 else
@@ -339,7 +369,7 @@ void RTDEClient::setupInputs()
339369 while (num_retries < MAX_REQUEST_RETRIES)
340370 {
341371 std::unique_ptr<RTDEPackage> package;
342- if (!pipeline_. getLatestProduct (package, std::chrono::milliseconds (1000 )))
372+ if (!pipeline_-> getLatestProduct (package, std::chrono::milliseconds (1000 )))
343373 {
344374 URCL_LOG_ERROR (" Did not receive confirmation on RTDE input recipe, disconnecting" );
345375 disconnect ();
@@ -395,7 +425,7 @@ void RTDEClient::disconnect()
395425 if (client_state_ > ClientState::UNINITIALIZED)
396426 {
397427 sendPause ();
398- pipeline_. stop ();
428+ pipeline_-> stop ();
399429 stream_.disconnect ();
400430 }
401431 client_state_ = ClientState::UNINITIALIZED;
@@ -421,7 +451,7 @@ bool RTDEClient::isRobotBooted()
421451 {
422452 // Set timeout based on target frequency, to make sure that reading doesn't timeout
423453 int timeout = static_cast <int >((1 / target_frequency_) * 1000 ) * 10 ;
424- if (pipeline_. getLatestProduct (package, std::chrono::milliseconds (timeout)))
454+ if (pipeline_-> getLatestProduct (package, std::chrono::milliseconds (timeout)))
425455 {
426456 rtde_interface::DataPackage* tmp_input = dynamic_cast <rtde_interface::DataPackage*>(package.get ());
427457 tmp_input->getData (" timestamp" , timestamp);
@@ -451,7 +481,7 @@ bool RTDEClient::start()
451481 return false ;
452482 }
453483
454- pipeline_. run ();
484+ pipeline_-> run ();
455485
456486 if (sendStart ())
457487 {
@@ -501,7 +531,7 @@ bool RTDEClient::sendStart()
501531 unsigned int num_retries = 0 ;
502532 while (num_retries < MAX_REQUEST_RETRIES)
503533 {
504- if (!pipeline_. getLatestProduct (package, std::chrono::milliseconds (1000 )))
534+ if (!pipeline_-> getLatestProduct (package, std::chrono::milliseconds (1000 )))
505535 {
506536 URCL_LOG_ERROR (" Could not get response to RTDE communication start request from robot" );
507537 return false ;
@@ -543,7 +573,7 @@ bool RTDEClient::sendPause()
543573 int seconds = 5 ;
544574 while (std::chrono::steady_clock::now () - start < std::chrono::seconds (seconds))
545575 {
546- if (!pipeline_. getLatestProduct (package, std::chrono::milliseconds (1000 )))
576+ if (!pipeline_-> getLatestProduct (package, std::chrono::milliseconds (1000 )))
547577 {
548578 URCL_LOG_ERROR (" Could not get response to RTDE communication pause request from robot" );
549579 return false ;
@@ -605,7 +635,7 @@ std::vector<std::string> RTDEClient::ensureTimestampIsPresent(const std::vector<
605635std::unique_ptr<rtde_interface::DataPackage> RTDEClient::getDataPackage (std::chrono::milliseconds timeout)
606636{
607637 std::unique_ptr<RTDEPackage> urpackage;
608- if (pipeline_. getLatestProduct (urpackage, timeout))
638+ if (pipeline_-> getLatestProduct (urpackage, timeout))
609639 {
610640 rtde_interface::DataPackage* tmp = dynamic_cast <rtde_interface::DataPackage*>(urpackage.get ());
611641 if (tmp != nullptr )
0 commit comments