|
| 1 | +#include <rcl/rcl.h> |
| 2 | +#include <rcl/graph.h> |
| 3 | +#include <rcl/error_handling.h> |
| 4 | + |
| 5 | +#include <stdio.h> |
| 6 | +#include <unistd.h> |
| 7 | + |
| 8 | +#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){printf("Failed status on line %d: %d. Aborting.\n",__LINE__,(int)temp_rc); return 1;}} |
| 9 | +#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){printf("Failed status on line %d: %d. Continuing.\n",__LINE__,(int)temp_rc);}} |
| 10 | + |
| 11 | +int main(int argc, const char * const * argv) |
| 12 | +{ |
| 13 | + rcl_init_options_t options = rcl_get_zero_initialized_init_options(); |
| 14 | + rcl_allocator_t allocator = rcl_get_default_allocator(); |
| 15 | + RCCHECK(rcl_init_options_init(&options, allocator)); |
| 16 | + |
| 17 | + rcl_context_t context = rcl_get_zero_initialized_context(); |
| 18 | + RCCHECK(rcl_init(argc, argv, &options, &context)); |
| 19 | + |
| 20 | + rcl_node_options_t node_ops = rcl_node_get_default_options(); |
| 21 | + rcl_node_t node = rcl_get_zero_initialized_node(); |
| 22 | + RCCHECK(rcl_node_init(&node, "microros_graph_tester", "", &context, &node_ops)); |
| 23 | + |
| 24 | + rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); |
| 25 | + RCCHECK(rcl_wait_set_init(&wait_set, 0, 1, 0, 0, 0, 0, &context, allocator)); |
| 26 | + |
| 27 | + const rcl_guard_condition_t * graph_guard_condition = |
| 28 | + rcl_node_get_graph_guard_condition(&node); |
| 29 | + if (NULL == graph_guard_condition) { |
| 30 | + printf("Error: node graph guard condition is invalid\n"); |
| 31 | + RCCHECK(rcl_node_fini(&node)); |
| 32 | + RCCHECK(rcl_shutdown(&context)); |
| 33 | + return 1; |
| 34 | + } |
| 35 | + |
| 36 | + while (true) |
| 37 | + { |
| 38 | + RCSOFTCHECK(rcl_wait_set_clear(&wait_set)); |
| 39 | + |
| 40 | + size_t index; |
| 41 | + RCCHECK(rcl_wait_set_add_guard_condition( |
| 42 | + &wait_set, graph_guard_condition, &index)); |
| 43 | + |
| 44 | + rcl_ret_t unused = rcl_wait(&wait_set, RCL_MS_TO_NS(100)); |
| 45 | + |
| 46 | + for (size_t i = 0; i < wait_set.size_of_guard_conditions; ++i) { |
| 47 | + if (wait_set.guard_conditions[i]) { |
| 48 | + // Topic names and types |
| 49 | + rcl_names_and_types_t topic_names_and_types = |
| 50 | + rcl_get_zero_initialized_names_and_types(); |
| 51 | + RCCHECK(rcl_get_topic_names_and_types(&node, &allocator, false, &topic_names_and_types)); |
| 52 | + |
| 53 | + printf("\n---------------------------------------------------------------\n"); |
| 54 | + printf(" 'rcl_get_topic_names_and_types' result\n"); |
| 55 | + printf("---------------------------------------------------------------\n"); |
| 56 | + size_t topic_num = topic_names_and_types.names.size; |
| 57 | + printf("Current number of ROS 2 and micro-ROS topics: %lu\n", topic_num); |
| 58 | + |
| 59 | + for (size_t j = 0; j < topic_num; ++j) { |
| 60 | + rcutils_string_array_t * topic_types = &topic_names_and_types.types[j]; |
| 61 | + printf(" %lu) topic: '%s', types: ", j + 1, topic_names_and_types.names.data[j]); |
| 62 | + for (size_t k = 0; k < topic_types->size; ++k) { |
| 63 | + printf("%s", topic_types->data[k]); |
| 64 | + if (k < (topic_types->size - 1)) { |
| 65 | + printf(", "); |
| 66 | + } else { |
| 67 | + printf("\n"); |
| 68 | + } |
| 69 | + } |
| 70 | + rcl_topic_endpoint_info_array_t publishers_info = |
| 71 | + rcl_get_zero_initialized_topic_endpoint_info_array(); |
| 72 | + RCCHECK(rcl_get_publishers_info_by_topic(&node, &allocator, |
| 73 | + topic_names_and_types.names.data[j], false, &publishers_info)); |
| 74 | + printf(" topic endpoint information:\n"); |
| 75 | + for (size_t k = 0; k < publishers_info.size; ++k) { |
| 76 | + printf(" Node: '%s%s', type: '%s', '%s'\n", |
| 77 | + publishers_info.info_array[k].node_namespace, |
| 78 | + publishers_info.info_array[k].node_name, |
| 79 | + publishers_info.info_array[k].topic_type, |
| 80 | + RMW_ENDPOINT_PUBLISHER == publishers_info.info_array[k].endpoint_type ? "publisher" : "error"); |
| 81 | + } |
| 82 | + rcl_topic_endpoint_info_array_fini(&publishers_info, &allocator); |
| 83 | + |
| 84 | + rcl_topic_endpoint_info_array_t subscriptions_info = |
| 85 | + rcl_get_zero_initialized_topic_endpoint_info_array(); |
| 86 | + RCCHECK(rcl_get_subscriptions_info_by_topic(&node, &allocator, |
| 87 | + topic_names_and_types.names.data[j], false, &subscriptions_info)); |
| 88 | + for (size_t k = 0; k < subscriptions_info.size; ++k) { |
| 89 | + printf(" Node: '%s%s', type: '%s', '%s'\n", |
| 90 | + subscriptions_info.info_array[k].node_namespace, |
| 91 | + subscriptions_info.info_array[k].node_name, |
| 92 | + subscriptions_info.info_array[k].topic_type, |
| 93 | + RMW_ENDPOINT_SUBSCRIPTION == subscriptions_info.info_array[k].endpoint_type ? "subscription" : "error"); |
| 94 | + } |
| 95 | + rcl_topic_endpoint_info_array_fini(&subscriptions_info, &allocator); |
| 96 | + } |
| 97 | + |
| 98 | + RCSOFTCHECK(rcl_names_and_types_fini(&topic_names_and_types)); |
| 99 | + |
| 100 | + // Service names and types |
| 101 | + rcl_names_and_types_t service_names_and_types = |
| 102 | + rcl_get_zero_initialized_names_and_types(); |
| 103 | + RCCHECK(rcl_get_service_names_and_types(&node, &allocator, &service_names_and_types)); |
| 104 | + |
| 105 | + printf("\n---------------------------------------------------------------\n"); |
| 106 | + printf(" 'rcl_get_service_names_and_types' result\n"); |
| 107 | + printf("---------------------------------------------------------------\n"); |
| 108 | + size_t service_num = service_names_and_types.names.size; |
| 109 | + printf("Current number of ROS 2 and micro-ROS services: %lu\n", service_num); |
| 110 | + |
| 111 | + for (size_t j = 0; j < service_num; ++j) { |
| 112 | + rcutils_string_array_t * service_types = &service_names_and_types.types[j]; |
| 113 | + printf(" %lu) service: '%s', types: ", j + 1, service_names_and_types.names.data[j]); |
| 114 | + for (size_t k = 0; k < service_types->size; ++k) { |
| 115 | + printf("%s", service_types->data[k]); |
| 116 | + if (k < (service_types->size - 1)) { |
| 117 | + printf(", "); |
| 118 | + } else { |
| 119 | + printf("\n"); |
| 120 | + } |
| 121 | + } |
| 122 | + } |
| 123 | + |
| 124 | + RCSOFTCHECK(rcl_names_and_types_fini(&service_names_and_types)); |
| 125 | + |
| 126 | + // Node names |
| 127 | + rcutils_string_array_t node_names = rcutils_get_zero_initialized_string_array(); |
| 128 | + rcutils_string_array_t node_namespaces = rcutils_get_zero_initialized_string_array(); |
| 129 | + RCCHECK(rcl_get_node_names(&node, allocator, &node_names, &node_namespaces)); |
| 130 | + |
| 131 | + printf("\n---------------------------------------------------------------\n"); |
| 132 | + printf(" 'rcl_get_node_names' result\n"); |
| 133 | + printf("---------------------------------------------------------------\n"); |
| 134 | + size_t node_num = node_names.size; |
| 135 | + printf("Current number of ROS 2 and micro-ROS nodes: %lu\n", node_num); |
| 136 | + |
| 137 | + for (size_t j = 0; j < node_num; ++j) { |
| 138 | + printf(" %lu) node: '%s%s'\n", j + 1, node_namespaces.data[j], node_names.data[j]); |
| 139 | + printf(" 'rcl_get_publisher_names_and_types_by_node' result for this node:\n"); |
| 140 | + rcl_names_and_types_t publisher_names_and_types = rcl_get_zero_initialized_names_and_types(); |
| 141 | + RCCHECK(rcl_get_publisher_names_and_types_by_node( |
| 142 | + &node, &allocator, false, node_names.data[j], node_namespaces.data[j], |
| 143 | + &publisher_names_and_types)); |
| 144 | + for (size_t k = 0; k < publisher_names_and_types.names.size; ++k) { |
| 145 | + printf(" %lu.%lu) %s, with types: ", j + 1, k + 1, |
| 146 | + publisher_names_and_types.names.data[k]); |
| 147 | + for (size_t l = 0; l < publisher_names_and_types.types[k].size; ++l) { |
| 148 | + printf("%s", publisher_names_and_types.types[k].data[l]); |
| 149 | + if (l < (publisher_names_and_types.types[k].size - 1)) { |
| 150 | + printf(", "); |
| 151 | + } else { |
| 152 | + printf("\n"); |
| 153 | + } |
| 154 | + } |
| 155 | + } |
| 156 | + RCSOFTCHECK(rcl_names_and_types_fini(&publisher_names_and_types)); |
| 157 | + } |
| 158 | + |
| 159 | + if (RCUTILS_RET_OK != rcutils_string_array_fini(&node_names) || |
| 160 | + RCUTILS_RET_OK != rcutils_string_array_fini(&node_namespaces)) { |
| 161 | + printf("Error while freeing rcutils resources\n"); |
| 162 | + return 1; |
| 163 | + } |
| 164 | + } |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + RCCHECK(rcl_node_fini(&node)); |
| 169 | + RCCHECK(rcl_shutdown(&context)); |
| 170 | + return 0; |
| 171 | +} |
0 commit comments