4545#include " ur_client_library/exceptions.h"
4646#include " ur_client_library/ur/tool_communication.h"
4747#include " ur_client_library/ur/version_information.h"
48+ #include " ur_client_library/ur/robot_receive_timeout.h"
4849
4950#include < rclcpp/logging.hpp>
5051#include " hardware_interface/types/hardware_interface_type_values.hpp"
@@ -93,9 +94,10 @@ URPositionHardwareInterface::on_init(const hardware_interface::HardwareInfo& sys
9394 freedrive_mode_abort_ = 0.0 ;
9495 passthrough_trajectory_transfer_state_ = 0.0 ;
9596 passthrough_trajectory_abort_ = 0.0 ;
96- trajectory_joint_positions_.clear ();
97- trajectory_joint_velocities_.clear ();
98- trajectory_joint_accelerations_.clear ();
97+ passthrough_trajectory_size_ = 0.0 ;
98+ trajectory_joint_positions_.reserve (32768 );
99+ trajectory_joint_velocities_.reserve (32768 );
100+ trajectory_joint_accelerations_.reserve (32768 );
99101
100102 for (const hardware_interface::ComponentInfo& joint : info_.joints ) {
101103 if (joint.command_interfaces .size () != 2 ) {
@@ -381,6 +383,9 @@ std::vector<hardware_interface::CommandInterface> URPositionHardwareInterface::e
381383 command_interfaces.emplace_back (
382384 hardware_interface::CommandInterface (tf_prefix + PASSTHROUGH_GPIO, " abort" , &passthrough_trajectory_abort_));
383385
386+ command_interfaces.emplace_back (hardware_interface::CommandInterface (tf_prefix + PASSTHROUGH_GPIO, " trajectory_size" ,
387+ &passthrough_trajectory_size_));
388+
384389 for (size_t i = 0 ; i < 6 ; ++i) {
385390 command_interfaces.emplace_back (hardware_interface::CommandInterface (tf_prefix + PASSTHROUGH_GPIO,
386391 " setpoint_positions_" + std::to_string (i),
@@ -527,6 +532,9 @@ URPositionHardwareInterface::on_configure(const rclcpp_lifecycle::State& previou
527532 std::bind (&URPositionHardwareInterface::handleRobotProgramState, this , std::placeholders::_1), headless_mode,
528533 std::move (tool_comm_setup), (uint32_t )reverse_port, (uint32_t )script_sender_port, servoj_gain,
529534 servoj_lookahead_time, non_blocking_read_, reverse_ip, trajectory_port, script_command_port);
535+ if (ur_driver_->getControlFrequency () != info_.rw_rate ) {
536+ ur_driver_->resetRTDEClient (output_recipe_filename, input_recipe_filename, info_.rw_rate );
537+ }
530538 } catch (urcl::ToolCommNotAvailable& e) {
531539 RCLCPP_FATAL_STREAM (rclcpp::get_logger (" URPositionHardwareInterface" ), " See parameter use_tool_communication" );
532540
@@ -773,7 +781,9 @@ hardware_interface::return_type URPositionHardwareInterface::write(const rclcpp:
773781 ur_driver_->writeFreedriveControlMessage (urcl::control::FreedriveControlMessage::FREEDRIVE_NOOP);
774782
775783 } else if (passthrough_trajectory_controller_running_) {
776- ur_driver_->writeTrajectoryControlMessage (urcl::control::TrajectoryControlMessage::TRAJECTORY_NOOP);
784+ ur_driver_->writeTrajectoryControlMessage (
785+ urcl::control::TrajectoryControlMessage::TRAJECTORY_NOOP, 0 ,
786+ urcl::RobotReceiveTimeout::millisec (1000 * 5.0 / static_cast <double >(info_.rw_rate )));
777787 check_passthrough_trajectory_controller ();
778788 } else {
779789 ur_driver_->writeKeepalive ();
@@ -1309,59 +1319,87 @@ void URPositionHardwareInterface::stop_force_mode()
13091319void URPositionHardwareInterface::check_passthrough_trajectory_controller ()
13101320{
13111321 static double last_time = 0.0 ;
1322+ static size_t point_index_received = 0 ;
1323+ static size_t point_index_sent = 0 ;
1324+ static bool trajectory_started = false ;
13121325 // See passthrough_trajectory_controller.hpp for an explanation of the passthrough_trajectory_transfer_state_ values.
13131326
13141327 // We should abort and are not in state IDLE
13151328 if (passthrough_trajectory_abort_ == 1.0 && passthrough_trajectory_transfer_state_ != 0.0 ) {
13161329 ur_driver_->writeTrajectoryControlMessage (urcl::control::TrajectoryControlMessage::TRAJECTORY_CANCEL);
1330+ } else if (passthrough_trajectory_transfer_state_ == 1.0 ) {
1331+ if (passthrough_trajectory_size_ != trajectory_joint_positions_.size ()) {
1332+ RCLCPP_INFO (get_logger (), " Got a new trajectory with %lu points." ,
1333+ static_cast <size_t >(passthrough_trajectory_size_));
1334+ trajectory_joint_positions_.resize (passthrough_trajectory_size_);
1335+ trajectory_joint_velocities_.resize (passthrough_trajectory_size_);
1336+ trajectory_joint_accelerations_.resize (passthrough_trajectory_size_);
1337+ trajectory_times_.resize (passthrough_trajectory_size_);
1338+ point_index_received = 0 ;
1339+ point_index_sent = 0 ;
1340+ trajectory_started = false ;
1341+ last_time = 0.0 ;
1342+ }
13171343 } else if (passthrough_trajectory_transfer_state_ == 2.0 ) {
13181344 passthrough_trajectory_abort_ = 0.0 ;
1319- trajectory_joint_positions_. push_back ( passthrough_trajectory_positions_) ;
1345+ trajectory_joint_positions_[point_index_received] = passthrough_trajectory_positions_;
13201346
1321- trajectory_times_. push_back ( passthrough_trajectory_time_from_start_ - last_time) ;
1347+ trajectory_times_[point_index_received] = passthrough_trajectory_time_from_start_ - last_time;
13221348 last_time = passthrough_trajectory_time_from_start_;
13231349
1324- if (!std::isnan (passthrough_trajectory_velocities_[0 ])) {
1325- trajectory_joint_velocities_.push_back (passthrough_trajectory_velocities_);
1326- }
1327- if (!std::isnan (passthrough_trajectory_accelerations_[0 ])) {
1328- trajectory_joint_accelerations_.push_back (passthrough_trajectory_accelerations_);
1329- }
1350+ // if (!std::isnan(passthrough_trajectory_velocities_[0])) {
1351+ trajectory_joint_velocities_[point_index_received] = passthrough_trajectory_velocities_;
1352+ // }
1353+ // if (!std::isnan(passthrough_trajectory_accelerations_[0])) {
1354+ trajectory_joint_accelerations_[point_index_received] = passthrough_trajectory_accelerations_;
1355+ // }
1356+
1357+ point_index_received++;
13301358 passthrough_trajectory_transfer_state_ = 1.0 ;
1359+
1360+ // Once we received enough points so we can move for at least 5 cycles, we start executing
1361+ if ((passthrough_trajectory_time_from_start_ > 5.0 / static_cast <double >(info_.rw_rate ) ||
1362+ point_index_received == passthrough_trajectory_size_ - 1 ) &&
1363+ !trajectory_started) {
1364+ ur_driver_->writeTrajectoryControlMessage (urcl::control::TrajectoryControlMessage::TRAJECTORY_START,
1365+ trajectory_joint_positions_.size ());
1366+ trajectory_started = true ;
1367+ }
13311368 /* When all points have been read, write them to the physical robot controller.*/
13321369 } else if (passthrough_trajectory_transfer_state_ == 3.0 ) {
1333- /* Tell robot controller how many points are in the trajectory. */
1334- ur_driver_->writeTrajectoryControlMessage (urcl::control::TrajectoryControlMessage::TRAJECTORY_START,
1335- trajectory_joint_positions_.size ());
1370+ passthrough_trajectory_abort_ = 0.0 ;
1371+ passthrough_trajectory_transfer_state_ = 4.0 ;
1372+ } else if (passthrough_trajectory_transfer_state_ == 4.0 ) {
1373+ if (point_index_sent == trajectory_joint_positions_.size ()) {
1374+ trajectory_joint_positions_.clear ();
1375+ trajectory_joint_accelerations_.clear ();
1376+ trajectory_joint_velocities_.clear ();
1377+ trajectory_times_.clear ();
1378+ last_time = 0.0 ;
1379+ }
1380+ }
1381+
1382+ // We basically get a setpoint from the controller in each cycle. We send all the points that we
1383+ // already received down to the hardware.
1384+ if (trajectory_started && point_index_sent <= trajectory_joint_positions_.size () &&
1385+ point_index_sent < point_index_received) {
13361386 /* Write the appropriate type of point depending on the combination of positions, velocities and accelerations. */
1337- if (! has_velocities (trajectory_joint_velocities_) && ! has_accelerations (trajectory_joint_accelerations_) ) {
1338- for ( size_t i = 0 ; i < trajectory_joint_positions_. size (); i++ ) {
1387+ for ( size_t i = point_index_sent; i < point_index_received; i++ ) {
1388+ if (! has_velocities (trajectory_joint_velocities_) && ! has_accelerations (trajectory_joint_accelerations_) ) {
13391389 ur_driver_->writeTrajectorySplinePoint (trajectory_joint_positions_[i], urcl::vector6d_t { 0 , 0 , 0 , 0 , 0 , 0 },
13401390 trajectory_times_[i]);
1341- }
1342- } else if (has_velocities (trajectory_joint_velocities_) && !has_accelerations (trajectory_joint_accelerations_)) {
1343- for (size_t i = 0 ; i < trajectory_joint_positions_.size (); i++) {
1391+ } else if (has_velocities (trajectory_joint_velocities_) && !has_accelerations (trajectory_joint_accelerations_)) {
13441392 ur_driver_->writeTrajectorySplinePoint (trajectory_joint_positions_[i], trajectory_joint_velocities_[i],
13451393 trajectory_times_[i]);
1346- }
1347- } else if (!has_velocities (trajectory_joint_velocities_) && has_accelerations (trajectory_joint_accelerations_)) {
1348- for (size_t i = 0 ; i < trajectory_joint_positions_.size (); i++) {
1394+ } else if (!has_velocities (trajectory_joint_velocities_) && has_accelerations (trajectory_joint_accelerations_)) {
13491395 ur_driver_->writeTrajectorySplinePoint (trajectory_joint_positions_[i], trajectory_joint_accelerations_[i],
13501396 trajectory_times_[i]);
1351- }
1352- } else if (has_velocities (trajectory_joint_velocities_) && has_accelerations (trajectory_joint_accelerations_)) {
1353- for (size_t i = 0 ; i < trajectory_joint_positions_.size (); i++) {
1397+ } else if (has_velocities (trajectory_joint_velocities_) && has_accelerations (trajectory_joint_accelerations_)) {
13541398 ur_driver_->writeTrajectorySplinePoint (trajectory_joint_positions_[i], trajectory_joint_velocities_[i],
13551399 trajectory_joint_accelerations_[i], trajectory_times_[i]);
13561400 }
1401+ point_index_sent++;
13571402 }
1358- trajectory_joint_positions_.clear ();
1359- trajectory_joint_accelerations_.clear ();
1360- trajectory_joint_velocities_.clear ();
1361- trajectory_times_.clear ();
1362- last_time = 0.0 ;
1363- passthrough_trajectory_abort_ = 0.0 ;
1364- passthrough_trajectory_transfer_state_ = 4.0 ;
13651403 }
13661404}
13671405
@@ -1378,12 +1416,12 @@ void URPositionHardwareInterface::trajectory_done_callback(urcl::control::Trajec
13781416
13791417bool URPositionHardwareInterface::has_velocities (std::vector<std::array<double , 6 >> velocities)
13801418{
1381- return (velocities.size () > 0 );
1419+ return (velocities.size () > 0 && ! std::isnan (velocities[ 0 ][ 0 ]) );
13821420}
13831421
13841422bool URPositionHardwareInterface::has_accelerations (std::vector<std::array<double , 6 >> accelerations)
13851423{
1386- return (accelerations.size () > 0 );
1424+ return (accelerations.size () > 0 && ! std::isnan (accelerations[ 0 ][ 0 ]) );
13871425}
13881426
13891427} // namespace ur_robot_driver
0 commit comments