Skip to content

Commit c6ea1bc

Browse files
committed
Fix failure in on_activate if feedback not available
1 parent 28c3ad5 commit c6ea1bc

File tree

2 files changed

+45
-25
lines changed

2 files changed

+45
-25
lines changed

multi_time_trajectory_controller/include/multi_time_trajectory_controller/multi_time_trajectory_controller.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ class MultiTimeTrajectoryController : public controller_interface::ControllerInt
336336
ControllerFeedbackMsg last_odom_feedback_;
337337
ControllerReferenceMsg last_reference_;
338338
ControllerReferenceMsg last_reliable_reference_;
339+
bool current_state_initialized_{false};
339340
using JointTrajectoryPoint = control_msgs::msg::AxisTrajectoryPoint;
340341

341342
// Command subscribers and Controller State publisher
@@ -350,6 +351,8 @@ class MultiTimeTrajectoryController : public controller_interface::ControllerInt
350351
bool contains_interface_type(
351352
const std::vector<std::string> & interface_type_list, const std::string & interface_type);
352353

354+
bool initialize_current_state();
355+
353356
void init_hold_position_msg();
354357
};
355358
} // namespace multi_time_trajectory_controller

multi_time_trajectory_controller/src/multi_time_trajectory_controller.cpp

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ controller_interface::return_type MultiTimeTrajectoryController::update(
160160
{
161161
return controller_interface::return_type::OK;
162162
}
163+
164+
// bail if haven't initialized current state and still can't
165+
if (!current_state_initialized_ && !initialize_current_state())
166+
{
167+
return controller_interface::return_type::OK;
168+
}
169+
163170
// update dynamic parameters
164171
if (param_listener_->is_old(params_))
165172
{
@@ -1240,31 +1247,6 @@ controller_interface::CallbackReturn MultiTimeTrajectoryController::on_activate(
12401247

12411248
subscriber_is_active_ = true;
12421249

1243-
// Initialize current state storage if hardware state has tracking offset
1244-
// Handle restart of controller by reading from commands if those are not NaN (a controller was
1245-
// running already)
1246-
std::vector<control_msgs::msg::AxisTrajectoryPoint> state;
1247-
state.resize(dof_);
1248-
1249-
// Handle restart of controller by reading from commands if
1250-
// those are not nan
1251-
if (!read_state_from_command_interfaces(state))
1252-
{
1253-
// Initialize current state storage from hardware
1254-
if (!read_state_from_hardware(state))
1255-
{
1256-
return CallbackReturn::ERROR;
1257-
};
1258-
}
1259-
state_current_ = state;
1260-
state_desired_ = state;
1261-
last_commanded_state_ = state;
1262-
last_commanded_time_ = std::vector<rclcpp::Time>{dof_, rclcpp::Time()};
1263-
1264-
// The controller should start by holding position at the beginning of active state
1265-
add_new_trajectory_msg(set_hold_position());
1266-
rt_is_holding_.writeFromNonRT(true);
1267-
12681250
// parse timeout parameter
12691251
if (params_.cmd_timeout > 0.0)
12701252
{
@@ -1287,6 +1269,8 @@ controller_interface::CallbackReturn MultiTimeTrajectoryController::on_activate(
12871269
cmd_timeout_ = 0.0;
12881270
}
12891271

1272+
initialize_current_state();
1273+
12901274
RCLCPP_DEBUG(get_node()->get_logger(), "MAC successfully activated");
12911275
return CallbackReturn::SUCCESS;
12921276
}
@@ -1895,6 +1879,39 @@ void MultiTimeTrajectoryController::update_pids()
18951879
}
18961880
}
18971881

1882+
bool MultiTimeTrajectoryController::initialize_current_state()
1883+
{
1884+
// Initialize current state storage if hardware state has tracking offset
1885+
// Handle restart of controller by reading from commands if those are not NaN (a controller was
1886+
// running already)
1887+
std::vector<control_msgs::msg::AxisTrajectoryPoint> state;
1888+
state.resize(dof_);
1889+
1890+
// Handle restart of controller by reading from commands if
1891+
// those are not nan
1892+
if (!read_state_from_command_interfaces(state))
1893+
{
1894+
// Initialize current state storage from hardware
1895+
if (!read_state_from_hardware(state))
1896+
{
1897+
RCLCPP_WARN(get_node()->get_logger(), "Failed to read feedback state from hardware");
1898+
return false;
1899+
};
1900+
}
1901+
state_current_ = state;
1902+
state_desired_ = state;
1903+
last_commanded_state_ = state;
1904+
last_commanded_time_ = std::vector<rclcpp::Time>{dof_, rclcpp::Time()};
1905+
1906+
// The controller should start by holding position at the beginning of active state
1907+
add_new_trajectory_msg(set_hold_position());
1908+
rt_is_holding_.writeFromNonRT(true);
1909+
1910+
current_state_initialized_ = true;
1911+
1912+
return true;
1913+
}
1914+
18981915
void MultiTimeTrajectoryController::init_hold_position_msg()
18991916
{
19001917
hold_position_msg_ptr_ = std::make_shared<control_msgs::msg::MultiAxisTrajectory>();

0 commit comments

Comments
 (0)