Configuration
- ROS Distro: Humble
- OS Version: Ubuntu 22.04
Description
Hi,
I am trying to create a hardware_interface
plugin for ros2_control. I want to create a publisher to write()
and a subscriber to read()
.
I am running into issues setting up the subscriber.
Then code is given below.
Code
#include
#include
#include
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/float64.hpp"
#include "sensor_msgs/msg/joint_state.hpp"
#include "custom_interfaces/msg/motor_command.hpp"
#include "test_hardware_interface/test_hardware_interface.hpp"
#include "hardware_interface/actuator_interface.hpp"
#include "hardware_interface/types/hardware_interface_type_values.hpp"
using namespace hardware_interface;
static const auto LOGGER = rclcpp::get_logger("Grab-Hardware");
namespace test_hardware_interface
{
//HardwareComms Methods
HardwareComms::HardwareComms() : Node("joint_comms")
{
//Lamda callback for stateSub_
auto stateCB =
[this](const std_msgs::msg::Float64::SharedPtr state) -> void
{
RCLCPP_INFO(this->get_logger(), "Callback");
state_ = state->data;
};
commandPub_ = this->create_publisher(
"/test_pub",
0
);
stateSub_ = this->create_subscription(
"/test_sub",
0,
stateCB
);
}
void HardwareComms::sendCommand(double position, double velocity, double acceleration)
{
auto command = custom_interfaces::msg::MotorCommand();
command.position = position;
command.velocity = velocity;
command.acceleration = acceleration;
commandPub_->publish(command);
}
double HardwareComms::getState()
{
return state_;
}
//HardwareInterface Methods
CallbackReturn HardwareInterface::on_init(const hardware_interface::HardwareInfo &info)
{
RCLCPP_INFO(LOGGER, "Initialising...");
if(
hardware_interface::ActuatorInterface::on_init(info) !=
hardware_interface::CallbackReturn::SUCCESS)
{
return hardware_interface::CallbackReturn::ERROR;
}
comms = std::make_shared();
hw_joint_state_ = std::numeric_limits::quiet_NaN();
hw_position_command_ = std::numeric_limits::quiet_NaN();
hw_velocity_command_ = std::numeric_limits::quiet_NaN();
hw_acceleration_command_ = std::numeric_limits::quiet_NaN();
const ComponentInfo &joint = info_.joints[0];
if(joint.command_interfaces.size() != 3) {
RCLCPP_FATAL(
LOGGER,
"Joint '%s' has %zu command interfaces found. 3 expected.", joint.name.c_str(),
joint.command_interfaces.size()
);
return hardware_interface::CallbackReturn::ERROR;
}
RCLCPP_INFO(LOGGER, "Checking Position IF");
if (joint.command_interfaces[0].name != hardware_interface::HW_IF_POSITION) {
RCLCPP_FATAL(
LOGGER,
"Joint '%s' have %s command interfaces found. '%s' expected.", joint.name.c_str(),
joint.command_interfaces[0].name.c_str(), hardware_interface::HW_IF_POSITION
);
return hardware_interface::CallbackReturn::ERROR;
}
RCLCPP_INFO(LOGGER, "Clear!");
RCLCPP_INFO(LOGGER, "Checking Velocity IF");
if (joint.command_interfaces[1].name != hardware_interface::HW_IF_VELOCITY) {
RCLCPP_FATAL(
LOGGER,
"Joint '%s' have %s command interfaces found. '%s' expected.", joint.name.c_str(),
joint.command_interfaces[1].name.c_str(), hardware_interface::HW_IF_VELOCITY
);
return hardware_interface::CallbackReturn::ERROR;
}
RCLCPP_INFO(LOGGER, "Clear!");
RCLCPP_INFO(LOGGER, "Checking Acceleration IF");
if (joint.command_interfaces[2].name != hardware_interface::HW_IF_ACCELERATION) {
RCLCPP_FATAL(
LOGGER,
"Joint '%s' have %s command interfaces found. '%s' expected.", joint.name.c_str(),
joint.command_interfaces[2].name.c_str(), hardware_interface::HW_IF_ACCELERATION
);
return hardware_interface::CallbackReturn::ERROR;
}
RCLCPP_INFO(LOGGER, "Clear!");
if (joint.state_interfaces.size() != 1) {
RCLCPP_FATAL(
LOGGER, "Joint '%s' has %zu state interface. 1 expected.",
joint.name.c_str(), joint.state_interfaces.size());
return hardware_interface::CallbackReturn::ERROR;
}
if (joint.state_interfaces[0].name != hardware_interface::HW_IF_POSITION) {
RCLCPP_FATAL(
LOGGER, "Joint '%s' have %s state interface. '%s' expected.",
joint.name.c_str(), joint.state_interfaces[0].name.c_str(),
hardware_interface::HW_IF_POSITION);
return hardware_interface::CallbackReturn::ERROR;
}
RCLCPP_INFO(LOGGER, "Done!");
return hardware_interface::CallbackReturn::SUCCESS;
}
CallbackReturn HardwareInterface::on_configure(const rclcpp_lifecycle::State & /*previous_state*/)
{
RCLCPP_INFO(LOGGER, "Configuring...");
return hardware_interface::CallbackReturn::SUCCESS;
}
std::vector HardwareInterface::export_state_interfaces()
{
std::vector state_interfaces;
state_interfaces.emplace_back(hardware_interface::StateInterface(
info_.joints[0].name, hardware_interface::HW_IF_POSITION, &hw_joint_state_));
return state_interfaces;
}
std::vector HardwareInterface::export_command_interfaces()
{
std::vector command_interfaces;
command_interfaces.emplace_back(hardware_interface::CommandInterface(
info_.joints[0].name, hardware_interface::HW_IF_POSITION, &hw_position_command_));
command_interfaces.emplace_back(hardware_interface::CommandInterface(
info_.joints[0].name, hardware_interface::HW_IF_VELOCITY, &hw_velocity_command_));
command_interfaces.emplace_back(hardware_interface::CommandInterface(
info_.joints[0].name, hardware_interface::HW_IF_ACCELERATION, &hw_acceleration_command_));
return command_interfaces;
}
CallbackReturn HardwareInterface::on_activate(const rclcpp_lifecycle::State & /*previous_state*/)
{
if (std::isnan(hw_joint_state_)) {
hw_joint_state_ = 0.0;
hw_position_command_ = 0.0;
hw_velocity_command_ = 5.0;
hw_acceleration_command_ = 0.0;
}
RCLCPP_INFO(LOGGER, "Successfully activated!");
return hardware_interface::CallbackReturn::SUCCESS;
}
CallbackReturn HardwareInterface::on_deactivate(
const rclcpp_lifecycle::State & /*previous_state*/)
{
RCLCPP_INFO(LOGGER, "Successfully deactivated!");
return hardware_interface::CallbackReturn::SUCCESS;
}
return_type HardwareInterface::read(
const rclcpp::Time & /*time*/,
const rclcpp::Duration & /*period*/)
{
hw_joint_state_ = comms->getState();
RCLCPP_INFO(rclcpp::get_logger("HardwareRead"), "State: %f", hw_joint_state_);
return hardware_interface::return_type::OK;
}
return_type HardwareInterface::write(
const rclcpp::Time & /*time*/,
const rclcpp::Duration & /*period*/)
{
comms->sendCommand(hw_position_command_, hw_velocity_command_, hw_acceleration_command_);
return hardware_interface::return_type::OK;
}
} //namespace grab_hardware
#include "pluginlib/class_list_macros.hpp"
PLUGINLIB_EXPORT_CLASS(test_hardware_interface::HardwareInterface, hardware_interface::ActuatorInterface)
The publisher works fine, but the callback of the subscriber does not get called. Am I missing something? Any help is appreciated Thank you.
Originally posted by Cryoschrome on ROS Answers with karma: 75 on 2022-06-28
Post score: 0