3131#include " ur_client_library/log.h"
3232#include < algorithm>
3333#include < chrono>
34+ #include < string>
3435
3536namespace urcl
3637{
3738namespace rtde_interface
3839{
3940RTDEClient::RTDEClient (std::string robot_ip, comm::INotifier& notifier, const std::string& output_recipe_file,
40- const std::string& input_recipe_file, double target_frequency, bool ignore_unavailable_outputs)
41- : stream_(robot_ip, UR_RTDE_PORT)
41+ const std::string& input_recipe_file, double target_frequency, bool ignore_unavailable_outputs,
42+ const uint32_t port)
43+ : stream_(robot_ip, port)
4244 , output_recipe_(ensureTimestampIsPresent(readRecipe(output_recipe_file)))
4345 , ignore_unavailable_outputs_(ignore_unavailable_outputs)
4446 , parser_(output_recipe_)
@@ -61,8 +63,8 @@ RTDEClient::RTDEClient(std::string robot_ip, comm::INotifier& notifier, const st
6163
6264RTDEClient::RTDEClient (std::string robot_ip, comm::INotifier& notifier, const std::vector<std::string>& output_recipe,
6365 const std::vector<std::string>& input_recipe, double target_frequency,
64- bool ignore_unavailable_outputs)
65- : stream_(robot_ip, UR_RTDE_PORT )
66+ bool ignore_unavailable_outputs, const uint32_t port )
67+ : stream_(robot_ip, port )
6668 , output_recipe_(ensureTimestampIsPresent(output_recipe))
6769 , ignore_unavailable_outputs_(ignore_unavailable_outputs)
6870 , input_recipe_(input_recipe)
@@ -103,6 +105,11 @@ bool RTDEClient::init(const size_t max_connection_attempts, const std::chrono::m
103105 return true ;
104106 }
105107
108+ max_connection_attempts_ = max_connection_attempts;
109+ reconnection_timeout_ = reconnection_timeout;
110+ max_initialization_attempts_ = max_initialization_attempts;
111+ initialization_timeout_ = initialization_timeout;
112+
106113 prod_->setReconnectionCallback (nullptr );
107114
108115 unsigned int attempts = 0 ;
@@ -132,24 +139,27 @@ bool RTDEClient::init(const size_t max_connection_attempts, const std::chrono::m
132139
133140bool RTDEClient::setupCommunication (const size_t max_num_tries, const std::chrono::milliseconds reconnection_time)
134141{
135- // The state initializing is used inside disconnect to stop the pipeline again.
136- client_state_ = ClientState::INITIALIZING;
137- // A running pipeline is needed inside setup.
142+ client_state_ = ClientState::UNINITIALIZED;
138143 try
139144 {
140145 pipeline_->init (max_num_tries, reconnection_time);
141146 }
142147 catch (const UrException& exc)
143148 {
144- URCL_LOG_ERROR (" Caught exception %s , while trying to initialize pipeline" , exc.what ());
149+ URCL_LOG_ERROR (" Caught exception '%s' , while trying to initialize pipeline" , exc.what ());
145150 return false ;
146151 }
152+ // The state initializing is used inside disconnect to stop the pipeline again.
153+ // A running pipeline is needed inside setup.
154+ client_state_ = ClientState::INITIALIZING;
155+
147156 pipeline_->run ();
148157
149158 uint16_t protocol_version = negotiateProtocolVersion ();
150159 // Protocol version must be above zero
151160 if (protocol_version == 0 )
152161 {
162+ client_state_ = ClientState::UNINITIALIZED;
153163 return false ;
154164 }
155165
@@ -286,7 +296,8 @@ void RTDEClient::setTargetFrequency()
286296 else if (target_frequency_ <= 0.0 || target_frequency_ > max_frequency_)
287297 {
288298 // Target frequency outside valid range
289- throw UrException (" Invalid target frequency of RTDE connection" );
299+ std::string error = " Invalid target frequency of RTDE connection: " + std::to_string (target_frequency_);
300+ throw UrException (error.c_str ());
290301 }
291302}
292303
@@ -348,7 +359,7 @@ bool RTDEClient::setupOutputs(const uint16_t protocol_version)
348359 dynamic_cast <rtde_interface::ControlPackageSetupOutputs*>(package.get ()))
349360
350361 {
351- std::vector<std::string> variable_types = splitVariableTypes (tmp_output->variable_types_ );
362+ std::vector<std::string> variable_types = splitString (tmp_output->variable_types_ , " , " );
352363 std::vector<std::string> available_variables;
353364 std::vector<std::string> unavailable_variables;
354365 assert (output_recipe_.size () == variable_types.size ());
@@ -441,7 +452,7 @@ bool RTDEClient::setupInputs()
441452 dynamic_cast <rtde_interface::ControlPackageSetupInputs*>(package.get ()))
442453
443454 {
444- std::vector<std::string> variable_types = splitVariableTypes (tmp_input->variable_types_ );
455+ std::vector<std::string> variable_types = splitString (tmp_input->variable_types_ , " , " );
445456 assert (input_recipe_.size () == variable_types.size ());
446457 for (std::size_t i = 0 ; i < variable_types.size (); ++i)
447458 {
@@ -745,36 +756,24 @@ RTDEWriter& RTDEClient::getWriter()
745756 return writer_;
746757}
747758
748- std::vector<std::string> RTDEClient::splitVariableTypes (const std::string& variable_types) const
749- {
750- std::vector<std::string> result;
751- std::stringstream ss (variable_types);
752- std::string substr = " " ;
753- while (getline (ss, substr, ' ,' ))
754- {
755- result.push_back (substr);
756- }
757- return result;
758- }
759-
760759void RTDEClient::reconnect ()
761760{
762761 URCL_LOG_INFO (" Reconnecting to the RTDE interface" );
763762 // Locking mutex to ensure that calling getDataPackage doesn't influence the communication needed for reconfiguring
764763 // the RTDE connection
765764 std::lock_guard<std::mutex> lock (reconnect_mutex_);
766765 ClientState cur_client_state = client_state_;
766+ client_state_ = ClientState::CONNECTION_LOST;
767767 disconnect ();
768768
769- const size_t max_initialization_attempts = 3 ;
770769 size_t cur_initialization_attempt = 0 ;
771770 bool client_reconnected = false ;
772- while (cur_initialization_attempt < max_initialization_attempts )
771+ while (cur_initialization_attempt < max_initialization_attempts_ )
773772 {
774773 bool is_communication_setup = false ;
775774 try
776775 {
777- is_communication_setup = setupCommunication (1 , std::chrono::milliseconds{ 10000 } );
776+ is_communication_setup = setupCommunication (max_connection_attempts_, reconnection_timeout_ );
778777 }
779778 catch (const UrException& exc)
780779 {
@@ -797,24 +796,22 @@ void RTDEClient::reconnect()
797796 break ;
798797 }
799798
800- auto duration = std::chrono::seconds (1 );
801799 if (stream_.getState () != comm::SocketState::Connected)
802800 {
803801 // We don't wanna count it as an initialization attempt if we cannot connect to the socket and we want to wait
804802 // longer before reconnecting.
805- duration = std::chrono::seconds (10 );
806- URCL_LOG_ERROR (" Failed to connect to the RTDE server, retrying in %i seconds" , duration.count ());
803+ URCL_LOG_ERROR (" Failed to connect to the RTDE server, retrying in %i seconds" , reconnection_timeout_.count ());
807804 }
808805 else
809806 {
810- URCL_LOG_ERROR (" Failed to initialize RTDE client, retrying in %i second" , duration .count ());
807+ URCL_LOG_ERROR (" Failed to initialize RTDE client, retrying in %i second" , initialization_timeout_ .count ());
811808 cur_initialization_attempt += 1 ;
812809 }
813810
814811 disconnect ();
815812
816813 auto start_time = std::chrono::steady_clock::now ();
817- while (std::chrono::steady_clock::now () - start_time < duration )
814+ while (std::chrono::steady_clock::now () - start_time < initialization_timeout_ )
818815 {
819816 std::this_thread::sleep_for (std::chrono::milliseconds (250 ));
820817 if (stop_reconnection_)
@@ -828,12 +825,14 @@ void RTDEClient::reconnect()
828825 if (client_reconnected == false )
829826 {
830827 URCL_LOG_ERROR (" Failed to initialize RTDE client after %i attempts, unable to reconnect" ,
831- max_initialization_attempts );
828+ max_initialization_attempts_ );
832829 disconnect ();
833830 reconnecting_ = false ;
834831 return ;
835832 }
836833
834+ URCL_LOG_INFO (" Successfully reconnected to the RTDE interface, starting communication again" );
835+
837836 start ();
838837 if (cur_client_state == ClientState::PAUSED)
839838 {
0 commit comments