Skip to content

Commit f99ba18

Browse files
committed
update
1 parent 2e69bc1 commit f99ba18

File tree

7 files changed

+114
-1
lines changed

7 files changed

+114
-1
lines changed

include/ur_client_library/comm/control_mode.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ enum class ControlMode : int32_t
4545
MODE_SPEEDJ = 2, ///< Set when speedj control is active.
4646
MODE_FORWARD = 3, ///< Set when trajectory forwarding is active.
4747
MODE_SPEEDL = 4, ///< Set when cartesian velocity control is active.
48-
MODE_POSE = 5 ///< Set when cartesian pose control is active.
48+
MODE_POSE = 5, ///< Set when cartesian pose control is active.
49+
MODE_FREEDRIVE = 6 ///< Set when freedrive mode is active.
4950
};
5051
} // namespace comm
5152
} // namespace urcl

include/ur_client_library/control/reverse_interface.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ enum class TrajectoryControlMessage : int32_t
5151
TRAJECTORY_START = 1, ///< Represents command to start a new trajectory.
5252
};
5353

54+
/*!
55+
* \brief Control messages for starting and stopping freedrive mode.
56+
*/
57+
enum class FreedriveControlMessage : int32_t
58+
{
59+
FREEDRIVE_STOP = -1, ///< Represents command to stop freedrive mode.
60+
FREEDRIVE_NOOP = 0, ///< Represents keep running in freedrive mode.
61+
FREEDRIVE_START = 1, ///< Represents command to start freedrive mode.
62+
};
63+
5464
/*!
5565
* \brief The ReverseInterface class handles communication to the robot. It starts a server and
5666
* waits for the robot to connect via its URCaps program.
@@ -95,6 +105,15 @@ class ReverseInterface
95105
*/
96106
bool writeTrajectoryControlMessage(const TrajectoryControlMessage trajectory_action, const int point_number = 0);
97107

