46 static const std::string
TIME_REPLACE(
"{{TIME_REPLACE}}");
56 const std::string& output_recipe_file,
const std::string& input_recipe_file,
57 std::function<
void(
bool)> handle_program_state,
bool headless_mode,
58 std::unique_ptr<ToolCommSetup> tool_comm_setup,
const uint32_t reverse_port,
59 const uint32_t script_sender_port,
int servoj_gain,
double servoj_lookahead_time,
60 bool non_blocking_read,
const std::string& reverse_ip,
const uint32_t trajectory_port,
61 const uint32_t script_command_port,
double force_mode_damping,
double force_mode_gain_scaling)
63 , servoj_gain_(servoj_gain)
64 , servoj_lookahead_time_(servoj_lookahead_time)
65 , handle_program_state_(handle_program_state)
83 throw UrException(
"Initialization of RTDE client went wrong.");
90 std::string local_ip = reverse_ip.empty() ?
rtde_client_->getIP() : reverse_ip;
104 std::ostringstream out;
129 std::to_string(script_command_port));
134 if (force_mode_damping < 0 || force_mode_damping > 1)
136 std::stringstream ss;
137 ss <<
"Force mode damping, should be between 0 and 1, but it is " << force_mode_damping;
138 force_mode_damping = 0.025;
139 ss <<
" setting it to default " << force_mode_damping;
143 std::to_string(force_mode_damping));
152 std::stringstream ss;
154 prog.replace(prog.find(ss.str()), ss.str().length(),
"");
158 if (force_mode_gain_scaling < 0 || force_mode_gain_scaling > 2)
160 std::stringstream ss;
161 ss <<
"Force mode gain scaling, should be between 0 and 2, but it is " << force_mode_gain_scaling;
162 force_mode_gain_scaling = 0.5;
163 ss <<
" setting it to default " << force_mode_gain_scaling;
167 std::to_string(force_mode_gain_scaling));
173 std::stringstream begin_replace;
174 if (tool_comm_setup !=
nullptr)
178 throw ToolCommNotAvailable(
"Tool communication setup requested, but this robot version does not support using " 179 "the tool communication interface. Please check your configuration.",
182 begin_replace <<
"set_tool_voltage(" 183 <<
static_cast<std::underlying_type<ToolVoltage>::type
>(tool_comm_setup->getToolVoltage()) <<
")\n";
184 begin_replace <<
"set_tool_communication(" 186 <<
", " << tool_comm_setup->getBaudRate() <<
", " 187 <<
static_cast<std::underlying_type<Parity>::type
>(tool_comm_setup->getParity()) <<
", " 188 << tool_comm_setup->getStopBits() <<
", " << tool_comm_setup->getRxIdleChars() <<
", " 189 << tool_comm_setup->getTxIdleChars() <<
")";
198 std::istringstream prog_stream(prog);
200 while (std::getline(prog_stream, line))
221 const std::string& output_recipe_file,
const std::string& input_recipe_file,
222 std::function<
void(
bool)> handle_program_state,
bool headless_mode,
223 std::unique_ptr<ToolCommSetup> tool_comm_setup,
const std::string& calibration_checksum,
224 const uint32_t reverse_port,
const uint32_t script_sender_port,
int servoj_gain,
225 double servoj_lookahead_time,
bool non_blocking_read,
const std::string& reverse_ip,
226 const uint32_t trajectory_port,
const uint32_t script_command_port,
double force_mode_damping,
227 double force_mode_gain_scaling)
228 :
UrDriver(robot_ip, script_file, output_recipe_file, input_recipe_file, handle_program_state, headless_mode,
229 std::move(tool_comm_setup), reverse_port, script_sender_port, servoj_gain, servoj_lookahead_time,
230 non_blocking_read, reverse_ip, trajectory_port, script_command_port, force_mode_damping,
231 force_mode_gain_scaling)
233 URCL_LOG_WARN(
"DEPRECATION NOTICE: Passing the calibration_checksum to the UrDriver's constructor has been " 234 "deprecated. Instead, use the checkCalibration(calibration_checksum) function separately. This " 235 "notice is for application developers using this library. If you are only using an application using " 236 "this library, you can ignore this message.");
243 URCL_LOG_ERROR(
"The calibration parameters of the connected robot don't match the ones from the given kinematics " 244 "config file. Please be aware that this can lead to critical inaccuracies of tcp positions. Use " 245 "the ur_calibration tool to extract the correct calibration from the robot and pass that into the " 247 "[https://github.com/UniversalRobots/Universal_Robots_ROS_Driver#extract-calibration-information] " 268 const float blend_radius)
274 const vector6d_t& accelerations,
const float goal_time)
276 return trajectory_interface_->writeTrajectorySplinePoint(&positions, &velocities, &accelerations, goal_time);
280 const float goal_time)
282 return trajectory_interface_->writeTrajectorySplinePoint(&positions, &velocities,
nullptr, goal_time);
291 const int point_number)
293 return reverse_interface_->writeTrajectoryControlMessage(trajectory_action, point_number);
305 std::stringstream ss;
306 ss <<
"Zeroing the Force-Torque sensor is only available for e-Series robots (Major version >= 5). This robot's " 320 URCL_LOG_WARN(
"Script command interface is not running. Falling back to sending plain script code. This will " 321 "only work, if the robot is in remote_control mode.");
322 std::stringstream cmd;
323 cmd <<
"sec tareSetup():" << std::endl <<
" zero_ftsensor()" << std::endl <<
"end";
337 URCL_LOG_WARN(
"Script command interface is not running. Falling back to sending plain script code. On e-Series " 338 "robots this will only work, if the robot is in remote_control mode.");
339 std::stringstream cmd;
340 cmd.imbue(std::locale::classic());
341 cmd <<
"sec setup():" << std::endl
342 <<
" set_payload(" << mass <<
", [" << cog[0] <<
", " << cog[1] <<
", " << cog[2] <<
"])" << std::endl
360 std::stringstream ss;
361 ss <<
"The tool voltage should be 0, 12 or 24. The tool voltage is " <<
toUnderlying(voltage);
372 URCL_LOG_WARN(
"Script command interface is not running. Falling back to sending plain script code. On e-Series " 373 "robots this will only work, if the robot is in remote_control mode.");
374 std::stringstream cmd;
375 cmd <<
"sec setup():" << std::endl <<
" set_tool_voltage(" <<
toUnderlying(voltage) <<
")" << std::endl <<
"end";
393 std::stringstream ss;
394 ss <<
"The type should be 1, 2 or 3. The type is " << type;
398 for (
unsigned int i = 0; i < selection_vector.size(); ++i)
400 if (selection_vector[i] > 1)
402 URCL_LOG_ERROR(
"The selection vector should only consist of 0's and 1's");
413 URCL_LOG_ERROR(
"Script command interface is not running. Unable to start Force mode.");
426 URCL_LOG_ERROR(
"Script command interface is not running. Unable to end Force mode.");
435 std::stringstream ss;
436 ss <<
"Tool contact is only available for e-Series robots (Major version >= 5). This robot's " 449 URCL_LOG_ERROR(
"Script command interface is not running. Unable to enable tool contact mode.");
458 std::stringstream ss;
459 ss <<
"Tool contact is only available for e-Series robots (Major version >= 5). This robot's " 472 URCL_LOG_ERROR(
"Script command interface is not running. Unable to end tool contact mode.");
496 std::ifstream ifs(filename);
497 std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
506 throw std::runtime_error(
"checkCalibration() called without a primary interface connection being established.");
521 std::this_thread::sleep_for(std::chrono::seconds(1));
536 throw std::runtime_error(
"Sending script to robot requested while there is no primary interface established. " 538 "should not happen.");
544 auto program_with_newline = program +
'\n';
546 size_t len = program_with_newline.size();
547 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(program_with_newline.c_str());
552 URCL_LOG_DEBUG(
"Sent program to robot:\n%s", program_with_newline.c_str());
567 URCL_LOG_ERROR(
"Tried to send robot program directly while not in headless mode");
static const std::string SERVER_IP_REPLACE("{{SERVER_IP_REPLACE}}")
std::unique_ptr< control::ReverseInterface > reverse_interface_
UrDriver(const std::string &robot_ip, const std::string &script_file, const std::string &output_recipe_file, const std::string &input_recipe_file, std::function< void(bool)> handle_program_state, bool headless_mode, std::unique_ptr< ToolCommSetup > tool_comm_setup, const uint32_t reverse_port=50001, const uint32_t script_sender_port=50002, int servoj_gain=2000, double servoj_lookahead_time=0.03, bool non_blocking_read=false, const std::string &reverse_ip="", const uint32_t trajectory_port=50003, const uint32_t script_command_port=50004, double force_mode_damping=0.025, double force_mode_gain_scaling=0.5)
Constructs a new UrDriver object. Upon initialization this class will check the calibration checksum ...
#define URCL_LOG_ERROR(...)
This is the main class for interfacing the driver.
ToolVoltage
Possible values for the tool voltage.
static const int32_t MULT_JOINTSTATE
bool writeJointCommand(const vector6d_t &values, const comm::ControlMode control_mode)
Writes a joint command together with a keepalive signal onto the socket being sent to the robot...
void setupProducer() override
Triggers the stream to connect to the robot.
void run()
Starts the producer and, if existing, the consumer in new threads.
The ScriptCommandInterface class starts a TCPServer for a robot to connect to and this connection is ...
comm::INotifier notifier_
VersionInformation robot_version_
FreedriveControlMessage
Control messages for starting and stopping freedrive mode.
The TrajectoryPointInterface class handles trajectory forwarding to the robot. Full trajectories are ...
static const std::string JOINT_STATE_REPLACE("{{JOINT_STATE_REPLACE}}")
The stream is an abstraction of the TCPSocket that offers reading a full UR data package out of the s...
std::string readScriptFile(const std::string &filename)
std::vector< std::string > getRTDEOutputRecipe()
Getter for the RTDE output recipe used in the RTDE client.
static const std::string TIME_REPLACE("{{TIME_REPLACE}}")
bool sendRobotProgram()
Sends the external control program to the robot.
The primary specific parser. Interprets a given byte stream as serialized primary packages and parses...
bool endToolContact()
This will stop the robot from looking for a tool contact, it will also enable sending move commands t...
bool writeTrajectorySplinePoint(const vector6d_t &positions, const vector6d_t &velocities, const vector6d_t &accelerations, const float goal_time=0.0)
Writes a trajectory spline point for quintic spline interpolation onto the dedicated socket...
std::array< double, 3 > vector3d_t
void startRTDECommunication()
Starts the RTDE communication.
Set when no controller is currently active controlling the robot.
bool setPayload(const float mass, const vector3d_t &cog)
Set the payload mass and center of gravity. Note: It requires the external control script to be runni...
The RTDEWriter class offers an abstraction layer to send data to the robot via the RTDE interface...
bool stopControl()
Sends a stop command to the socket interface which will signal the program running on the robot to no...
std::unique_ptr< control::ScriptSender > script_sender_
const VersionInformation & getVersion()
Returns version information about the currently connected robot.
std::unique_ptr< control::ScriptCommandInterface > script_command_interface_
std::unique_ptr< control::TrajectoryPointInterface > trajectory_interface_
rtde_interface::RTDEWriter & getRTDEWriter()
Getter for the RTDE writer used to write to the robot's RTDE interface.
static const std::string SERVO_J_REPLACE("{{SERVO_J_REPLACE}}")
Parent class for notifiers.
std::string full_robot_program_
#define URCL_LOG_DEBUG(...)
static const std::string FORCE_MODE_SET_GAIN_SCALING_REPLACE("{{FORCE_MODE_SET_GAIN_SCALING_REPLACE}}")
static const std::string SERVER_PORT_REPLACE("{{SERVER_PORT_REPLACE}}")
bool writeKeepalive()
Write a keepalive signal only.
bool sendScript(const std::string &program)
Sends a custom script program to the robot.
std::unique_ptr< comm::URStream< primary_interface::PrimaryPackage > > primary_stream_
bool setToolVoltage(const ToolVoltage voltage)
Set the tool voltage. Note: It requires the external control script to be running or the robot to be ...
bool isChecked()
Used to make sure the calibration check is not performed several times.
static const std::string TRAJECTORY_PORT_REPLACE("{{TRAJECTORY_SERVER_PORT_REPLACE}}")
bool zeroFTSensor()
Zero the force torque sensor (only availbe on e-Series). Note: It requires the external control scrip...
ControlMode
Control modes as interpreted from the script runnning on the robot.
bool startForceMode(const vector6d_t &task_frame, const vector6uint32_t &selection_vector, const vector6d_t &wrench, const unsigned int type, const vector6d_t &limits)
Start the robot to be controlled in force mode.
When this is set, the program is expected to stop and exit.
#define URCL_LOG_WARN(...)
std::unique_ptr< rtde_interface::DataPackage > getDataPackage()
Access function to receive the latest data package sent from the robot through RTDE interface...
The ScriptSender class starts a TCPServer for a robot to connect to and waits for a request to receiv...
bool writeTrajectoryPoint(const vector6d_t &positions, const bool cartesian, const float goal_time=0.0, const float blend_radius=0.052)
Writes a trajectory point onto the dedicated socket.
bool startToolContact()
This will make the robot look for tool contact in the tcp directions that the robot is currently movi...
std::unique_ptr< rtde_interface::RTDEClient > rtde_client_
bool writeFreedriveControlMessage(const control::FreedriveControlMessage freedrive_action)
Writes a control message in freedrive mode.
constexpr std::underlying_type< E >::type toUnderlying(const E e) noexcept
Converts an enum type to its underlying type.
TrajectoryControlMessage
Control messages for forwarding and aborting trajectories.
bool writeTrajectoryControlMessage(const control::TrajectoryControlMessage trajectory_action, const int point_number=0)
Writes a control message in trajectory forward mode.
The CalibrationChecker class consumes primary packages ignoring all but KinematicsInfo packages...
The RTDEClient class manages communication over the RTDE interface. It contains the RTDE handshake an...
static const int UR_SECONDARY_PORT
bool checkCalibration(const std::string &checksum)
Checks if the kinematics information in the used model fits the actual robot.
double servoj_lookahead_time_
static const std::string BEGIN_REPLACE("{{BEGIN_REPLACE}}")
std::array< uint32_t, 6 > vector6uint32_t
static const std::string SCRIPT_COMMAND_PORT_REPLACE("{{SCRIPT_COMMAND_SERVER_PORT_REPLACE}}")
std::array< double, 6 > vector6d_t
static const std::string FORCE_MODE_SET_DAMPING_REPLACE("{{FORCE_MODE_SET_DAMPING_REPLACE}}")
bool checkSuccessful()
Returns whether the calibration check was successful.
static const int32_t MULT_TIME
The Pipepline manages the production and optionally consumption of packages. Cyclically the producer ...
#define URCL_LOG_INFO(...)
std::unique_ptr< comm::URStream< primary_interface::PrimaryPackage > > secondary_stream_
A general producer for URPackages. Implements funcionality to produce packages by reading and parsing...
The ReverseInterface class handles communication to the robot. It starts a server and waits for the r...
Our base class for exceptions. Specialized exceptions should inherit from those.
static const int UR_PRIMARY_PORT
void setKeepaliveCount(const uint32_t &count)
Set the Keepalive count. This will set the number of allowed timeout reads on the robot...
bool endForceMode()
Stop force mode and put the robot into normal operation mode.