Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ sure to
* run it from the package's main folder, as for simplicity reasons it doesn't use any sophisticated
method to locate the required files.

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

RTDEWriter
^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# -- Project information -----------------------------------------------------

project = "ur_client_library"
copyright = "2022, Felix Exner"
copyright = "2022, Universal Robots A/S"
author = "Felix Exner"

# The short X.Y version
Expand Down
37 changes: 34 additions & 3 deletions include/ur_client_library/ur/ur_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class UrDriver

uint32_t getControlFrequency() const
{
return rtde_frequency_;
return rtde_client_->getTargetFrequency();
}

/*!
Expand Down Expand Up @@ -487,6 +487,36 @@ class UrDriver
script_command_interface_->setToolContactResultCallback(tool_contact_result_cb);
}

/**
* \brief Reset the RTDE client. As during initialization the driver will start RTDE communication
* with the maximum available frequency, this enables users to start RTDE communication with a
* custom rate.
*
* Note: After calling this function startRTDECommunication() has to be called again to actually
* start RTDE communication.
*
* \param output_recipe Vector containing the output recipe
* \param input_recipe Vector containing the input recipe
* \param target_frequency Frequency to run the RTDE client at. Defaults to 0.0 which means maximum frequency.
*/
void resetRTDEClient(const std::vector<std::string>& output_recipe, const std::vector<std::string>& input_recipe,
double target_frequency = 0.0);

/**
* \brief Reset the RTDE client. As during initialization the driver will start RTDE communication
* with the maximum available frequency, this enables users to start RTDE communication with a
* custom rate.
*
* Note: After calling this function startRTDECommunication() has to be called again to actually
* start RTDE communication.
*
* \param output_recipe_filename Filename where the output recipe is stored in.
* \param input_recipe_filename Filename where the input recipe is stored in.
* \param target_frequency Frequency to run the RTDE client at. Defaults to 0.0 which means maximum frequency.
*/
void resetRTDEClient(const std::string& output_recipe_filename, const std::string& input_recipe_filename,
double target_frequency = 0.0);

private:
static std::string readScriptFile(const std::string& filename);
/*!
Expand All @@ -498,7 +528,9 @@ class UrDriver
*/
bool reconnectSecondaryStream();

int rtde_frequency_;
void initRTDE();
void setupReverseInterface(const uint32_t reverse_port);

comm::INotifier notifier_;
std::unique_ptr<rtde_interface::RTDEClient> rtde_client_;
std::unique_ptr<control::ReverseInterface> reverse_interface_;
Expand All @@ -510,7 +542,6 @@ class UrDriver

uint32_t servoj_gain_;
double servoj_lookahead_time_;
std::chrono::milliseconds step_time_;

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

Expand Down
42 changes: 33 additions & 9 deletions src/ur/ur_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ urcl::UrDriver::UrDriver(const std::string& robot_ip, const std::string& script_
const uint32_t script_command_port, double force_mode_damping, double force_mode_gain_scaling)
: servoj_gain_(servoj_gain)
, servoj_lookahead_time_(servoj_lookahead_time)
, step_time_(std::chrono::milliseconds(8))
, handle_program_state_(handle_program_state)
, robot_ip_(robot_ip)
{
Expand All @@ -78,13 +77,8 @@ urcl::UrDriver::UrDriver(const std::string& robot_ip, const std::string& script_
non_blocking_read_ = non_blocking_read;
get_packet_timeout_ = non_blocking_read_ ? 0 : 100;

if (!rtde_client_->init())
{
throw UrException("Initialization of RTDE client went wrong.");
}

rtde_frequency_ = rtde_client_->getMaxFrequency();
step_time_ = std::chrono::milliseconds(1000 / rtde_frequency_);
initRTDE();
setupReverseInterface(reverse_port);

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

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

Expand Down Expand Up @@ -621,4 +614,35 @@ void UrDriver::setKeepaliveCount(const uint32_t count)
reverse_interface_->setKeepaliveCount(count);
}

void UrDriver::resetRTDEClient(const std::vector<std::string>& output_recipe,
const std::vector<std::string>& input_recipe, double target_frequency)
{
rtde_client_.reset(
new rtde_interface::RTDEClient(robot_ip_, notifier_, output_recipe, input_recipe, target_frequency));
initRTDE();
}

void UrDriver::resetRTDEClient(const std::string& output_recipe_filename, const std::string& input_recipe_filename,
double target_frequency)
{
rtde_client_.reset(new rtde_interface::RTDEClient(robot_ip_, notifier_, output_recipe_filename, input_recipe_filename,
target_frequency));
initRTDE();
}

void UrDriver::initRTDE()
{
if (!rtde_client_->init())
{
throw UrException("Initialization of RTDE client went wrong.");
}
}

void UrDriver::setupReverseInterface(const uint32_t reverse_port)
{
auto rtde_frequency = rtde_client_->getTargetFrequency();
auto step_time = std::chrono::milliseconds(static_cast<int>(1000 / rtde_frequency));
reverse_interface_.reset(new control::ReverseInterface(reverse_port, handle_program_state_, step_time));
}

} // namespace urcl
7 changes: 7 additions & 0 deletions tests/test_ur_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,13 @@ TEST_F(UrDriverTest, send_robot_program_retry_on_failure)
EXPECT_TRUE(g_ur_driver_->sendRobotProgram());
}

TEST_F(UrDriverTest, reset_rtde_client)
{
double target_frequency = 50;
g_ur_driver_->resetRTDEClient(OUTPUT_RECIPE, INPUT_RECIPE, target_frequency);
ASSERT_EQ(g_ur_driver_->getControlFrequency(), target_frequency);
}

// TODO we should add more tests for the UrDriver class.

int main(int argc, char* argv[])
Expand Down
Loading