Skip to content

Commit 6772bbe

Browse files
committed
Handle splines also as MotionPrimitives
That makes the whole interface more consistent. The public-facing API isn't affected by that.
1 parent 5c96176 commit 6772bbe

File tree

6 files changed

+90
-109
lines changed

6 files changed

+90
-109
lines changed

doc/architecture/trajectory_point_interface.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ representations in 21 datafields. The data fields have the following meaning:
4747

4848
- 12: velocity (Multiplied by ``MULT_JOINTSTATE``)
4949
- 13: acceleration (Multiplied by ``MULT_JOINTSTATE``)
50-
- 14: mode
50+
- 14: mode (Multiplied by ``MULT_JOINTSTATE``)
5151

5252
18 trajectory point type
5353

include/ur_client_library/control/motion_primitives.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#define UR_CLIENT_LIBRARY_MOTION_PRIMITIVES_H_INCLUDED
3333

3434
#include <chrono>
35+
#include <optional>
3536
#include <ur_client_library/types.h>
3637

3738
namespace urcl
@@ -49,6 +50,15 @@ enum class MotionType : uint8_t
4950
UNKNOWN = 255
5051
};
5152

53+
/*!
54+
* Spline types
55+
*/
56+
enum class TrajectorySplineType : int32_t
57+
{
58+
SPLINE_CUBIC = 1,
59+
SPLINE_QUINTIC = 2
60+
};
61+
5262
struct MotionPrimitive
5363
{
5464
MotionType type = MotionType::UNKNOWN;
@@ -123,6 +133,35 @@ struct MoveCPrimitive : public MotionPrimitive
123133
urcl::Pose target_pose;
124134
int32_t mode = 0;
125135
};
136+
137+
struct SplinePrimitive : public MotionPrimitive
138+
{
139+
SplinePrimitive(const urcl::vector6d_t& target_positions, const vector6d_t& target_velocities,
140+
const std::optional<vector6d_t>& target_accelerations,
141+
const std::chrono::duration<double> duration = std::chrono::milliseconds(0))
142+
{
143+
type = MotionType::SPLINE;
144+
this->target_positions = target_positions;
145+
this->target_velocities = target_velocities;
146+
this->target_accelerations = target_accelerations;
147+
this->duration = duration;
148+
}
149+
150+
control::TrajectorySplineType getSplineType() const
151+
{
152+
if (target_accelerations.has_value())
153+
{
154+
return control::TrajectorySplineType::SPLINE_QUINTIC;
155+
}
156+
else
157+
{
158+
return control::TrajectorySplineType::SPLINE_CUBIC;
159+
}
160+
}
161+
vector6d_t target_positions;
162+
vector6d_t target_velocities;
163+
std::optional<vector6d_t> target_accelerations;
164+
};
126165
} // namespace control
127166
} // namespace urcl
128167
#endif // UR_CLIENT_LIBRARY_MOTION_PRIMITIVES_H_INCLUDED

include/ur_client_library/control/trajectory_point_interface.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,6 @@ enum class TrajectoryResult : int32_t
5555

5656
std::string trajectoryResultToString(const TrajectoryResult result);
5757

