Skip to content

Commit a7a12c2

Browse files
committed
Add acceleration and velocity information to writeTrajectoryPoint
1 parent 6bc1553 commit a7a12c2

File tree

6 files changed

+107
-16
lines changed

6 files changed

+107
-16
lines changed

include/ur_client_library/control/trajectory_point_interface.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#ifndef UR_CLIENT_LIBRARY_TRAJECTORY_INTERFACE_H_INCLUDED
3030
#define UR_CLIENT_LIBRARY_TRAJECTORY_INTERFACE_H_INCLUDED
3131

32+
#include <optional>
33+
3234
#include "ur_client_library/control/reverse_interface.h"
3335
#include "ur_client_library/comm/control_mode.h"
3436
#include "ur_client_library/types.h"
@@ -44,6 +46,7 @@ namespace control
4446
enum class TrajectoryResult : int32_t
4547
{
4648

49+
TRAJECTORY_RESULT_UNKNOWN = -1, ///< No result received, yet
4750
TRAJECTORY_RESULT_SUCCESS = 0, ///< Successful execution
4851
TRAJECTORY_RESULT_CANCELED = 1, ///< Canceled by user
4952
TRAJECTORY_RESULT_FAILURE = 2 ///< Aborted due to error during execution
@@ -76,6 +79,7 @@ class TrajectoryPointInterface : public ReverseInterface
7679
{
7780
public:
7881
static const int32_t MULT_TIME = 1000;
82+
static const int MESSAGE_LENGTH = 21;
7983

8084
TrajectoryPointInterface() = delete;
8185
/*!
@@ -103,6 +107,23 @@ class TrajectoryPointInterface : public ReverseInterface
103107
bool writeTrajectoryPoint(const vector6d_t* positions, const float goal_time, const float blend_radius,
104108
const bool cartesian);
105109

110+
/*!
111+
* \brief Writes information for a robot motion to the robot to be read by the URScript program.
112+
*
113+
* \param positions A vector of joint or cartesian targets for the robot
114+
* \param acceleration Joint acceleration of leading axis [rad/s^2] / tool acceleration [m/s^2]
115+
* for Cartesian motions
116+
* \param velocity Joint speed of leading axis [rad/s] / tool speed [m/s] for Cartesian motions
117+
* \param goal_time The goal time to reach the target. When a non-zero goal time is specified,
118+
* this has priority over speed and acceleration settings.
119+
* \param blend_radius The radius to be used for blending between control points
120+
* \param cartesian True, if the written point is specified in Cartesian space, false if in joint space
121+
*
122+
* \returns True, if the write was performed successfully, false otherwise.
123+
*/
124+
bool writeTrajectoryPoint(const vector6d_t* positions, const float acceleration = 1.4, const float velocity = 1.05,
125+
const float goal_time = 0, const float blend_radius = 0, const bool cartesian = false);
126+
106127
/*!
107128
* \brief Writes needed information to the robot to be read by the URScript program including
108129
* velocity and acceleration information. Depending on the information given the robot will do quadratic (positions
@@ -131,7 +152,6 @@ class TrajectoryPointInterface : public ReverseInterface
131152
virtual void messageCallback(const int filedescriptor, char* buffer, int nbytesrecv) override;
132153

133154
private:
134-
static const int MESSAGE_LENGTH = 21;
135155
std::function<void(TrajectoryResult)> handle_trajectory_end_;
136156
};
137157

include/ur_client_library/ur/ur_driver.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,23 @@ class UrDriver
272272
bool writeTrajectoryPoint(const vector6d_t& positions, const bool cartesian, const float goal_time = 0.0,
273273
const float blend_radius = 0.052);
274274

275+
/*!
276+
* \brief Writes a trajectory point onto the dedicated socket.
277+
*
278+
* \param positions Desired joint or cartesian positions
279+
* \param cartesian True, if the point sent is cartesian, false if joint-based
280+
* \param acceleration Joint acceleration of leading axis [rad/s^2] / tool acceleration [m/s^2]
281+
* for Cartesian motions
282+
* \param velocity Joint speed of leading axis [rad/s] / tool speed [m/s] for Cartesian motions
283+
* \param goal_time Time for the robot to reach this point. When a non-zero goal time is specified,
284+
* this has priority over speed and acceleration settings.
285+
* \param blend_radius The radius to be used for blending between control points
286+
*
287+
* \returns True on successful write.
288+
*/
289+
bool writeTrajectoryPoint(const vector6d_t& positions, float acceleration, float velocity, const bool cartesian,
290+
const float goal_time = 0.0, const float blend_radius = 0.052);
291+
275292
/*!
276293
* \brief Writes a trajectory spline point for quintic spline interpolation onto the dedicated socket.
277294
*

resources/external_control.urscript

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,15 +479,19 @@ thread trajectoryThread():
479479
end
480480
# MoveJ point
481481
if raw_point[INDEX_POINT_TYPE] == TRAJECTORY_POINT_JOINT:
482-
movej(q, t = tmptime, r = blend_radius)
482+
acceleration = raw_point[7] / MULT_jointstate
483+
velocity = raw_point[13] / MULT_jointstate
484+
movej(q, a = acceleration, v = velocity, t = tmptime, r = blend_radius)
483485

484486
# reset old acceleration
485487
spline_qdd = [0, 0, 0, 0, 0, 0]
486488
spline_qd = [0, 0, 0, 0, 0, 0]
487489

488490
# Movel point
489491
elif raw_point[INDEX_POINT_TYPE] == TRAJECTORY_POINT_CARTESIAN:
490-
movel(p[q[0], q[1], q[2], q[3], q[4], q[5]], t = tmptime, r = blend_radius)
492+
acceleration = raw_point[7] / MULT_jointstate
493+
velocity = raw_point[13] / MULT_jointstate
494+
movel(p[q[0], q[1], q[2], q[3], q[4], q[5]], a = acceleration, v = velocity, t = tmptime, r = blend_radius)
491495

492496
# reset old acceleration
493497
spline_qdd = [0, 0, 0, 0, 0, 0]

src/control/trajectory_point_interface.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ TrajectoryPointInterface::TrajectoryPointInterface(uint32_t port) : ReverseInter
3838
{
3939
}
4040

41-
bool TrajectoryPointInterface::writeTrajectoryPoint(const vector6d_t* positions, const float goal_time,
41+
bool TrajectoryPointInterface::writeTrajectoryPoint(const vector6d_t* positions, const float acceleration,
42+
const float velocity, const float goal_time,
4243
const float blend_radius, const bool cartesian)
4344
{
4445
if (client_fd_ == -1)
@@ -56,16 +57,24 @@ bool TrajectoryPointInterface::writeTrajectoryPoint(const vector6d_t* positions,
5657
val = htobe32(val);
5758
b_pos += append(b_pos, val);
5859
}
60+
for (size_t i = 0; i < positions->size(); ++i)
61+
{
62+
int32_t val = static_cast<int32_t>(round(velocity * MULT_JOINTSTATE));
63+
val = htobe32(val);
64+
b_pos += append(b_pos, val);
65+
}
66+
for (size_t i = 0; i < positions->size(); ++i)
67+
{
68+
int32_t val = static_cast<int32_t>(round(acceleration * MULT_JOINTSTATE));
69+
val = htobe32(val);
70+
b_pos += append(b_pos, val);
71+
}
5972
}
6073
else
6174
{
6275
b_pos += 6 * sizeof(int32_t);
6376
}
6477

65-
// Fill in velocity and acceleration, not used for this point type
66-
b_pos += 6 * sizeof(int32_t);
67-
b_pos += 6 * sizeof(int32_t);
68-
6978
int32_t val = static_cast<int32_t>(round(goal_time * MULT_TIME));
7079
val = htobe32(val);
7180
b_pos += append(b_pos, val);
@@ -91,6 +100,12 @@ bool TrajectoryPointInterface::writeTrajectoryPoint(const vector6d_t* positions,
91100
return server_.write(client_fd_, buffer, sizeof(buffer), written);
92101
}
93102

103+
bool TrajectoryPointInterface::writeTrajectoryPoint(const vector6d_t* positions, const float goal_time,
104+
const float blend_radius, const bool cartesian)
105+
{
106+
return writeTrajectoryPoint(positions, 1.4, 1.05, goal_time, blend_radius, cartesian);
107+
}
108+
94109
bool TrajectoryPointInterface::writeTrajectorySplinePoint(const vector6d_t* positions, const vector6d_t* velocities,
95110
const vector6d_t* accelerations, const float goal_time)
96111
{

src/ur/ur_driver.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,13 @@ bool UrDriver::writeJointCommand(const vector6d_t& values, const comm::ControlMo
232232
return reverse_interface_->write(&values, control_mode, robot_receive_timeout);
233233
}
234234

235+
bool UrDriver::writeTrajectoryPoint(const vector6d_t& positions, const float acceleration, const float velocity,
236+
const bool cartesian, const float goal_time, const float blend_radius)
237+
{
238+
return trajectory_interface_->writeTrajectoryPoint(&positions, acceleration, velocity, goal_time, blend_radius,
239+
cartesian);
240+
}
241+
235242
bool UrDriver::writeTrajectoryPoint(const vector6d_t& positions, const bool cartesian, const float goal_time,
236243
const float blend_radius)
237244
{

tests/test_trajectory_point_interface.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,15 @@ class TrajectoryPointInterfaceTest : public ::testing::Test
6363
int32_t& blend_radius_or_spline_type, int32_t& motion_type)
6464
{
6565
// Read message
66-
uint8_t buf[sizeof(int32_t) * 21];
66+
uint8_t buf[sizeof(int32_t) * urcl::control::TrajectoryPointInterface::MESSAGE_LENGTH];
6767
uint8_t* b_pos = buf;
6868
size_t read = 0;
69-
size_t remainder = sizeof(int32_t) * 21;
69+
size_t remainder = sizeof(int32_t) * urcl::control::TrajectoryPointInterface::MESSAGE_LENGTH;
7070
while (remainder > 0)
7171
{
7272
if (!TCPSocket::read(b_pos, remainder, read))
7373
{
74-
std::cout << "Failed to read from socket, this should not happen during a test!" << std::endl;
75-
break;
74+
throw(std::runtime_error("Failed to read from socket, this should not happen during a test!"));
7675
}
7776
b_pos += read;
7877
remainder -= read;
@@ -135,6 +134,14 @@ class TrajectoryPointInterfaceTest : public ::testing::Test
135134
return vel;
136135
}
137136

137+
vector6int32_t getAcceleration()
138+
{
139+
int32_t goal_time, blend_radius_or_spline_type, motion_type;
140+
vector6int32_t pos, vel, acc;
141+
readMessage(pos, vel, acc, goal_time, blend_radius_or_spline_type, motion_type);
142+
return acc;
143+
}
144+
138145
int32_t getGoalTime()
139146
{
140147
int32_t goal_time, blend_radius_or_spline_type, motion_type;
@@ -218,13 +225,13 @@ class TrajectoryPointInterfaceTest : public ::testing::Test
218225
private:
219226
std::condition_variable trajectory_end_;
220227
std::mutex trajectory_end_mutex_;
221-
control::TrajectoryResult result_;
228+
control::TrajectoryResult result_ = control::TrajectoryResult::TRAJECTORY_RESULT_UNKNOWN;
222229
};
223230

224231
TEST_F(TrajectoryPointInterfaceTest, write_postions)
225232
{
226233
urcl::vector6d_t send_positions = { 1.2, 3.1, 2.2, -3.4, -1.1, -1.2 };
227-
traj_point_interface_->writeTrajectoryPoint(&send_positions, 0, 0, 0);
234+
traj_point_interface_->writeTrajectoryPoint(&send_positions, 0, 0, false);
228235
vector6int32_t received_positions = client_->getPosition();
229236

230237
EXPECT_EQ(send_positions[0], ((double)received_positions[0]) / traj_point_interface_->MULT_JOINTSTATE);
@@ -361,17 +368,38 @@ TEST_F(TrajectoryPointInterfaceTest, write_goal_time)
361368
{
362369
urcl::vector6d_t send_positions = { 0, 0, 0, 0, 0, 0 };
363370
float send_goal_time = 0.5;
364-
traj_point_interface_->writeTrajectoryPoint(&send_positions, send_goal_time, 0, 0);
371+
traj_point_interface_->writeTrajectoryPoint(&send_positions, send_goal_time, 0, false);
372+
int32_t received_goal_time = client_->getGoalTime();
373+
374+
EXPECT_EQ(send_goal_time, ((float)received_goal_time) / traj_point_interface_->MULT_TIME);
375+
}
376+
377+
TEST_F(TrajectoryPointInterfaceTest, write_acceleration_velocity)
378+
{
379+
urcl::vector6d_t send_positions = { 0, 0, 0, 0, 0, 0 };
380+
float send_move_acceleration = 0.123;
381+
float send_move_velocity = 0.456;
382+
float send_goal_time = 0.5;
383+
traj_point_interface_->writeTrajectoryPoint(&send_positions, send_move_acceleration, send_move_velocity,
384+
send_goal_time, 0, 0);
385+
int32_t received_move_acceleration = client_->getAcceleration()[0];
386+
traj_point_interface_->writeTrajectoryPoint(&send_positions, send_move_acceleration, send_move_velocity,
387+
send_goal_time, 0, 0);
388+
int32_t received_move_velocity = client_->getVelocity()[0];
389+
traj_point_interface_->writeTrajectoryPoint(&send_positions, send_move_acceleration, send_move_velocity,
390+
send_goal_time, 0, 0);
365391
int32_t received_goal_time = client_->getGoalTime();
366392

393+
EXPECT_EQ(send_move_acceleration, ((float)received_move_acceleration) / traj_point_interface_->MULT_JOINTSTATE);
394+
EXPECT_EQ(send_move_velocity, ((float)received_move_velocity) / traj_point_interface_->MULT_JOINTSTATE);
367395
EXPECT_EQ(send_goal_time, ((float)received_goal_time) / traj_point_interface_->MULT_TIME);
368396
}
369397

370398
TEST_F(TrajectoryPointInterfaceTest, write_blend_radius)
371399
{
372400
urcl::vector6d_t send_positions = { 0, 0, 0, 0, 0, 0 };
373401
float send_blend_radius = 0.5;
374-
traj_point_interface_->writeTrajectoryPoint(&send_positions, 0, send_blend_radius, 0);
402+
traj_point_interface_->writeTrajectoryPoint(&send_positions, 0, send_blend_radius, false);
375403
int32_t received_blend_radius = client_->getBlendRadius();
376404

377405
EXPECT_EQ(send_blend_radius, ((float)received_blend_radius) / traj_point_interface_->MULT_TIME);

0 commit comments

Comments
 (0)