Skip to content

Commit df9f95c

Browse files
author
Felix Exner (fexner)
authored
Allow resetting the RTDE client (#218)
With some control modes such as the trajectory passthrough controller it is actually possible to run the communication at much lower frequencies. However, so far we always initialize the `RTDEClient` with the maximum frequency that is possible on the respective model. This adds a function to `UrDriver` to reset the `RTDEClient` with another communication frequency. ## ToDo - [x] Implementation - [x] Write tests - [x] Write documentation
1 parent 881adb0 commit df9f95c

File tree

5 files changed

+80
-13
lines changed

5 files changed

+80
-13
lines changed

doc/architecture.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ sure to
6363
* run it from the package's main folder, as for simplicity reasons it doesn't use any sophisticated
6464
method to locate the required files.
6565

66+
.. note::
67+
The ``URDriver`` class creates a ``RTDEClient`` during initialization using the provided
68+
recipes and utilizing the robot model's maximum frequency. If you would like to use a different
69+
frequency, please use the ``resetRTDEClient()`` method after the ``UrDriver`` object has been
70+
created.
6671

6772
RTDEWriter
6873
^^^^^^^^^^

doc/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
# -- Project information -----------------------------------------------------
2828

2929
project = "ur_client_library"
30-
copyright = "2022, Felix Exner"
30+
copyright = "2022, Universal Robots A/S"
3131
author = "Felix Exner"
3232

3333
# The short X.Y version

include/ur_client_library/ur/ur_driver.h

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ class UrDriver
195195

196196
uint32_t getControlFrequency() const
197197
{
198-
return rtde_frequency_;
198+
return rtde_client_->getTargetFrequency();
199199
}
200200

201201
/*!
@@ -487,6 +487,36 @@ class UrDriver
487487
script_command_interface_->setToolContactResultCallback(tool_contact_result_cb);
488488
}
489489

490+
/**
491+
* \brief Reset the RTDE client. As during initialization the driver will start RTDE communication
492+
* with the maximum available frequency, this enables users to start RTDE communication with a
493+
* custom rate.
494+
*
495+
* Note: After calling this function startRTDECommunication() has to be called again to actually
496+
* start RTDE communication.
497+
*
498+
* \param output_recipe Vector containing the output recipe
499+
* \param input_recipe Vector containing the input recipe
500+
* \param target_frequency Frequency to run the RTDE client at. Defaults to 0.0 which means maximum frequency.
501+
*/
502+
void resetRTDEClient(const std::vector<std::string>& output_recipe, const std::vector<std::string>& input_recipe,
503+
double target_frequency = 0.0);
504+
505+
/**
506+
* \brief Reset the RTDE client. As during initialization the driver will start RTDE communication
507+
* with the maximum available frequency, this enables users to start RTDE communication with a
508+
* custom rate.
509+
*
510+
* Note: After calling this function startRTDECommunication() has to be called again to actually
511+
* start RTDE communication.
512+
*
513+
* \param output_recipe_filename Filename where the output recipe is stored in.
514+
* \param input_recipe_filename Filename where the input recipe is stored in.
515+
* \param target_frequency Frequency to run the RTDE client at. Defaults to 0.0 which means maximum frequency.
516+
*/
517+
void resetRTDEClient(const std::string& output_recipe_filename, const std::string& input_recipe_filename,
518+
double target_frequency = 0.0);
519+
490520
private:
491521
static std::string readScriptFile(const std::string& filename);
492522
/*!
@@ -498,7 +528,9 @@ class UrDriver
498528
*/
499529
bool reconnectSecondaryStream();
500530

501-
int rtde_frequency_;
531+
void initRTDE();
532+
void setupReverseInterface(const uint32_t reverse_port);
533+
502534
comm::INotifier notifier_;
503535
std::unique_ptr<rtde_interface::RTDEClient> rtde_client_;
504536
std::unique_ptr<control::ReverseInterface> reverse_interface_;
@@ -510,7 +542,6 @@ class UrDriver
510542

511543
uint32_t servoj_gain_;
512544
double servoj_lookahead_time_;
513-
std::chrono::milliseconds step_time_;
514545

515546
std::function<void(bool)> handle_program_state_;
516547

src/ur/ur_driver.cpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ urcl::UrDriver::UrDriver(const std::string& robot_ip, const std::string& script_
6161
const uint32_t script_command_port, double force_mode_damping, double force_mode_gain_scaling)
6262
: servoj_gain_(servoj_gain)
6363
, servoj_lookahead_time_(servoj_lookahead_time)
64-
, step_time_(std::chrono::milliseconds(8))
6564
, handle_program_state_(handle_program_state)
6665
, robot_ip_(robot_ip)
6766
{
@@ -78,13 +77,8 @@ urcl::UrDriver::UrDriver(const std::string& robot_ip, const std::string& script_
7877
non_blocking_read_ = non_blocking_read;
7978
get_packet_timeout_ = non_blocking_read_ ? 0 : 100;
8079

81-
if (!rtde_client_->init())
82-
{
83-
throw UrException("Initialization of RTDE client went wrong.");
84-
}
85-
86-
rtde_frequency_ = rtde_client_->getMaxFrequency();
87-
step_time_ = std::chrono::milliseconds(1000 / rtde_frequency_);
80+
initRTDE();
81+
setupReverseInterface(reverse_port);
8882

8983
// Figure out the ip automatically if the user didn't provide it
9084
std::string local_ip = reverse_ip.empty() ? rtde_client_->getIP() : reverse_ip;
@@ -210,7 +204,6 @@ urcl::UrDriver::UrDriver(const std::string& robot_ip, const std::string& script_
210204
URCL_LOG_DEBUG("Created script sender");
211205
}
212206

213-
reverse_interface_.reset(new control::ReverseInterface(reverse_port, handle_program_state, step_time_));
214207
trajectory_interface_.reset(new control::TrajectoryPointInterface(trajectory_port));
215208
script_command_interface_.reset(new control::ScriptCommandInterface(script_command_port));
216209

@@ -621,4 +614,35 @@ void UrDriver::setKeepaliveCount(const uint32_t count)
621614
reverse_interface_->setKeepaliveCount(count);
622615
}
623616

617+
void UrDriver::resetRTDEClient(const std::vector<std::string>& output_recipe,
618+
const std::vector<std::string>& input_recipe, double target_frequency)
619+
{
620+
rtde_client_.reset(
621+
new rtde_interface::RTDEClient(robot_ip_, notifier_, output_recipe, input_recipe, target_frequency));
622+
initRTDE();
623+
}
624+
625+
void UrDriver::resetRTDEClient(const std::string& output_recipe_filename, const std::string& input_recipe_filename,
626+
double target_frequency)
627+
{
628+
rtde_client_.reset(new rtde_interface::RTDEClient(robot_ip_, notifier_, output_recipe_filename, input_recipe_filename,
629+
target_frequency));
630+
initRTDE();
631+
}
632+
633+
void UrDriver::initRTDE()
634+
{
635+
if (!rtde_client_->init())
636+
{
637+
throw UrException("Initialization of RTDE client went wrong.");
638+
}
639+
}
640+
641+
void UrDriver::setupReverseInterface(const uint32_t reverse_port)
642+
{
643+
auto rtde_frequency = rtde_client_->getTargetFrequency();
644+
auto step_time = std::chrono::milliseconds(static_cast<int>(1000 / rtde_frequency));
645+
reverse_interface_.reset(new control::ReverseInterface(reverse_port, handle_program_state_, step_time));
646+
}
647+
624648
} // namespace urcl

tests/test_ur_driver.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,13 @@ TEST_F(UrDriverTest, send_robot_program_retry_on_failure)
372372
EXPECT_TRUE(g_ur_driver_->sendRobotProgram());
373373
}
374374

375+
TEST_F(UrDriverTest, reset_rtde_client)
376+
{
377+
double target_frequency = 50;
378+
g_ur_driver_->resetRTDEClient(OUTPUT_RECIPE, INPUT_RECIPE, target_frequency);
379+
ASSERT_EQ(g_ur_driver_->getControlFrequency(), target_frequency);
380+
}
381+
375382
// TODO we should add more tests for the UrDriver class.
376383

377384
int main(int argc, char* argv[])

0 commit comments

Comments
 (0)