force_mode_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 <chrono>
28 #include <cstdlib>
29 #include <iostream>
30 #include <memory>
31 #include <thread>
33 
34 using namespace urcl;
35 
36 const std::string DEFAULT_ROBOT_IP = "192.168.56.101";
37 const std::string SCRIPT_FILE = "resources/external_control.urscript";
38 const std::string OUTPUT_RECIPE = "examples/resources/rtde_output_recipe.txt";
39 const std::string INPUT_RECIPE = "examples/resources/rtde_input_recipe.txt";
40 const std::string CALIBRATION_CHECKSUM = "calib_12788084448423163542";
41 
42 std::unique_ptr<UrDriver> g_my_driver;
43 std::unique_ptr<DashboardClient> g_my_dashboard;
44 
45 // We need a callback function to register. See UrDriver's parameters for details.
46 void handleRobotProgramState(bool program_running)
47 {
48  // Print the text in green so we see it better
49  std::cout << "\033[1;32mProgram running: " << std::boolalpha << program_running << "\033[0m\n" << std::endl;
50 }
51 
53 {
54  bool ret = g_my_driver->writeFreedriveControlMessage(freedrive_action);
55  if (!ret)
56  {
57  URCL_LOG_ERROR("Could not send joint command. Is the robot in remote control?");
58  exit(1);
59  }
60 }
61 
62 int main(int argc, char* argv[])
63 {
65  // Parse the ip arguments if given
66  std::string robot_ip = DEFAULT_ROBOT_IP;
67  if (argc > 1)
68  {
69  robot_ip = std::string(argv[1]);
70  }
71 
72  // Parse how many seconds to run
73  auto second_to_run = std::chrono::seconds(0);
74  if (argc > 2)
75  {
76  second_to_run = std::chrono::seconds(std::stoi(argv[2]));
77  }
78 
79  // Making the robot ready for the program by:
80  // Connect the robot Dashboard
81  g_my_dashboard.reset(new DashboardClient(robot_ip));
82  if (!g_my_dashboard->connect())
83  {
84  URCL_LOG_ERROR("Could not connect to dashboard");
85  return 1;
86  }
87 
88  // // Stop program, if there is one running
89  if (!g_my_dashboard->commandStop())
90  {
91  URCL_LOG_ERROR("Could not send stop program command");
92  return 1;
93  }
94 
95  // Power it off
96  // if (!g_my_dashboard->commandPowerOff())
97  //{
98  // URCL_LOG_ERROR("Could not send Power off command");
99  // return 1;
100  //}
101 
102  // Power it on
103  // if (!g_my_dashboard->commandPowerOn())
104  //{
105  // URCL_LOG_ERROR("Could not send Power on command");
106  // return 1;
107  //}
108 
109  // Release the brakes
110  // if (!g_my_dashboard->commandBrakeRelease())
111  //{
112  // URCL_LOG_ERROR("Could not send BrakeRelease command");
113  // return 1;
114  //}
115 
116  // Now the robot is ready to receive a program
117  std::unique_ptr<ToolCommSetup> tool_comm_setup;
118  const bool HEADLESS = true;
120  std::move(tool_comm_setup), CALIBRATION_CHECKSUM));
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. Therefore, do this directly before starting your main
124  // loop.
125  g_my_driver->startRTDECommunication();
126 
127  std::chrono::duration<double> time_done(0);
128  std::chrono::duration<double> timeout(second_to_run);
129  auto stopwatch_last = std::chrono::steady_clock::now();
130  auto stopwatch_now = stopwatch_last;
131  g_my_driver->writeKeepalive();
132  // Task frame at the robot's base with limits being large enough to cover the whole workspace
133  // Compliance in z axis and rotation around z axis
134  g_my_driver->startForceMode({ 0, 0, 0, 0, 0, 0 }, // Task frame at the robot's base
135  { 0, 0, 1, 0, 0, 1 }, // Compliance in z axis and rotation around z axis
136  { 0, 0, 0, 0, 0, 0 }, // do not apply any active wrench
137  2, // do not transform the force frame at all
138  { 0.1, 0.1, 1.5, 3.14, 3.14, 0.5 }); // limits. See ScriptManual for
139  // details.
140 
141  while (true)
142  {
143  // Read latest RTDE package. This will block for a hard-coded timeout (see UrDriver), so the
144  // robot will effectively be in charge of setting the frequency of this loop.
145  // In a real-world application this thread should be scheduled with real-time priority in order
146  // to ensure that this is called in time.
147  std::unique_ptr<rtde_interface::DataPackage> data_pkg = g_my_driver->getDataPackage();
148  if (data_pkg)
149  {
150  g_my_driver->writeKeepalive();
151 
152  if (time_done > timeout && second_to_run.count() != 0)
153  {
154  URCL_LOG_INFO("Timeout reached.");
155  break;
156  }
157  }
158  else
159  {
160  URCL_LOG_WARN("Could not get fresh data package from robot");
161  }
162 
163  stopwatch_now = std::chrono::steady_clock::now();
164  time_done += stopwatch_now - stopwatch_last;
165  stopwatch_last = stopwatch_now;
166  }
167  g_my_driver->endForceMode();
168 }
#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< UrDriver > g_my_driver
void sendFreedriveMessageOrDie(const control::FreedriveControlMessage freedrive_action)
FreedriveControlMessage
Control messages for starting and stopping freedrive mode.
const std::string DEFAULT_ROBOT_IP
int main(int argc, char *argv[])
std::unique_ptr< DashboardClient > g_my_dashboard
void setLogLevel(LogLevel level)
Set log level this will disable messages with lower log level.
Definition: log.cpp:101
const std::string OUTPUT_RECIPE
const std::string SCRIPT_FILE
void handleRobotProgramState(bool program_running)
const std::string INPUT_RECIPE
#define URCL_LOG_WARN(...)
Definition: log.h:24
const std::string CALIBRATION_CHECKSUM
This class is a wrapper around the dashboard server.
#define URCL_LOG_INFO(...)
Definition: log.h:25


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