Skip to content

Commit d0b3929

Browse files
committed
Support optimove motions in InstructionExecutor
1 parent b4c6c8f commit d0b3929

File tree

11 files changed

+264
-5
lines changed

11 files changed

+264
-5
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ endif()
1717
add_library(urcl
1818
src/comm/tcp_socket.cpp
1919
src/comm/tcp_server.cpp
20+
src/control/motion_primitives.cpp
2021
src/control/reverse_interface.cpp
2122
src/control/script_reader.cpp
2223
src/control/script_sender.cpp

doc/architecture/instruction_executor.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ to point motions easily accessible. Currently, it supports the following instruc
1212
* Execute MoveL point to point motions
1313
* Execute MoveP point to point motions
1414
* Execute MoveC circular motions
15+
* Execute OptimoveJ point to point motions (For PolyScope 5.21 / PolyScope 10.8 and later)
16+
* Execute OptimoveL point to point motions (For PolyScope 5.21 / PolyScope 10.8 and later)
1517
* Execute sequences consisting of the motion primitives above
1618

1719
The Instruction Executor uses the :ref:`trajectory_point_interface` and the

doc/examples/instruction_executor.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ To run a sequence of motions, create an
4444
:end-at: instruction_executor->executeMotion(motion_sequence);
4545

4646
Each element in the motion sequence can be a different motion type. In the example, there are two
47-
``MoveJ`` motions, a ``MoveL`` motion and a ``MoveP`` motion. The primitives' parameters are directly forwarded to
48-
the underlying script functions, so the parameter descriptions for them apply, as well.
49-
Particularly, you may want to choose between either a time-based execution speed or an acceleration
50-
/ velocity parametrization for some move functions. The latter will be ignored if a time > 0 is given.
47+
``MoveJ`` motions, a ``MoveL`` motion, a ``MoveP`` motion, a ``OptimiveJ`` motion and a
48+
``OptimoveL`` motion. The primitives' parameters are directly forwarded to the underlying script
49+
functions, so the parameter descriptions for them apply, as well. Particularly, you may want to
50+
choose between either a time-based execution speed or an acceleration / velocity parametrization
51+
for some move functions. The latter will be ignored if a time > 0 is given.
5152

5253
Please refer to the script manual for details.
5354

examples/instruction_executor.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ int main(int argc, char* argv[])
5858
robot_ip = std::string(argv[1]);
5959
}
6060

61-
bool headless_mode = true;
61+
bool headless_mode = false;
6262
g_my_robot = std::make_unique<urcl::ExampleRobotWrapper>(robot_ip, OUTPUT_RECIPE, INPUT_RECIPE, headless_mode,
6363
"external_control.urp");
6464
if (!g_my_robot->getUrDriver()->checkCalibration(CALIBRATION_CHECKSUM))
@@ -91,6 +91,10 @@ int main(int argc, char* argv[])
9191
std::chrono::seconds(2)),
9292
std::make_shared<urcl::control::MovePPrimitive>(urcl::Pose{ -0.203, 0.463, 0.559, 0.68, -1.083, -2.076 }, 0.1, 0.4,
9393
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),
9498
};
9599
instruction_executor->executeMotion(motion_sequence);
96100

include/ur_client_library/control/motion_primitives.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ enum class MotionType : uint8_t
4646
MOVEL = 1,
4747
MOVEP = 2,
4848
MOVEC = 3,
49+
OPTIMOVEJ = 4,
50+
OPTIMOVEL = 5,
4951
SPLINE = 51,
5052
UNKNOWN = 255
5153
};
@@ -66,6 +68,8 @@ struct MotionPrimitive
6668
double acceleration;
6769
double velocity;
6870
double blend_radius;
71+
72+
virtual bool validate() const;
6973
};
7074

