@@ -51,7 +51,18 @@ bool RTDEClient::init()
51
51
pipeline_.init ();
52
52
pipeline_.run ();
53
53
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);
55
66
parser_.setProtocolVersion (protocol_version);
56
67
57
68
queryURControlVersion ();
@@ -70,64 +81,93 @@ bool RTDEClient::init()
70
81
return true ;
71
82
}
72
83
73
- uint16_t RTDEClient::negotiateProtocolVersion ()
84
+ bool RTDEClient::negotiateProtocolVersion (const uint16_t protocol_version )
74
85
{
86
+ static unsigned num_retries = 0 ;
75
87
uint8_t buffer[4096 ];
76
88
size_t size;
77
89
size_t written;
78
- uint16_t protocol_version = 2 ;
79
90
size = RequestProtocolVersionRequest::generateSerializedRequest (buffer, protocol_version);
80
91
if (!stream_.write (buffer, size, written))
81
92
throw UrException (" Sending protocol version query to robot failed." );
93
+
82
94
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)
88
96
{
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." );
93
97
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_ )
97
98
{
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 ());
99
118
}
100
119
}
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 ());
102
125
}
103
126
104
127
void RTDEClient::queryURControlVersion ()
105
128
{
129
+ static unsigned num_retries = 0 ;
106
130
uint8_t buffer[4096 ];
107
131
size_t size;
108
132
size_t written;
109
- std::unique_ptr<RTDEPackage> package;
110
133
size = GetUrcontrolVersionRequest::generateSerializedRequest (buffer);
111
134
if (!stream_.write (buffer, size, written))
112
135
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 ());
117
136
118
- if (tmp_urcontrol_version == nullptr )
137
+ std::unique_ptr<RTDEPackage> package;
138
+ while (num_retries < MAX_REQUEST_RETRIES)
119
139
{
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
+ }
121
157
}
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 ());
123
163
}
124
164
125
165
void RTDEClient::setupOutputs (const uint16_t protocol_version)
126
166
{
167
+ static unsigned num_retries = 0 ;
127
168
size_t size;
128
169
size_t written;
129
170
uint8_t buffer[4096 ];
130
- std::unique_ptr<RTDEPackage> package;
131
171
LOG_INFO (" Setting up RTDE communication with frequency %f" , max_frequency_);
132
172
if (protocol_version == 2 )
133
173
{
@@ -141,71 +181,112 @@ void RTDEClient::setupOutputs(const uint16_t protocol_version)
141
181
// Send output recipe to robot
142
182
if (!stream_.write (buffer, size, written))
143
183
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)
145
187
{
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
+ }
148
192
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 ()))
151
195
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" )
158
196
{
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 ());
162
218
}
163
219
}
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 ());
164
225
}
165
226
166
227
void RTDEClient::setupInputs ()
167
228
{
229
+ static unsigned num_retries = 0 ;
168
230
size_t size;
169
231
size_t written;
170
232
uint8_t buffer[4096 ];
171
- std::unique_ptr<RTDEPackage> package;
172
233
size = ControlPackageSetupInputsRequest::generateSerializedRequest (buffer, input_recipe_);
173
234
if (!stream_.write (buffer, size, written))
174
235
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
- }
183
236
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)
187
239
{
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
+
190
246
{
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 ;
194
270
}
195
- else if (variable_types[i] == " IN_USE " )
271
+ else
196
272
{
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 ());
201
278
}
202
279
}
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 ());
205
285
}
206
286
207
287
bool RTDEClient::start ()
208
288
{
289
+ static unsigned num_retries = 0 ;
209
290
uint8_t buffer[4096 ];
210
291
size_t size;
211
292
size_t written;
@@ -214,12 +295,30 @@ bool RTDEClient::start()
214
295
std::unique_ptr<RTDEPackage> package;
215
296
if (!stream_.write (buffer, size, written))
216
297
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 ());
222
320
}
321
+
223
322
std::vector<std::string> RTDEClient::readRecipe (const std::string& recipe_file)
224
323
{
225
324
std::vector<std::string> recipe;
0 commit comments