Skip to content

Commit 03ed71e

Browse files
committed
Minor changes and Add Allocator explanation
1 parent d706eb6 commit 03ed71e

6 files changed

Lines changed: 221 additions & 99 deletions

File tree

_docs/tutorials/programming_rcl_rclc/executor/executor.md

Lines changed: 0 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ permalink: /docs/tutorials/programming_rcl_rclc/executor/
77
- [Initialization](#initialization)
88
- [Callback](#callback)
99
- [Cleaning Up](#cleaning-up)
10-
- [Lifecycle](#lifecycle)
11-
- [Initialization](#initialization-1)
12-
- [Callbacks](#callbacks)
13-
- [Running](#running)
14-
- [Cleaning Up](#cleaning-up-1)
15-
- [Limitations](#limitations)
1610
- [Executor](#executor)
1711
- [Example 1: 'Hello World'](#example-1-hello-world)
1812
- [Example 2: Triggered execution](#example-2-triggered-execution)
@@ -71,88 +65,6 @@ rcl_timer_fini(&timer);
7165

7266
This will deallocate used memory and make the timer invalid
7367

74-
## Lifecycle
75-
76-
The rclc lifecycle package provides convenience functions in C to bundle an rcl node with the ROS 2 Node Lifecycle state machine, similar to the [rclcpp Lifecycle Node](https://github.com/ros2/rclcpp/blob/master/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp) for C++. Further information about ROS 2 node lifecycle can be found [here](https://design.ros2.org/articles/node_lifecycle.html)
77-
78-
An usage example is given in the [rclc_examples](https://github.com/ros2/rclc/blob/master/rclc_examples/src/example_lifecycle_node.c) package.
79-
80-
### Initialization
81-
82-
Creation of a lifecycle node as a bundle of an rcl node and the rcl lifecycle state machine. Assuming an already initialized node and executor:
83-
84-
```c
85-
// Create rcl state machine
86-
rcl_lifecycle_state_machine_t state_machine =
87-
rcl_lifecycle_get_zero_initialized_state_machine();
88-
89-
// Create the lifecycle node
90-
rclc_lifecycle_node_t my_lifecycle_node;
91-
rcl_ret_t rc = rclc_make_node_a_lifecycle_node(
92-
&my_lifecycle_node,
93-
&node,
94-
&state_machine,
95-
&allocator);
96-
97-
// Register lifecycle services on the allocator
98-
rclc_lifecycle_add_get_state_service(&lifecycle_node, &executor);
99-
rclc_lifecycle_add_get_available_states_service(&lifecycle_node, &executor);
100-
rclc_lifecycle_add_change_state_service(&lifecycle_node, &executor);
101-
```
102-
103-
*Note: Executor needsto be equipped with 1 handle per node and per service*
104-
105-
### Callbacks
106-
107-
Optional callbacks are supported to act on lifecycle state changes. Example:
108-
109-
```c
110-
rcl_ret_t my_on_configure() {
111-
printf(" >>> my_lifecycle_node: on_configure() callback called.\n");
112-
return RCL_RET_OK;
113-
}
114-
```
115-
116-
To add them to the lifecycle node:
117-
118-
```c
119-
// Register lifecycle service callbacks
120-
rclc_lifecycle_register_on_configure(&lifecycle_node, &my_on_configure);
121-
rclc_lifecycle_register_on_activate(&lifecycle_node, &my_on_activate);
122-
rclc_lifecycle_register_on_deactivate(&lifecycle_node, &my_on_deactivate);
123-
rclc_lifecycle_register_on_cleanup(&lifecycle_node, &my_on_cleanup);
124-
```
125-
126-
### Running
127-
128-
To change states of the lifecycle node:
129-
130-
```c
131-
bool publish_transition = true;
132-
rc += rclc_lifecycle_change_state(
133-
&my_lifecycle_node,
134-
lifecycle_msgs__msg__Transition__TRANSITION_CONFIGURE,
135-
publish_transition);
136-
137-
rc += rclc_lifecycle_change_state(
138-
&my_lifecycle_node,
139-
lifecycle_msgs__msg__Transition__TRANSITION_ACTIVATE,
140-
publish_transition);
141-
```
142-
143-
Except for error processing transitions, transitions are usually triggered from outside, e.g., by ROS 2 services.
144-
145-
### Cleaning Up
146-
147-
To clean everything up, simply do
148-
149-
```c
150-
rc += rcl_lifecycle_node_fini(&my_lifecycle_node, &allocator);
151-
```
152-
153-
### Limitations
154-
155-
Lifecycle services cannot yet be called via ros2 lifecycle client (`ros2 lifecycle set /node ...`). Instead use the ros2 service CLI, (Example: `ros2 service call /node/change_state lifecycle_msgs/ChangeState "{transition: {id: 1, label: configure}}"`).
15668

15769
## Executor
15870

_docs/tutorials/programming_rcl_rclc/micro-ROS/micro-ROS.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,121 @@ permalink: /docs/tutorials/programming_rcl_rclc/micro-ROS/
55

66
// TODO: Change section name
77

8+
- [Allocators](#allocators)
9+
- [Custom allocator](#custom-allocator)
810
- [Time sync](#time-sync)
911
- [Ping agent](#ping-agent)
1012
- [Continous serialization](#continous-serialization)
1113

14+
## Allocators
15+
16+
The allocator object wraps the dynamic memory allocation and deallocating methods used in micro-ROS
17+
18+
```c
19+
// Get micro-ROS default allocator
20+
rcl_allocator_t allocator = rcl_get_default_allocator();
21+
```
22+
23+
The default allocator wraps the following methods:
24+
25+
```c
26+
- allocate = wraps malloc()
27+
- deallocate = wraps free()
28+
- reallocate = wraps realloc()
29+
- zero_allocate = wraps calloc()
30+
- state = `NULL`
31+
```
32+
33+
### Custom allocator
34+
35+
Working in embedded systems, the user might need to modify this default functions with its own memory allocation methods.
36+
To archieve this, the user can modify the default allocator with its own methods:
37+
38+
```c
39+
// Get empty allocator
40+
rcl_allocator_t custom_allocator = rcutils_get_zero_initialized_allocator();
41+
42+
// Set custom allocation methods
43+
custom_allocator.allocate = microros_allocate;
44+
custom_allocator.deallocate = microros_deallocate;
45+
custom_allocator.reallocate = microros_reallocate;
46+
custom_allocator.zero_allocate = microros_zero_allocate;
47+
48+
// Set custom allocator as default
49+
if (!rcutils_set_default_allocator(&custom_allocator)) {
50+
... // Handle error
51+
return -1;
52+
}
53+
```
54+
55+
Custom methods prototypes and examples:
56+
57+
- allocate:
58+
59+
Allocates memory given a size, an error should be indicated by returning `NULL`:
60+
61+
```c
62+
// Function prototype:
63+
void * (*allocate)(size_t size, void * state);
64+
65+
// Implementation example:
66+
void * microros_allocate(size_t size, void * state){
67+
(void) state;
68+
void * ptr = malloc(size);
69+
return ptr;
70+
}
71+
```
72+
73+
- deallocate
74+
75+
Deallocate previously allocated memory, mimicking free():
76+
77+
```c
78+
// Function prototype:
79+
void (* deallocate)(void * pointer, void * state);
80+
81+
// Implementation example:
82+
void microros_deallocate(void * pointer, void * state){
83+
(void) state;
84+
free(pointer);
85+
}
86+
```
87+
88+
- reallocate:
89+
90+
Reallocate memory if possible, otherwise it deallocates and allocates:
91+
92+
```c
93+
// Function prototype:
94+
void * (*reallocate)(void * pointer, size_t size, void * state);
95+
96+
// Implementation example:
97+
void * microros_reallocate(void * pointer, size_t size, void * state){
98+
(void) state;
99+
void * ptr = realloc(pointer, size);
100+
return ptr;
101+
}
102+
```
103+
104+
- zero_allocate:
105+
106+
Allocate memory with all elements set to zero, given a number of elements and their size. An error should be indicated by returning `NULL`:
107+
108+
```c
109+
// Function prototype:
110+
void * (*zero_allocate)(size_t number_of_elements, size_t size_of_element, void * state);
111+
112+
// Implementation example:
113+
void * microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void * state){
114+
(void) state;
115+
void * ptr = malloc(number_of_elements * size_of_element);
116+
memset(ptr, 0, number_of_elements * size_of_element);
117+
return ptr;
118+
}
119+
```
120+
121+
*Note: the `state` input argument is espected to be unused*
122+
12123
## Time sync
13124
micro-ROS Clients can synchronize their epoch time with the connected Agent, this can be very useful when working in embedded environments that do not provide any time synchronization mechanism.
14125
This utility is based on the NTP protocol, taking into account delays caused by the transport layer. An usage example can be found on [`micro-ROS-demos/rclc/epoch_synchronization`](https://github.com/micro-ROS/micro-ROS-demos/blob/galactic/rclc/epoch_synchronization/main.c).

_docs/tutorials/programming_rcl_rclc/node/node.md

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ permalink: /docs/tutorials/programming_rcl_rclc/node/
55

66
ROS 2 nodes are the main participants on ROS 2 ecosystem. They will communicate between each other using publishers, subscriptions, services, etc. Further information about ROS 2 nodes can be found [here](https://docs.ros.org/en/galactic/Tutorials/Understanding-ROS2-Nodes.html)
77

8-
// TODO: explain general micro-ROS initialization (allocator and support). Where?
98

109
- [Initialization](#initialization)
1110
- [Cleaning Up](#cleaning-up)
11+
- [Lifecycle](#lifecycle)
12+
- [Initialization](#initialization-1)
13+
- [Callbacks](#callbacks)
14+
- [Running](#running)
15+
- [Cleaning Up](#cleaning-up-1)
16+
- [Limitations](#limitations)
1217

1318
## Initialization
1419

@@ -113,3 +118,86 @@ rcl_node_fini(&node);
113118
```
114119

115120
This will delete the node from ROS2 graph, including any generated infrastructure on the agent (if possible) and used memory on the client.
121+
122+
## Lifecycle
123+
124+
The rclc lifecycle package provides convenience functions in C to bundle an rcl node with the ROS 2 Node Lifecycle state machine, similar to the [rclcpp Lifecycle Node](https://github.com/ros2/rclcpp/blob/master/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp) for C++. Further information about ROS 2 node lifecycle can be found [here](https://design.ros2.org/articles/node_lifecycle.html)
125+
126+
An usage example is given in the [rclc_examples](https://github.com/ros2/rclc/blob/master/rclc_examples/src/example_lifecycle_node.c) package.
127+
128+
### Initialization
129+
130+
Creation of a lifecycle node as a bundle of an rcl node and the rcl lifecycle state machine. Assuming an already initialized node and executor:
131+
132+
```c
133+
// Create rcl state machine
134+
rcl_lifecycle_state_machine_t state_machine =
135+
rcl_lifecycle_get_zero_initialized_state_machine();
136+
137+
// Create the lifecycle node
138+
rclc_lifecycle_node_t my_lifecycle_node;
139+
rcl_ret_t rc = rclc_make_node_a_lifecycle_node(
140+
&my_lifecycle_node,
141+
&node,
142+
&state_machine,
143+
&allocator);
144+
145+
// Register lifecycle services on the allocator
146+
rclc_lifecycle_add_get_state_service(&lifecycle_node, &executor);
147+
rclc_lifecycle_add_get_available_states_service(&lifecycle_node, &executor);
148+
rclc_lifecycle_add_change_state_service(&lifecycle_node, &executor);
149+
```
150+
151+
*Note: Executor needsto be equipped with 1 handle per node and per service*
152+
153+
### Callbacks
154+
155+
Optional callbacks are supported to act on lifecycle state changes. Example:
156+
157+
```c
158+
rcl_ret_t my_on_configure() {
159+
printf(" >>> my_lifecycle_node: on_configure() callback called.\n");
160+
return RCL_RET_OK;
161+
}
162+
```
163+
164+
To add them to the lifecycle node:
165+
166+
```c
167+
// Register lifecycle service callbacks
168+
rclc_lifecycle_register_on_configure(&lifecycle_node, &my_on_configure);
169+
rclc_lifecycle_register_on_activate(&lifecycle_node, &my_on_activate);
170+
rclc_lifecycle_register_on_deactivate(&lifecycle_node, &my_on_deactivate);
171+
rclc_lifecycle_register_on_cleanup(&lifecycle_node, &my_on_cleanup);
172+
```
173+
174+
### Running
175+
176+
To change states of the lifecycle node:
177+
178+
```c
179+
bool publish_transition = true;
180+
rc += rclc_lifecycle_change_state(
181+
&my_lifecycle_node,
182+
lifecycle_msgs__msg__Transition__TRANSITION_CONFIGURE,
183+
publish_transition);
184+
185+
rc += rclc_lifecycle_change_state(
186+
&my_lifecycle_node,
187+
lifecycle_msgs__msg__Transition__TRANSITION_ACTIVATE,
188+
publish_transition);
189+
```
190+
191+
Except for error processing transitions, transitions are usually triggered from outside, e.g., by ROS 2 services.
192+
193+
### Cleaning Up
194+
195+
To clean everything up, simply do
196+
197+
```c
198+
rc += rcl_lifecycle_node_fini(&my_lifecycle_node, &allocator);
199+
```
200+
201+
### Limitations
202+
203+
Lifecycle services cannot yet be called via ros2 lifecycle client (`ros2 lifecycle set /node ...`). Instead use the ros2 service CLI, (Example: `ros2 service call /node/change_state lifecycle_msgs/ChangeState "{transition: {id: 1, label: configure}}"`).

_docs/tutorials/programming_rcl_rclc/parameters/parameters.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Parameter server
33
permalink: /docs/tutorials/programming_rcl_rclc/parameters/
44
---
55

6-
ROS 2 parameter allow the user to create variables on a node and manipulate/read them with different ROS2 commands. Further information about ROS 2 parameters can be found [here](https://docs.ros.org/en/galactic/Tutorials/Parameters/Understanding-ROS2-Parameters.html)
6+
ROS 2 parameters allow the user to create variables on a node and manipulate/read them with different ROS2 commands. Further information about ROS 2 parameters can be found [here](https://docs.ros.org/en/galactic/Tutorials/Parameters/Understanding-ROS2-Parameters.html)
77

88
Ready to use code related to this tutorial can be found in [`rclc/rclc_examples/src/example_parameter_server.c`](https://github.com/ros2/rclc/blob/master/rclc_examples/src/example_parameter_server.c). Fragments of code from this example is used on this tutorial.
99

@@ -31,13 +31,15 @@ Note: micro-ROS parameter server is only supported on ROS2 galactic distribution
3131
}
3232
```
3333

34-
// TODO: explain options
3534
- Custom options:
35+
36+
The user can configure whether to notify parameter changes to the rest of nodes (`notify_changed_over_dds`) and the maximum number of parameters (`max_params`) allowed on the `rclc_parameter_server_t` object:
37+
3638
```c
3739
// Parameter server object
3840
rclc_parameter_server_t param_server;
3941

40-
// Define parameter server options
42+
// Initialize parameter server options
4143
const rclc_parameter_options_t options = {
4244
.notify_changed_over_dds = true,
4345
.max_params = 4 };
@@ -125,12 +127,11 @@ Note that this callback is optional as its just an event information for the use
125127
rc = rclc_executor_add_parameter_server(&executor, &param_server, NULL);
126128
```
127129

128-
129130
## Add a parameter
130131

131-
// TODO: improve explanation of types
132+
micro-ROS parameter server supports the following parameter types:
132133

133-
- Bool parameter
134+
- Boolean:
134135
```c
135136
const char * parameter_name = "parameter_bool";
136137
bool param_value = true;
@@ -150,7 +151,7 @@ if (RCL_RET_OK != rc) {
150151
}
151152
```
152153

153-
- Integer parameter
154+
- Integer:
154155
```c
155156
const char * parameter_name = "parameter_int";
156157
int param_value = 100;
@@ -165,7 +166,7 @@ rc = rclc_parameter_set_int(&param_server, parameter_name, param_value);
165166
rc = rclc_parameter_get_int(&param_server, parameter_name, &param_value);
166167
```
167168

168-
- Double parameter
169+
- Double:
169170
```c
170171
const char * parameter_name = "parameter_double";
171172
double param_value = 0.15;

0 commit comments

Comments
 (0)