Send script example
This example shows how to send arbitrary URScript code to the robot using the
PrimaryClient. It demonstrates both the blocking variant (sendScriptBlocking), which
waits for execution feedback, and the non-blocking variant (sendScript), which only confirms
that the script has been forwarded to the robot.
The full source code can be found in send_script.cpp.
Setting up the primary client
The example connects to the robot’s primary interface by creating a PrimaryClient. After
starting the client, the robot’s brakes are released so that motion scripts can actually run, and
the safety state is checked before any script is sent:
19 auto notif = comm::INotifier();
20 auto client = primary_interface::PrimaryClient(robot_ip, notif);
21 client.start(10);
22
23 // --------------- INITIALIZATION END -------------------
24
25 // Make sure the robot is running
26 client.commandBrakeRelease();
27
28 if (!client.safetyModeAllowsExecution())
29 {
30 URCL_LOG_ERROR("Robot is not in a safety state where script execution is possible. Exiting.");
31 return 1;
32 }
Sending scripts with execution feedback
The sendScriptBlocking function uploads URScript code to the robot and waits until the robot
reports the result of the execution. The given code can be a fully defined script (with its own
def ... end block) or a snippet that will automatically be wrapped into a function on the
client side. Comments and whitespace-only lines are stripped before the script is sent.
36 const std::string fully_defined_script = R"""(
37# This is a fully defined script, function definition and all
38# All comments in this script will be stripped before sending the script to the robot
39
40# Any whitespace-only lines will also be removed
41def example_fun():
42 movej([0,-1.2,1.2,-0.1,1.57,0])
43 sleep(0.1)
44 current_pose = get_target_tcp_pose()
45 relative_move = p[0,-0.1,0,0,0,0]
46 movel(pose_trans(current_pose, relative_move), t=1)
47end)""";
48 client.sendScriptBlocking(fully_defined_script);
If you don’t provide a function definition, the library wraps the snippet in one for you. You can
optionally pass a script_name (used in log messages on both the client and the robot) and a
start_timeout that limits how long the call waits for the robot to confirm that the script has
started. A timeout of 0 means “wait indefinitely”:
51 client.sendScriptBlocking(R"(textmsg("Successful program execution"))");
52 // A script-function name can also be passed to the method
53 // A timeout can also be given to limit the wait for the passed function to start. If timeout = 0, it will
54 // wait indefinitely.
55 client.sendScriptBlocking(R"(textmsg("hello"))", "cool_function_name", std::chrono::milliseconds(0));
Secondary programs can also be uploaded through sendScriptBlocking. Since the robot does not
report execution feedback for secondary programs, the call returns as soon as the script has been
accepted. Note that secondary programs must be fully defined by the user (sec ... end):
59 std::string secondary_script = R"(
60sec sec_script():
61 textmsg("Named secondary program")
62end
63)";
64 client.sendScriptBlocking(secondary_script);
Reporting bad script code
When a script contains errors (e.g. a typo or an undefined symbol), sendScriptBlocking will
report this back to the caller. The example sends a script that uses an undefined variable
current_pos instead of current_pose, and logs the result:
67 const std::string bad_script_code = R"""(
68def bad_code():
69 current_pose = get_target_tcp_pose()
70 movel(current_pos) # note pose vs pos
71end)""";
72 URCL_LOG_INFO("Sending bad script code...");
73 try
74 {
75 client.sendScriptBlocking(bad_script_code);
76 }
77 catch (const RobotRuntimeException& exc)
78 {
79 URCL_LOG_INFO("Caught expected runtime exception from sendScriptBlocking");
80 URCL_LOG_INFO(exc.what());
81 }
82 catch (const UrException& exc)
83 {
84 URCL_LOG_ERROR("Caught unexpected exception from sendScriptBlocking");
85 URCL_LOG_ERROR(exc.what());
86 }
Sending scripts without feedback
For situations where execution feedback is not needed, sendScript can be
used. It returns true as soon as the script has been transferred to the robot. The library
performs no further checks, so faulty script code will not be reported back here:
88 // We can also send script code without any checks
89 URCL_LOG_INFO("Executing motion without feedback");
90 client.sendScript("movej([0.1,-0.9,0.9,0,0,0])");
91 // But we won't know when that is done or even if our code was correct.
92 // E.g. sending the bad script here will not give us any information
93 // The return value will only tell us that the script code has been sent to the robot.
94 URCL_LOG_INFO("Sending bad script code without feedback...");
95 bool success = client.sendScript(bad_script_code);
96 {
97 std::stringstream ss;
98 ss << "Bad code sent to robot successfully? " << std::boolalpha << success;
99 URCL_LOG_INFO("%s", ss.str().c_str());
100 }