Skip to content

Commit

Permalink
Support to publish serialized messages
Browse files Browse the repository at this point in the history
This patch implements the feature that a publisher can publish a raw
message, and an example is added.

Fix #646
  • Loading branch information
Minggang Wang committed Sep 30, 2020
1 parent 768eab4 commit f574a34
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 11 deletions.
43 changes: 43 additions & 0 deletions example/publisher-raw-message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2020 Intel Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

/* eslint-disable camelcase */

const rclnodejs = require('../index.js');

rclnodejs
.init()
.then(() => {
const node = rclnodejs.createNode('publisher_message_example_node');

// We have to make sure the message type of publisher and subscription is
// the same, although it seems meaningless when sending raw messages.
const publisher = node.createPublisher(
'test_msgs/msg/BasicTypes',
'chatter'
);
let count = 0;

setInterval(function () {
publisher.publish(Buffer.from('Hello ROS World'));
console.log(`Publish ${++count} messages.`);
}, 1000);

rclnodejs.spin(node);
})
.catch((e) => {
console.log(e);
});
28 changes: 17 additions & 11 deletions lib/publisher.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,27 @@ class Publisher extends Entity {

/**
* Publish a message
* @param {object} message - The message to be sent.
* @param {object|Buffer} message - The message to be sent, could be kind of JavaScript message generated from .msg
* or be a Buffer for a raw message.
* @return {undefined}
*/
publish(message) {
// Enables call by plain object/number/string argument
// e.g. publisher.publish(3.14);
// publisher.publish('The quick brown fox...');
// publisher.publish({linear: {x: 0, y: 1, z: 2}, ...});
let messageToSend =
message instanceof this._typeClass
? message
: new this._typeClass(message);
if (message instanceof Buffer) {
rclnodejs.publishRawMessage(this._handle, message);
} else {
// Enables call by plain object/number/string argument
// e.g. publisher.publish(3.14);
// publisher.publish('The quick brown fox...');
// publisher.publish({linear: {x: 0, y: 1, z: 2}, ...});
let messageToSend =
message instanceof this._typeClass
? message
: new this._typeClass(message);

let rawMessage = messageToSend.serialize();
rclnodejs.publish(this._handle, rawMessage);
}

let rawMessage = messageToSend.serialize();
rclnodejs.publish(this._handle, rawMessage);
debug(`Message of topic ${this.topic} has been published.`);
}

Expand Down
22 changes: 22 additions & 0 deletions src/rcl_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1692,6 +1692,27 @@ NAN_METHOD(ServiceServerIsAvailable) {
info.GetReturnValue().Set(result);
}

NAN_METHOD(PublishRawMessage) {
rcl_publisher_t* publisher = reinterpret_cast<rcl_publisher_t*>(
RclHandle::Unwrap<RclHandle>(
Nan::To<v8::Object>(info[0]).ToLocalChecked())
->ptr());

auto object = Nan::To<v8::Object>(info[1]).ToLocalChecked();
rcl_serialized_message_t serialized_msg =
rmw_get_zero_initialized_serialized_message();
serialized_msg.buffer_capacity = node::Buffer::Length(object);
serialized_msg.buffer_length = serialized_msg.buffer_capacity;
serialized_msg.buffer =
reinterpret_cast<uint8_t*>(node::Buffer::Data(object));

THROW_ERROR_IF_NOT_EQUAL(
rcl_publish_serialized_message(publisher, &serialized_msg, nullptr),
RCL_RET_OK, rcl_get_error_string().str);

info.GetReturnValue().Set(Nan::Undefined());
}

std::vector<BindingMethod> binding_methods = {
{"init", Init},
{"createNode", CreateNode},
Expand Down Expand Up @@ -1757,6 +1778,7 @@ std::vector<BindingMethod> binding_methods = {
{"countPublishers", CountPublishers},
{"countSubscribers", CountSubscribers},
{"serviceServerIsAvailable", ServiceServerIsAvailable},
{"publishRawMessage", PublishRawMessage},
{"", nullptr}};

} // namespace rclnodejs

0 comments on commit f574a34

Please sign in to comment.