7175
struct MoveJPrimitive : public MotionPrimitive
@@ -162,6 +166,40 @@ struct SplinePrimitive : public MotionPrimitive
162166
vector6d_t target_velocities;
163167
std::optional<vector6d_t> target_accelerations;
164168
};
169+
170+
struct OptimoveJPrimitive : public MotionPrimitive
171+
{
172+
OptimoveJPrimitive(const urcl::vector6d_t& target, const double blend_radius = 0,
173+
const double acceleration_fraction = 0.3, const double velocity_fraction = 0.3)
174+
{
175+
type = MotionType::OPTIMOVEJ;
176+
target_joint_configuration = target;
177+
this->blend_radius = blend_radius;
178+
this->acceleration = acceleration_fraction;
179+
this->velocity = velocity_fraction;
180+
}
181+
182+
urcl::vector6d_t target_joint_configuration;
183+
184+
bool validate() const override;
185+
};
186+
187+
struct OptimoveLPrimitive : public MotionPrimitive
188+
{
189+
OptimoveLPrimitive(const urcl::Pose& target, const double blend_radius = 0, const double acceleration_fraction = 0.3,
190+
const double velocity_fraction = 0.3)
191+
{
192+
type = MotionType::OPTIMOVEL;
193+
target_pose = target;
194+
this->blend_radius = blend_radius;
195+
this->acceleration = acceleration_fraction;
196+
this->velocity = velocity_fraction;
197+
}
198+
199+
bool validate() const override;
200+
201+
urcl::Pose target_pose;
202+
};
165203
} // namespace control
166204
} // namespace urcl
167205
#endif // UR_CLIENT_LIBRARY_MOTION_PRIMITIVES_H_INCLUDED

include/ur_client_library/ur/instruction_executor.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,42 @@ class InstructionExecutor
132132
bool moveC(const urcl::Pose& via, const urcl::Pose& target, const double acceleration = 1.4,
133133
const double velocity = 1.04, const double blend_radius = 0.0, const int32_t mode = 0);
134134