58-
/*!
59-
* Spline types
60-
*/
61-
enum class TrajectorySplineType : int32_t
62-
{
63-
SPLINE_CUBIC = 1,
64-
SPLINE_QUINTIC = 2
65-
};
66-
6758
/*!
6859
* \brief The TrajectoryPointInterface class handles trajectory forwarding to the robot. Full
6960
* trajectories are forwarded to the robot controller and are executed there.

resources/external_control.urscript

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ thread trajectoryThread():
523523
target = p[q[0], q[1], q[2], q[3], q[4], q[5]]
524524
acceleration = raw_point[13] / MULT_jointstate
525525
velocity = raw_point[14] / MULT_jointstate
526-
mode = raw_point[15]
526+
mode = raw_point[15] / MULT_jointstate
527527
movec(via, target, acceleration, velocity, blend_radius, mode)
528528

529529
# reset old acceleration

src/control/trajectory_point_interface.cpp

Lines changed: 46 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -69,34 +69,59 @@ bool TrajectoryPointInterface::writeMotionPrimitive(const std::shared_ptr<contro
6969
std::array<int32_t, MESSAGE_LENGTH> buffer;
7070

7171
vector6d_t positions;
72+
vector6d_t second_block;
73+
vector6d_t third_block;
7274

7375
switch (primitive->type)
7476
{
7577
case MotionType::MOVEJ:
7678
{
7779
auto movej_primitive = std::static_pointer_cast<control::MoveJPrimitive>(primitive);
7880
positions = movej_primitive->target_joint_configuration;
81+
second_block.fill(primitive->velocity);
82+
third_block.fill(primitive->acceleration);
7983
break;
8084
}
8185
case MotionType::MOVEL:
8286
{
8387
auto movel_primitive = std::static_pointer_cast<control::MoveLPrimitive>(primitive);
8488
positions = { movel_primitive->target_pose.x, movel_primitive->target_pose.y, movel_primitive->target_pose.z,
8589
movel_primitive->target_pose.rx, movel_primitive->target_pose.ry, movel_primitive->target_pose.rz };
90+
second_block.fill(primitive->velocity);
91+
third_block.fill(primitive->acceleration);
8692
break;
8793
}
8894
case MotionType::MOVEP:
8995
{
9096
auto movep_primitive = std::static_pointer_cast<control::MovePPrimitive>(primitive);
9197
positions = { movep_primitive->target_pose.x, movep_primitive->target_pose.y, movep_primitive->target_pose.z,
9298
movep_primitive->target_pose.rx, movep_primitive->target_pose.ry, movep_primitive->target_pose.rz };
99+
second_block.fill(primitive->velocity);
100+
third_block.fill(primitive->acceleration);
93101
break;
94102
}
95103
case MotionType::MOVEC:
96104
{
97105
auto movec_primitive = std::static_pointer_cast<control::MoveCPrimitive>(primitive);
98106
positions = { movec_primitive->target_pose.x, movec_primitive->target_pose.y, movec_primitive->target_pose.z,
99107
movec_primitive->target_pose.rx, movec_primitive->target_pose.ry, movec_primitive->target_pose.rz };
108+
second_block = { movec_primitive->via_point_pose.x, movec_primitive->via_point_pose.y,
109+
movec_primitive->via_point_pose.z, movec_primitive->via_point_pose.rx,
110+
movec_primitive->via_point_pose.ry, movec_primitive->via_point_pose.rz };
111+
third_block = {
112+
primitive->velocity, primitive->acceleration, static_cast<double>(movec_primitive->mode), 0, 0, 0
113+
};
114+
break;
115+
}
116+
case control::MotionType::SPLINE:
117+
{
118+
auto spline_primitive = std::static_pointer_cast<control::SplinePrimitive>(primitive);
119+
positions = spline_primitive->target_positions;
120+
second_block = spline_primitive->target_velocities;
121+
if (spline_primitive->target_accelerations.has_value())
122+
{
123+
third_block = spline_primitive->target_accelerations.value();
124+
}
100125
break;
101126
}
102127
default:
@@ -110,56 +135,31 @@ bool TrajectoryPointInterface::writeMotionPrimitive(const std::shared_ptr<contro
110135
buffer[index] = htobe32(val);
111136
index++;
112137
}
113-
114-
if (primitive->type == MotionType::MOVEC)
138+
for (auto const& item : second_block)
115139
{
116-
auto movec_primitive = std::static_pointer_cast<control::MoveCPrimitive>(primitive);
117-
auto via = { movec_primitive->via_point_pose.x, movec_primitive->via_point_pose.y,
118-
movec_primitive->via_point_pose.z, movec_primitive->via_point_pose.rx,
119-
movec_primitive->via_point_pose.ry, movec_primitive->via_point_pose.rz };
120-
for (auto const& pos : via)
121-
{
122-
int32_t val = static_cast<int32_t>(round(pos * MULT_JOINTSTATE));
123-
buffer[index] = htobe32(val);
124-
index++;
125-
}
126-
int32_t val = static_cast<int32_t>(round(primitive->velocity * MULT_JOINTSTATE));
140+
int32_t val = static_cast<int32_t>(round(item * MULT_JOINTSTATE));
127141
buffer[index] = htobe32(val);
128142
index++;
129-
val = static_cast<int32_t>(round(primitive->acceleration * MULT_JOINTSTATE));
130-
buffer[index] = htobe32(val);
131-
index++;
132-
val = static_cast<int32_t>(round(movec_primitive->mode));
133-
buffer[index] = htobe32(val);
134-
index++;
135-
for (size_t i = 0; i < positions.size() - 3; ++i)
136-
{
137-
val = 0;
138-
buffer[index] = htobe32(val);
139-
index++;
140-
}
141143
}
142-
else
144+
for (auto const& item : third_block)
143145
{
144-
for (size_t i = 0; i < positions.size(); ++i)
145-
{
146-
int32_t val = static_cast<int32_t>(round(primitive->velocity * MULT_JOINTSTATE));
147-
buffer[index] = htobe32(val);
148-
index++;
149-
}
150-
for (size_t i = 0; i < positions.size(); ++i)
151-
{
152-
int32_t val = static_cast<int32_t>(round(primitive->acceleration * MULT_JOINTSTATE));
153-
buffer[index] = htobe32(val);
154-
index++;
155-
}
146+
int32_t val = static_cast<int32_t>(round(item * MULT_JOINTSTATE));
147+
buffer[index] = htobe32(val);
148+
index++;
156149
}
157150

158151
int32_t val = static_cast<int32_t>(round(primitive->duration.count() * MULT_TIME));
159152
buffer[index] = htobe32(val);
160153
index++;
161154

162-
val = static_cast<int32_t>(round(primitive->blend_radius * MULT_TIME));
155+
if (primitive->type == MotionType::SPLINE)
156+
{
157+
val = static_cast<int32_t>(std::static_pointer_cast<control::SplinePrimitive>(primitive)->getSplineType());
158+
}
159+
else
160+
{
161+
val = static_cast<int32_t>(round(primitive->blend_radius * MULT_TIME));
162+
}
163163
buffer[index] = htobe32(val);
164164
index++;
165165

@@ -204,76 +204,26 @@ bool TrajectoryPointInterface::writeTrajectoryPoint(const vector6d_t* positions,
204204
bool TrajectoryPointInterface::writeTrajectorySplinePoint(const vector6d_t* positions, const vector6d_t* velocities,
205205
const vector6d_t* accelerations, const float goal_time)
206206
{
207-
if (client_fd_ == -1)
208-
{
209-
return false;
210-
}
211-
212-
control::TrajectorySplineType spline_type = control::TrajectorySplineType::SPLINE_CUBIC;
213-
214-
// 6 positions, 6 velocities, 6 accelerations, 1 goal time, spline type, 1 point type
215-
uint8_t buffer[sizeof(int32_t) * MESSAGE_LENGTH] = { 0 };
216-
uint8_t* b_pos = buffer;
217-
if (positions != nullptr)
218-
{
219-
for (auto const& pos : *positions)
220-
{
221-
int32_t val = static_cast<int32_t>(round(pos * MULT_JOINTSTATE));
222-
val = htobe32(val);
223-
b_pos += append(b_pos, val);
224-
}
225-
}
226-
else
207+
if (positions == nullptr)
227208
{
228209
throw urcl::UrException("TrajectoryPointInterface::writeTrajectorySplinePoint is only getting a nullptr for "
229210
"positions\n");
230211
}
231212

232-
if (velocities != nullptr)
233-
{
234-
spline_type = control::TrajectorySplineType::SPLINE_CUBIC;
235-
for (auto const& vel : *velocities)
236-
{
237-
int32_t val = static_cast<int32_t>(round(vel * MULT_JOINTSTATE));
238-
val = htobe32(val);
239-
b_pos += append(b_pos, val);
240-
}
241-
}
242-
else
213+
if (velocities == nullptr)
243214
{
244215
throw urcl::UrException("TrajectoryPointInterface::writeTrajectorySplinePoint is only getting a nullptr for "
245216
"velocities\n");
246217
}
247218

219+
std::optional<vector6d_t> target_accelerations;
248220
if (accelerations != nullptr)
249221
{
250-
spline_type = control::TrajectorySplineType::SPLINE_QUINTIC;
251-
for (auto const& acc : *accelerations)
252-
{
253-
int32_t val = static_cast<int32_t>(round(acc * MULT_JOINTSTATE));
254-
val = htobe32(val);
255-
b_pos += append(b_pos, val);
256-
}
257-
}
258-
else
259-
{
260-
b_pos += 6 * sizeof(int32_t);
222+
target_accelerations = *accelerations;
261223
}
262224

263-
int32_t val = static_cast<int32_t>(round(goal_time * MULT_TIME));
264-
val = htobe32(val);
265-
b_pos += append(b_pos, val);
266-
267-
val = static_cast<int32_t>(spline_type);
268-
val = htobe32(val);
269-
b_pos += append(b_pos, val);
270-
271-
val = static_cast<int32_t>(control::MotionType::SPLINE);
272-
val = htobe32(val);
273-
b_pos += append(b_pos, val);
274-
275-
size_t written;
276-
return server_.write(client_fd_, buffer, sizeof(buffer), written);
225+
return writeMotionPrimitive(std::make_shared<SplinePrimitive>(
226+
*positions, *velocities, target_accelerations, std::chrono::milliseconds(static_cast<int>(goal_time * 1000))));
277227
}
278228

279229
void TrajectoryPointInterface::connectionCallback(const socket_t filedescriptor)
@@ -323,4 +273,4 @@ void TrajectoryPointInterface::messageCallback(const socket_t filedescriptor, ch
323273
}
324274
}
325275
} // namespace control
326-
} // namespace urcl
276+
} // namespace urcl

tests/test_trajectory_point_interface.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,8 @@ class TrajectoryPointInterfaceTest : public ::testing::Test
244244
((double)spl.pos[5]) / control::TrajectoryPointInterface::MULT_JOINTSTATE },
245245
(double)spl.blend_radius_or_spline_type / control::TrajectoryPointInterface::MULT_TIME,
246246
(double)spl.acc[1] / control::TrajectoryPointInterface::MULT_JOINTSTATE,
247-
(double)spl.acc[0] / control::TrajectoryPointInterface::MULT_JOINTSTATE, (double)spl.acc[2]);
247+
(double)spl.acc[0] / control::TrajectoryPointInterface::MULT_JOINTSTATE,
248+
(double)spl.acc[2] / control::TrajectoryPointInterface::MULT_JOINTSTATE);
248249
}
249250
else
250251
{
@@ -602,4 +603,4 @@ int main(int argc, char* argv[])
602603
::testing::InitGoogleTest(&argc, argv);
603604

604605
return RUN_ALL_TESTS();
605-
}
606+
}

0 commit comments

Comments
 (0)