Skip to content

Commit ebaa2e3

Browse files
committed
Implement MotionTargets for all motion types
1 parent 16b14dd commit ebaa2e3

6 files changed

Lines changed: 315 additions & 29 deletions

File tree

examples/instruction_executor.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,44 @@ int main(int argc, char* argv[])
9898
std::make_shared<urcl::control::OptimoveLPrimitive>(urcl::Pose(-0.203, 0.263, 0.559, 0.68, -1.083, -2.076), 0.1,
9999
0.4, 0.7),
100100
};
101-
// instruction_executor->executeMotion(motion_sequence);
101+
instruction_executor->executeMotion(motion_sequence);
102102

103103
double goal_time_sec = 2.0;
104104

105-
// acceleration / velocity parametrization
106-
// instruction_executor->moveJ({ -1.57, -1.57, 0, 0, 0, 0 }, 2.0, 2.0);
105+
// acceleration / velocity parametrization brace-init style will be interpreted as joint
106+
// positions
107+
instruction_executor->moveJ({ -1.57, -1.57, 0, 0, 0, 0 }, 2.0, 2.0);
108+
107109
// goal time parametrization -- acceleration and velocity will be ignored
108110
instruction_executor->moveJ({ -1.57, -1.6, 1.6, -0.7, 0.7, 0.2 }, 0.1, 0.1, goal_time_sec);
111+
112+
// moveL calls with brace-init style is interpreted as a pose
109113
instruction_executor->moveL({ -0.0203, 0.363, 0.559, 0.68, -1.083, -2.076 }, 1.5, 1.5);
114+
// A pose can also be explicitly passed to moveL
115+
instruction_executor->moveL(urcl::Pose{ -0.0203, 0.363, 0.559, 0.68, -1.083, -2.076 }, 1.5, 1.5);
116+
// moveL can also accept a joint position target, if explicitly wrapped into a urcl::Q object
110117
instruction_executor->moveL(urcl::Q{ -1.572, -1.686, 1.707, -0.833, 0.782, 0.479 }, 1.5, 1.5, goal_time_sec);
118+
119+
// moveJ can also accept a Cartesian pose, when given explicitly
111120
instruction_executor->moveJ(urcl::Pose{ -0.0203, 0.363, 0.559, 0.68, -1.083, -2.076 }, 0.1, 0.1, goal_time_sec);
112121

113-
// instruction_executor->moveP({ -0.203, 0.463, 0.759, 0.68, -1.083, -2.076 }, 1.5, 1.5);
122+
// moveP can also be called with brace-init (interpreted as pose) or explicitly using a Pose or Q
123+
instruction_executor->moveP({ -0.2, 0.363, 0.559, 0.68, -1.083, -2.076 }, 0.1, 0.1, goal_time_sec);
124+
instruction_executor->moveP(urcl::Pose{ -0.0203, 0.303, 0.559, 0.68, -1.083, -2.076 }, 0.1, 0.1, goal_time_sec);
125+
instruction_executor->moveP(urcl::Q{ -1.57, -1.83, 1.707, -0.833, 0.782, 0.479 }, 0.1, 0.1, goal_time_sec);
126+
127+
// For moveC via and target can be a Pose or Q. When brace-init style lists are given, values are
128+
// interpreted as Pose.
129+
instruction_executor->moveC(urcl::Pose{ -0.1, 0.463, 0.559, 0.68, -1.083, -2.076 },
130+
urcl::Pose{ -0.0203, 0.303, 0.559, 0.68, -1.083, -2.076 }, 0.1, 0.1, goal_time_sec);
131+
instruction_executor->moveC(urcl::Pose{ -0.1, 0.463, 0.559, 0.68, -1.083, -2.076 },
132+
urcl::Q{ -1.57, -1.83, 1.707, -0.833, 0.782, 0.479 }, 0.1, 0.1, goal_time_sec);
133+
134+
// For optimove functions, the same target rules as for moveJ and moveL apply.
135+
instruction_executor->optimoveJ({ -1.57, -1.6, 1.6, -0.7, 0.7, 0.2 }, 1.0, 1.0);
136+
instruction_executor->optimoveL(urcl::Pose{ -0.0203, 0.363, 0.559, 0.68, -1.083, -2.076 }, 1.0, 1.0);
137+
instruction_executor->optimoveL(urcl::Q{ -1.572, -1.686, 1.707, -0.833, 0.782, 0.479 }, 1.0, 1.0);
138+
instruction_executor->optimoveJ(urcl::Pose{ -0.0203, 0.363, 0.559, 0.68, -1.083, -2.076 }, 1.0, 1.0);
114139

