Script command interface
The Script Command Interface allows sending predefined commands to the robot while there is URScript running that is connected to it.
An example to utilize the script command interface can be found in the freedrive_example.cpp.
In order to use the ScriptCommandInterface
, there has to be a script code running on the robot
that connects to the ScriptCommandInterface
. This happens as part of the big
external_control.urscript. In order to reuse that with this example, we will create a full
UrDriver
and leverage the ScriptCommandInterface
through this.
At first, we create a ExampleRobotWrapper
object in order to initialize communication with the
robot.
106 g_my_robot =
107 std::make_unique<ExampleRobotWrapper>(robot_ip, OUTPUT_RECIPE, INPUT_RECIPE, g_HEADLESS, "external_control.urp");
108
109 if (!g_my_robot->isHealthy())
110 {
111 URCL_LOG_ERROR("Something in the robot initialization went wrong. Exiting. Please check the output above.");
112 return 1;
113 }
114
115 // We will send script commands from a separate thread. That will stay active as long as
116 // g_running is true.
117 g_running = true;
118 std::thread script_command_send_thread(sendScriptCommands);
The script commands will be sent in a separate thread which will be explained later.
Since the connection to the script command interface runs as part of the bigger external_control
script, we’ll wrap the calls alongside a full ExampleRobotWrapper
. Hence, we’ll have to send
keepalive signals regularly to keep the script running:
122 std::chrono::duration<double> time_done(0);
123 std::chrono::duration<double> timeout(second_to_run);
124 auto stopwatch_last = std::chrono::steady_clock::now();
125 auto stopwatch_now = stopwatch_last;
126 while ((time_done < timeout || second_to_run.count() == 0) && g_my_robot->isHealthy())
127 {
128 g_my_robot->getUrDriver()->writeKeepalive();
129
130 stopwatch_now = std::chrono::steady_clock::now();
131 time_done += stopwatch_now - stopwatch_last;
132 stopwatch_last = stopwatch_now;
133 std::this_thread::sleep_for(
134 std::chrono::milliseconds(static_cast<int>(1.0 / g_my_robot->getUrDriver()->getControlFrequency())));
135 }
136
137 URCL_LOG_INFO("Timeout reached.");
138 g_my_robot->getUrDriver()->stopControl();
Sending script commands
Once the script is running on the robot, a connection to the driver’s script command interface
should be established. The UrDriver
forwards most calls of the ScriptCommandInterface
and
we will use that interface in this example. To send a script command, we can e.g. use
g_my_robot->getUrDriver()->zeroFTSensor()
.
In the example, we have wrapped the calls into a lambda function that will wait a specific timeout, print a log output what command will be sent and then call the respective command:
67 run_cmd("Setting tool voltage to 24V",
68 []() { g_my_robot->getUrDriver()->setToolVoltage(urcl::ToolVoltage::_24V); });
69 run_cmd("Enabling tool contact mode", []() { g_my_robot->getUrDriver()->startToolContact(); });
70 run_cmd("Setting friction_compensation variable to `false`",
71 []() { g_my_robot->getUrDriver()->setFrictionCompensation(false); });
72 run_cmd("Setting tool voltage to 0V", []() { g_my_robot->getUrDriver()->setToolVoltage(urcl::ToolVoltage::OFF); });
73 run_cmd("Zeroing the force torque sensor", []() { g_my_robot->getUrDriver()->zeroFTSensor(); });
74 run_cmd("Disabling tool contact mode", []() { g_my_robot->getUrDriver()->endToolContact(); });
75 run_cmd("Setting friction_compensation variable to `true`",
76 []() { g_my_robot->getUrDriver()->setFrictionCompensation(true); });
77 }
The lambda itself looks like this:
51 auto run_cmd = [](const std::string& log_output, std::function<void()> func) {
52 const std::chrono::seconds timeout(3);
53 if (g_running)
54 {
55 // We wait a fixed time so that not each command is run directly behind each other.
56 // This is done for example purposes only, so users can follow the effect on the teach
57 // pendant.
58 std::this_thread::sleep_for(timeout);
59 URCL_LOG_INFO(log_output.c_str());
60 func();
61 }
62 };
For a list of all available script commands, please refer to the ScriptCommandInterface
class
here.