@foxglove/rosbag2
Version:
ROS 2 (Robot Operating System) bag reader and writer abstract implementation
140 lines • 7.12 kB
JavaScript
;
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Rosbag2_messageReaders, _Rosbag2_databases, _Rosbag2_messageReaderOptions, _Rosbag2_decodeMessage;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Rosbag2 = exports.ROS2_DEFINITIONS_ARRAY = exports.ROS2_TO_DEFINITIONS = void 0;
const rosmsg_msgs_common_1 = require("@foxglove/rosmsg-msgs-common");
const rosmsg2_serialization_1 = require("@foxglove/rosmsg2-serialization");
const rostime_1 = require("@foxglove/rostime");
const internal_1 = require("@foxglove/schemas/internal");
const MessageIterator_1 = require("./MessageIterator");
exports.ROS2_TO_DEFINITIONS = new Map();
exports.ROS2_DEFINITIONS_ARRAY = [];
// Add ROS2 common message definitions (rcl_interfaces, common_interfaces, etc)
for (const [dataType, msgdef] of Object.entries(rosmsg_msgs_common_1.ros2galactic)) {
exports.ROS2_DEFINITIONS_ARRAY.push(msgdef);
// Handle the datatype naming difference used in rosbag2 (but not the .msg files)
exports.ROS2_TO_DEFINITIONS.set(dataTypeToFullName(dataType), msgdef);
}
// Add foxglove message definitions
for (const schema of Object.values(internal_1.foxgloveMessageSchemas)) {
const { rosMsgInterfaceName, rosFullInterfaceName, fields } = (0, internal_1.generateRosMsgDefinition)(schema, {
rosVersion: 2,
});
const msgdef = { name: rosMsgInterfaceName, definitions: fields };
if (!exports.ROS2_TO_DEFINITIONS.has(rosFullInterfaceName)) {
exports.ROS2_DEFINITIONS_ARRAY.push(msgdef);
exports.ROS2_TO_DEFINITIONS.set(rosFullInterfaceName, msgdef);
}
}
// Add the legacy foxglove_msgs/ImageMarkerArray message definition
const imageMarkerArray = {
name: "foxglove_msgs/ImageMarkerArray",
definitions: [
{ type: "visualization_msgs/ImageMarker", isArray: true, name: "markers", isComplex: true },
],
};
exports.ROS2_DEFINITIONS_ARRAY.push(imageMarkerArray);
exports.ROS2_TO_DEFINITIONS.set("foxglove_msgs/msg/ImageMarkerArray", imageMarkerArray);
class Rosbag2 {
constructor(files, messageReaderOptions) {
_Rosbag2_messageReaders.set(this, new Map());
_Rosbag2_databases.set(this, void 0);
_Rosbag2_messageReaderOptions.set(this, void 0);
_Rosbag2_decodeMessage.set(this, (rawMessage) => {
// Find or create a message reader for this message
let reader = __classPrivateFieldGet(this, _Rosbag2_messageReaders, "f").get(rawMessage.topic.type);
if (reader == undefined) {
const msgdef = exports.ROS2_TO_DEFINITIONS.get(rawMessage.topic.type);
if (msgdef == undefined) {
throw new Error(`Unknown message type: ${rawMessage.topic.type}`);
}
reader = new rosmsg2_serialization_1.MessageReader([msgdef, ...exports.ROS2_DEFINITIONS_ARRAY], __classPrivateFieldGet(this, _Rosbag2_messageReaderOptions, "f"));
__classPrivateFieldGet(this, _Rosbag2_messageReaders, "f").set(rawMessage.topic.type, reader);
}
return reader.readMessage(rawMessage.data);
});
__classPrivateFieldSet(this, _Rosbag2_databases, files, "f");
__classPrivateFieldSet(this, _Rosbag2_messageReaderOptions, messageReaderOptions, "f");
}
async open() {
for (const db of __classPrivateFieldGet(this, _Rosbag2_databases, "f")) {
await db.open();
}
}
async close() {
for (const db of __classPrivateFieldGet(this, _Rosbag2_databases, "f")) {
await db.close();
}
__classPrivateFieldSet(this, _Rosbag2_databases, [], "f");
}
async readTopics() {
if (__classPrivateFieldGet(this, _Rosbag2_databases, "f").length === 0) {
return [];
}
const firstDb = __classPrivateFieldGet(this, _Rosbag2_databases, "f")[0];
return await firstDb.readTopics();
}
readMessages(opts = {}) {
if (__classPrivateFieldGet(this, _Rosbag2_databases, "f").length === 0) {
return new MessageIterator_1.MessageIterator([]);
}
const rowIterators = __classPrivateFieldGet(this, _Rosbag2_databases, "f").map((db) => db.readMessages(opts));
return new MessageIterator_1.MessageIterator(rowIterators, opts.rawMessages !== true ? __classPrivateFieldGet(this, _Rosbag2_decodeMessage, "f") : undefined);
}
async timeRange() {
if (__classPrivateFieldGet(this, _Rosbag2_databases, "f").length === 0) {
return [
{ sec: 0, nsec: 0 },
{ sec: 0, nsec: 0 },
];
}
let min = { sec: Number.MAX_SAFE_INTEGER, nsec: 0 };
let max = { sec: Number.MIN_SAFE_INTEGER, nsec: 0 };
for (const db of __classPrivateFieldGet(this, _Rosbag2_databases, "f")) {
const [curMin, curMax] = await db.timeRange();
min = minTime(min, curMin);
max = maxTime(max, curMax);
}
return [min, max];
}
async messageCounts() {
const allCounts = new Map();
if (__classPrivateFieldGet(this, _Rosbag2_databases, "f").length === 0) {
return allCounts;
}
for (const db of __classPrivateFieldGet(this, _Rosbag2_databases, "f")) {
const counts = await db.messageCounts();
for (const [topic, count] of counts) {
allCounts.set(topic, (allCounts.get(topic) ?? 0) + count);
}
}
return allCounts;
}
}
exports.Rosbag2 = Rosbag2;
_Rosbag2_messageReaders = new WeakMap(), _Rosbag2_databases = new WeakMap(), _Rosbag2_messageReaderOptions = new WeakMap(), _Rosbag2_decodeMessage = new WeakMap();
function minTime(a, b) {
return (0, rostime_1.isLessThan)(a, b) ? a : b;
}
function maxTime(a, b) {
return (0, rostime_1.isLessThan)(a, b) ? b : a;
}
function dataTypeToFullName(dataType) {
const parts = dataType.split("/");
if (parts.length === 2) {
return `${parts[0]}/msg/${parts[1]}`;
}
return dataType;
}
//# sourceMappingURL=Rosbag2.js.map