115-
g_my_robot->getUrDriver()->stopControl();
116140
return 0;
117141
}

include/ur_client_library/control/motion_primitives.h

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <chrono>
3535
#include <optional>
3636
#include <variant>
37+
#include "ur_client_library/exceptions.h"
3738
#include <ur_client_library/types.h>
3839

3940
namespace urcl
@@ -51,6 +52,12 @@ enum class MotionType : uint8_t
5152
OPTIMOVEL = 5,
5253
MOVEJ_POSE = 6,
5354
MOVEL_JOINT = 7,
55+
MOVEP_JOINT = 8,
56+
MOVEC_JOINT = 9,
57+
MOVEC_JOINT_POSE = 10,
58+
MOVEC_POSE_JOINT = 11,
59+
OPTIMOVEJ_POSE = 12,
60+
OPTIMOVEL_JOINT = 13,
5461
SPLINE = 51,
5562
UNKNOWN = 255
5663
};
@@ -172,8 +179,31 @@ struct MovePPrimitive : public MotionPrimitive
172179
this->velocity = velocity;
173180
this->blend_radius = blend_radius;
174181
}
182+
MovePPrimitive(const MotionTarget& target, const double blend_radius = 0, const double acceleration = 1.4,
183+
const double velocity = 1.04)
184+
{
185+
std::visit(
186+
[&](const auto& target_variant) {
187+
using T = std::decay_t<decltype(target_variant)>;
188+
if constexpr (std::is_same_v<T, urcl::Pose>)
189+
{
190+
type = MotionType::MOVEP;
191+
target_pose = target_variant;
192+
}
193+
else if constexpr (std::is_same_v<T, Q>)
194+
{
195+
type = MotionType::MOVEP_JOINT;
196+
target_joint_configuration = target_variant.values;
197+
}
198+
},
199+
target);
200+
this->acceleration = acceleration;
201+
this->velocity = velocity;
202+
this->blend_radius = blend_radius;
203+
}
175204

176205
urcl::Pose target_pose;
206+
urcl::vector6d_t target_joint_configuration;
177207
};
178208

179209
struct MoveCPrimitive : public MotionPrimitive
@@ -190,8 +220,65 @@ struct MoveCPrimitive : public MotionPrimitive
190220
this->mode = mode;
191221
}
192222