135+
/**
136+
* \brief Move the robot to a joint target using optimoveJ.
137+
*
138+
* This function will move the robot to the given joint target using the optimoveJ motion
139+
* primitive. The robot will move with the given acceleration and velocity fractions.
140+
*
141+
* \param target The joint target to move to.
142+
* \param acceleration_fraction The fraction of the maximum acceleration to use for the motion
143+
* (0.0 < fraction <= 1.0).
144+
* \param velocity_fraction The fraction of the maximum velocity to use for the motion_sequence
145+
* (0.0 < fraction <= 1.0).
146+
* \param blend_radius The blend radius to use for the motion.
147+
*
148+
* \return True if the robot has reached the target, false otherwise.
149+
*/
150+
bool optimoveJ(const urcl::vector6d_t& target, const double acceleration_fraction = 0.3,
151+
const double velocity_fraction = 0.3, const double blend_radius = 0);
152+
153+
/**
154+
* \brief Move the robot to a pose target using optimoveL.
155+
*
156+
* This function will move the robot to the given pose target using the optimoveL motion
157+
* primitive. The robot will move with the given acceleration and velocity fractions.
158+
*
159+
* \param target The pose target to move to.
160+
* \param acceleration_fraction The fraction of the maximum acceleration to use for the motion
161+
* (0.0 < fraction <= 1.0).
162+
* \param velocity_fraction The fraction of the maximum velocity to use for the motion_sequence
163+
* (0.0 < fraction <= 1.0).
164+
* \param blend_radius The blend radius to use for the motion.
165+
*
166+
* \return True if the robot has reached the target, false otherwise.
167+
*/
168+
bool optimoveL(const urcl::Pose& target, const double acceleration_fraction = 0.3,
169+
const double velocity_fraction = 0.3, const double blend_radius = 0);
170+
135171
/**
136172
* \brief Cancel the current motion.
137173
*
@@ -154,6 +190,7 @@ class InstructionExecutor
154190
private:
155191
void trajDoneCallback(const urcl::control::TrajectoryResult& result);
156192
void trajDisconnectCallback(const int filedescriptor);
193+
157194
std::shared_ptr<urcl::UrDriver> driver_;
158195
std::atomic<bool> trajectory_running_ = false;
159196
std::atomic<bool> cancel_requested_ = false;

resources/external_control.urscript

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ textmsg("ExternalControl: steptime=", steptime)
88
MULT_jointstate = {{JOINT_STATE_REPLACE}}
99
MULT_time = {{TIME_REPLACE}}
1010

11+
DEBUG = False
12+
1113
STOPJ_ACCELERATION = 4.0
1214

1315
#Constants
@@ -35,6 +37,8 @@ MOTION_TYPE_MOVEJ = 0
3537
MOTION_TYPE_MOVEL = 1
3638
MOTION_TYPE_MOVEP = 2
3739
MOTION_TYPE_MOVEC = 3
40+
MOTION_TYPE_OPTIMOVEJ = 4
41+
MOTION_TYPE_OPTIMOVEL = 5
3842
MOTION_TYPE_SPLINE = 51
3943
TRAJECTORY_DATA_DIMENSION = 3 * 6 + 1
4044

@@ -551,6 +555,63 @@ thread trajectoryThread():
551555
clear_remaining_trajectory_points()
552556
trajectory_result = TRAJECTORY_RESULT_FAILURE
553557
end
558+
559+
# OptimoveJ point
560+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEJ:
561+
acceleration = raw_point[13] / MULT_jointstate
562+
velocity = raw_point[7] / MULT_jointstate
563+
{% if ROBOT_SOFTWARE_VERSION >= v5.21.0 %}
564+
{% if ROBOT_SOFTWARE_VERSION < v6.0.0 %}
565+
optimovej(q, a = acceleration, v = velocity, r = blend_radius)
566+
{% elif ROBOT_SOFTWARE_VERSION >= v10.8.0 %}
567+
optimovej(q, a = acceleration, v = velocity, r = blend_radius)
568+
{% else %}
569+
popup("Optimovej is only supported from software 10.8.0 and upwards.", error=True, blocking=True)
570+
{% endif %}
571+
{% else %}
572+
popup("Optimovej is only supported from software 5.21.0 and upwards.", error=True, blocking=True)
573+
{% endif %}
574+
575+
if DEBUG:
576+
textmsg(str_cat("optimovej(", str_cat(
577+
str_cat("q=", q), str_cat(
578+
str_cat(", a=", acceleration), str_cat(
579+
str_cat(", v=", velocity), str_cat(
580+
str_cat(", r=", blend_radius), ")"))))))
581+
end
582+
583+
# reset old acceleration
584+
spline_qdd = [0, 0, 0, 0, 0, 0]
585+
spline_qd = [0, 0, 0, 0, 0, 0]
586+
587+
# OptimoveL point
588+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEL:
589+
acceleration = raw_point[13] / MULT_jointstate
590+
velocity = raw_point[7] / MULT_jointstate
591+
592+
{% if ROBOT_SOFTWARE_VERSION >= v5.21.0 %}
593+
{% if ROBOT_SOFTWARE_VERSION < v6.0.0 %}
594+
optimovel(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, r = blend_radius)
595+
{% elif ROBOT_SOFTWARE_VERSION >= v10.8.0 %}
596+
optimovel(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, r = blend_radius)
597+
{% else %}
598+
popup("Optimovel is only supported from software 10.8.0 and upwards.", error=True, blocking=True)
599+
{% endif %}
600+
{% else %}
601+
popup("Optimovel is only supported from software 5.21.0 and upwards.", error=True, blocking=True)
602+
{% endif %}
603+
604+
if DEBUG:
605+
textmsg(str_cat("optimovel(", str_cat(
606+
str_cat("q=", p[q[0], q[1], q[2], q[3], q[4], q[5]]), str_cat(
607+
str_cat(", a=", acceleration), str_cat(
608+
str_cat(", v=", velocity), str_cat(
609+
str_cat(", r=", blend_radius), ")"))))))
610+
end
611+
612+
# reset old acceleration
613+
spline_qdd = [0, 0, 0, 0, 0, 0]
614+
spline_qd = [0, 0, 0, 0, 0, 0]
554615
end
555616
else:
556617
textmsg("Receiving trajectory point failed!")

src/control/trajectory_point_interface.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ TrajectoryPointInterface::TrajectoryPointInterface(uint32_t port) : ReverseInter
6262

6363
bool TrajectoryPointInterface::writeMotionPrimitive(const std::shared_ptr<control::MotionPrimitive> primitive)
6464
{
65+
if (!primitive->validate())
66+
{
67+
URCL_LOG_ERROR("Motion primitive validation failed.");
68+
return false;
69+
}
70+
6571
if (client_fd_ == -1)
6672
{
6773
return false;
@@ -131,6 +137,25 @@ bool TrajectoryPointInterface::writeMotionPrimitive(const std::shared_ptr<contro
131137
}
132138
break;
133139
}
140+
case control::MotionType::OPTIMOVEJ:
141+
{
142+
auto optimovej_primitive = std::static_pointer_cast<control::OptimoveJPrimitive>(primitive);
143+
first_block = optimovej_primitive->target_joint_configuration;
144+
second_block.fill(primitive->velocity);
145+
third_block.fill(primitive->acceleration);
146+
break;
147+
}
148+
case control::MotionType::OPTIMOVEL:
149+
{
150+
URCL_LOG_INFO("Executing OptimoveL motion.");
151+
auto optimovel_primitive = std::static_pointer_cast<control::OptimoveLPrimitive>(primitive);
152+
first_block = { optimovel_primitive->target_pose.x, optimovel_primitive->target_pose.y,
153+
optimovel_primitive->target_pose.z, optimovel_primitive->target_pose.rx,
154+
optimovel_primitive->target_pose.ry, optimovel_primitive->target_pose.rz };
155+
second_block.fill(primitive->velocity);
156+
third_block.fill(primitive->acceleration);
157+
break;
158+
}
134159
default:
135160
throw UnsupportedMotionType();
136161
}

src/ur/instruction_executor.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ bool urcl::InstructionExecutor::moveJ(const urcl::vector6d_t& target, const doub
9999
return executeMotion({ std::make_shared<control::MoveJPrimitive>(
100100
target, blend_radius, std::chrono::milliseconds(static_cast<int>(time * 1000)), acceleration, velocity) });
101101
}
102+
102103
bool urcl::InstructionExecutor::moveL(const urcl::Pose& target, const double acceleration, const double velocity,
103104
const double time, const double blend_radius)
104105
{
@@ -119,6 +120,18 @@ bool urcl::InstructionExecutor::moveC(const urcl::Pose& via, const urcl::Pose& t
119120
{ std::make_shared<control::MoveCPrimitive>(via, target, blend_radius, acceleration, velocity, mode) });
120121
}
121122

123+
bool urcl::InstructionExecutor::optimoveJ(const urcl::vector6d_t& target, const double acceleration,
124+
const double velocity, const double blend_radius)
125+
{
126+
return executeMotion({ std::make_shared<control::OptimoveJPrimitive>(target, blend_radius, acceleration, velocity) });
127+
}
128+
129+
bool urcl::InstructionExecutor::optimoveL(const urcl::Pose& target, const double acceleration, const double velocity,
130+
const double blend_radius)
131+
{
132+
return executeMotion({ std::make_shared<control::OptimoveLPrimitive>(target, blend_radius, acceleration, velocity) });
133+
}
134+
122135
bool urcl::InstructionExecutor::cancelMotion()
123136
{
124137
cancel_requested_ = true;

src/ur/ur_driver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ void UrDriver::init(const UrDriverConfiguration& config)
127127
<< config.tool_comm_setup->getTxIdleChars() << ")";
128128
}
129129
data[BEGIN_REPLACE] = begin_replace.str();
130+
131+
data["ROBOT_SOFTWARE_VERSION"] = getVersion();
132+
130133
script_reader_.reset(new control::ScriptReader());
131134
std::string prog = script_reader_->readScriptFile(config.script_file, data);
132135

0 commit comments

Comments
 (0)