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

Ros2 node info does not show info for nodes of the same name #279

Open
rotu opened this issue Jun 10, 2019 · 7 comments
Open

Ros2 node info does not show info for nodes of the same name #279

rotu opened this issue Jun 10, 2019 · 7 comments
Labels

Comments

@rotu
Copy link

rotu commented Jun 10, 2019

It is possible to launch multiple nodes of the same name. When this happens, those multiple nodes show up in ros2 node list but it is impossible to get info on these nodes with ros2 node info.

In the below example, I have launched a single amcl process which spins up 3 nodes. But since the three nodes were assigned the same name, I can't introspect to see what topics those nodes are listening/publishing on.

$ ros2 node list
/KeystrokeListen
/launch_ros
/launch_ros
/launch_ros
/rover_serial
/ArrowsToTwist
/se_node
/bno055_driver
/rviz
/robot_state_publisher
/joint_state_publisher
/amcl
/rplidar_node
/amcl
/rover
/se_node/transform_listener_impl/transform_listener_impl
/amcl

$ ros2 node info /amcl
/amcl
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /amcl/transition_event: lifecycle_msgs/msg/TransitionEvent
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
  Services:
    /amcl/change_state: lifecycle_msgs/srv/ChangeState
    /amcl/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /amcl/get_available_states: lifecycle_msgs/srv/GetAvailableStates
    /amcl/get_available_transitions: lifecycle_msgs/srv/GetAvailableTransitions
    /amcl/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /amcl/get_parameters: rcl_interfaces/srv/GetParameters
    /amcl/get_state: lifecycle_msgs/srv/GetState
    /amcl/get_transition_graph: lifecycle_msgs/srv/GetAvailableTransitions
    /amcl/list_parameters: rcl_interfaces/srv/ListParameters
    /amcl/set_parameters: rcl_interfaces/srv/SetParameters
    /amcl/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
@ivanpauno
Copy link
Member

I think that the idea is to enforce node name uniqueness, but it has not been applied yet (see here).
The only ticket I see tracking that is ros2/design#187.

@rotu
Copy link
Author

rotu commented Jun 11, 2019

I think that the idea is to enforce node name uniqueness

I think that that's a great idea down the road, and it would obviate this issue. But it's also way too easy to have nodes not be unique right now and it's extremely confusing when the tools make this harder to introspect. My naive expectation is that the cli tools should throw up a warning and print info on all the nodes with that same name.

Is that duplicate node in ros2 node list a caching issue in the daemon (and therefore not actually a live node at all)? Is it two instances of the same node accidentally being spun up in a launch file? Is it a TransformListener node being launched deep in some library my code is using? Is it someone else on the same network using ROS?

@ivanpauno
Copy link
Member

My naive expectation is that the cli tools should throw up a warning and print info on all the nodes with that same name.

The problem is that that change would require changes in the cli, rclpy, rcl, rmw, and in each rmw implementation.
For example, for getting the subscribers info, the cli creates a node (with rclpy). Through that node, it ends up calling rcl_get_subscriber_names_and_types_by_node
https://github.com/ros2/rcl/blob/ec8539b65c4c2b46d71c3bd6a5a9e25d8ab316b4/rcl/include/rcl/graph.h#L91-L136
That function wraps a similar rmw function. For each rmw implementation that function returns the subscribers info of the first node with that name found.

@rotu
Copy link
Author

rotu commented Jun 12, 2019

Ouch! So RCL doesn’t even have a globally unique identifier for nodes?

@jacobperron
Copy link
Member

Ouch! So RCL doesn’t even have a globally unique identifier for nodes?

No. I think originally it was assumed that the node names were unique, but this isn't enforced (possibly an oversight?). IMO we should first decide if node names should be unique (ros2/design#187), if not, then we should implement GUIDs for nodes and use it throughout the stack.

@nikhilkkr12
Copy link

#include <alsa/asoundlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "rcl/rcl.h"
#include "std_msgs/msg/byte_multi_array.h"
#include "rosidl_runtime_c/primitives_sequence_functions.h" // Include this header for sequence functions

#define PCM_DEVICE "default"
#define AUDIO_BUFFER_SIZE 4096

// Function declarations
int initialize_ros2(int argc, char *argv[], rcl_context_t *context, rcl_node_t *node, rcl_publisher_t *publisher);
int capture_and_publish_audio(rcl_context_t *context, rcl_publisher_t *publisher);
void cleanup_ros2(rcl_context_t *context, rcl_node_t *node, rcl_publisher_t *publisher);

int main(int argc, char *argv[])
{
rcl_context_t context;
rcl_node_t node;
rcl_publisher_t publisher;

if (initialize_ros2(argc, argv, &context, &node, &publisher) != 0) {
    return 1;
}

if (capture_and_publish_audio(&context, &publisher) != 0) {
    cleanup_ros2(&context, &node, &publisher);
    return 1;
}

cleanup_ros2(&context, &node, &publisher);
return 0;

}

