Skip to content

Commit 4e9814b

Browse files
Update control law also for hold position
1 parent 408357c commit 4e9814b

File tree

4 files changed

+78
-25
lines changed

4 files changed

+78
-25
lines changed

joint_trajectory_controller/include/joint_trajectory_controller/joint_trajectory_controller.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,10 @@ class JointTrajectoryController : public controller_interface::ControllerInterfa
237237
JOINT_TRAJECTORY_CONTROLLER_PUBLIC
238238
bool validate_trajectory_msg(const trajectory_msgs::msg::JointTrajectory & trajectory) const;
239239
JOINT_TRAJECTORY_CONTROLLER_PUBLIC
240-
void add_new_trajectory_msg(
240+
void add_new_trajectory_msg_nonRT(
241+
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & traj_msg);
242+
JOINT_TRAJECTORY_CONTROLLER_PUBLIC
243+
void add_new_trajectory_msg_RT(
241244
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & traj_msg);
242245
JOINT_TRAJECTORY_CONTROLLER_PUBLIC
243246
bool validate_trajectory_point_field(

joint_trajectory_controller/src/joint_trajectory_controller.cpp

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,7 @@ controller_interface::return_type JointTrajectoryController::update(
256256
{
257257
RCLCPP_WARN(get_node()->get_logger(), "Aborted due to command timeout");
258258

259-
traj_msg_external_point_ptr_.reset();
260-
traj_msg_external_point_ptr_.initRT(set_hold_position());
259+
add_new_trajectory_msg_RT(set_hold_position());
261260
}
262261

263262
// Check state/goal tolerance
@@ -358,8 +357,7 @@ controller_interface::return_type JointTrajectoryController::update(
358357

359358
RCLCPP_WARN(get_node()->get_logger(), "Aborted due to state tolerance violation");
360359

361-
traj_msg_external_point_ptr_.reset();
362-
traj_msg_external_point_ptr_.initRT(set_hold_position());
360+
add_new_trajectory_msg_RT(set_hold_position());
363361
}
364362
// check goal tolerance
365363
else if (!before_last_point)
@@ -376,8 +374,7 @@ controller_interface::return_type JointTrajectoryController::update(
376374

377375
RCLCPP_INFO(get_node()->get_logger(), "Goal reached, success!");
378376

379-
traj_msg_external_point_ptr_.reset();
380-
traj_msg_external_point_ptr_.initRT(set_success_trajectory_point());
377+
add_new_trajectory_msg_RT(set_success_trajectory_point());
381378
}
382379
else if (!within_goal_time)
383380
{
@@ -393,8 +390,7 @@ controller_interface::return_type JointTrajectoryController::update(
393390
get_node()->get_logger(), "Aborted due goal_time_tolerance exceeding by %f seconds",
394391
time_difference);
395392

396-
traj_msg_external_point_ptr_.reset();
397-
traj_msg_external_point_ptr_.initRT(set_hold_position());
393+
add_new_trajectory_msg_RT(set_hold_position());
398394
}
399395
}
400396
}
@@ -403,16 +399,14 @@ controller_interface::return_type JointTrajectoryController::update(
403399
// we need to ensure that there is no pending goal -> we get a race condition otherwise
404400
RCLCPP_ERROR(get_node()->get_logger(), "Holding position due to state tolerance violation");
405401

406-
traj_msg_external_point_ptr_.reset();
407-
traj_msg_external_point_ptr_.initRT(set_hold_position());
402+
add_new_trajectory_msg_RT(set_hold_position());
408403
}
409404
else if (
410405
!before_last_point && !within_goal_time && *(rt_has_pending_goal_.readFromRT()) == false)
411406
{
412407
RCLCPP_ERROR(get_node()->get_logger(), "Exceeded goal_time_tolerance: holding position...");
413408

414-
traj_msg_external_point_ptr_.reset();
415-
traj_msg_external_point_ptr_.initRT(set_hold_position());
409+
add_new_trajectory_msg_RT(set_hold_position());
416410
}
417411
// else, run another cycle while waiting for outside_goal_tolerance
418412
// to be satisfied (will stay in this state until new message arrives)
@@ -1024,7 +1018,7 @@ controller_interface::CallbackReturn JointTrajectoryController::on_activate(
10241018
}
10251019

10261020
// The controller should start by holding position at the beginning of active state
1027-
add_new_trajectory_msg(set_hold_position());
1021+
add_new_trajectory_msg_nonRT(set_hold_position());
10281022
rt_is_holding_.writeFromNonRT(true);
10291023

10301024
// parse timeout parameter
@@ -1180,7 +1174,7 @@ void JointTrajectoryController::topic_callback(
11801174
// always replace old msg with new one for now
11811175
if (subscriber_is_active_)
11821176
{
1183-
add_new_trajectory_msg(msg);
1177+
add_new_trajectory_msg_nonRT(msg);
11841178
rt_is_holding_.writeFromNonRT(false);
11851179
}
11861180
};
@@ -1226,7 +1220,7 @@ rclcpp_action::CancelResponse JointTrajectoryController::goal_cancelled_callback
12261220
rt_active_goal_.writeFromNonRT(RealtimeGoalHandlePtr());
12271221

12281222
// Enter hold current position mode
1229-
add_new_trajectory_msg(set_hold_position());
1223+
add_new_trajectory_msg_nonRT(set_hold_position());
12301224
}
12311225
return rclcpp_action::CancelResponse::ACCEPT;
12321226
}
@@ -1243,7 +1237,7 @@ void JointTrajectoryController::goal_accepted_callback(
12431237
auto traj_msg =
12441238
std::make_shared<trajectory_msgs::msg::JointTrajectory>(goal_handle->get_goal()->trajectory);
12451239

1246-
add_new_trajectory_msg(traj_msg);
1240+
add_new_trajectory_msg_nonRT(traj_msg);
12471241
rt_is_holding_.writeFromNonRT(false);
12481242
}
12491243

@@ -1516,27 +1510,47 @@ bool JointTrajectoryController::validate_trajectory_msg(
15161510
return true;
15171511
}
15181512

1519-
void JointTrajectoryController::add_new_trajectory_msg(
1513+
void JointTrajectoryController::add_new_trajectory_msg_nonRT(
15201514
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & traj_msg)
15211515
{
15221516
traj_msg_external_point_ptr_.writeFromNonRT(traj_msg);
15231517

1524-
// compute gains of controller
1518+
// compute control law
15251519
if (traj_contr_)
15261520
{
1521+
// this can take some time; trajectory won't start until control law is computed
15271522
if (traj_contr_->computeControlLawNonRT(traj_msg) == false)
15281523
{
15291524
RCLCPP_ERROR(get_node()->get_logger(), "Failed to compute gains for trajectory.");
15301525
}
15311526
}
15321527
}
15331528

1529+
void JointTrajectoryController::add_new_trajectory_msg_RT(
1530+
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & traj_msg)
1531+
{
1532+
// TODO(christophfroehlich): Need a lock-free write here
1533+
// See https://github.com/ros-controls/ros2_controllers/issues/168
1534+
traj_msg_external_point_ptr_.reset();
1535+
traj_msg_external_point_ptr_.initRT(traj_msg);
1536+
1537+
// compute control law
1538+
if (traj_contr_)
1539+
{
1540+
// this is used for set_hold_position() only -> this should (and must) not take a long time
1541+
if (traj_contr_->computeControlLawRT(traj_msg) == false)
1542+
{
1543+
RCLCPP_ERROR(get_node()->get_logger(), "Failed to compute gains for trajectory.");
1544+
}
1545+
}
1546+
}
1547+
15341548
void JointTrajectoryController::preempt_active_goal()
15351549
{
15361550
const auto active_goal = *rt_active_goal_.readFromNonRT();
15371551
if (active_goal)
15381552
{
1539-
add_new_trajectory_msg(set_hold_position());
1553+
add_new_trajectory_msg_nonRT(set_hold_position());
15401554
auto action_res = std::make_shared<FollowJTrajAction::Result>();
15411555
action_res->set__error_code(FollowJTrajAction::Result::INVALID_GOAL);
15421556
action_res->set__error_string("Current goal cancelled due to new incoming action.");

joint_trajectory_controller_plugins/include/joint_trajectory_controller_plugins/pid_trajectory_plugin.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,14 @@ class PidTrajectoryPlugin : public TrajectoryControllerBase
3939

4040
bool activate() override;
4141

42-
bool computeControlLaw(
42+
bool computeControlLawNonRT_impl(
43+
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & /*trajectory*/) override
44+
{
45+
// nothing to do
46+
return true;
47+
}
48+
49+
bool computeControlLawRT_impl(
4350
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & /*trajectory*/) override
4451
{
4552
// nothing to do

joint_trajectory_controller_plugins/include/joint_trajectory_controller_plugins/trajectory_controller_base.hpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class TrajectoryControllerBase
6767
* of the trajectory until it finishes
6868
*
6969
* this method is not virtual, any overrides won't be called by JTC. Instead, override
70-
* computeControlLaw for your implementation
70+
* computeControlLawNonRT_impl for your implementation
7171
*
7272
* @return true if the gains were computed, false otherwise
7373
*/
@@ -76,7 +76,28 @@ class TrajectoryControllerBase
7676
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & trajectory)
7777
{
7878
rt_control_law_ready_.writeFromNonRT(false);
79-
auto ret = computeControlLaw(trajectory);
79+
auto ret = computeControlLawNonRT_impl(trajectory);
80+
rt_control_law_ready_.writeFromNonRT(true);
81+
return ret;
82+
}
83+
84+
/**
85+
* @brief compute the control law for the given trajectory
86+
*
87+
* this method must finish quickly (within one controller-update rate)
88+
*
89+
* this method is not virtual, any overrides won't be called by JTC. Instead, override
90+
* computeControlLawRT_impl for your implementation
91+
*
92+
* @return true if the gains were computed, false otherwise
93+
*/
94+
JOINT_TRAJECTORY_CONTROLLER_PLUGINS_PUBLIC
95+
bool computeControlLawRT(
96+
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & trajectory)
97+
{
98+
// TODO(christophfroehlich): Need a lock-free write here
99+
rt_control_law_ready_.writeFromNonRT(false);
100+
auto ret = computeControlLawRT_impl(trajectory);
80101
rt_control_law_ready_.writeFromNonRT(true);
81102
return ret;
82103
}
@@ -135,11 +156,19 @@ class TrajectoryControllerBase
135156
realtime_tools::RealtimeBuffer<bool> rt_control_law_ready_;
136157

137158
/**
138-
* @brief compute the control law from the given trajectory
159+
* @brief compute the control law from the given trajectory (in the non-RT loop)
160+
* @return true if the gains were computed, false otherwise
161+
*/
162+
JOINT_TRAJECTORY_CONTROLLER_PLUGINS_PUBLIC
163+
virtual bool computeControlLawNonRT_impl(
164+
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & trajectory) = 0;
165+
166+
/**
167+
* @brief compute the control law for a single point (in the RT loop)
139168
* @return true if the gains were computed, false otherwise
140169
*/
141170
JOINT_TRAJECTORY_CONTROLLER_PLUGINS_PUBLIC
142-
virtual bool computeControlLaw(
171+
virtual bool computeControlLawRT_impl(
143172
const std::shared_ptr<trajectory_msgs::msg::JointTrajectory> & trajectory) = 0;
144173
};
145174

0 commit comments

Comments
 (0)