How to perform constrained freedrive using ur client library

HI
I am using ur client library to put the robot in free drive and log a csv file for TCP pose and some other metrics. My code is similar to the example provided in the ur client library. I have the following issues and questions.

1- when I put the robot in freedrive using this method it gets into the freedrive mode however it feels stiff to move by hand in a sense that I can still move it the way I want but at the same time it is resisting with the motion and I have to put a lot of physical workload to move the TCP by hand. This is not the case when I put the robot in free drive mode directly using the URsim GUI . Is there anything I should do in the code to get a similar behavior as the GUI?

2- In the GUI it is possible to constraint some or all axes of the robot and only allow the freedrive to happen along certain desired axis. Is there a way to accomplish this using the ur client library as well ?

3- If I switch to using the GUI to put the robot in the freedrive mode, is there a way I can get a data file that has the time stamp of the TCP positions and joints directly from the GUI and retrieve it? if so what is the way to do it.

Here is the code I use to do this.

const std::chrono::milliseconds loop_period(2);
my_robot->getUrDriver()->writeFreedriveControlMessage(urcl::control::FreedriveControlMessage::FREEDRIVE_START);

while (1) {

vector6d_t actual_q_urcl,  actual_tcp_urcl;
 double ts;
  data_pkg->getData("actual_q", actual_q_urcl);
  data_pkg->getData("actual_TCP_pose", actual_tcp_urcl);
  data_pkg->getData("timestamp", ts);
    
auto now = std::chrono::high_resolution_clock::now();
double elapsed = std::chrono::duration(now - last_freedrive_tick).count();
if (elapsed >= 0.02) { // 50 hz
my_robot->getUrDriver()->writeFreedriveControlMessage(urcl::control::FreedriveControlMessage::FREEDRIVE_NOOP);
last_freedrive_tick = now;
}

if (std::chrono::duration(now - last_log_time).count() >=
log_interval) { // 1 hz
csv_file << ts << “,” << vectorToCSV(actual_q_urcl) << “,”
<< vectorToCSV(actual_tcp_urcl) << “\\n”;
last_log_time = now;
}

next_loop_time += loop_period;
std::this_thread::sleep_until(next_loop_time);

}

}

Thanks

Hi, such development questions are best asked in the client_library’s GitHub page, we tend to be much more aware of things getting posted there. I’ll try to answer your questions below.

  1. Using freedrive mode from the client library basically calls this function with default parameters. I don’t know exactly what the TP does but to my knowledge that should be the same (and to be honest, at least on a UR3e I could not feel a difference).
  2. That’s something we currently haven’t got implemented. If it’s always the same, you could modify the script code sent through the client library here.
  3. You can use the client library to create an RTDE client and record data from there. This will also work if you put the robot into freedrive mode from the TP.

I hope that helps, but feel free to add any follow-up comments.

Edit: Did you use constrained freedrive on the teach pendant? If you for example lock freedrive to translation only, it is a lot easier to push the robot around. That also would be the case, if the script function was called with an axis argument.

Thanks for the note. I also looked into the ur client library documentation in here Universal_Robots_Client_Library/doc/examples/freedrive.rst at master · UniversalRobots/Universal_Robots_Client_Library · GitHub and they say The joints move with little resistance because the brakes are released. I am trying to understand why releasing the joints can cause joints to move with resistance and they also say little resistance by we had to put a lot more effort so from my perspective it is high resistance

I guess “little” isn’t a very well defined amount of friction, but I think it is fair, since the robot can be moved around with one hand grabbing it at its tcp.

Just for context: Which robot model are you using?

I am using ur10e robot.
the thing that is strange to me is that there is clear difference between resistance I feel when I use free drive functionality directly from GUI versus doing it through the ur client library.

Are you comparing the same thing? As written above, constrained freedrive (where you lock certain axes) often has less friction and the URCL call always using unconstrained freedrive. Thus, in order to compare the TP to the client_library version, you would have to disable all axis locks on the teach pendant.

For constrained freedrive there’s a feature issue in Add support for Constrained Freedrive · Issue #483 · UniversalRobots/Universal_Robots_Client_Library · GitHub but for now, only unconstrained freedrive is supported by the client library.

yes comparing the same thing. I put the robot in the un-constrained freedrive through ur client lib and also un-constrained freedrive through polyscope GUI and I see the resistance difference between the two. I was thinking that could it be the reason that I also try to log data during free drive and query the joint angles and TCP positions and that somehow makes the robot controller to behave differently . basically in using the urclienet library I send the Free drive NOOP cmd at roughly 50 hz and log a csv at 10 hz all inside a big while (1) loop that runs 500hz . I tried to send the freedrive NOOP cmd at the same rate as 500 hz but it errors out somehow, I think it is complaining about multiple commands being sent or something however the only command I am sending is Freedrive NOOP cmd

We compared both methods on a UR10e trying to do the same motion once with free drive through URCL and once through the TP. We recorded measurements from the force torque sensor and they are very similar (taken the human error of executing “the same motion” into account).

Regarding the 500Hz multiple commands issue: Instead of sleeping in your main loop, you might want to wait for new RTDE packages to arrive to pace your loop.