Skip to content

Commit 5e43c92

Browse files
authored
Add assertLiveliness() method for publisher (#1331)
This PR adds support for liveliness assertions in publishers by introducing the `assertLiveliness()` method and extending the QoS configuration with liveliness policy options. - Adds `LivelinessPolicy` enum with five policy options (SYSTEM_DEFAULT, AUTOMATIC, MANUAL_BY_TOPIC, UNKNOWN, BEST_AVAILABLE) - Adds `assertLiveliness()` method to Publisher class for manual liveliness assertions - Extends QoS class to support liveliness configuration as a constructor parameter and property Fix: #1330
1 parent cd267c5 commit 5e43c92

File tree

8 files changed

+121
-0
lines changed

8 files changed

+121
-0
lines changed

lib/publisher.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ class Publisher extends Entity {
112112
return rclnodejs.waitForAllAcked(this._handle, timeout);
113113
}
114114

115+
/**
116+
* Manually assert that this Publisher is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC).
117+
* @return {undefined}
118+
*/
119+
assertLiveliness() {
120+
rclnodejs.assertLiveliness(this._handle);
121+
}
122+
115123
/**
116124
* Get the event handlers for this publisher.
117125
* @returns {Array} The array of event handlers for this publisher.

lib/qos.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,24 @@ let DurabilityPolicy = {
5858
RMW_QOS_POLICY_DURABILITY_VOLATILE: 2,
5959
};
6060

61+
/**
62+
* Enum for LivelinessPolicy
63+
* @readonly
64+
* @enum {number}
65+
*/
66+
let LivelinessPolicy = {
67+
/** @member {number} */
68+
RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT: 0,
69+
/** @member {number} */
70+
RMW_QOS_POLICY_LIVELINESS_AUTOMATIC: 1,
71+
/** @member {number} */
72+
RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC: 3,
73+
/** @member {number} */
74+
RMW_QOS_POLICY_LIVELINESS_UNKNOWN: 4,
75+
/** @member {number} */
76+
RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE: 5,
77+
};
78+
6179
/** Class representing middleware quality of service */
6280
class QoS {
6381
/**
@@ -73,12 +91,14 @@ class QoS {
7391
depth = 0,
7492
reliability = ReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT,
7593
durability = DurabilityPolicy.RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT,
94+
liveliness = LivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT,
7695
avoidRosNameSpaceConventions = false
7796
) {
7897
this._history = history;
7998
this._depth = depth;
8099
this._reliability = reliability;
81100
this._durability = durability;
101+
this._liveliness = liveliness;
82102
this._avoidRosNameSpaceConventions = avoidRosNameSpaceConventions;
83103
}
84104

@@ -112,6 +132,16 @@ class QoS {
112132
return DurabilityPolicy;
113133
}
114134

135+
/**
136+
* Get LivelinessPolicy enum.
137+
* @name QoS#static get:LivelinessPolicy
138+
* @function
139+
* @return {LivelinessPolicy}
140+
*/
141+
static get LivelinessPolicy() {
142+
return LivelinessPolicy;
143+
}
144+
115145
/**
116146
* Get the history value.
117147
* @name QoS#get:history
@@ -220,6 +250,33 @@ class QoS {
220250
this._durability = durability;
221251
}
222252

253+
/**
254+
* Get the liveliness value.
255+
* @name QoS#get:liveliness
256+
* @function
257+
* @return {number}
258+
*/
259+
get liveliness() {
260+
return this._liveliness;
261+
}
262+
263+
/**
264+
* Set the liveliness value.
265+
* @param {number} liveliness - value to be set.
266+
* @name QoS#set:liveliness
267+
* @function
268+
* @return {undefined}
269+
*/
270+
set liveliness(liveliness) {
271+
if (typeof liveliness !== 'number') {
272+
throw new TypeValidationError('liveliness', liveliness, 'number', {
273+
entityType: 'qos',
274+
});
275+
}
276+
277+
this._liveliness = liveliness;
278+
}
279+
223280
/**
224281
* Get the avoidRosNameSpaceConventions value.
225282
* @name QoS#get:avoidRosNameSpaceConventions

src/rcl_publisher_bindings.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ Napi::Value WaitForAllAcked(const Napi::CallbackInfo& info) {
147147
return env.Undefined();
148148
}
149149

150+
Napi::Value AssertLiveliness(const Napi::CallbackInfo& info) {
151+
Napi::Env env = info.Env();
152+
rcl_publisher_t* publisher = reinterpret_cast<rcl_publisher_t*>(
153+
RclHandle::Unwrap(info[0].As<Napi::Object>())->ptr());
154+
155+
THROW_ERROR_IF_NOT_EQUAL(rcl_publisher_assert_liveliness(publisher),
156+
RCL_RET_OK, rcl_get_error_string().str);
157+
158+
return env.Undefined();
159+
}
160+
150161
Napi::Object InitPublisherBindings(Napi::Env env, Napi::Object exports) {
151162
exports.Set("createPublisher", Napi::Function::New(env, CreatePublisher));
152163
exports.Set("publish", Napi::Function::New(env, Publish));
@@ -155,6 +166,7 @@ Napi::Object InitPublisherBindings(Napi::Env env, Napi::Object exports) {
155166
exports.Set("getSubscriptionCount",
156167
Napi::Function::New(env, GetSubscriptionCount));
157168
exports.Set("waitForAllAcked", Napi::Function::New(env, WaitForAllAcked));
169+
exports.Set("assertLiveliness", Napi::Function::New(env, AssertLiveliness));
158170
return exports;
159171
}
160172

src/rcl_utilities.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ std::unique_ptr<rmw_qos_profile_t> GetQosProfileFromObject(
5555
auto depth = object.Get("depth");
5656
auto reliability = object.Get("reliability");
5757
auto durability = object.Get("durability");
58+
auto liveliness = object.Get("liveliness");
5859
auto avoid_ros_namespace_conventions =
5960
object.Get("avoidRosNameSpaceConventions");
6061

@@ -65,6 +66,8 @@ std::unique_ptr<rmw_qos_profile_t> GetQosProfileFromObject(
6566
reliability.As<Napi::Number>().Uint32Value());
6667
qos_profile->durability = static_cast<rmw_qos_durability_policy_t>(
6768
durability.As<Napi::Number>().Uint32Value());
69+
qos_profile->liveliness = static_cast<rmw_qos_liveliness_policy_t>(
70+
liveliness.As<Napi::Number>().Uint32Value());
6871
qos_profile->avoid_ros_namespace_conventions =
6972
avoid_ros_namespace_conventions.As<Napi::Boolean>();
7073

test/test-publisher.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,21 @@ describe('rclnodejs publisher test suite', function () {
6969
publisher.publish('Hello World');
7070
assert.strictEqual(publisher.waitForAllAcked(BigInt(1000000000)), true);
7171
});
72+
73+
it('Test assertLiveliness', function () {
74+
const node = rclnodejs.createNode('publisher_node');
75+
const String = 'std_msgs/msg/String';
76+
const qos = new rclnodejs.QoS(
77+
rclnodejs.QoS.HistoryPolicy.RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT,
78+
0,
79+
rclnodejs.QoS.ReliabilityPolicy.RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT,
80+
rclnodejs.QoS.DurabilityPolicy.RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT,
81+
rclnodejs.QoS.LivelinessPolicy.RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC
82+
);
83+
const publisher = node.createPublisher(String, 'topic', { qos: qos });
84+
assert.doesNotThrow(() => {
85+
publisher.assertLiveliness();
86+
});
87+
rclnodejs.spin(node);
88+
});
7289
});

test/types/index.test-d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ expectType<boolean>(publisher.waitForAllAcked(BigInt(1000)));
163163
node.createPublisher(TYPE_CLASS, TOPIC, publisher.options, (event: object) => {
164164
const receivedEvent = event;
165165
});
166+
expectType<void>(publisher.assertLiveliness());
166167
expectType<string>(publisher.loggerName);
167168

168169
// ---- LifecyclePublisher ----

types/publisher.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ declare module 'rclnodejs' {
3838
*/
3939
waitForAllAcked(timeout: bigint): boolean;
4040

41+
/**
42+
* Manually assert that this Publisher is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC).
43+
*/
44+
assertLiveliness(): void;
45+
4146
/**
4247
* Get the logger name for this publisher.
4348
*/

types/qos.d.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ declare module 'rclnodejs' {
1111
* @param depth - The depth value, default = 0.
1212
* @param reliability - The reliability value, default = RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT
1313
* @param durability - The durability value, default = RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT
14+
* @param liveliness - The liveliness value, default = RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT
1415
* @param avoidRosNameSpaceConventions - The avoidRosNameSpaceConventions value, default = false.
1516
*/
1617
constructor(
1718
history?: QoS.HistoryPolicy,
1819
depth?: number,
1920
reliability?: QoS.ReliabilityPolicy,
2021
durability?: QoS.DurabilityPolicy,
22+
liveliness?: QoS.LivelinessPolicy,
2123
avoidRosNameSpaceConventions?: boolean
2224
);
2325

@@ -41,6 +43,11 @@ declare module 'rclnodejs' {
4143
*/
4244
durability: QoS.DurabilityPolicy;
4345

46+
/**
47+
* Get the liveliness value.
48+
*/
49+
liveliness: QoS.LivelinessPolicy;
50+
4451
/**
4552
* Get the avoidRosNameSpaceConventions value.
4653
*/
@@ -115,5 +122,16 @@ declare module 'rclnodejs' {
115122
RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL = 1,
116123
RMW_QOS_POLICY_DURABILITY_VOLATILE = 2,
117124
}
125+
126+
/**
127+
* LivelinessPolicy
128+
*/
129+
enum LivelinessPolicy {
130+
RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT = 0,
131+
RMW_QOS_POLICY_LIVELINESS_AUTOMATIC = 1,
132+
RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC = 3,
133+
RMW_QOS_POLICY_LIVELINESS_UNKNOWN = 4,
134+
RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE = 5,
135+
}
118136
}
119137
}

0 commit comments

Comments
 (0)