You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9240ced
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: _docs/tutorials/core/programming_rcl_rclc/index.md
+79-2Lines changed: 79 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -420,13 +420,90 @@ return 0;
420
420
This completes the example. The source code can be found in [rclc-examples/example_executor_convenience.c](https://github.com/micro-ROS/rclc-examples/example_executor_convenience.c).
421
421
422
422
#### Example 2: Triggered rclc_executor
423
+
Sesor fusion is the first step in robotic applications when multiple sensor are used to improve localization precision. These sensors can have different frequencies, for example, a high frequency IMU sensor and a low frequency laser scanner. One way is to trigger execution upon arrival of a laser scan and only then evaluate the most recent data from the aggregated IMU data.
423
424
424
-
rclc_example_trigger
425
+
This example demonstrates the additional feature of the rclc executor to trigger the execution of callbacks based on the availability of input data.
426
+
427
+
We setup one executor with two publishers, one with 100ms and one with 1000ms period. Then we setup one executor for two subsciptions. Their callbacks shall both be executed if the message of the publisher with the lower frequency arrives.
428
+
429
+
You learn in this tutorial
430
+
- how to write custom-defined trigger conditions
431
+
- how to run multiple executors
432
+
- how to setup communication objects only using rcl API
433
+
434
+
We start with the necessary includes for string and int messages as well as the rclc executor:
435
+
```C
436
+
#include <stdio.h>
437
+
#include <unistd.h>
438
+
#include <std_msgs/msg/string.h>
439
+
#include <std_msgs/msg/int32.h>
440
+
#include <rclc/executor.h>
441
+
```
442
+
Then, global variables are defined, which are initialized in main and also used in the callbacks:
443
+
```C
444
+
rcl_publisher_t my_pub;
445
+
rcl_publisher_t my_int_pub;
446
+
std_msgs__msg__String sub_msg;
447
+
std_msgs__msg__Int32 pub_int_msg;
448
+
int pub_int_value;
449
+
std_msgs__msg__Int32 sub_int_msg;
450
+
int pub_string_value;
451
+
```
452
+
For the custom-defined trigger conditions, the type `pub_trigger_object_t` and the type `sub_trigger_object_t` are defined.
453
+
```C
454
+
typedefstruct
455
+
{
456
+
rcl_timer_t * timer1;
457
+
rcl_timer_t * timer2;
458
+
} pub_trigger_object_t;
459
+
460
+
typedefstruct
461
+
{
462
+
rcl_subscription_t * sub1;
463
+
rcl_subscription_t * sub2;
464
+
} sub_trigger_object_t;
465
+
```
466
+
The executor for the publishers, shall publish when any of corresponding timers for the publishers is ready. That is the or-logic. You could also use the predefined `rclc_executor_trigger_any` trigger condition, but this example shows, how you can write your own trigger conditions.
467
+
468
+
In principle the condition gets a list of handles, the length of this list, and the pre-defined condition type, in this case we expect `pub_trigger_object_t`. First, the parameter `obj` is cased to this type (`comm_obj`). Then, each element of the handle list is checked for new data (or a timer is ready) by evaluating the field `handles[i].data_available` and its handle pointer is compared to the pointer of the communicatoin object. If at least one timer is ready, then the trigger condition returns true.
469
+
```C
470
+
boolpub_trigger(rclc_executor_handle_t * handles, unsigned int size, void * obj)
471
+
{
472
+
if (handles == NULL) {
473
+
printf("Error in pub_trigger: 'handles' is a NULL pointer\n");
474
+
return false;
475
+
}
476
+
if (obj == NULL) {
477
+
printf("Error in pub_trigger: 'obj' is a NULL pointer\n");
The source code can be found in [rclc-examples/example_executor_trigger.c](https://github.com/micro-ROS/rclc-examples/example_executor_trigger.c).
427
504
428
505
429
-
#### Example 2: Sense-plan-act pipeline in mobile robotics
506
+
#### Example 3: Sense-plan-act pipeline in mobile robotics
430
507
431
508
A common design paradigm in mobile robotics is a control loop, consisting of several phases: A sensing phase to aquire sensor data, a plan phase for localization and path planning and an actuation-phase to steer the mobile robot. Of course, more phases are possible, here these three phases shall serve as an example.
0 commit comments