diff --git a/package-lock.json b/package-lock.json
index 6c808eb..bffe290 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2782,9 +2782,9 @@
"integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
},
"caniuse-lite": {
- "version": "1.0.30001109",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001109.tgz",
- "integrity": "sha512-4JIXRodHzdS3HdK8nSgIqXYLExOvG+D2/EenSvcub2Kp3QEADjo2v2oUn5g0n0D+UNwG9BtwKOyGcSq2qvQXvQ==",
+ "version": "1.0.30001296",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001296.tgz",
+ "integrity": "sha512-WfrtPEoNSoeATDlf4y3QvkwiELl9GyPLISV5GejTbbQRtQx4LhsXmc9IQ6XCL2d7UxCyEzToEZNMeqR79OUw8Q==",
"dev": true
},
"caseless": {
@@ -4335,9 +4335,9 @@
}
},
"engine.io-client": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz",
- "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.3.tgz",
+ "integrity": "sha512-PXIgpzb1brtBzh8Q6vCjzCMeu4nfEPmaDm+L3Qb2sVHwLkxC1qRiBMSjOB0NJNjZ0hbPNUKQa+s8J2XxLOIEeQ==",
"requires": {
"component-emitter": "1.2.1",
"component-inherit": "0.0.3",
@@ -4348,7 +4348,7 @@
"parseqs": "0.0.5",
"parseuri": "0.0.5",
"ws": "~6.1.0",
- "xmlhttprequest-ssl": "~1.5.4",
+ "xmlhttprequest-ssl": "~1.6.3",
"yeast": "0.1.2"
},
"dependencies": {
@@ -11801,9 +11801,9 @@
"integrity": "sha512-ryT4RVDlSlwrRtCFgtH5PTRrAC+JGfzFxXJ1E5Wdfu2xVVcoeBkl2ocVp4XgOhzWJQWiSaHyq30VmSBhBPcigQ=="
},
"three-spritetext": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/three-spritetext/-/three-spritetext-1.6.2.tgz",
- "integrity": "sha512-VALj40t81Z6x/fDnY/tts8QU+mBl77bxoynBbcn/DW4oxfzZSwjaOfkQOe0jYpLoK2vtP0bAULvGgwIYnsN6oQ=="
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/three-spritetext/-/three-spritetext-1.6.3.tgz",
+ "integrity": "sha512-AE9AzUvY3xpQryTy+H5ylYkaWs+ZgsPqbF7yGXPEjthX5n/coIxobSVZAcPCTyl77DnM0Ub/YH7gLI54Eyg+dQ=="
},
"through": {
"version": "2.3.8",
@@ -13346,9 +13346,9 @@
}
},
"ws": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz",
- "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw=="
+ "version": "7.5.6",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
+ "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA=="
},
"x-is-string": {
"version": "0.1.0",
@@ -13361,9 +13361,9 @@
"integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ=="
},
"xmlhttprequest-ssl": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
- "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
+ "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q=="
},
"xstream": {
"version": "11.14.0",
diff --git a/package.json b/package.json
index d671bb3..1316376 100644
--- a/package.json
+++ b/package.json
@@ -46,7 +46,7 @@
"three": "^0.117.0"
},
"scripts": {
- "start": "webpack-dev-server --config webpack.app.dev.js --host 192.168.64.6",
+ "start": "webpack-dev-server --config webpack.app.dev.js --host 10.82.207.213",
"build": "webpack --config webpack.app.prod.js",
"build-lib": "webpack --config webpack.lib.prod.js",
"lint": "eslint src/**/*.{js,jsx} --fix",
diff --git a/path.py b/path.py
new file mode 100644
index 0000000..fd4866f
--- /dev/null
+++ b/path.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+import rospy
+
+from nav_msgs.msg import Path
+from nav_msgs.msg import Odometry
+from geometry_msgs.msg import PoseStamped
+
+path = Path()
+
+def odom_cb(data):
+ global path
+ path.header = data.header
+ pose = PoseStamped()
+ pose.header = data.header
+ pose.pose = data.pose.pose
+ path.poses.append(pose)
+ path_pub.publish(path)
+
+rospy.init_node('path_node')
+
+odom_sub = rospy.Subscriber('/odom', Odometry, odom_cb)
+path_pub = rospy.Publisher('/path', Path, queue_size=10)
+
+if __name__ == '__main__':
+ rospy.spin()
diff --git a/src/panels/addModal/index.jsx b/src/panels/addModal/index.jsx
index 22a3f82..a8023d6 100644
--- a/src/panels/addModal/index.jsx
+++ b/src/panels/addModal/index.jsx
@@ -54,6 +54,7 @@ class AddModal extends React.Component {
ros,
rosParams,
rosTopics,
+ rosVersion,
} = this.props;
const { selectedViz, tabType } = this.state;
return (
@@ -87,12 +88,14 @@ class AddModal extends React.Component {
rosTopics={rosTopics}
rosParams={rosParams}
closeModal={closeModal}
+ rosVersion={rosVersion}
/>
) : (
)}
>
diff --git a/src/panels/addModal/tabTopicName.jsx b/src/panels/addModal/tabTopicName.jsx
index cd2a2de..af99a74 100644
--- a/src/panels/addModal/tabTopicName.jsx
+++ b/src/panels/addModal/tabTopicName.jsx
@@ -1,6 +1,7 @@
import React from 'react';
import _ from 'lodash';
import { vizOptions } from '../../utils/vizOptions';
+import { ros2vizOptions } from '../../utils/vizOptions';
import { ButtonPrimary, FlexGrow } from '../../components/styled';
import {
AddVizForm,
@@ -41,16 +42,17 @@ class TopicName extends React.Component {
}
render() {
- const { closeModal, rosTopics } = this.props;
+ const { closeModal, rosTopics, rosVersion } = this.props;
const { selectedViz } = this.state;
return (
{_.map(_.sortBy(rosTopics, 'name'), ({ name, messageType }) => {
- const vizOption = _.find(vizOptions, v =>
+ const vizOption = _.find(rosVersion === 1 ? vizOptions : ros2vizOptions, v =>
_.includes(v.messageTypes, messageType),
);
+ console.log(vizOptions);
return vizOption ? (
- {_.map(vizOptions, op => {
+ {_.map(rosVersion === 1 ? vizOptions : ros2vizOptions, op => {
return (
{
this.setState({ rosParams: _.map(rosParams, p => _.trimStart(p, '/')) });
});
+ this.ros_version_service.callService(ROSLIB.ServiceRequest(), result => {
+ this.setState({ rosVersion: result.version });
+ });
}
componentWillUnmount() {
@@ -319,6 +324,7 @@ class Wrapper extends React.Component {
graphModalOpen,
rosEndpoint,
rosParams,
+ rosVersion,
rosStatus,
rosTopics,
} = this.state;
@@ -360,6 +366,7 @@ class Wrapper extends React.Component {
ros={this.ros}
rosTopics={rosTopics}
rosParams={rosParams}
+ rosVersion={rosVersion}
closeModal={this.toggleAddModal}
addVisualization={this.addVisualization}
/>
@@ -380,6 +387,7 @@ class Wrapper extends React.Component {
rosInstance={this.ros}
rosTopics={rosTopics}
rosStatus={rosStatus}
+ rosVersion={rosVersion}
vizInstances={this.vizInstances}
visualizations={visualizations}
viewer={this.viewer}
@@ -420,6 +428,7 @@ class Wrapper extends React.Component {
key={vizItem.key}
viewer={this.viewer}
rosTopics={rosTopics}
+ rosVersion={rosVersion}
rosInstance={this.ros}
/>
))}
diff --git a/src/panels/info/index.jsx b/src/panels/info/index.jsx
index 6c86832..ebfc3db 100644
--- a/src/panels/info/index.jsx
+++ b/src/panels/info/index.jsx
@@ -27,15 +27,22 @@ import AddInfoPanelModal from './addInfoPanelModal';
const MESSAGE_BUFFER_MAX_LENGTH = 1000;
const compressionTypes = new Set([
'sensor_msgs/Image',
+ 'sensor_msgs/msg/Image',
'sensor_msgs/PointCloud2',
+ 'sensor_msgs/msg/PointCloud2',
'sensor_msgs/PointCloud',
'sensor_msgs/LaserScan',
+ 'sensor_msgs/msg/LaserScan',
'nav_msgs/Path',
+ 'nav_msgs/msg/Path',
'nav_msgs/OccupancyGrid',
+ 'nav_msgs/msg/OccupancyGrid',
'visualization_msgs/MarkerArray',
+ 'visualization_msgs/msg/MarkerArray',
'geometry_msgs/Polygon',
'geometry_msgs/PolygonStamped',
'geometry_msgs/PoseArray',
+ 'geometry_msgs/msg/PoseArray',
]);
const getTopicOptions = messageType => {
if (compressionTypes.has(messageType)) {
diff --git a/src/panels/sidebar/index.jsx b/src/panels/sidebar/index.jsx
index 1c85c26..98c2d84 100644
--- a/src/panels/sidebar/index.jsx
+++ b/src/panels/sidebar/index.jsx
@@ -3,6 +3,7 @@ import _ from 'lodash';
import { ROS_SOCKET_STATUSES } from '../../utils';
import { vizOptions } from '../../utils/vizOptions';
+import { ros2vizOptions } from '../../utils/vizOptions';
import GlobalOptions from './globalOptions';
import {
ButtonPrimary,
@@ -73,6 +74,7 @@ class Sidebar extends React.Component {
rosInstance,
rosStatus,
rosTopics,
+ rosVersion,
toggleAddModal,
toggleConfigurationModal,
toggleVisibility,
@@ -120,7 +122,7 @@ class Sidebar extends React.Component {
)}
{_.map(visualizations, vizItem => {
const vizObject = _.find(
- vizOptions,
+ rosVersion === 1 ? vizOptions : ros2vizOptions,
v => v.type === vizItem.vizType,
);
if (!vizObject) {
diff --git a/src/panels/sidebar/vizOptions/vizSpecificOption.jsx b/src/panels/sidebar/vizOptions/vizSpecificOption.jsx
index 56ace4f..5cd7676 100644
--- a/src/panels/sidebar/vizOptions/vizSpecificOption.jsx
+++ b/src/panels/sidebar/vizOptions/vizSpecificOption.jsx
@@ -15,22 +15,37 @@ import RobotModelLinksJoints from './robotModel';
const {
VIZ_TYPE_IMAGE,
+ VIZ_TYPE_IMAGE2,
VIZ_TYPE_INTERACTIVEMARKER,
+ VIZ_TYPE_INTERACTIVEMARKER2,
VIZ_TYPE_LASERSCAN,
+ VIZ_TYPE_LASERSCAN2,
VIZ_TYPE_MAP,
+ VIZ_TYPE_MAP2,
VIZ_TYPE_MARKER,
+ VIZ_TYPE_MARKER2,
VIZ_TYPE_MARKERARRAY,
+ VIZ_TYPE_MARKERARRAY2,
VIZ_TYPE_ODOMETRY,
+ VIZ_TYPE_ODOMETRY2,
VIZ_TYPE_PATH,
+ VIZ_TYPE_PATH2,
VIZ_TYPE_POINT,
+ VIZ_TYPE_POINT2,
VIZ_TYPE_POINTCLOUD,
+ VIZ_TYPE_ROS2POINTCLOUD,
VIZ_TYPE_POLYGON,
VIZ_TYPE_POSE,
+ VIZ_TYPE_POSE2,
VIZ_TYPE_POSEARRAY,
+ VIZ_TYPE_POSEARRAY2,
VIZ_TYPE_RANGE,
+ VIZ_TYPE_RANGE2,
VIZ_TYPE_ROBOTMODEL,
VIZ_TYPE_TF,
+ VIZ_TYPE_ROS2_TF,
VIZ_TYPE_WRENCH,
+ VIZ_TYPE_WRENCH2,
} = CONSTANTS;
const VizSpecificOptions = ({
@@ -44,6 +59,8 @@ const VizSpecificOptions = ({
switch (vizType) {
case VIZ_TYPE_IMAGE:
return null;
+ case VIZ_TYPE_IMAGE2:
+ return null;
case VIZ_TYPE_INTERACTIVEMARKER:
return (
);
+ case VIZ_TYPE_INTERACTIVEMARKER2:
+ return (
+
+ );
case VIZ_TYPE_LASERSCAN:
return (
);
+ case VIZ_TYPE_LASERSCAN2:
+ return (
+
+ );
case VIZ_TYPE_MAP:
return (
);
+ case VIZ_TYPE_MAP2:
+ return (
+
+ );
case VIZ_TYPE_MARKER:
return (
);
+ case VIZ_TYPE_MARKER2:
+ return (
+
+ );
case VIZ_TYPE_MARKERARRAY:
return null;
+ case VIZ_TYPE_MARKERARRAY2:
+ return null;
case VIZ_TYPE_ODOMETRY:
return (
);
+ case VIZ_TYPE_ODOMETRY2:
+ return (
+
+ );
case VIZ_TYPE_PATH:
return (
);
+ case VIZ_TYPE_PATH2:
+ return (
+
+ );
case VIZ_TYPE_POINT:
return (
);
+ case VIZ_TYPE_POINT2:
+ return (
+
+ );
case VIZ_TYPE_POINTCLOUD:
return (
);
+ case VIZ_TYPE_ROS2POINTCLOUD:
+ return (
+
+ );
case VIZ_TYPE_POLYGON:
return null;
case VIZ_TYPE_POSE:
return (
);
+ case VIZ_TYPE_POSE2:
+ return (
+
+ );
case VIZ_TYPE_POSEARRAY:
return null;
+ case VIZ_TYPE_POSEARRAY2:
+ return null;
case VIZ_TYPE_RANGE:
return (
);
+ case VIZ_TYPE_RANGE2:
+ return (
+
+ );
case VIZ_TYPE_ROBOTMODEL:
return ;
case VIZ_TYPE_TF:
return null;
+ case VIZ_TYPE_ROS2_TF:
+ return null;
case VIZ_TYPE_WRENCH:
return (
);
+ case VIZ_TYPE_WRENCH2:
+ return (
+
+ );
default:
return null;
}
diff --git a/src/panels/visualizations/index.jsx b/src/panels/visualizations/index.jsx
index d48b7d4..cc88f6a 100644
--- a/src/panels/visualizations/index.jsx
+++ b/src/panels/visualizations/index.jsx
@@ -4,6 +4,7 @@ import Amphion from 'amphion';
import _, { map } from 'lodash';
import { getTfTopics } from '../../utils';
+import { getROS2TfTopics } from '../../utils';
import { VizImageContainer, VizImageHeader } from '../../components/styled/viz';
import {
VIZ_TYPE_DEPTHCLOUD_STREAM,
@@ -13,19 +14,33 @@ import { getOrCreateRosTopicDataSource } from '../sources';
const {
MESSAGE_TYPE_IMAGE,
+ MESSAGE_TYPE_IMAGE2,
MESSAGE_TYPE_LASERSCAN,
+ MESSAGE_TYPE_LASERSCAN2,
MESSAGE_TYPE_MARKER,
+ MESSAGE_TYPE_MARKER2,
MESSAGE_TYPE_MARKERARRAY,
+ MESSAGE_TYPE_MARKERARRAY2,
MESSAGE_TYPE_OCCUPANCYGRID,
+ MESSAGE_TYPE_OCCUPANCYGRID2,
MESSAGE_TYPE_ODOMETRY,
+ MESSAGE_TYPE_ODOMETRY2,
MESSAGE_TYPE_PATH,
+ MESSAGE_TYPE_PATH2,
MESSAGE_TYPE_POINT,
+ MESSAGE_TYPE_POINT2,
MESSAGE_TYPE_POINTCLOUD2,
+ MESSAGE_TYPE_ROS2POINTCLOUD2,
MESSAGE_TYPE_POSEARRAY,
+ MESSAGE_TYPE_POSEARRAY2,
MESSAGE_TYPE_POSESTAMPED,
+ MESSAGE_TYPE_POSESTAMPED2,
MESSAGE_TYPE_RANGE,
+ MESSAGE_TYPE_RANGE2,
MESSAGE_TYPE_TF2,
+ MESSAGE_TYPE_ROS2_TF2,
MESSAGE_TYPE_WRENCH,
+ MESSAGE_TYPE_WRENCH2,
VIZ_TYPE_IMAGE,
VIZ_TYPE_INTERACTIVEMARKER,
VIZ_TYPE_LASERSCAN,
@@ -52,7 +67,8 @@ class Visualization extends React.PureComponent {
this.resetVisualization = this.resetVisualization.bind(this);
}
- static getNewViz(vizType, ros, resourceName, viewer, options) {
+ static getNewViz(vizType, ros, resourceName, viewer, options, rosVersion) {
+
switch (vizType) {
case VIZ_TYPE_IMAGE_STREAM: {
return new Amphion.ImageStream(resourceName);
@@ -61,10 +77,10 @@ class Visualization extends React.PureComponent {
const imageSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_IMAGE,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_IMAGE : MESSAGE_TYPE_IMAGE2,
queueSize: 1,
queueLength: 0,
- compression: 'cbor',
+ compression: rosVersion == 1 ? 'cbor' : '',
});
return new Amphion.Image(imageSource, options);
}
@@ -82,8 +98,8 @@ class Visualization extends React.PureComponent {
const laserScanSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_LASERSCAN,
- compression: 'cbor',
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_LASERSCAN : MESSAGE_TYPE_LASERSCAN2,
+ compression: rosVersion == 1 ? 'cbor' : '',
});
return new Amphion.LaserScan(laserScanSource, options);
}
@@ -91,8 +107,8 @@ class Visualization extends React.PureComponent {
const mapSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_OCCUPANCYGRID,
- compression: 'cbor',
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_OCCUPANCYGRID : MESSAGE_TYPE_OCCUPANCYGRID2,
+ compression: rosVersion == 1 ? 'cbor' : '',
queueSize: 1,
queueLength: 0,
});
@@ -102,7 +118,7 @@ class Visualization extends React.PureComponent {
const markerSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_MARKER,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_MARKER : MESSAGE_TYPE_MARKER2,
});
return new Amphion.Marker(markerSource, options);
}
@@ -110,7 +126,7 @@ class Visualization extends React.PureComponent {
const markerArraySource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_MARKERARRAY,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_MARKERARRAY: MESSAGE_TYPE_MARKERARRAY2,
queueLength: 0,
queueSize: 1,
});
@@ -120,7 +136,7 @@ class Visualization extends React.PureComponent {
const odometrySource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_ODOMETRY,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_ODOMETRY : MESSAGE_TYPE_ODOMETRY2,
});
return new Amphion.Odometry(odometrySource, options);
}
@@ -128,7 +144,7 @@ class Visualization extends React.PureComponent {
const pathSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_PATH,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_PATH : MESSAGE_TYPE_PATH2,
});
return new Amphion.Path(pathSource, options);
}
@@ -136,7 +152,7 @@ class Visualization extends React.PureComponent {
const pointSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_POINT,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_POINT : MESSAGE_TYPE_POINT2,
});
return new Amphion.Point(pointSource, options);
}
@@ -144,8 +160,8 @@ class Visualization extends React.PureComponent {
const pointcloudSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_POINTCLOUD2,
- compression: 'cbor',
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_POINTCLOUD2 : MESSAGE_TYPE_ROS2POINTCLOUD2,
+ compression: rosVersion == 1 ? 'cbor' : '',
queueSize: 1,
queueLength: 1,
});
@@ -155,7 +171,7 @@ class Visualization extends React.PureComponent {
const poseSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_POSESTAMPED,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_POSESTAMPED : MESSAGE_TYPE_POSESTAMPED2,
});
return new Amphion.Pose(poseSource, options);
}
@@ -171,7 +187,7 @@ class Visualization extends React.PureComponent {
const rangeSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_RANGE,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_RANGE : MESSAGE_TYPE_RANGE2,
});
return new Amphion.Range(rangeSource, options);
}
@@ -181,7 +197,7 @@ class Visualization extends React.PureComponent {
const tfSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_TF2,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_TF2 : MESSAGE_TYPE_ROS2_TF2,
});
return new Amphion.Tf(tfSource, options);
}
@@ -189,13 +205,14 @@ class Visualization extends React.PureComponent {
const wrenchSource = getOrCreateRosTopicDataSource({
ros,
topicName: resourceName,
- messageType: MESSAGE_TYPE_WRENCH,
+ messageType: rosVersion == 1 ? MESSAGE_TYPE_WRENCH : MESSAGE_TYPE_WRENCH2,
});
return new Amphion.Wrench(wrenchSource, options);
}
default:
return null;
}
+
}
componentDidMount() {
@@ -208,11 +225,12 @@ class Visualization extends React.PureComponent {
options,
rosInstance,
rosTopics,
+ rosVersion,
} = this.props;
if (vizType !== prevProps.options.vizType) {
this.resetVisualization();
}
- if (vizType === VIZ_TYPE_TF) {
+ if (vizType === VIZ_TYPE_TF && rosVersion === 1) {
const currentTfTopics = getTfTopics(rosTopics);
const prevTfTopics = getTfTopics(prevProps.rosTopics);
if (
@@ -228,6 +246,22 @@ class Visualization extends React.PureComponent {
);
this.vizInstance.changeSources(sources);
}
+ } else if (vizType === VIZ_TYPE_TF && rosVersion === 2) {
+ const currentTfTopics = getROS2TfTopics(rosTopics);
+ const prevTfTopics = getROS2TfTopics(prevProps.rosTopics);
+ if (
+ _.join(_.sortBy(_.map(currentTfTopics, 'name'))) !==
+ _.join(_.sortBy(_.map(prevTfTopics, 'name')))
+ ) {
+ const sources = map(currentTfTopics, topic =>
+ getOrCreateRosTopicDataSource({
+ ros: rosInstance,
+ topicName: topic.name,
+ messageType: topic.messageType,
+ }),
+ );
+ this.vizInstance.changeSources(sources);
+ }
} else if (topicName !== prevProps.options.topicName) {
if (this.vizInstance.changeTopic) {
// TODO: remove this when all visualizations get ported
@@ -257,6 +291,7 @@ class Visualization extends React.PureComponent {
rosInstance,
viewer,
vizInstances,
+ rosVersion,
} = this.props;
if (this.vizInstance) {
this.vizInstance.destroy();
@@ -269,6 +304,7 @@ class Visualization extends React.PureComponent {
topicName,
viewer,
options,
+ rosVersion,
);
if (!this.vizInstance) {
return;
diff --git a/src/utils/index.js b/src/utils/index.js
index fe3d10a..af71815 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -1,6 +1,7 @@
import { CONSTANTS } from 'amphion';
import _ from 'lodash';
import { TF_MESSAGE_TYPES } from './vizOptions';
+import { ROS2_TF_MESSAGE_TYPES } from './vizOptions';
const { DEFAULT_OPTIONS_SCENE } = CONSTANTS;
@@ -14,6 +15,9 @@ export const ROS_SOCKET_STATUSES = {
export const getTfTopics = rosTopics =>
_.filter(rosTopics, t => _.includes(TF_MESSAGE_TYPES, t.messageType));
+export const getROS2TfTopics = rosTopics =>
+ _.filter(rosTopics, t => _.includes(ROS2_TF_MESSAGE_TYPES, t.messageType));
+
export const stopPropagation = e => e.stopPropagation();
export const downloadFile = (content, filename, options = {}) => {
diff --git a/src/utils/sanitize.js b/src/utils/sanitize.js
index 1329122..f37ff0c 100644
--- a/src/utils/sanitize.js
+++ b/src/utils/sanitize.js
@@ -4,23 +4,40 @@ const replacementMap = {
'sensor_msgs/Image': {
key: 'data',
},
+ 'sensor_msgs/msg/Image': {
+ key: 'data',
+ },
'visualization_msgs/MarkerArray': {
key: 'markers',
validation: it => size(it) <= 1000,
},
+ 'visualization_msgs/msg/MarkerArray': {
+ key: 'markers',
+ validation: it => size(it) <= 1000,
+ },
'nav_msgs/OccupancyGrid': {
key: 'data',
},
+ 'nav_msgs/msg/OccupancyGrid': {
+ key: 'data',
+ },
'nav_msgs/Path': {
key: 'poses',
validation: it => size(it) <= 1000,
},
+ 'nav_msgs/msg/Path': {
+ key: 'poses',
+ validation: it => size(it) <= 1000,
+ },
'sensor_msgs/PointCloud': {
key: 'points',
},
'sensor_msgs/PointCloud2': {
key: 'data',
},
+ 'sensor_msgs/msg/PointCloud2': {
+ key: 'data',
+ },
'geometry_msgs/Polygon': {
key: 'points',
},
@@ -31,6 +48,10 @@ const replacementMap = {
key: 'poses',
validation: it => size(it) <= 1000,
},
+ 'geometry_msgs/msg/PoseArray': {
+ key: 'poses',
+ validation: it => size(it) <= 1000,
+ },
};
export const sanitizeMessage = (topic, message) => {
diff --git a/src/utils/vizOptions.jsx b/src/utils/vizOptions.jsx
index 615ca1d..ab79d8f 100644
--- a/src/utils/vizOptions.jsx
+++ b/src/utils/vizOptions.jsx
@@ -4,46 +4,80 @@ import { iconFillStyle, iconLineStyle } from './common';
const {
MESSAGE_TYPE_IMAGE,
+ MESSAGE_TYPE_IMAGE2,
MESSAGE_TYPE_INTERACTIVEMARKER,
+ MESSAGE_TYPE_INTERACTIVEMARKER2,
MESSAGE_TYPE_INTERACTIVEMARKER_FEEDBACK,
+ MESSAGE_TYPE_INTERACTIVEMARKER_FEEDBACK2,
MESSAGE_TYPE_INTERACTIVEMARKER_UPDATE,
+ MESSAGE_TYPE_INTERACTIVEMARKER_UPDATE2,
MESSAGE_TYPE_LASERSCAN,
+ MESSAGE_TYPE_LASERSCAN2,
MESSAGE_TYPE_MARKER,
+ MESSAGE_TYPE_MARKER2,
MESSAGE_TYPE_MARKERARRAY,
+ MESSAGE_TYPE_MARKERARRAY2,
MESSAGE_TYPE_OCCUPANCYGRID,
+ MESSAGE_TYPE_OCCUPANCYGRID2,
MESSAGE_TYPE_ODOMETRY,
+ MESSAGE_TYPE_ODOMETRY2,
MESSAGE_TYPE_PATH,
+ MESSAGE_TYPE_PATH2,
MESSAGE_TYPE_POINTCLOUD2,
+ MESSAGE_TYPE_ROS2POINTCLOUD2,
MESSAGE_TYPE_POINTSTAMPED,
+ MESSAGE_TYPE_POINTSTAMPED2,
MESSAGE_TYPE_POSEARRAY,
+ MESSAGE_TYPE_POSEARRAY2,
MESSAGE_TYPE_POSESTAMPED,
+ MESSAGE_TYPE_POSESTAMPED2,
MESSAGE_TYPE_RANGE,
+ MESSAGE_TYPE_RANGE2,
MESSAGE_TYPE_ROBOT_MODEL,
MESSAGE_TYPE_TF,
+ MESSAGE_TYPE_ROS2_TF,
MESSAGE_TYPE_TF2,
+ MESSAGE_TYPE_ROS2_TF2,
MESSAGE_TYPE_WRENCHSTAMPED,
+ MESSAGE_TYPE_WRENCHSTAMPED2,
VIZ_TYPE_IMAGE,
+ VIZ_TYPE_IMAGE2,
VIZ_TYPE_INTERACTIVEMARKER,
+ VIZ_TYPE_INTERACTIVEMARKER2,
VIZ_TYPE_LASERSCAN,
+ VIZ_TYPE_LASERSCAN2,
VIZ_TYPE_MAP,
+ VIZ_TYPE_MAP2,
VIZ_TYPE_MARKER,
+ VIZ_TYPE_MARKER2,
VIZ_TYPE_MARKERARRAY,
+ VIZ_TYPE_MARKERARRAY2,
VIZ_TYPE_ODOMETRY,
+ VIZ_TYPE_ODOMETRY2,
VIZ_TYPE_PATH,
+ VIZ_TYPE_PATH2,
VIZ_TYPE_POINT,
+ VIZ_TYPE_POINT2,
VIZ_TYPE_POINTCLOUD,
+ VIZ_TYPE_ROS2POINTCLOUD,
VIZ_TYPE_POSE,
+ VIZ_TYPE_POSE2,
VIZ_TYPE_POSEARRAY,
+ VIZ_TYPE_POSEARRAY2,
VIZ_TYPE_RANGE,
+ VIZ_TYPE_RANGE2,
VIZ_TYPE_ROBOTMODEL,
VIZ_TYPE_TF,
+ VIZ_TYPE_ROS2_TF,
VIZ_TYPE_WRENCH,
+ VIZ_TYPE_WRENCH2,
} = CONSTANTS;
export const VIZ_TYPE_DEPTHCLOUD_STREAM = 'Depthcloud stream';
export const VIZ_TYPE_IMAGE_STREAM = 'Image stream';
export const TF_MESSAGE_TYPES = [MESSAGE_TYPE_TF, MESSAGE_TYPE_TF2];
+export const ROS2_TF_MESSAGE_TYPES = [MESSAGE_TYPE_ROS2_TF, MESSAGE_TYPE_ROS2_TF2];
const DOCS_ROOT_URL = 'https://github.com/rapyuta-robotics/zethus/wiki/';
@@ -563,3 +597,443 @@ export const vizOptions = [
docsLink: `${DOCS_ROOT_URL}Wrench`,
},
];
+
+export const ros2vizOptions = [
+ {
+ type: VIZ_TYPE_IMAGE,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_IMAGE2],
+ description: `Creates a container to visualize the image data represented by a sensor_msgs/msg/Image topic.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Image`,
+ },
+ {
+ type: VIZ_TYPE_IMAGE_STREAM,
+ icon: (
+
+ ),
+ messageTypes: [],
+ description: `Creates a container to visualize the image data as a video stream coming via
+ [web-video-server](http://wiki.ros.org/web_video_server).
+ `,
+ docsLink: `${DOCS_ROOT_URL}ImageStream`,
+ },
+ {
+ type: VIZ_TYPE_LASERSCAN,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_LASERSCAN2],
+ description: `Adds a visualization represented by a sensor_msgs/msg/LaserScan topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Laser-Scan`,
+ },
+ {
+ type: VIZ_TYPE_MAP,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_OCCUPANCYGRID2],
+ description: `Adds a visualization represented by a nav_msgs/msg/OccupancyGrid topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Map`,
+ },
+ {
+ type: VIZ_TYPE_MARKER,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_MARKER2],
+ description: `Adds a visualization represented by a visualization_msgs/msg/Marker or visualization_msgs/msg/MarkerArray topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Marker`,
+ },
+ {
+ type: VIZ_TYPE_MARKERARRAY,
+ icon: markerArrayIcon,
+ messageTypes: [MESSAGE_TYPE_MARKERARRAY2],
+ description: `Adds a visualization represented by a visualization_msgs/msg/Marker or visualization_msgs/msg/MarkerArray topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Marker-Array`,
+ },
+ {
+ type: VIZ_TYPE_INTERACTIVEMARKER,
+ icon: markerArrayIcon,
+ messageTypes: [MESSAGE_TYPE_INTERACTIVEMARKER2],
+ additionalMessageTypes: [
+ MESSAGE_TYPE_INTERACTIVEMARKER_UPDATE2,
+ MESSAGE_TYPE_INTERACTIVEMARKER_FEEDBACK2,
+ ],
+ description: `Adds an interactive visualization represented by a visualization_msgs/msg/InteractiveMarker topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Interactive-Marker`,
+ },
+ {
+ type: VIZ_TYPE_ODOMETRY,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_ODOMETRY2],
+ description: `Adds a visualization represented by a nav_msgs/msg/Odometry topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Odometry`,
+ isDisplay: false,
+ },
+ {
+ type: VIZ_TYPE_PATH,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_PATH2],
+ description: `Adds a visualization represented by a nav_msgs/msg/Path topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Path`,
+ },
+ {
+ type: VIZ_TYPE_POINTCLOUD,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_ROS2POINTCLOUD2],
+ description: `Adds a visualization represented by a sensor_msgs/msg/PointCloud2 topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Point-Cloud-2`,
+ },
+ {
+ type: VIZ_TYPE_POINT,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_POINTSTAMPED2],
+ description: `Adds a visualization represented by a geometry_msgs/msg/PointStamped topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Point`,
+ },
+ {
+ type: VIZ_TYPE_POSE,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_POSESTAMPED2],
+ description: `Adds a visualization represented by a geometry_msgs/msg/PoseStamped topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Pose`,
+ },
+ {
+ type: VIZ_TYPE_POSEARRAY,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_POSEARRAY2],
+ description: `Adds a visualization represented by a geometry_msgs/msg/PoseArray topic to the scene. An array of pose is added to the scene based on the Shape type selected.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Pose-Array`,
+ },
+ {
+ type: VIZ_TYPE_RANGE,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_RANGE2],
+ description: `Adds a visualization represented by a sensor_msgs/msg/Range topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Range`,
+ },
+ {
+ type: VIZ_TYPE_DEPTHCLOUD_STREAM,
+ icon: (
+
+ ),
+ messageTypes: [],
+ description: `Visualizes depthcloud from the
+ [depthcloud_encoder](http://wiki.ros.org/depthcloud_encoder)
+ via [web-video-server](http://wiki.ros.org/web_video_server) stream`,
+ docsLink: `${DOCS_ROOT_URL}Depthcloud`,
+ },
+ {
+ type: VIZ_TYPE_TF,
+ icon: (
+
+ ),
+ messageTypes: ROS2_TF_MESSAGE_TYPES,
+ description: `Adds a visualization represented by a tf/tfMessage and tf2_msgs/msg/TFMessage topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Tf`,
+ },
+ {
+ type: VIZ_TYPE_WRENCH,
+ icon: (
+
+ ),
+ messageTypes: [MESSAGE_TYPE_WRENCHSTAMPED2],
+ description: `Adds a visualization represented by a geometry_msgs/msg/WrenchStamped topic to the scene.
+ `,
+ docsLink: `${DOCS_ROOT_URL}Wrench`,
+ },
+];
\ No newline at end of file