108+
/*!
109+
* \brief Writes needed information to the robot to be read by the URScript program.
110+
*
111+
* \param freedrive_action 1 if freedrive mode is to be started, -1 if it should be stopped and 0 to keep it running
112+
*
113+
* \returns True, if the write was performed successfully, false otherwise.
114+
*/
115+
bool writeFreedriveControlMessage(const FreedriveControlMessage freedrive_action);
116+
98117
/*!
99118
* \brief Set the Keepalive count. This will set the number of allowed timeout reads on the robot.
100119
*

include/ur_client_library/ur/ur_driver.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,15 @@ class UrDriver
222222
bool writeTrajectoryControlMessage(const control::TrajectoryControlMessage trajectory_action,
223223
const int point_number = 0);
224224

225+
/*!
226+
* \brief Writes a control message in freedrive mode.
227+
*
228+
* \param freedrive_action The action to be taken, such as starting or stopping freedrive
229+
*
230+
* \returns True on successful write.
231+
*/
232+
bool writeFreedriveControlMessage(const control::FreedriveControlMessage freedrive_action);
233+
225234
/*!
226235
* \brief Zero the force torque sensor (only availbe on e-Series). Note: It requires the external control script to
227236
* be running or the robot to be in headless mode

resources/external_control.urscript

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ MODE_SPEEDJ = 2
2121
MODE_FORWARD = 3
2222
MODE_SPEEDL = 4
2323
MODE_POSE = 5
24+
MODE_FREEDRIVE = 6
2425

2526
TRAJECTORY_MODE_RECEIVE = 1
2627
TRAJECTORY_MODE_CANCEL = -1
@@ -38,6 +39,9 @@ SET_PAYLOAD = 1
3839
SET_TOOL_VOLTAGE = 2
3940
SCRIPT_COMMAND_DATA_DIMENSION = 5
4041

42+
FREEDRIVE_MODE_START = 1
43+
FREEDRIVE_MODE_STOP = -1
44+
4145
#Global variables are also showed in the Teach pendants variable list
4246
global cmd_servo_state = SERVO_UNINITIALIZED
4347
global cmd_servo_qd = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
@@ -265,6 +269,9 @@ while keepalive > 0 and control_mode > MODE_STOPPED:
265269
if control_mode == MODE_FORWARD:
266270
kill thread_trajectory
267271
clear_remaining_trajectory_points()
272+
# Stop freedrive
273+
elif control_mode == MODE_FREEDRIVE:
274+
end_freedrive_mode()
268275
end
269276
control_mode = params_mult[8]
270277
join thread_move
@@ -304,6 +311,12 @@ while keepalive > 0 and control_mode > MODE_STOPPED:
304311
elif control_mode == MODE_POSE:
305312
pose = p[params_mult[2] / MULT_jointstate, params_mult[3] / MULT_jointstate, params_mult[4] / MULT_jointstate, params_mult[5] / MULT_jointstate, params_mult[6] / MULT_jointstate, params_mult[7] / MULT_jointstate]
306313
set_servo_pose(pose)
314+
elif control_mode == MODE_FREEDRIVE:
315+
if params_mult[2] == FREEDRIVE_MODE_START:
316+
freedrive_mode()
317+
elif params_mult[2] == FREEDRIVE_MODE_STOP:
318+
end_freedrive_mode()
319+
end
307320
end
308321
else:
309322
keepalive = keepalive - 1

src/control/reverse_interface.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,38 @@ bool ReverseInterface::writeTrajectoryControlMessage(const TrajectoryControlMess
114114
return server_.write(client_fd_, buffer, sizeof(buffer), written);
115115
}
116116

117+
bool ReverseInterface::writeFreedriveControlMessage(const FreedriveControlMessage freedrive_action)
118+
{
119+
const int message_length = 2;
120+
if (client_fd_ == -1)
121+
{
122+
return false;
123+
}
124+
uint8_t buffer[sizeof(int32_t) * 8];
125+
uint8_t* b_pos = buffer;
126+
127+
// The first element is always the keepalive signal.
128+
int32_t val = htobe32(keepalive_count_);
129+
b_pos += append(b_pos, val);
130+
131+
val = htobe32(toUnderlying(freedrive_action));
132+
b_pos += append(b_pos, val);
133+
134+
// writing zeros to allow usage with other script commands
135+
for (size_t i = message_length; i < 8 - 1; i++)
136+
{
137+
val = htobe32(0);
138+
b_pos += append(b_pos, val);
139+
}
140+
141+
val = htobe32(toUnderlying(comm::ControlMode::MODE_FREEDRIVE));
142+
b_pos += append(b_pos, val);
143+
144+
size_t written;
145+
146+
return server_.write(client_fd_, buffer, sizeof(buffer), written);
147+
}
148+
117149
void ReverseInterface::connectionCallback(const int filedescriptor)
118150
{
119151
if (client_fd_ < 0)

src/ur/ur_driver.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ bool UrDriver::writeTrajectoryControlMessage(const control::TrajectoryControlMes
233233
return reverse_interface_->writeTrajectoryControlMessage(trajectory_action, point_number);
234234
}
235235

236+
bool UrDriver::writeFreedriveControlMessage(const control::FreedriveControlMessage freedrive_action)
237+
{
238+
return reverse_interface_->writeFreedriveControlMessage(freedrive_action);
239+
}
240+
236241
bool UrDriver::zeroFTSensor()
237242
{
238243
if (getVersion().major < 5)

tests/test_reverse_interface.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ class ReverseIntefaceTest : public ::testing::Test
136136
return pos[1];
137137
}
138138

139+
int32_t getFreedriveControlMode()
140+
{
141+
// received_pos[0]=control::FreedriveControlMessage, when writing a trajectory control message
142+
int32_t keep_alive_signal;
143+
int32_t control_mode;
144+
vector6int32_t pos;
145+
readMessage(keep_alive_signal, pos, control_mode);
146+
return pos[0];
147+
}
148+
139149
protected:
140150
virtual bool open(int socket_fd, struct sockaddr* address, size_t address_len)
141151
{
@@ -360,6 +370,30 @@ TEST_F(ReverseIntefaceTest, write_control_mode)
360370
EXPECT_EQ(toUnderlying(expected_control_mode), received_control_mode);
361371
}
362372

373+
TEST_F(ReverseIntefaceTest, write_freedrive_control_message)
374+
{
375+
// Wait for the client to connect to the server
376+
EXPECT_TRUE(waitForProgramState(1000, true));
377+
378+
control::FreedriveControlMessage written_freedrive_message = control::FreedriveControlMessage::FREEDRIVE_STOP;
379+
reverse_interface_->writeFreedriveControlMessage(written_freedrive_message);
380+
int32_t received_freedrive_message = client_->getFreedriveControlMode();
381+
382+
EXPECT_EQ(toUnderlying(written_freedrive_message), received_freedrive_message);
383+
384+
written_freedrive_message = control::FreedriveControlMessage::FREEDRIVE_NOOP;
385+
reverse_interface_->writeFreedriveControlMessage(written_freedrive_message);
386+
received_freedrive_message = client_->getFreedriveControlMode();
387+
388+
EXPECT_EQ(toUnderlying(written_freedrive_message), received_freedrive_message);
389+
390+
written_freedrive_message = control::FreedriveControlMessage::FREEDRIVE_START;
391+
reverse_interface_->writeFreedriveControlMessage(written_freedrive_message);
392+
received_freedrive_message = client_->getFreedriveControlMode();
393+
394+
EXPECT_EQ(toUnderlying(written_freedrive_message), received_freedrive_message);
395+
}
396+
363397
int main(int argc, char* argv[])
364398
{
365399
::testing::InitGoogleTest(&argc, argv);

0 commit comments

Comments
 (0)