Skip to content

Commit ab8c451

Browse files
authored
Added publication and subscription on same node example (#19)
* Added publication and subscription on same node example * Managing publication timing with a guard condition
1 parent f01af04 commit ab8c451

3 files changed

Lines changed: 112 additions & 0 deletions

File tree

rcl/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export_executable(fibonacci_action_server)
3939
export_executable(fibonacci_action_client)
4040
export_executable(int32_multinode)
4141
export_executable(guard_condition)
42+
export_executable(int32_publisher_subscriber)
4243

4344
if(EXISTS ${CMAKE_BINARY_DIR}/temp_install/)
4445
install(
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
3+
project(int32_publisher_subscriber LANGUAGES C)
4+
5+
find_package(ament_cmake REQUIRED)
6+
find_package(rcl REQUIRED)
7+
find_package(std_msgs REQUIRED)
8+
find_package(rmw_microxrcedds REQUIRED)
9+
10+
add_executable(${PROJECT_NAME} main.c)
11+
12+
ament_target_dependencies(${PROJECT_NAME}
13+
rcl
14+
std_msgs
15+
rmw_microxrcedds
16+
)
17+
18+
install(TARGETS ${PROJECT_NAME}
19+
DESTINATION ${PROJECT_NAME}
20+
)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include <rcl/rcl.h>
2+
#include <rcl/error_handling.h>
3+
#include <std_msgs/msg/int32.h>
4+
5+
#include <rmw_uros/options.h>
6+
7+
#include <stdio.h>
8+
#include <unistd.h>
9+
#include <pthread.h>
10+
11+
#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;}}
12+
#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);}}
13+
14+
void * trigger_guard_condition(void *args){
15+
rcl_guard_condition_t * guard_condition = (rcl_guard_condition_t *)args;
16+
17+
while(true){
18+
RCSOFTCHECK(rcl_trigger_guard_condition(guard_condition))
19+
sleep(1);
20+
}
21+
}
22+
23+
int main(int argc, const char * const * argv)
24+
{
25+
rcl_init_options_t options = rcl_get_zero_initialized_init_options();
26+
RCCHECK(rcl_init_options_init(&options, rcl_get_default_allocator()))
27+
28+
rcl_context_t context = rcl_get_zero_initialized_context();
29+
RCCHECK(rcl_init(argc, argv, &options, &context))
30+
31+
rcl_node_options_t node_ops = rcl_node_get_default_options();
32+
rcl_node_t node = rcl_get_zero_initialized_node();
33+
RCCHECK(rcl_node_init(&node, "int32_publisher_subscriber_rcl", "", &context, &node_ops))
34+
35+
rcl_guard_condition_t guard_condition = rcl_get_zero_initialized_guard_condition();
36+
rcl_guard_condition_options_t guard_condition_options = rcl_guard_condition_get_default_options();
37+
RCCHECK(rcl_guard_condition_init(&guard_condition, &context, guard_condition_options))
38+
39+
pthread_t guard_condition_thread;
40+
pthread_create(&guard_condition_thread, NULL, trigger_guard_condition, &guard_condition);
41+
42+
rcl_subscription_options_t subscription_ops = rcl_subscription_get_default_options();
43+
rcl_subscription_t subscription = rcl_get_zero_initialized_subscription();
44+
RCCHECK(rcl_subscription_init(&subscription, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "/int32_subscriber", &subscription_ops))
45+
46+
rcl_publisher_options_t publisher_ops = rcl_publisher_get_default_options();
47+
rcl_publisher_t publisher = rcl_get_zero_initialized_publisher();
48+
RCCHECK(rcl_publisher_init(&publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32), "/int32_publisher", &publisher_ops))
49+
50+
rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set();
51+
RCCHECK(rcl_wait_set_init(&wait_set, 1, 1, 0, 0, 0, 0, &context, rcl_get_default_allocator()))
52+
53+
std_msgs__msg__Int32 msg;
54+
msg.data = 0;
55+
56+
rcl_ret_t rc;
57+
do {
58+
RCSOFTCHECK(rcl_wait_set_clear(&wait_set))
59+
60+
size_t index_subscription;
61+
RCSOFTCHECK(rcl_wait_set_add_subscription(&wait_set, &subscription, &index_subscription))
62+
63+
size_t index_guardcondition;
64+
RCSOFTCHECK(rcl_wait_set_add_guard_condition(&wait_set, &guard_condition, &index_guardcondition))
65+
66+
RCSOFTCHECK(rcl_wait(&wait_set, RCL_MS_TO_NS(100)))
67+
68+
if (wait_set.subscriptions[index_subscription]) {
69+
std_msgs__msg__Int32 msg;
70+
71+
rc = rcl_take(wait_set.subscriptions[index_subscription], &msg, NULL, NULL);
72+
if (RCL_RET_OK == rc) {
73+
printf("I received: [%i]\n", msg.data);
74+
}
75+
}
76+
77+
if (wait_set.guard_conditions[index_guardcondition]) {
78+
// Use the guard condition trigger to publish in a slower loop
79+
80+
rc = rcl_publish(&publisher, (const void*)&msg, NULL);
81+
if (RCL_RET_OK == rc ) {
82+
printf("Sent: '%i'\n", msg.data++);
83+
}
84+
}
85+
} while ( true );
86+
87+
RCCHECK(rcl_subscription_fini(&subscription, &node))
88+
RCCHECK(rcl_node_fini(&node))
89+
90+
return 0;
91+
}

0 commit comments

Comments
 (0)