Skip to content

Commit 60b487e

Browse files
committed
Replace the secondary stream with using the primary client
1 parent 60a46ba commit 60b487e

File tree

5 files changed

+88
-71
lines changed

5 files changed

+88
-71
lines changed

include/ur_client_library/primary/primary_client.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,35 @@ class PrimaryClient
6868
void removePrimaryConsumer(std::shared_ptr<comm::IConsumer<PrimaryPackage>> primary_consumer);
6969
void start(const size_t max_connection_attempts = 0,
7070
const std::chrono::milliseconds reconnection_timeout = urcl::comm::TCPSocket::DEFAULT_RECONNECTION_TIME);
71+
void stop();
7172

7273
/*!
7374
* \brief Retrieves previously raised error codes from PrimaryClient. After calling this, recorded errors will be
7475
* deleted.
7576
*/
7677
std::deque<ErrorCode> getErrorCodes();
7778

79+
/*!
80+
* \brief Sends a custom script program to the robot.
81+
*
82+
* The given code must be valid according the UR Scripting Manual.
83+
*
84+
* \param program URScript code that shall be executed by the robot.
85+
*
86+
* \returns true on successful upload, false otherwise.
87+
*/
88+
bool sendScript(const std::string& program);
89+
7890
private:
91+
/*!
92+
* \brief Reconnects the primary stream used to send program to the robot.
93+
*
94+
* Only for use in headless mode, as it replaces the use of the URCaps program.
95+
*
96+
* \returns true of on successful reconnection, false otherwise
97+
*/
98+
bool reconnectStream();
99+
79100
// The function is called whenever an error code message is received
80101
void errorMessageCallback(ErrorCode& code);
81102

include/ur_client_library/ur/ur_driver.h

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -868,18 +868,18 @@ class UrDriver
868868
*/
869869
void startPrimaryClientCommunication();
870870

871+
void stopPrimaryClientCommunication()
872+
{
873+
primary_client_->stop();
874+
}
875+
871876
void registerTrajectoryInterfaceDisconnectedCallback(std::function<void(const int)> fun)
872877
{
873878
trajectory_interface_->registerDisconnectionCallback(fun);
874879
}
875880

876881
static std::string readScriptFile(const std::string& filename);
877882

878-
void closeSecondaryStream()
879-
{
880-
secondary_stream_->close();
881-
}
882-
883883
bool isReverseInterfaceConnected() const
884884
{
885885
return reverse_interface_->isConnected();
@@ -893,15 +893,6 @@ class UrDriver
893893
private:
894894
void init(const UrDriverConfiguration& config);
895895

896-
/*!
897-
* \brief Reconnects the secondary stream used to send program to the robot.
898-
*
899-
* Only for use in headless mode, as it replaces the use of the URCaps program.
900-
*
901-
* \returns true of on successful reconnection, false otherwise
902-
*/
903-
bool reconnectSecondaryStream();
904-
905896
void initRTDE();
906897
void setupReverseInterface(const uint32_t reverse_port);
907898

@@ -913,7 +904,6 @@ class UrDriver
913904
std::unique_ptr<control::ScriptCommandInterface> script_command_interface_;
914905
std::unique_ptr<control::ScriptSender> script_sender_;
915906
std::unique_ptr<comm::URStream<primary_interface::PrimaryPackage>> primary_stream_;
916-
std::unique_ptr<comm::URStream<primary_interface::PrimaryPackage>> secondary_stream_;
917907

918908
size_t socket_connection_attempts_ = 0;
919909
std::chrono::milliseconds socket_reconnection_timeout_ = std::chrono::milliseconds(10000);

src/primary/primary_client.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ void PrimaryClient::start(const size_t max_num_tries, const std::chrono::millise
6767
pipeline_->run();
6868
}
6969

70+
void PrimaryClient::stop()
71+
{
72+
pipeline_->stop();
73+
stream_.close();
74+
}
75+
7076
void PrimaryClient::addPrimaryConsumer(std::shared_ptr<comm::IConsumer<PrimaryPackage>> primary_consumer)
7177
{
7278
multi_consumer_->addConsumer(primary_consumer);
@@ -91,5 +97,54 @@ std::deque<ErrorCode> PrimaryClient::getErrorCodes()
9197
error_code_queue_.clear();
9298
return error_codes;
9399
}
100+
101+
bool PrimaryClient::sendScript(const std::string& program)
102+
{
103+
// urscripts (snippets) must end with a newline, or otherwise the controller's runtime will
104+
// not execute them. To avoid problems, we always just append a newline here, even if
105+
// there may already be one.
106+
auto program_with_newline = program + '\n';
107+
108+
size_t len = program_with_newline.size();
109+
const uint8_t* data = reinterpret_cast<const uint8_t*>(program_with_newline.c_str());
110+
size_t written;
111+
112+
const auto send_script_contents = [this, program_with_newline, data, len,
113+
&written](const std::string&& description) -> bool {
114+
if (stream_.write(data, len, written))
115+
{
116+
URCL_LOG_DEBUG("Sent program to robot:\n%s", program_with_newline.c_str());
117+
return true;
118+
}
119+
const std::string error_message = "Could not send program to robot: " + description;
120+
URCL_LOG_ERROR(error_message.c_str());
121+
return false;
122+
};
123+
124+
if (send_script_contents("initial attempt"))
125+
{
126+
return true;
127+
}
128+
129+
if (reconnectStream())
130+
{
131+
return send_script_contents("after reconnecting primary stream");
132+
}
133+
134+
return false;
135+
}
136+
137+
bool PrimaryClient::reconnectStream()
138+
{
139+
URCL_LOG_DEBUG("Closing primary stream...");
140+
stream_.close();
141+
if (stream_.connect())
142+
{
143+
URCL_LOG_DEBUG("Primary stream connected");
144+
return true;
145+
}
146+
URCL_LOG_ERROR("Failed to reconnect primary stream!");
147+
return false;
148+
}
94149
} // namespace primary_interface
95-
} // namespace urcl
150+
} // namespace urcl