223+
MoveCPrimitive(const MotionTarget& via_point, const MotionTarget& target, const double blend_radius = 0,
224+
const double acceleration = 1.4, const double velocity = 1.04, const int32_t mode = 0)
225+
{
226+
if (std::holds_alternative<Q>(via_point))
227+
{
228+
if (std::holds_alternative<Q>(target))
229+
{
230+
type = MotionType::MOVEC_JOINT;
231+
via_point_pose = urcl::Pose();
232+
target_pose = urcl::Pose();
233+
via_point_joint_configuration = std::get<Q>(via_point).values;
234+
target_joint_configuration = std::get<Q>(target).values;
235+
}
236+
else if (std::holds_alternative<urcl::Pose>(target))
237+
{
238+
type = MotionType::MOVEC_POSE_JOINT;
239+
via_point_pose = urcl::Pose();
240+
target_pose = std::get<urcl::Pose>(target);
241+
via_point_joint_configuration = std::get<Q>(via_point).values;
242+
}
243+
else
244+
{
245+
throw urcl::UrException("Unhandled motion target type for target point passed to MoveCPrimitive constructor");
246+
}
247+
}
248+
else if (std::holds_alternative<urcl::Pose>(via_point))
249+
{
250+
if (std::holds_alternative<Q>(target))
251+
{
252+
type = MotionType::MOVEC_JOINT_POSE;
253+
via_point_pose = std::get<urcl::Pose>(via_point);
254+
target_pose = urcl::Pose();
255+
target_joint_configuration = std::get<Q>(target).values;
256+
}
257+
else if (std::holds_alternative<urcl::Pose>(target))
258+
{
259+
type = MotionType::MOVEC;
260+
via_point_pose = std::get<urcl::Pose>(via_point);
261+
target_pose = std::get<urcl::Pose>(target);
262+
}
263+
else
264+
{
265+
throw urcl::UrException("Unhandled motion target type for target point passed to MoveCPrimitive constructor");
266+
}
267+
}
268+
else
269+
{
270+
throw urcl::UrException("Unhandled motion target type for via_point passed to MoveCPrimitive constructor");
271+
}
272+
this->acceleration = acceleration;
273+
this->velocity = velocity;
274+
this->blend_radius = blend_radius;
275+
this->mode = mode;
276+
}
277+
193278
urcl::Pose via_point_pose;
194279
urcl::Pose target_pose;
280+
urcl::vector6d_t via_point_joint_configuration;
281+
urcl::vector6d_t target_joint_configuration;
195282
int32_t mode = 0;
196283
};
197284

@@ -239,9 +326,33 @@ struct OptimoveJPrimitive : public MotionPrimitive
239326
this->velocity = velocity_fraction;
240327
}
241328

329+
OptimoveJPrimitive(const MotionTarget& target, const double blend_radius = 0,
330+
const double acceleration_fraction = 0.3, const double velocity_fraction = 0.3)
331+
{
332+
std::visit(
333+
[&](const auto& target_variant) {
334+
using T = std::decay_t<decltype(target_variant)>;
335+
if constexpr (std::is_same_v<T, urcl::Pose>)
336+
{
337+
type = MotionType::OPTIMOVEJ_POSE;
338+
target_pose = target_variant;
339+
}
340+
else if constexpr (std::is_same_v<T, Q>)
341+
{
342+
type = MotionType::OPTIMOVEJ;
343+
target_joint_configuration = target_variant.values;
344+
}
345+
},
346+
target);
347+
this->blend_radius = blend_radius;
348+
this->acceleration = acceleration_fraction;
349+
this->velocity = velocity_fraction;
350+
}
351+
242352
bool validate() const override;
243353

244354
urcl::vector6d_t target_joint_configuration;
355+
Pose target_pose;
245356
};
246357

247358
struct OptimoveLPrimitive : public MotionPrimitive
@@ -255,10 +366,33 @@ struct OptimoveLPrimitive : public MotionPrimitive
255366
this->acceleration = acceleration_fraction;
256367
this->velocity = velocity_fraction;
257368
}
369+
OptimoveLPrimitive(const MotionTarget& target, const double blend_radius = 0,
370+
const double acceleration_fraction = 0.3, const double velocity_fraction = 0.3)
371+
{
372+
std::visit(
373+
[&](const auto& target_variant) {
374+
using T = std::decay_t<decltype(target_variant)>;
375+
if constexpr (std::is_same_v<T, urcl::Pose>)
376+
{
377+
type = MotionType::OPTIMOVEL;
378+
target_pose = target_variant;
379+
}
380+
else if constexpr (std::is_same_v<T, Q>)
381+
{
382+
type = MotionType::OPTIMOVEL_JOINT;
383+
target_joint_configuration = target_variant.values;
384+
}
385+
},
386+
target);
387+
this->blend_radius = blend_radius;
388+
this->acceleration = acceleration_fraction;
389+
this->velocity = velocity_fraction;
390+
}
258391

