Instruction Executor example
This example shows how to use the Instruction Executor class. It can be used for easily executing a sequence of instructions such as motions on the robot using the built-in URScript functions.
The instruction_executor.cpp shows how to use this class:
Note
For the instruciton executor to work there has to be an established connection to the ReverseInterface. That means, the respective program has to be running on the robot. The example below will do that automatically, if the connected robot is in remote_control mode.
61 bool headless_mode = true;
62 g_my_robot = std::make_unique<urcl::ExampleRobotWrapper>(robot_ip, OUTPUT_RECIPE, INPUT_RECIPE, headless_mode,
63 "external_control.urp");
64 if (!g_my_robot->getUrDriver()->checkCalibration(CALIBRATION_CHECKSUM))
65 {
66 URCL_LOG_ERROR("Calibration checksum does not match actual robot.");
67 URCL_LOG_ERROR("Use the ur_calibration tool to extract the correct calibration from the robot and pass that into "
68 "the description. See "
69 "[https://github.com/UniversalRobots/Universal_Robots_ROS_Driver#extract-calibration-information] "
70 "for details.");
71 }
72 if (!g_my_robot->isHealthy())
73 {
74 URCL_LOG_ERROR("Something in the robot initialization went wrong. Exiting. Please check the output above.");
75 return 1;
76 }
77
78 auto instruction_executor = std::make_shared<urcl::InstructionExecutor>(g_my_robot->getUrDriver());
At first, a InstructionExecutor object is created with the URDriver object as it needs that
for communication with the robot.
Currently, the InstructionExecutor can either be used to run sequences of motions or single motions.
Execute a sequence of motions
To run a sequence of motions, create an
std::vector<std::shared_ptr<urcl::cointrol::MotionPrimitive>> and pass it to the
executeMotion function:
82 // Trajectory definition
83 std::vector<std::shared_ptr<urcl::control::MotionPrimitive>> motion_sequence{
84 std::make_shared<urcl::control::MoveJPrimitive>(urcl::vector6d_t{ -1.57, -1.57, 0, 0, 0, 0 }, 0.1,
85 std::chrono::seconds(5)),
86 // This point uses acceleration / velocity parametrization
87 std::make_shared<urcl::control::MoveJPrimitive>(urcl::vector6d_t{ -1.57, -1.6, 1.6, -0.7, 0.7, 0.2 }, 0.1,
88 std::chrono::seconds(0), 1.4, 2.0),
89
90 std::make_shared<urcl::control::MoveLPrimitive>(urcl::Pose(-0.203, 0.263, 0.559, 0.68, -1.083, -2.076), 0.1,
91 std::chrono::seconds(2)),
92 std::make_shared<urcl::control::MovePPrimitive>(urcl::Pose{ -0.203, 0.463, 0.559, 0.68, -1.083, -2.076 }, 0.1, 0.4,
93 0.4),
94 std::make_shared<urcl::control::OptimoveJPrimitive>(urcl::vector6d_t{ -1.57, -1.57, 1.6, -0.5, 0.4, 0.3 }, 0.1, 0.4,
95 0.7),
96 std::make_shared<urcl::control::OptimoveLPrimitive>(urcl::Pose(-0.203, 0.263, 0.559, 0.68, -1.083, -2.076), 0.1,
97 0.4, 0.7),
98 };
99 instruction_executor->executeMotion(motion_sequence);
Each element in the motion sequence can be a different motion type. In the example, there are two
MoveJ motions, a MoveL motion, a MoveP motion, a OptimiveJ motion and a
OptimoveL motion. The primitives’ parameters are directly forwarded to the underlying script
functions, so the parameter descriptions for them apply, as well. Particularly, you may want to
choose between either a time-based execution or an acceleration / velocity parametrization
for some move functions. The latter will be ignored if a time > 0 is given.
Please refer to the script manual for details.
Execute a single motion
To run a single motion, the InstructionExecutor provides the methods moveJ(...) and
moveL(...):
101 double goal_time_sec = 2.0;
102
103 // acceleration / velocity parametrization
104 instruction_executor->moveJ({ -1.57, -1.57, 0, 0, 0, 0 }, 2.0, 2.0);
105 // goal time parametrization -- acceleration and velocity will be ignored
106 instruction_executor->moveJ({ -1.57, -1.6, 1.6, -0.7, 0.7, 0.2 }, 0.1, 0.1, goal_time_sec);
107 // acceleration / velocity parametrization
108 instruction_executor->moveL({ -0.203, 0.263, 0.559, 0.68, -1.083, -2.076 }, 1.5, 1.5);
109 // goal time parametrization -- acceleration and velocity will be ignored
110 instruction_executor->moveL({ -0.203, 0.463, 0.559, 0.68, -1.083, -2.076 }, 0.1, 0.1, goal_time_sec);
111
112 instruction_executor->moveP({ -0.203, 0.463, 0.759, 0.68, -1.083, -2.076 }, 1.5, 1.5);
Again, time parametrization has priority over acceleration / velocity parameters.