tool_contact_example.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // Copyright 2022 Universal Robots A/S
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 //
10 // http://www.apache.org/licenses/LICENSE-2.0
11 //
12 // Unless required by applicable law or agreed to in writing, software
13 // distributed under the License is distributed on an "AS IS" BASIS,
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 // See the License for the specific language governing permissions and
16 // limitations under the License.
17 //
18 // -- END LICENSE BLOCK ------------------------------------------------
19 
20 // In a real-world example it would be better to get those values from command line parameters / a
21 // better configuration system such as Boost.Program_options
22 
26 
27 #include <iostream>
28 #include <memory>
29 
30 using namespace urcl;
31 
32 const std::string DEFAULT_ROBOT_IP = "192.168.56.101";
33 const std::string SCRIPT_FILE = "resources/external_control.urscript";
34 const std::string OUTPUT_RECIPE = "examples/resources/rtde_output_recipe.txt";
35 const std::string INPUT_RECIPE = "examples/resources/rtde_input_recipe.txt";
36 const std::string CALIBRATION_CHECKSUM = "calib_12788084448423163542";
37 
38 std::unique_ptr<UrDriver> g_my_driver;
39 std::unique_ptr<DashboardClient> g_my_dashboard;
42 
43 // We need a callback function to register. See UrDriver's parameters for details.
44 void handleRobotProgramState(bool program_running)
45 {
46  // Print the text in green so we see it better
47  std::cout << "\033[1;32mProgram running: " << std::boolalpha << program_running << "\033[0m\n" << std::endl;
48 }
49 
51 {
52  // Print the text in green so we see it better
53  std::cout << "\033[1;32mTool contact result: " << toUnderlying(result) << "\033[0m\n" << std::endl;
54  g_tool_contact_result = result;
56 }
57 
58 int main(int argc, char* argv[])
59 {
61  // Parse the ip arguments if given
62  std::string robot_ip = DEFAULT_ROBOT_IP;
63  if (argc > 1)
64  {
65  robot_ip = std::string(argv[1]);
66  }
67 
68  // Parse how many seconds to run
69  auto second_to_run = std::chrono::seconds(0);
70  if (argc > 2)
71  {
72  second_to_run = std::chrono::seconds(std::stoi(argv[2]));
73  }
74 
75  // Making the robot ready for the program by:
76  // Connect the the robot Dashboard
77  g_my_dashboard.reset(new DashboardClient(robot_ip));
78  if (!g_my_dashboard->connect())
79  {
80  URCL_LOG_ERROR("Could not connect to dashboard");
81  return 1;
82  }
83 
84  // // Stop program, if there is one running
85  if (!g_my_dashboard->commandStop())
86  {
87  URCL_LOG_ERROR("Could not send stop program command");
88  return 1;
89  }
90 
91  // Power it off
92  if (!g_my_dashboard->commandPowerOff())
93  {
94  URCL_LOG_ERROR("Could not send Power off command");
95  return 1;
96  }
97 
98  // Power it on
99  if (!g_my_dashboard->commandPowerOn())
100  {
101  URCL_LOG_ERROR("Could not send Power on command");
102  return 1;
103  }
104 
105  // Release the brakes
106  if (!g_my_dashboard->commandBrakeRelease())
107  {
108  URCL_LOG_ERROR("Could not send BrakeRelease command");
109  return 1;
110  }
111 
112  // Now the robot is ready to receive a program
113  std::unique_ptr<ToolCommSetup> tool_comm_setup;
114  const bool HEADLESS = true;
116  std::move(tool_comm_setup), CALIBRATION_CHECKSUM));
117  g_my_driver->setKeepaliveCount(5); // This is for example purposes only. This will make the example running more
118  // reliable on non-realtime systems. Do not use this in productive applications.
119 
120  g_my_driver->registerToolContactResultCallback(&handleToolContactResult);
121 
122  // Once RTDE communication is started, we have to make sure to read from the interface buffer, as
123  // otherwise we will get pipeline overflows. Therefor, do this directly before starting your main
124  // loop.
125  g_my_driver->startRTDECommunication();
126 
127  // This will move the robot downward in the z direction of the base until a tool contact is detected or seconds_to_run
128  // is reached
129  std::chrono::duration<double> time_done(0);
130  std::chrono::duration<double> timeout(second_to_run);
131  vector6d_t tcp_speed = { 0.0, 0.0, -0.02, 0.0, 0.0, 0.0 };
132  auto stopwatch_last = std::chrono::steady_clock::now();
133  auto stopwatch_now = stopwatch_last;
134  g_my_driver->startToolContact();
135 
136  while (true)
137  {
138  // Read latest RTDE package. This will block for a hard-coded timeout (see UrDriver), so the
139  // robot will effectively be in charge of setting the frequency of this loop.
140  // In a real-world application this thread should be scheduled with real-time priority in order
141  // to ensure that this is called in time.
142  std::unique_ptr<rtde_interface::DataPackage> data_pkg = g_my_driver->getDataPackage();
143  if (data_pkg)
144  {
145  bool ret = g_my_driver->writeJointCommand(tcp_speed, comm::ControlMode::MODE_SPEEDL);
146  if (!ret)
147  {
148  URCL_LOG_ERROR("Could not send joint command. Is the robot in remote control?");
149  return 1;
150  }
151 
153  {
154  URCL_LOG_INFO("Tool contact result triggered. Received tool contact result %i.",
156  break;
157  }
158 
159  if (time_done > timeout && second_to_run.count() != 0)
160  {
161  URCL_LOG_INFO("Timed out before reaching tool contact.");
162  break;
163  }
164  }
165  else
166  {
167  URCL_LOG_WARN("Could not get fresh data package from robot");
168  }
169 
170  stopwatch_now = std::chrono::steady_clock::now();
171  time_done += stopwatch_now - stopwatch_last;
172  stopwatch_last = stopwatch_now;
173  }
174 }
#define URCL_LOG_ERROR(...)
Definition: log.h:26
This is the main class for interfacing the driver.
Definition: ur_driver.h:52
std::unique_ptr< DashboardClient > g_my_dashboard
bool g_tool_contact_result_triggered
const std::string SCRIPT_FILE
void handleToolContactResult(control::ToolContactResult result)
void setLogLevel(LogLevel level)
Set log level this will disable messages with lower log level.
Definition: log.cpp:101
const std::string INPUT_RECIPE
control::ToolContactResult g_tool_contact_result
int main(int argc, char *argv[])
const std::string CALIBRATION_CHECKSUM
const std::string OUTPUT_RECIPE
#define URCL_LOG_WARN(...)
Definition: log.h:24
void handleRobotProgramState(bool program_running)
const std::string DEFAULT_ROBOT_IP
constexpr std::underlying_type< E >::type toUnderlying(const E e) noexcept
Converts an enum type to its underlying type.
Definition: types.h:58
This class is a wrapper around the dashboard server.
ToolContactResult
Types for encoding until tool contact execution result.
std::array< double, 6 > vector6d_t
Definition: types.h:30
Set when cartesian velocity control is active.
#define URCL_LOG_INFO(...)
Definition: log.h:25
std::unique_ptr< UrDriver > g_my_driver


ur_client_library
Author(s): Thomas Timm Andersen, Simon Rasmussen, Felix Exner, Lea Steffen, Tristan Schnell
autogenerated on Tue Jul 4 2023 02:09:47