259392
bool validate() const override;
260393

261394
urcl::Pose target_pose;
395+
vector6d_t target_joint_configuration;
262396
};
263397
} // namespace control
264398
} // namespace urcl

include/ur_client_library/ur/instruction_executor.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ class InstructionExecutor
118118
*/
119119
bool moveP(const urcl::Pose& target, const double acceleration = 1.4, const double velocity = 1.04,
120120
const double blend_radius = 0.0);
121+
bool moveP(const MotionTarget& target, const double acceleration = 1.4, const double velocity = 1.04,
122+
const double blend_radius = 0.0);
121123

122124
/**
123125
* \brief Move the robot to a pose target using movec
@@ -136,6 +138,8 @@ class InstructionExecutor
136138
*/
137139
bool moveC(const urcl::Pose& via, const urcl::Pose& target, const double acceleration = 1.4,
138140
const double velocity = 1.04, const double blend_radius = 0.0, const int32_t mode = 0);
141+
bool moveC(const MotionTarget& via, const MotionTarget& target, const double acceleration = 1.4,
142+
const double velocity = 1.04, const double blend_radius = 0.0, const int32_t mode = 0);
139143

140144
/**
141145
* \brief Move the robot to a joint target using optimoveJ.
@@ -154,6 +158,8 @@ class InstructionExecutor
154158
*/
155159
bool optimoveJ(const urcl::vector6d_t& target, const double acceleration_fraction = 0.3,
156160
const double velocity_fraction = 0.3, const double blend_radius = 0);
161+
bool optimoveJ(const MotionTarget& target, const double acceleration_fraction = 0.3,
162+
const double velocity_fraction = 0.3, const double blend_radius = 0);
157163

158164
/**
159165
* \brief Move the robot to a pose target using optimoveL.
@@ -172,6 +178,8 @@ class InstructionExecutor
172178
*/
173179
bool optimoveL(const urcl::Pose& target, const double acceleration_fraction = 0.3,
174180
const double velocity_fraction = 0.3, const double blend_radius = 0);
181+
bool optimoveL(const MotionTarget& target, const double acceleration_fraction = 0.3,
182+
const double velocity_fraction = 0.3, const double blend_radius = 0);
175183