int initialize_ros2(int argc, char *argv[], rcl_context_t *context, rcl_node_t *node, rcl_publisher_t *publisher)
{
rcl_ret_t ret;

// Initialize ROS 2 options
rcl_init_options_t init_options = rcl_get_zero_initialized_init_options();
rcl_allocator_t allocator = rcl_get_default_allocator();
ret = rcl_init_options_init(&init_options, allocator);
if (ret != RCL_RET_OK)
{
    fprintf(stderr, "Error initializing ROS 2 options\n");
    return 1;
}

// Initialize ROS 2 context
*context = rcl_get_zero_initialized_context();
ret = rcl_init(argc, (const char * const *)argv, &init_options, context);
if (ret != RCL_RET_OK)
{
    fprintf(stderr, "Error initializing ROS 2 context\n");
    return 1;
}

// Create a ROS 2 node
*node = rcl_get_zero_initialized_node();
const char * node_name = "audio_publisher";
rcl_node_options_t node_options = rcl_node_get_default_options();
ret = rcl_node_init(node, node_name, "", context, &node_options);
if (ret != RCL_RET_OK)
{
    fprintf(stderr, "Error initializing ROS 2 node\n");
    return 1;
}

// Create a ROS 2 publisher
*publisher = rcl_get_zero_initialized_publisher();
const rosidl_message_type_support_t * msg_type_support = ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, ByteMultiArray);
const char * topic_name = "audio_data";
rcl_publisher_options_t publisher_options = rcl_publisher_get_default_options();
ret = rcl_publisher_init(publisher, node, msg_type_support, topic_name, &publisher_options);
if (ret != RCL_RET_OK)
{
    fprintf(stderr, "Error initializing ROS 2 publisher\n");
    return 1;
}

return 0;

}

int capture_and_publish_audio(rcl_context_t *context, rcl_publisher_t *publisher)
{
// Open the PCM device for recording
snd_pcm_t *handle;
if (snd_pcm_open(&handle, PCM_DEVICE, SND_PCM_STREAM_CAPTURE, 0) < 0) {
fprintf(stderr, "Error opening PCM device %s\n", PCM_DEVICE);
return 1;
}

// Set parameters for recording
snd_pcm_hw_params_t *params;
snd_pcm_hw_params_alloca(&params);
snd_pcm_hw_params_any(handle, params);
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(handle, params, 2);
unsigned int sample_rate = 44100;
snd_pcm_hw_params_set_rate_near(handle, params, &sample_rate, 0);
if (snd_pcm_hw_params(handle, params) < 0) {
    fprintf(stderr, "Error setting PCM parameters\n");
    snd_pcm_close(handle);
    return 1;
}

// Buffer for captured audio
uint8_t buffer[AUDIO_BUFFER_SIZE];

// Create ROS 2 message
std_msgs__msg__ByteMultiArray msg;
std_msgs__msg__ByteMultiArray__init(&msg);
if (!rosidl_runtime_c__uint8__Sequence__init((rosidl_runtime_c__uint8__Sequence *)&msg.data, AUDIO_BUFFER_SIZE)) {
    fprintf(stderr, "Error initializing ByteMultiArray sequence\n");
    return 1;
}

// Publish captured audio
while (rcl_context_is_valid(context))
{
    // Read audio data
    int frames = snd_pcm_readi(handle, buffer, AUDIO_BUFFER_SIZE / 4); // 2 bytes per sample, 2 channels
    if (frames < 0) {
        frames = snd_pcm_recover(handle, frames, 0);
    }
    if (frames < 0) {
        fprintf(stderr, "Error reading audio data: %s\n", snd_strerror(frames));
        break;
    }

    // Assign buffer data to ROS 2 message
    memcpy(msg.data.data, buffer, frames * 4); // 4 bytes per frame (2 bytes per sample, 2 channels)
    msg.data.size = frames * 4;

    // Publish audio data
    rcl_ret_t ret = rcl_publish(publisher, &msg, NULL);
    if (ret != RCL_RET_OK)
    {
        fprintf(stderr, "Error publishing audio\n");
    }

    // Sleep for a short duration
    usleep(10000); // 10 ms
}

// Clean up ROS 2 message
std_msgs__msg__ByteMultiArray__fini(&msg);

// Close PCM device
snd_pcm_close(handle);

return 0;

}

void cleanup_ros2(rcl_context_t *context, rcl_node_t *node, rcl_publisher_t *publisher)
{
rcl_ret_t ret;

// Shutdown ROS 2 resources
ret = rcl_publisher_fini(publisher, node);
if (ret != RCL_RET_OK)
{
    fprintf(stderr, "Error finalizing ROS 2 publisher\n");
}

ret = rcl_node_fini(node);
if (ret != RCL_RET_OK)
{
    fprintf(stderr, "Error finalizing ROS 2 node\n");
}

ret = rcl_shutdown(context);
if (ret != RCL_RET_OK)
{
    fprintf(stderr, "Error shutting down ROS 2 context\n");
}

}
this is my publisher code, i am trying to capture the audio and send it to the P.C means from SOM to PC, SOM(nvidia jetson agx developer kit 64 gb). The environment is ROS2 environment. Can you please help me out.

@clalancette
Copy link
Contributor

That question has nothing to do with this issue. Please open a question over on https://robotics.stackexchange.com/questions/tagged/ros, which is our central Question and Answer site. You'll get a better answer there, and it will be searchable for the future.

Make sure to include a lot of information on what platform you are using, which ROS distribution you are using, and the exact steps you took.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants