Force Mode example
The ur_client_library
supports leveraging the robot’s force mode directly. An example on how to
use it can be found in force_mode_example.cpp.
In order to utilize force mode, we’ll have to create and initialize a driver object
first. We use the ExampleRobotWrapper
class for this example. That starts a UrDriver
and a DashboardClient to communicate with the robot:
85 bool headless_mode = true;
86 g_my_robot = std::make_unique<ExampleRobotWrapper>(robot_ip, OUTPUT_RECIPE, INPUT_RECIPE, headless_mode,
87 "external_control.urp");
88
89 if (!g_my_robot->isHealthy())
90 {
91 URCL_LOG_ERROR("Something in the robot initialization went wrong. Exiting. Please check the output above.");
92 return 1;
93 }
94 if (!g_my_robot->ur_driver_->checkCalibration(CALIBRATION_CHECKSUM))
95 {
96 URCL_LOG_ERROR("Calibration checksum does not match actual robot.");
97 URCL_LOG_ERROR("Use the ur_calibration tool to extract the correct calibration from the robot and pass that into "
98 "the description. See "
99 "[https://github.com/UniversalRobots/Universal_Robots_ROS_Driver#extract-calibration-information] "
100 "for details.");
101 }
102
103 // End of initialization -- We've started the external control program, which means we have to
Start force mode
After that, we can start force mode by calling the startForceMode()
function:
106 // Start force mode
107 // Task frame at the robot's base with limits being large enough to cover the whole workspace
108 // Compliance in z axis and rotation around z axis
109 bool success;
110 if (g_my_robot->ur_driver_->getVersion().major < 5)
111 success =
112 g_my_robot->ur_driver_->startForceMode({ 0, 0, 0, 0, 0, 0 }, // Task frame at the robot's base
113 { 0, 0, 1, 0, 0, 1 }, // Compliance in z axis and rotation around z axis
114 { 0, 0, -2, 0, 0, 0 }, // Press in -z direction
115 2, // do not transform the force frame at all
116 { 0.1, 0.1, 1.5, 3.14, 3.14, 0.5 }, // limits
117 0.005); // damping_factor. See ScriptManual for details.
118 else
119 {
120 success =
121 g_my_robot->ur_driver_->startForceMode({ 0, 0, 0, 0, 0, 0 }, // Task frame at the robot's base
122 { 0, 0, 1, 0, 0, 1 }, // Compliance in z axis and rotation around z axis
123 { 0, 0, -2, 0, 0, 0 }, // Press in -z direction
124 2, // do not transform the force frame at all
125 { 0.1, 0.1, 1.5, 3.14, 3.14, 0.5 }, // limits
126 0.005, // damping_factor
127 1.0); // gain_scaling. See ScriptManual for details.
128 }
129 if (!success)
All parameters for the force mode are included into the startForceMode()
function call. If you
want to change the parameters, e.g. change the forces applied, you can simply call
startForceMode()
again with the new parameters.
Note
CB3 robots don’t support specifying force_mode’s gain_scaling
, so there are two different
functions available.
Once force mode is started successfully, we’ll have to send keepalive messages to the robot in order to keep the communication active:
135 std::chrono::duration<double> time_done(0);
136 std::chrono::duration<double> timeout(second_to_run);
137 auto stopwatch_last = std::chrono::steady_clock::now();
138 auto stopwatch_now = stopwatch_last;
139 while (time_done < timeout || second_to_run.count() == 0)
140 {
141 g_my_robot->ur_driver_->writeKeepalive();
142
143 stopwatch_now = std::chrono::steady_clock::now();
144 time_done += stopwatch_now - stopwatch_last;
145 stopwatch_last = stopwatch_now;
146 std::this_thread::sleep_for(std::chrono::milliseconds(2));
147 }
148 URCL_LOG_INFO("Timeout reached.");
Stop force mode
Once finished, force_mode can be stopped by calling endForceMode()
.
149 g_my_robot->ur_driver_->endForceMode();