Skip to content

Commit e7ae806

Browse files
ross-desmondwjwwood
authored andcommitted
Implement QoS: liveliness, deadline, lifespan (#171)
* initial qos interface changes Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * add creation of event waitable type Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Add rmw take_event interface Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * add rmw event type enum Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Modify events type from void** to rmw_event_t** Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * fix lint errors Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Added RMW QoS Event Definitions Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Added RMW QoS Event Definitions Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Code formatting fixes Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Change liveliness policy types to reflect actual settings Signed-off-by: Emerson Knapp <[email protected]> Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Comment out types of liveliness that will not be supported in this iteration of the feature Signed-off-by: Emerson Knapp <[email protected]> Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Re-enable manual liveliness, name to by_node Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Fixed style issues Removed unsupported QoS types Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Removed extra QoS types Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * add an invalid enum in rmw_event_type_t for variables to default to Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * change rmw_event_t APIs from create()/destroy() to init()/fini() pattern Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Move rmw_*_event_init implementation to rmw **Summary** Event initialization should require no modifications from the underlying rmw layer and therefore can be initialized in the rmw layer. Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Fix uncrustify divergence in event.c Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Remove erroneous rmw_delete_event Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Implement QoS: liveliness, deadline, lifespan **Summary** Provide init/fini and take functions for events. Modify wait_set to include event handles for notification of status changes. Details: * ADD initial qos interface changes * ADD rmw take_event interface * ADD rmw event type enum * MODIFY events type from void** to rmw_event_t** * ADD RMW QoS Event Definitions * ADD section about DCO to CONTRIBUTING.md * EDIT liveliness policy types to reflect actual settings * ADD an invalid enum in rmw_event_type_t for variables to default to * MOVE rmw_*_event_init implementation to rmw ** Event initialization should require no modifications from the underlying rmw layer and therefore can be initialized in the rmw layer. Signed-off-by: Ross Desmond <[email protected]> Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Added missing documentation Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Edited added struct names for consistency Edited method signatures to follow const correctness Addressed style / linting review comments Updated documentation style Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * add assert_liveliness() APIs Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * address comments in PR (github.com/aws-ros-dev/pull/4) Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Edited documentation to account for unexpected errors Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * modify doc string regarding the requirement of asserting liveliness Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Edit documentation block to fix linting errors Signed-off-by: Devin Bonnie <[email protected]> Signed-off-by: Burek <[email protected]> * Addressed documentation issues found in review Signed-off-by: Devin Bonnie <[email protected]>
1 parent 2a30008 commit e7ae806

File tree

5 files changed

+277
-0
lines changed

5 files changed

+277
-0
lines changed

rmw/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ include_directories(include)
2727
set(rmw_sources
2828
"src/allocators.c"
2929
"src/convert_rcutils_ret_to_rmw_ret.c"
30+
"src/event.c"
3031
"src/init.c"
3132
"src/init_options.c"
3233
"src/names_and_types.c"

rmw/include/rmw/event.h

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright 2019 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef RMW__EVENT_H_
16+
#define RMW__EVENT_H_
17+
18+
#ifdef __cplusplus
19+
extern "C"
20+
{
21+
#endif
22+
23+
#include <stdint.h>
24+
25+
#include "rcutils/allocator.h"
26+
27+
#include "rmw/macros.h"
28+
#include "rmw/types.h"
29+
#include "rmw/ret_types.h"
30+
#include "rmw/visibility_control.h"
31+
32+
/// Define QoS policy events
33+
typedef enum rmw_event_type_t
34+
{
35+
// subscription events
36+
RMW_EVENT_LIVELINESS_CHANGED,
37+
RMW_EVENT_REQUESTED_DEADLINE_MISSED,
38+
39+
// publisher events
40+
RMW_EVENT_LIVELINESS_LOST,
41+
RMW_EVENT_OFFERED_DEADLINE_MISSED,
42+
43+
// sentinel value
44+
RMW_EVENT_INVALID
45+
} rmw_event_type_t;
46+
47+
/// Encapsulate the RMW event implementation, data, and type.
48+
typedef struct RMW_PUBLIC_TYPE rmw_event_t
49+
{
50+
/// Implementation identifier, used to ensure two different implementations are not being mixed.
51+
const char * implementation_identifier;
52+
/// Data specific to this event type from either the publisher or subscriber.
53+
void * data;
54+
/// The event type that occurred.
55+
rmw_event_type_t event_type;
56+
} rmw_event_t;
57+
58+
/// Return a zero initialized event structure.
59+
RMW_PUBLIC
60+
RMW_WARN_UNUSED
61+
rmw_event_t
62+
rmw_get_zero_initialized_event(void);
63+
64+
/// Initialize a rmw publisher event.
65+
/**
66+
* \param[in|out] rmw_event to initialize
67+
* \param publisher to initialize with
68+
* \param event_type for the event to handle
69+
* \return `RMW_RET_OK` if successful, or
70+
* \return `RMW_RET_INVALID_ARGUMENT` if invalid argument
71+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
72+
*/
73+
RMW_PUBLIC
74+
RMW_WARN_UNUSED
75+
rmw_ret_t
76+
rmw_publisher_event_init(
77+
rmw_event_t * rmw_event,
78+
const rmw_publisher_t * publisher,
79+
rmw_event_type_t event_type);
80+
81+
/// Initialize a rmw subscription event.
82+
/**
83+
* \param[in|out] rmw_event to initialize
84+
* \param subscription to initialize with
85+
* \param event_type for the event to handle
86+
* \return `RMW_RET_OK` if successful, or
87+
* \return `RMW_RET_INVALID_ARGUMENT` if invalid argument
88+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
89+
*/
90+
RMW_PUBLIC
91+
RMW_WARN_UNUSED
92+
rmw_ret_t
93+
rmw_subscription_event_init(
94+
rmw_event_t * rmw_event,
95+
const rmw_subscription_t * subscription,
96+
rmw_event_type_t event_type);
97+
98+
/// Take an event from the event handle.
99+
/**
100+
* \param event_handle event object to take from
101+
* \param event_info event info object to write taken data into
102+
* \param taken boolean flag indicating if an event was taken or not
103+
* \return `RMW_RET_OK` if successful, or
104+
* \return `RMW_RET_BAD_ALLOC` if memory allocation failed, or
105+
* \return `RMW_RET_ERROR` if an unexpected error occurs.
106+
*/
107+
RMW_PUBLIC
108+
RMW_WARN_UNUSED
109+
rmw_ret_t
110+
rmw_take_event(
111+
const rmw_event_t * event_handle,
112+
void * event_info,
113+
bool * taken);
114+
115+
/// Finalize an rmw_event_t.
116+
/**
117+
* \param event to finalize
118+
*/
119+
RMW_PUBLIC
120+
RMW_WARN_UNUSED
121+
rmw_ret_t
122+
rmw_event_fini(rmw_event_t * event);
123+
124+
#ifdef __cplusplus
125+
}
126+
#endif
127+
128+
#endif // RMW__EVENT_H_

rmw/include/rmw/rmw.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,30 @@ RMW_WARN_UNUSED
183183
rmw_ret_t
184184
rmw_destroy_node(rmw_node_t * node);
185185

186+
/// Manually assert that this node is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE)
187+
/**
188+
* If the rmw Liveliness policy is set to RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE, the creator of
189+
* this node may manually call `assert_liveliness` at some point in time to signal to the rest
190+
* of the system that this Node is still alive.
191+
*
192+
* <hr>
193+
* Attribute | Adherence
194+
* ------------------ | -------------
195+
* Allocates Memory | No
196+
* Thread-Safe | Yes
197+
* Uses Atomics | No
198+
* Lock-Free | Yes
199+
*
200+
* \param[in] node handle to the node that needs liveliness to be asserted
201+
* \return `RMW_RET_OK` if the liveliness assertion was completed successfully, or
202+
* \return `RMW_RET_ERROR` if an unspecified error occurs, or
203+
* \return `RMW_RET_UNSUPPORTED` if the rmw implementation does not support asserting liveliness.
204+
*/
205+
RMW_PUBLIC
206+
RMW_WARN_UNUSED
207+
rmw_ret_t
208+
rmw_node_assert_liveliness(const rmw_node_t * node);
209+
186210
/// Return a guard condition which is triggered when the ROS graph changes.
187211
/**
188212
* The handle returned is a pointer to an internally held rmw guard condition.
@@ -373,6 +397,30 @@ rmw_get_serialized_message_size(
373397
const rosidl_message_bounds_t * message_bounds,
374398
size_t * size);
375399

400+
/// Manually assert that this Publisher is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC)
401+
/**
402+
* If the rmw Liveliness policy is set to RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC, the creator of
403+
* this publisher may manually call `assert_liveliness` at some point in time to signal to the rest
404+
* of the system that this Node is still alive.
405+
*
406+
* <hr>
407+
* Attribute | Adherence
408+
* ------------------ | -------------
409+
* Allocates Memory | No
410+
* Thread-Safe | Yes
411+
* Uses Atomics | No
412+
* Lock-Free | Yes
413+
*
414+
* \param[in] publisher handle to the publisher that needs liveliness to be asserted
415+
* \return `RMW_RET_OK` if the liveliness assertion was completed successfully, or
416+
* \return `RMW_RET_ERROR` if an unspecified error occurs, or
417+
* \return `RMW_RET_UNSUPPORTED` if the rmw implementation does not support asserting liveliness.
418+
*/
419+
RMW_PUBLIC
420+
RMW_WARN_UNUSED
421+
rmw_ret_t
422+
rmw_publisher_assert_liveliness(const rmw_publisher_t * publisher);
423+
376424
/// Serialize a ROS message into a rmw_serialized_message_t.
377425
/**
378426
* The ROS message is serialized into a byte stream contained within the
@@ -764,6 +812,7 @@ rmw_wait(
764812
rmw_guard_conditions_t * guard_conditions,
765813
rmw_services_t * services,
766814
rmw_clients_t * clients,
815+
rmw_events_t * events,
767816
rmw_wait_set_t * wait_set,
768817
const rmw_time_t * wait_timeout);
769818

rmw/include/rmw/types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ typedef struct RMW_PUBLIC_TYPE rmw_clients_t
137137
void ** clients;
138138
} rmw_clients_t;
139139

140+
typedef struct RMW_PUBLIC_TYPE rmw_events_t
141+
{
142+
/// The number of events represented by the array.
143+
size_t event_count;
144+
/// Pointer to an array of void * pointers of events.
145+
void ** events;
146+
} rmw_events_t;
147+
140148
/// Array of guard condition handles.
141149
/**
142150
* An array of void * pointers representing type-erased middleware-specific guard conditions.

rmw/src/event.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2019 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <stddef.h>
16+
17+
#include "rmw/error_handling.h"
18+
#include "rmw/event.h"
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
23+
24+
rmw_event_t
25+
rmw_get_zero_initialized_event(void)
26+
{
27+
const rmw_event_t event = {
28+
.implementation_identifier = NULL,
29+
.data = NULL,
30+
.event_type = RMW_EVENT_INVALID
31+
}; // NOLINT(readability/braces): false positive
32+
return event;
33+
}
34+
35+
rmw_ret_t
36+
__rmw_init_event(
37+
rmw_event_t * rmw_event,
38+
const char * implementation_identifier,
39+
void * data,
40+
const rmw_event_type_t event_type)
41+
{
42+
RMW_CHECK_ARGUMENT_FOR_NULL(implementation_identifier, RMW_RET_INVALID_ARGUMENT);
43+
RMW_CHECK_ARGUMENT_FOR_NULL(data, RMW_RET_INVALID_ARGUMENT);
44+
RMW_CHECK_ARGUMENT_FOR_NULL(rmw_event, RMW_RET_INVALID_ARGUMENT);
45+
if (NULL != rmw_event->implementation_identifier) {
46+
RMW_SET_ERROR_MSG("expected zero-initialized rmw_event");
47+
return RMW_RET_INVALID_ARGUMENT;
48+
}
49+
rmw_event->implementation_identifier = implementation_identifier;
50+
rmw_event->data = data;
51+
rmw_event->event_type = event_type;
52+
return RMW_RET_OK;
53+
}
54+
55+
rmw_ret_t
56+
rmw_publisher_event_init(
57+
rmw_event_t * rmw_event,
58+
const rmw_publisher_t * publisher,
59+
rmw_event_type_t event_type)
60+
{
61+
return __rmw_init_event(
62+
rmw_event,
63+
publisher->implementation_identifier,
64+
publisher->data,
65+
event_type);
66+
}
67+
68+
rmw_ret_t
69+
rmw_subscription_event_init(
70+
rmw_event_t * rmw_event,
71+
const rmw_subscription_t * subscription,
72+
rmw_event_type_t event_type)
73+
{
74+
return __rmw_init_event(
75+
rmw_event,
76+
subscription->implementation_identifier,
77+
subscription->data,
78+
event_type);
79+
}
80+
81+
rmw_ret_t
82+
rmw_event_fini(rmw_event_t * rmw_event)
83+
{
84+
RMW_CHECK_ARGUMENT_FOR_NULL(rmw_event, RMW_RET_INVALID_ARGUMENT);
85+
*rmw_event = rmw_get_zero_initialized_event();
86+
return RMW_RET_OK;
87+
}
88+
89+
#ifdef __cplusplus
90+
}
91+
#endif

0 commit comments

Comments
 (0)