Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Admittance] multiple state/command interfaces #1196

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ class AdmittanceController : public controller_interface::ChainableControllerInt
hardware_interface::HW_IF_ACCELERATION};

// internal reference values
const std::vector<std::string> allowed_reference_interfaces_types_ = {
hardware_interface::HW_IF_POSITION, hardware_interface::HW_IF_VELOCITY};
std::vector<std::reference_wrapper<double>> position_reference_;
std::vector<std::reference_wrapper<double>> velocity_reference_;

Expand Down
74 changes: 52 additions & 22 deletions admittance_controller/src/admittance_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ AdmittanceController::on_export_reference_interfaces()

// assign reference interfaces
auto index = 0ul;
for (const auto & interface : allowed_reference_interfaces_types_)
for (const auto & interface : admittance_->parameters_.chainable_command_interfaces)
MarcoMagriDev marked this conversation as resolved.
Show resolved Hide resolved
{
for (const auto & joint : admittance_->parameters_.joints)
{
Expand Down Expand Up @@ -258,6 +258,12 @@ controller_interface::CallbackReturn AdmittanceController::on_configure(
has_acceleration_state_interface_ = contains_interface_type(
admittance_->parameters_.state_interfaces, hardware_interface::HW_IF_ACCELERATION);

if (!has_position_state_interface_)
{
RCLCPP_ERROR(get_node()->get_logger(), "Position state interface is required.");
return CallbackReturn::FAILURE;
}

auto get_interface_list = [](const std::vector<std::string> & interface_types)
{
std::stringstream ss_command_interfaces;
Expand Down Expand Up @@ -406,13 +412,22 @@ controller_interface::return_type AdmittanceController::update_reference_from_su
// if message exists, load values into references
if (joint_command_msg_.get())
{
for (size_t i = 0; i < joint_command_msg_->positions.size(); ++i)
for (const auto & interface : admittance_->parameters_.chainable_command_interfaces)
{
position_reference_[i].get() = joint_command_msg_->positions[i];
}
for (size_t i = 0; i < joint_command_msg_->velocities.size(); ++i)
{
velocity_reference_[i].get() = joint_command_msg_->velocities[i];
if (interface == hardware_interface::HW_IF_POSITION)
{
for (size_t i = 0; i < joint_command_msg_->positions.size(); ++i)
{
position_reference_[i].get() = joint_command_msg_->positions[i];
}
}
else if (interface == hardware_interface::HW_IF_VELOCITY)
{
for (size_t i = 0; i < joint_command_msg_->velocities.size(); ++i)
{
velocity_reference_[i].get() = joint_command_msg_->velocities[i];
}
}
}
}

Expand Down Expand Up @@ -464,8 +479,13 @@ controller_interface::CallbackReturn AdmittanceController::on_deactivate(
// reset to prevent stale references
for (size_t i = 0; i < num_joints_; i++)
{
position_reference_[i].get() = std::numeric_limits<double>::quiet_NaN();
velocity_reference_[i].get() = std::numeric_limits<double>::quiet_NaN();
for (const auto & interface : admittance_->parameters_.chainable_command_interfaces)
{
if (interface == hardware_interface::HW_IF_POSITION)
position_reference_[i].get() = std::numeric_limits<double>::quiet_NaN();
else if (interface == hardware_interface::HW_IF_VELOCITY)
velocity_reference_[i].get() = std::numeric_limits<double>::quiet_NaN();
}
}

for (size_t index = 0; index < allowed_interface_types_.size(); ++index)
Expand Down Expand Up @@ -500,7 +520,7 @@ void AdmittanceController::read_state_from_hardware(
bool nan_acceleration = false;

size_t pos_ind = 0;
size_t vel_ind = pos_ind + has_velocity_command_interface_;
size_t vel_ind = pos_ind + has_velocity_state_interface_;
size_t acc_ind = vel_ind + has_acceleration_state_interface_;
for (size_t joint_ind = 0; joint_ind < num_joints_; ++joint_ind)
{
Expand Down Expand Up @@ -553,8 +573,9 @@ void AdmittanceController::write_state_to_hardware(
{
// if any interface has nan values, assume state_commanded is the last command state
size_t pos_ind = 0;
size_t vel_ind = pos_ind + has_velocity_command_interface_;
size_t acc_ind = vel_ind + has_acceleration_state_interface_;
size_t vel_ind =
(has_position_command_interface_) ? pos_ind + has_velocity_command_interface_ : pos_ind;
MarcoMagriDev marked this conversation as resolved.
Show resolved Hide resolved
size_t acc_ind = vel_ind + has_acceleration_command_interface_;
for (size_t joint_ind = 0; joint_ind < num_joints_; ++joint_ind)
{
if (has_position_command_interface_)
Expand Down Expand Up @@ -584,19 +605,28 @@ void AdmittanceController::read_state_reference_interfaces(
// if any interface has nan values, assume state_reference is the last set reference
for (size_t i = 0; i < num_joints_; ++i)
{
// update position
if (std::isnan(position_reference_[i]))
for (const auto & interface : admittance_->parameters_.chainable_command_interfaces)
{
position_reference_[i].get() = last_reference_.positions[i];
}
state_reference.positions[i] = position_reference_[i];
// update position
if (interface == hardware_interface::HW_IF_POSITION)
{
if (std::isnan(position_reference_[i]))
{
position_reference_[i].get() = last_reference_.positions[i];
}
state_reference.positions[i] = position_reference_[i];
}

// update velocity
if (std::isnan(velocity_reference_[i]))
{
velocity_reference_[i].get() = last_reference_.velocities[i];
// update velocity
if (interface == hardware_interface::HW_IF_VELOCITY)
{
if (std::isnan(velocity_reference_[i]))
{
velocity_reference_[i].get() = last_reference_.velocities[i];
}
state_reference.velocities[i] = velocity_reference_[i];
}
}
state_reference.velocities[i] = velocity_reference_[i];
}

last_reference_.positions = state_reference.positions;
Expand Down
43 changes: 43 additions & 0 deletions admittance_controller/test/test_admittance_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,49 @@ TEST_F(AdmittanceControllerTest, activate_success)
ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS);
}

TEST_F(AdmittanceControllerTest, missing_pos_state_interface)
{
auto overrides = {rclcpp::Parameter("state_interfaces", std::vector<std::string>{"velocity"})};
SetUpController("test_admittance_controller", overrides);
ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_FAILURE);
}

TEST_F(AdmittanceControllerTest, only_vel_command_interface)
{
command_interface_types_ = {"velocity"};
auto overrides = {rclcpp::Parameter("command_interfaces", std::vector<std::string>{"velocity"})};
SetUpController("test_admittance_controller", overrides);
ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS);
ASSERT_EQ(controller_->on_activate(rclcpp_lifecycle::State()), NODE_SUCCESS);
ASSERT_EQ(
controller_->update_and_write_commands(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)),
controller_interface::return_type::OK);
}

TEST_F(AdmittanceControllerTest, only_pos_reference_interface)
{
auto overrides = {
rclcpp::Parameter("chainable_command_interfaces", std::vector<std::string>{"position"})};
SetUpController("test_admittance_controller", overrides);
ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS);
}

TEST_F(AdmittanceControllerTest, only_vel_reference_interface)
{
auto overrides = {
rclcpp::Parameter("chainable_command_interfaces", std::vector<std::string>{"velocity"})};
SetUpController("test_admittance_controller", overrides);
ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_SUCCESS);
}

TEST_F(AdmittanceControllerTest, invalid_reference_interface)
{
auto overrides = {rclcpp::Parameter(
"chainable_command_interfaces", std::vector<std::string>{"invalid_interface"})};
SetUpController("test_admittance_controller", overrides);
ASSERT_EQ(controller_->on_configure(rclcpp_lifecycle::State()), NODE_ERROR);
}

TEST_F(AdmittanceControllerTest, update_success)
{
SetUpController();
Expand Down
2 changes: 1 addition & 1 deletion admittance_controller/test/test_admittance_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ class AdmittanceControllerTest : public ::testing::Test
// Controller-related parameters
const std::vector<std::string> joint_names_ = {"joint1", "joint2", "joint3",
"joint4", "joint5", "joint6"};
const std::vector<std::string> command_interface_types_ = {"position"};
std::vector<std::string> command_interface_types_ = {"position"};
const std::vector<std::string> state_interface_types_ = {"position"};
const std::string ft_sensor_name_ = "ft_sensor_name";

Expand Down
Loading