176184
/**
177185
* \brief Cancel the current motion.

resources/external_control.urscript

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ MOTION_TYPE_OPTIMOVEJ = 4
4242
MOTION_TYPE_OPTIMOVEL = 5
4343
MOTION_TYPE_MOVEJ_POSE = 6
4444
MOTION_TYPE_MOVEL_JOINT = 7
45+
MOTION_TYPE_MOVEP_JOINT = 8
46+
MOTION_TYPE_MOVEC_JOINT = 9
47+
MOTION_TYPE_MOVEC_JOINT_POSE = 10
48+
MOTION_TYPE_MOVEC_POSE_JOINT = 11
49+
MOTION_TYPE_OPTIMOVEJ_POSE = 12
50+
MOTION_TYPE_OPTIMOVEL_JOINT = 13
4551
MOTION_TYPE_SPLINE = 51
4652
TRAJECTORY_DATA_DIMENSION = 3 * 6 + 1
4753

@@ -604,11 +610,36 @@ thread trajectoryThread():
604610
# reset old acceleration
605611
spline_qdd = [0, 0, 0, 0, 0, 0]
606612
spline_qd = [0, 0, 0, 0, 0, 0]
613+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEP_JOINT:
614+
acceleration = raw_point[13] / MULT_jointstate
615+
velocity = raw_point[7] / MULT_jointstate
616+
movep(q, a = acceleration, v = velocity, r = blend_radius)
607617

608-
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC:
618+
# reset old acceleration
619+
spline_qdd = [0, 0, 0, 0, 0, 0]
620+
spline_qd = [0, 0, 0, 0, 0, 0]
621+
622+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC or
623+
raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC_JOINT or
624+
raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC_POSE_JOINT or
625+
raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC_JOINT_POSE:
609626
local v = [raw_point[7], raw_point[8], raw_point[9], raw_point[10], raw_point[11], raw_point[12]] / MULT_jointstate
610-
via = p[v[0], v[1], v[2], v[3], v[4], v[5]]
611-
target = p[q[0], q[1], q[2], q[3], q[4], q[5]]
627+
if raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC:
628+
via = p[v[0], v[1], v[2], v[3], v[4], v[5]]
629+
target = p[q[0], q[1], q[2], q[3], q[4], q[5]]
630+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC_JOINT:
631+
via = v
632+
target = q
633+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC_POSE_JOINT:
634+
via = v
635+
target = p[q[0], q[1], q[2], q[3], q[4], q[5]]
636+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_MOVEC_JOINT_POSE:
637+
via = p[v[0], v[1], v[2], v[3], v[4], v[5]]
638+
target = q
639+
end
640+
641+
textmsg(str_cat(str_cat("MOVEC via: ", via), str_cat(" target: ", target)))
642+
612643
acceleration = raw_point[13] / MULT_jointstate
613644
velocity = raw_point[14] / MULT_jointstate
614645
mode = raw_point[15] / MULT_jointstate
@@ -643,14 +674,22 @@ thread trajectoryThread():
643674
end
644675

645676
# OptimoveJ point
646-
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEJ:
677+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEJ or raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEJ_POSE:
647678
acceleration = raw_point[13] / MULT_jointstate
648679
velocity = raw_point[7] / MULT_jointstate
649680
{% if ROBOT_SOFTWARE_VERSION >= v5.21.0 %}
650681
{% if ROBOT_SOFTWARE_VERSION < v6.0.0 %}
651-
optimovej(q, a = acceleration, v = velocity, r = blend_radius)
682+
if raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEJ:
683+
optimovej(q, a = acceleration, v = velocity, r = blend_radius)
684+
else:
685+
optimovej(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, r = blend_radius)
686+
end
652687
{% elif ROBOT_SOFTWARE_VERSION >= v10.8.0 %}
653-
optimovej(q, a = acceleration, v = velocity, r = blend_radius)
688+
if raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEJ:
689+
optimovej(q, a = acceleration, v = velocity, r = blend_radius)
690+
else:
691+
optimovej(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, r = blend_radius)
692+
end
654693
{% else %}
655694
popup("Optimovej is only supported from software 10.8.0 and upwards.", error=True, blocking=False)
656695
{% endif %}
@@ -671,15 +710,23 @@ thread trajectoryThread():
671710
spline_qd = [0, 0, 0, 0, 0, 0]
672711

673712
# OptimoveL point
674-
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEL:
713+
elif raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEL or raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEL_JOINT:
675714
acceleration = raw_point[13] / MULT_jointstate
676715
velocity = raw_point[7] / MULT_jointstate
677716

678717
{% if ROBOT_SOFTWARE_VERSION >= v5.21.0 %}
679718
{% if ROBOT_SOFTWARE_VERSION < v6.0.0 %}
680-
optimovel(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, r = blend_radius)
719+
if raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEL:
720+
optimovel(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, r = blend_radius)
721+
else:
722+
optimovel(q, a = acceleration, v = velocity, r = blend_radius)
723+
end
681724
{% elif ROBOT_SOFTWARE_VERSION >= v10.8.0 %}
682-
optimovel(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, r = blend_radius)
725+
if raw_point[INDEX_POINT_TYPE] == MOTION_TYPE_OPTIMOVEL:
726+
optimovel(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, r = blend_radius)
727+
else:
728+
optimovel(q, a = acceleration, v = velocity, r = blend_radius)
729+
end
683730
{% else %}
684731
popup("Optimovel is only supported from software 10.8.0 and upwards.", error=True, blocking=False)
685732
{% endif %}

0 commit comments

Comments
 (0)