src/ur/ur_driver.cpp

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ void UrDriver::init(const UrDriverConfiguration& config)
7272

7373
primary_stream_.reset(
7474
new comm::URStream<primary_interface::PrimaryPackage>(robot_ip_, urcl::primary_interface::UR_PRIMARY_PORT));
75-
secondary_stream_.reset(
76-
new comm::URStream<primary_interface::PrimaryPackage>(robot_ip_, urcl::primary_interface::UR_SECONDARY_PORT));
77-
secondary_stream_->connect(socket_connection_attempts_, socket_reconnection_timeout_);
7875

7976
primary_client_.reset(new urcl::primary_interface::PrimaryClient(robot_ip_, notifier_));
8077

@@ -151,6 +148,7 @@ void UrDriver::init(const UrDriverConfiguration& config)
151148
trajectory_interface_.reset(new control::TrajectoryPointInterface(config.trajectory_port));
152149
script_command_interface_.reset(new control::ScriptCommandInterface(config.script_command_port));
153150

151+
startPrimaryClientCommunication();
154152
if (in_headless_mode_)
155153
{
156154
full_robot_program_ = "stop program\n";
@@ -591,44 +589,11 @@ rtde_interface::RTDEWriter& UrDriver::getRTDEWriter()
591589

592590
bool UrDriver::sendScript(const std::string& program)
593591
{
594-
if (secondary_stream_ == nullptr)
592+
if (primary_client_ == nullptr)
595593
{
596-
throw std::runtime_error("Sending script to robot requested while there is no secondary interface established. "
597-
"This should not happen.");
598-
}
599-
600-
// urscripts (snippets) must end with a newline, or otherwise the controller's runtime will
601-
// not execute them. To avoid problems, we always just append a newline here, even if
602-
// there may already be one.
603-
auto program_with_newline = program + '\n';
604-
605-
size_t len = program_with_newline.size();
606-
const uint8_t* data = reinterpret_cast<const uint8_t*>(program_with_newline.c_str());
607-
size_t written;
608-
609-
const auto send_script_contents = [this, program_with_newline, data, len,
610-
&written](const std::string&& description) -> bool {
611-
if (secondary_stream_->write(data, len, written))
612-
{
613-
URCL_LOG_DEBUG("Sent program to robot:\n%s", program_with_newline.c_str());
614-
return true;
615-
}
616-
const std::string error_message = "Could not send program to robot: " + description;
617-
URCL_LOG_ERROR(error_message.c_str());
618594
return false;
619-
};
620-
621-
if (send_script_contents("initial attempt"))
622-
{
623-
return true;
624595
}
625-
626-
if (reconnectSecondaryStream())
627-
{
628-
return send_script_contents("after reconnecting secondary stream");
629-
}
630-
631-
return false;
596+
return primary_client_->sendScript(program);
632597
}
633598

634599
bool UrDriver::sendRobotProgram()
@@ -644,19 +609,6 @@ bool UrDriver::sendRobotProgram()
644609
}
645610
}
646611

647-
bool UrDriver::reconnectSecondaryStream()
648-
{
649-
URCL_LOG_DEBUG("Closing secondary stream...");
650-
secondary_stream_->close();
651-
if (secondary_stream_->connect())
652-
{
653-
URCL_LOG_DEBUG("Secondary stream connected");
654-
return true;
655-
}
656-
URCL_LOG_ERROR("Failed to reconnect secondary stream!");
657-
return false;
658-
}
659-
660612
std::vector<std::string> UrDriver::getRTDEOutputRecipe()
661613
{
662614
return rtde_client_->getOutputRecipe();
@@ -718,4 +670,4 @@ std::deque<urcl::primary_interface::ErrorCode> UrDriver::getErrorCodes()
718670
{
719671
return primary_client_->getErrorCodes();
720672
}
721-
} // namespace urcl
673+
} // namespace urcl

tests/test_ur_driver.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,14 @@ TEST_F(UrDriverTest, target_outside_limits_pose)
235235

236236
TEST_F(UrDriverTest, send_robot_program_retry_on_failure)
237237
{
238-
// Check that sendRobotProgram is robust to the secondary stream being disconnected. This is what happens when
238+
// Check that sendRobotProgram is robust to the primary stream being disconnected. This is what happens when
239239
// switching from Remote to Local and back to Remote mode for example.
240240

241241
// To be able to re-send the robot program we'll have to make sure it isn't running
242242
g_my_robot->ur_driver_->stopControl();
243243
g_my_robot->waitForProgramNotRunning();
244244

245-
g_my_robot->ur_driver_->closeSecondaryStream();
245+
g_my_robot->ur_driver_->stopPrimaryClientCommunication();
246246

247247
EXPECT_TRUE(g_my_robot->resendRobotProgram());
248248

@@ -259,7 +259,6 @@ TEST_F(UrDriverTest, reset_rtde_client)
259259

260260
TEST_F(UrDriverTest, read_error_code)
261261
{
262-
g_my_robot->ur_driver_->startPrimaryClientCommunication();
263262
// Wait until we actually received a package
264263
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
265264
std::stringstream cmd;

0 commit comments

Comments
 (0)