6#ifndef _USE_MATH_DEFINES
7#define _USE_MATH_DEFINES
21#include <rcutils/logging_macros.h>
23using namespace std::chrono_literals;
46void ControlBoard_nws_ros2::closePorts()
77 m_publisherJointStates = m_node->create_publisher<sensor_msgs::msg::JointState>(m_jointStateTopicName, 10);
78 m_jointControlModeTopicName =
m_topic_name +
"/controlModes";
79 m_publisherControlModes = m_node->create_publisher<std_msgs::msg::Int8MultiArray>(m_jointControlModeTopicName, 10);
85bool ControlBoard_nws_ros2::initRos2Control(
const std::string& name){
87 m_posTopicName = name+
"/position";
88 m_posDirTopicName = name+
"/position_direct";
89 m_velTopicName = name+
"/velocity";
90 m_getModesSrvName = name+
"/get_modes";
91 m_setModesSrvName = name+
"/set_modes";
92 m_getVelocitySrvName = name+
"/get_velocity";
93 m_getPositionSrvName = name+
"/get_position";
94 m_getAvailableModesSrvName = name+
"/get_available_modes";
95 m_getJointsNamesSrvName = name+
"/get_joints_names";
99 if(m_iPositionControl){
100 m_posSubscription = m_node->create_subscription<yarp_control_msgs::msg::Position>(m_posTopicName, 10,
101 std::bind(&ControlBoard_nws_ros2::positionTopic_callback,
102 this, std::placeholders::_1));
103 if(!m_posSubscription){
105 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the Position msg subscription");
110 if(m_iPositionDirect){
111 m_posDirectSubscription = m_node->create_subscription<yarp_control_msgs::msg::PositionDirect>(m_posDirTopicName, 10,
112 std::bind(&ControlBoard_nws_ros2::positionDirectTopic_callback,
113 this, std::placeholders::_1));
114 if(!m_posDirectSubscription){
116 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the Position direct msg subscription");
121 if(m_iVelocityControl){
122 m_velSubscription = m_node->create_subscription<yarp_control_msgs::msg::Velocity>(m_velTopicName, 10,
123 std::bind(&ControlBoard_nws_ros2::velocityTopic_callback,
124 this, std::placeholders::_1));
125 if(!m_velSubscription){
127 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the Velocity msg subscription");
147 qos.liveliness_lease_duration=time;
151 qos.avoid_ros_namespace_conventions =
true;
152 m_getControlModesSrv = m_node->create_service<yarp_control_msgs::srv::GetControlModes>(m_getModesSrvName,
153 std::bind(&ControlBoard_nws_ros2::getControlModesCallback,
154 this,std::placeholders::_1,std::placeholders::_2,
155 std::placeholders::_3));
156 if(!m_getControlModesSrv){
158 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the GetControlModes service");
162 m_getPositionSrv = m_node->create_service<yarp_control_msgs::srv::GetPosition>(m_getPositionSrvName,
163 std::bind(&ControlBoard_nws_ros2::getPositionCallback,
164 this,std::placeholders::_1,std::placeholders::_2,
165 std::placeholders::_3));
166 if(!m_getPositionSrv){
168 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the GetPosition service");
172 m_getVelocitySrv = m_node->create_service<yarp_control_msgs::srv::GetVelocity>(m_getVelocitySrvName,
173 std::bind(&ControlBoard_nws_ros2::getVelocityCallback,
174 this,std::placeholders::_1,std::placeholders::_2,
175 std::placeholders::_3));
176 if(!m_getVelocitySrv){
178 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the GetVelocity service");
182 m_setControlModesSrv = m_node->create_service<yarp_control_msgs::srv::SetControlModes>(m_setModesSrvName,
183 std::bind(&ControlBoard_nws_ros2::setControlModesCallback,
184 this,std::placeholders::_1,std::placeholders::_2,
185 std::placeholders::_3));
186 if(!m_setControlModesSrv){
188 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the SetControlModes service");
192 m_getAvailableModesSrv = m_node->create_service<yarp_control_msgs::srv::GetAvailableControlModes>(m_getAvailableModesSrvName,
193 std::bind(&ControlBoard_nws_ros2::getAvailableModesCallback,
194 this,std::placeholders::_1,std::placeholders::_2,
195 std::placeholders::_3));
196 if(!m_getAvailableModesSrv){
198 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the GetAvailableModes service");
202 m_getJointsNamesSrv = m_node->create_service<yarp_control_msgs::srv::GetJointsNames>(m_getJointsNamesSrvName,
203 std::bind(&ControlBoard_nws_ros2::getJointsNamesCallback,
204 this,std::placeholders::_1,std::placeholders::_2,
205 std::placeholders::_3));
206 if(!m_getJointsNamesSrv){
208 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the GetJointsNames service");
216 RCLCPP_ERROR(m_node->get_logger(),
"Could not initialize the GetJointsNames service");
222 for(
size_t i=0; i<m_subdevice_joints; i++){
224 yCError(
CONTROLBOARD_ROS2) <<
"Error retrieving axis" << i <<
"name. For this device to work, every joint needs a name";
240 m_subdevice_ptr = driver;
242 m_subdevice_ptr->
view(m_iPositionControl);
243 if (!m_iPositionControl) {
247 m_subdevice_ptr->
view(m_iPositionDirect);
248 if (!m_iPositionDirect) {
252 m_subdevice_ptr->
view(m_iVelocityControl);
253 if (!m_iVelocityControl) {
257 m_subdevice_ptr->
view(m_iControlMode);
258 if (!m_iControlMode) {
262 m_subdevice_ptr->
view(m_iEncodersTimed);
263 if (!m_iEncodersTimed) {
268 m_subdevice_ptr->
view(m_iTorqueControl);
269 if (!m_iTorqueControl) {
273 m_subdevice_ptr->
view(m_iAxisInfo);
289 m_subdevice_joints =
static_cast<size_t>(
tmp_axes);
290 m_times.
resize(m_subdevice_joints);
291 m_ros_struct.name.resize(m_subdevice_joints);
292 m_ros_struct.position.resize(m_subdevice_joints);
293 m_ros_struct.velocity.resize(m_subdevice_joints);
294 m_ros_struct.effort.resize(m_subdevice_joints);
296 if (!updateAxisName()) {
304void ControlBoard_nws_ros2::closeDevice()
306 m_subdevice_ptr =
nullptr;
307 m_subdevice_joints = 0;
312 m_iPositionControl =
nullptr;
313 m_iEncodersTimed =
nullptr;
314 m_iTorqueControl =
nullptr;
315 m_iAxisInfo =
nullptr;
320 if (!setDevice(poly)) {
337 RCLCPP_ERROR(m_node->get_logger(),
"Error initializing the ROS2 control related topics and services");
343 if(!m_spinner->
start()){
363bool ControlBoard_nws_ros2::updateAxisName()
370 std::vector<std::string> tmpVect;
371 for (
size_t i = 0; i < m_subdevice_joints; i++) {
378 tmpVect.emplace_back(
tmp);
383 m_jointNames = tmpVect;
399 if (m_iTorqueControl) {
405 m_time.
update(std::accumulate(m_times.
begin(), m_times.
end(), 0.0) / m_subdevice_joints);
410 for (
size_t i = 0; i < m_subdevice_joints; i++) {
418 m_ros_struct.name = m_jointNames;
430 m_publisherJointStates->publish(m_ros_struct);
437 auto modes = std_msgs::msg::Int8MultiArray();
438 modes.data.resize(m_subdevice_joints);
439 for (
size_t i = 0; i < m_subdevice_joints; i++) {
442 m_publisherControlModes->publish(
modes);
double convertDegreesToRadians(double degrees)
bool parseParams(const yarp::os::Searchable &config) override
Parse the DeviceDriver parameters.
bool open(yarp::os::Searchable &prop) override
Open the DeviceDriver.
void run() override
Loop function.
bool attach(yarp::dev::PolyDriver *poly) override
Attach to another object.
bool detach() override
Detach the object (you must have first called attach).
bool close() override
Close the DeviceDriver.
static rclcpp::Node::SharedPtr createNode(std::string name)
Interface implemented by all device drivers.
bool view(T *&x)
Get an interface to the device driver.
virtual bool getAxisName(int axis, std::string &name)=0
virtual bool getJointType(int axis, yarp::dev::JointTypeEnum &type)
virtual bool getControlModes(int *modes)=0
Get the current control mode (multiple joints).
virtual bool getEncodersTimed(double *encs, double *time)=0
Read the instantaneous acceleration of all axes.
virtual bool getAxes(int *ax)=0
Get the number of controlled axes.
virtual bool getEncoderSpeeds(double *spds)=0
Read the instantaneous speed of all axes.
virtual bool getTorques(double *t)=0
Get the value of the torque for all joints (this is the feedback if you have torque sensors).
A container for a device driver.
A mini-server for performing network communication in the background.
An abstraction for a periodic thread.
bool setPeriod(double period)
Set the (new) period of the thread.
bool isRunning() const
Returns true when the thread is started, false otherwise.
bool start()
Call this to start the thread.
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
A base class for nested structures that can be searched.
An abstraction for a time stamp and/or sequence number.
void update()
Set the timestamp to the current time, and increment the sequence number (wrapping to 0 if the sequen...
bool stop()
Stop the thread.
bool isRunning()
Returns true if the thread is running (Thread::start has been called successfully and the thread has ...
bool start()
Start the new thread running.
void resize(size_t size) override
Resize the vector.
iterator begin() noexcept
Returns an iterator to the beginning of the VectorOf.
T * data()
Return a pointer to the first element of the vector.
iterator end() noexcept
Returns an iterator to the end of the VectorOf.
#define yCError(component,...)
#define yCAssert(component, x)
#define yCWarning(component,...)
#define YARP_LOG_COMPONENT(name,...)
For streams capable of holding different kinds of content, check what they actually have.
@ VOCAB_JOINTTYPE_REVOLUTE
An interface to the operating system, including Port based communication.
The main, catch-all namespace for YARP.