@@ -51,7 +51,18 @@ bool RTDEClient::init()
5151 pipeline_.init ();
5252 pipeline_.run ();
5353
54- uint16_t protocol_version = negotiateProtocolVersion ();
54+ uint16_t protocol_version = MAX_RTDE_PROTOCOL_VERSION;
55+ while (!negotiateProtocolVersion (protocol_version))
56+ {
57+ LOG_INFO (" Robot did not accept RTDE protocol version '%hu'. Trying lower protocol version" , protocol_version);
58+ protocol_version--;
59+ if (protocol_version == 0 )
60+ {
61+ throw UrException (" Protocol version for RTDE communication could not be established. Robot didn't accept any of "
62+ " the suggested versions." );
63+ }
64+ }
65+ LOG_INFO (" Negotiated RTDE protocol version to %hu." , protocol_version);
5566 parser_.setProtocolVersion (protocol_version);
5667
5768 queryURControlVersion ();
@@ -70,64 +81,93 @@ bool RTDEClient::init()
7081 return true ;
7182}
7283
73- uint16_t RTDEClient::negotiateProtocolVersion ()
84+ bool RTDEClient::negotiateProtocolVersion (const uint16_t protocol_version )
7485{
86+ static unsigned num_retries = 0 ;
7587 uint8_t buffer[4096 ];
7688 size_t size;
7789 size_t written;
78- uint16_t protocol_version = 2 ;
7990 size = RequestProtocolVersionRequest::generateSerializedRequest (buffer, protocol_version);
8091 if (!stream_.write (buffer, size, written))
8192 throw UrException (" Sending protocol version query to robot failed." );
93+
8294 std::unique_ptr<RTDEPackage> package;
83- if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
84- throw UrException (" Could not get urcontrol version from robot. This should not happen!" );
85- rtde_interface::RequestProtocolVersion* tmp_version =
86- dynamic_cast <rtde_interface::RequestProtocolVersion*>(package.get ());
87- if (!tmp_version->accepted_ )
95+ while (num_retries < MAX_REQUEST_RETRIES)
8896 {
89- protocol_version = 1 ;
90- size = RequestProtocolVersionRequest::generateSerializedRequest (buffer, protocol_version);
91- if (!stream_.write (buffer, size, written))
92- throw UrException (" Sending protocol version query to robot failed." );
9397 if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
94- throw UrException (" Could not get urcontrol version from robot. This should not happen!" );
95- tmp_version = dynamic_cast <rtde_interface::RequestProtocolVersion*>(package.get ());
96- if (!tmp_version->accepted_ )
9798 {
98- throw UrException (" Neither protocol version 1 nor 2 was accepted by the robot. This should not happen!" );
99+ throw UrException (" No answer to RTDE protocol version negotiation request was received from robot. This should "
100+ " not "
101+ " happen!" );
102+ }
103+
104+ if (rtde_interface::RequestProtocolVersion* tmp_version =
105+ dynamic_cast <rtde_interface::RequestProtocolVersion*>(package.get ()))
106+ {
107+ // Reset the num_tries variable in case we have to try with another protocol version.
108+ num_retries = 0 ;
109+ return tmp_version->accepted_ ;
110+ }
111+ else
112+ {
113+ std::stringstream ss;
114+ ss << " Did not receive protocol negotiation answer from robot. Message received instead: " << std::endl
115+ << package->toString () << " . Retrying..." ;
116+ num_retries++;
117+ LOG_WARN (" %s" , ss.str ().c_str ());
99118 }
100119 }
101- return protocol_version;
120+ std::stringstream ss;
121+ ss << " Could not negotiate RTDE protocol version after " << MAX_REQUEST_RETRIES
122+ << " tries. Please check the output of the "
123+ " negotiation attempts above to get a hint what could be wrong." ;
124+ throw UrException (ss.str ());
102125}
103126
104127void RTDEClient::queryURControlVersion ()
105128{
129+ static unsigned num_retries = 0 ;
106130 uint8_t buffer[4096 ];
107131 size_t size;
108132 size_t written;
109- std::unique_ptr<RTDEPackage> package;
110133 size = GetUrcontrolVersionRequest::generateSerializedRequest (buffer);
111134 if (!stream_.write (buffer, size, written))
112135 throw UrException (" Sending urcontrol version query request to robot failed." );
113- if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
114- throw UrException (" Could not get urcontrol version from robot. This should not happen!" );
115- rtde_interface::GetUrcontrolVersion* tmp_urcontrol_version =
116- dynamic_cast <rtde_interface::GetUrcontrolVersion*>(package.get ());
117136
118- if (tmp_urcontrol_version == nullptr )
137+ std::unique_ptr<RTDEPackage> package;
138+ while (num_retries < MAX_REQUEST_RETRIES)
119139 {
120- throw UrException (" Could not get urcontrol version from robot. This should not happen!" );
140+ if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
141+ throw UrException (" No answer to urcontrol version query was received from robot. This should not happen!" );
142+
143+ if (rtde_interface::GetUrcontrolVersion* tmp_urcontrol_version =
144+ dynamic_cast <rtde_interface::GetUrcontrolVersion*>(package.get ()))
145+ {
146+ urcontrol_version_ = tmp_urcontrol_version->version_information_ ;
147+ return ;
148+ }
149+ else
150+ {
151+ std::stringstream ss;
152+ ss << " Did not receive protocol negotiation answer from robot. Message received instead: " << std::endl
153+ << package->toString () << " . Retrying..." ;
154+ num_retries++;
155+ LOG_WARN (" %s" , ss.str ().c_str ());
156+ }
121157 }
122- urcontrol_version_ = tmp_urcontrol_version->version_information_ ;
158+ std::stringstream ss;
159+ ss << " Could not query urcontrol version after " << MAX_REQUEST_RETRIES
160+ << " tries. Please check the output of the "
161+ " negotiation attempts above to get a hint what could be wrong." ;
162+ throw UrException (ss.str ());
123163}
124164
125165void RTDEClient::setupOutputs (const uint16_t protocol_version)
126166{
167+ static unsigned num_retries = 0 ;
127168 size_t size;
128169 size_t written;
129170 uint8_t buffer[4096 ];
130- std::unique_ptr<RTDEPackage> package;
131171 LOG_INFO (" Setting up RTDE communication with frequency %f" , max_frequency_);
132172 if (protocol_version == 2 )
133173 {
@@ -141,71 +181,112 @@ void RTDEClient::setupOutputs(const uint16_t protocol_version)
141181 // Send output recipe to robot
142182 if (!stream_.write (buffer, size, written))
143183 throw UrException (" Could not send RTDE output recipe to robot." );
144- if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
184+
185+ std::unique_ptr<RTDEPackage> package;
186+ while (num_retries < MAX_REQUEST_RETRIES)
145187 {
146- throw UrException (" Did not receive confirmation on RTDE output recipe." );
147- }
188+ if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
189+ {
190+ throw UrException (" Did not receive confirmation on RTDE output recipe." );
191+ }
148192
149- rtde_interface::ControlPackageSetupOutputs* tmp_output =
150- dynamic_cast <rtde_interface::ControlPackageSetupOutputs*>(package.get ());
193+ if ( rtde_interface::ControlPackageSetupOutputs* tmp_output =
194+ dynamic_cast <rtde_interface::ControlPackageSetupOutputs*>(package.get ()))
151195
152- std::vector<std::string> variable_types = splitVariableTypes (tmp_output->variable_types_ );
153- assert (output_recipe_.size () == variable_types.size ());
154- for (std::size_t i = 0 ; i < variable_types.size (); ++i)
155- {
156- LOG_DEBUG (" %s confirmed as datatype: %s" , output_recipe_[i].c_str (), variable_types[i].c_str ());
157- if (variable_types[i] == " NOT_FOUND" )
158196 {
159- std::string message = " Variable '" + output_recipe_[i] +
160- " ' not recognized by the robot. Probably your output recipe contains errors" ;
161- throw UrException (message);
197+ std::vector<std::string> variable_types = splitVariableTypes (tmp_output->variable_types_ );
198+ assert (output_recipe_.size () == variable_types.size ());
199+ for (std::size_t i = 0 ; i < variable_types.size (); ++i)
200+ {
201+ LOG_DEBUG (" %s confirmed as datatype: %s" , output_recipe_[i].c_str (), variable_types[i].c_str ());
202+ return ;
203+ if (variable_types[i] == " NOT_FOUND" )
204+ {
205+ std::string message = " Variable '" + output_recipe_[i] +
206+ " ' not recognized by the robot. Probably your output recipe contains errors" ;
207+ throw UrException (message);
208+ }
209+ }
210+ }
211+ else
212+ {
213+ std::stringstream ss;
214+ ss << " Did not receive answer to RTDE output setup. Message received instead: " << std::endl
215+ << package->toString () << " . Retrying..." ;
216+ num_retries++;
217+ LOG_WARN (" %s" , ss.str ().c_str ());
162218 }
163219 }
220+ std::stringstream ss;
221+ ss << " Could not setup RTDE outputs after " << MAX_REQUEST_RETRIES
222+ << " tries. Please check the output of the "
223+ " negotiation attempts above to get a hint what could be wrong." ;
224+ throw UrException (ss.str ());
164225}
165226
166227void RTDEClient::setupInputs ()
167228{
229+ static unsigned num_retries = 0 ;
168230 size_t size;
169231 size_t written;
170232 uint8_t buffer[4096 ];
171- std::unique_ptr<RTDEPackage> package;
172233 size = ControlPackageSetupInputsRequest::generateSerializedRequest (buffer, input_recipe_);
173234 if (!stream_.write (buffer, size, written))
174235 throw UrException (" Could not send RTDE input recipe to robot." );
175- if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
176- throw UrException (" Did not receive confirmation on RTDE input recipe." );
177- rtde_interface::ControlPackageSetupInputs* tmp_input =
178- dynamic_cast <rtde_interface::ControlPackageSetupInputs*>(package.get ());
179- if (tmp_input == nullptr )
180- {
181- throw UrException (" Could not setup RTDE inputs." );
182- }
183236
184- std::vector<std::string> variable_types = splitVariableTypes (tmp_input->variable_types_ );
185- assert (input_recipe_.size () == variable_types.size ());
186- for (std::size_t i = 0 ; i < variable_types.size (); ++i)
237+ std::unique_ptr<RTDEPackage> package;
238+ while (num_retries < MAX_REQUEST_RETRIES)
187239 {
188- LOG_DEBUG (" %s confirmed as datatype: %s" , input_recipe_[i].c_str (), variable_types[i].c_str ());
189- if (variable_types[i] == " NOT_FOUND" )
240+ if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
241+ throw UrException (" Did not receive confirmation on RTDE input recipe." );
242+
243+ if (rtde_interface::ControlPackageSetupInputs* tmp_input =
244+ dynamic_cast <rtde_interface::ControlPackageSetupInputs*>(package.get ()))
245+
190246 {
191- std::string message =
192- " Variable '" + input_recipe_[i] + " ' not recognized by the robot. Probably your input recipe contains errors" ;
193- throw UrException (message);
247+ std::vector<std::string> variable_types = splitVariableTypes (tmp_input->variable_types_ );
248+ assert (input_recipe_.size () == variable_types.size ());
249+ for (std::size_t i = 0 ; i < variable_types.size (); ++i)
250+ {
251+ LOG_DEBUG (" %s confirmed as datatype: %s" , input_recipe_[i].c_str (), variable_types[i].c_str ());
252+ if (variable_types[i] == " NOT_FOUND" )
253+ {
254+ std::string message = " Variable '" + input_recipe_[i] +
255+ " ' not recognized by the robot. Probably your input recipe contains errors" ;
256+ throw UrException (message);
257+ }
258+ else if (variable_types[i] == " IN_USE" )
259+ {
260+ std::string message = " Variable '" + input_recipe_[i] +
261+ " ' is currently controlled by another RTDE client. The input recipe can't be used as "
262+ " configured" ;
263+ throw UrException (message);
264+ }
265+ }
266+
267+ writer_.init (tmp_input->input_recipe_id_ );
268+
269+ return ;
194270 }
195- else if (variable_types[i] == " IN_USE " )
271+ else
196272 {
197- std::string message = " Variable '" + input_recipe_[i] +
198- " ' is currently controlled by another RTDE client. The input recipe can't be used as "
199- " configured" ;
200- throw UrException (message);
273+ std::stringstream ss;
274+ ss << " Did not receive answer to RTDE input setup. Message received instead: " << std::endl
275+ << package->toString () << " . Retrying..." ;
276+ num_retries++;
277+ LOG_WARN (" %s" , ss.str ().c_str ());
201278 }
202279 }
203-
204- writer_.init (tmp_input->input_recipe_id_ );
280+ std::stringstream ss;
281+ ss << " Could not setup RTDE inputs after " << MAX_REQUEST_RETRIES
282+ << " tries. Please check the output of the "
283+ " negotiation attempts above to get a hint what could be wrong." ;
284+ throw UrException (ss.str ());
205285}
206286
207287bool RTDEClient::start ()
208288{
289+ static unsigned num_retries = 0 ;
209290 uint8_t buffer[4096 ];
210291 size_t size;
211292 size_t written;
@@ -214,12 +295,30 @@ bool RTDEClient::start()
214295 std::unique_ptr<RTDEPackage> package;
215296 if (!stream_.write (buffer, size, written))
216297 throw UrException (" Sending RTDE start command failed!" );
217- if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
218- throw UrException (" Could not get response to RTDE communication start request from robot. This should not "
219- " happen!" );
220- rtde_interface::ControlPackageStart* tmp = dynamic_cast <rtde_interface::ControlPackageStart*>(package.get ());
221- return tmp->accepted_ ;
298+ while (num_retries < MAX_REQUEST_RETRIES)
299+ {
300+ if (!pipeline_.getLatestProduct (package, std::chrono::milliseconds (1000 )))
301+ throw UrException (" Could not get response to RTDE communication start request from robot. This should not "
302+ " happen!" );
303+ if (rtde_interface::ControlPackageStart* tmp = dynamic_cast <rtde_interface::ControlPackageStart*>(package.get ()))
304+ {
305+ return tmp->accepted_ ;
306+ }
307+ else
308+ {
309+ std::stringstream ss;
310+ ss << " Did not receive answer to RTDE start request. Message received instead: " << std::endl
311+ << package->toString () << " . Retrying..." ;
312+ LOG_WARN (" %s" , ss.str ().c_str ());
313+ }
314+ }
315+ std::stringstream ss;
316+ ss << " Could not start RTDE communication after " << MAX_REQUEST_RETRIES
317+ << " tries. Please check the output of the "
318+ " negotiation attempts above to get a hint what could be wrong." ;
319+ throw UrException (ss.str ());
222320}
321+
223322std::vector<std::string> RTDEClient::readRecipe (const std::string& recipe_file)
224323{
225324 std::vector<std::string> recipe;
0 commit comments