Skip to content

Commit 9851f78

Browse files
authored
Merge pull request OpenNI#80 from plusone-robotics/add_roswtf/indigo_devel
Add a simple roswtf plugin that checks the number of connected devices
2 parents 93794e4 + 506b0d0 commit 9851f78

File tree

9 files changed

+225
-6
lines changed

9 files changed

+225
-6
lines changed

.travis.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,21 @@ env:
1818
- ROS_DISTRO="indigo" ROS_REPO=ros
1919
- ROS_DISTRO="indigo" ROS_REPO=ros-shadow-fixed
2020
- ROS_DISTRO="indigo" PRERELEASE=true
21-
- ROS_DISTRO="jade" ROS_REPO=ros
2221
- ROS_DISTRO="kinetic" ROS_REPO=ros ABICHECK_URL='github:ros-drivers/openni2_camera#indigo-devel'
2322
- ROS_DISTRO="kinetic" ROS_REPO=ros-shadow-fixed ABICHECK_URL='github:ros-drivers/openni2_camera#indigo-devel'
2423
- ROS_DISTRO="kinetic" PRERELEASE=true
25-
- ROS_DISTRO="lunar" ROS_REPO=ros ABICHECK_URL='github:ros-drivers/openni2_camera#indigo-devel'
26-
- ROS_DISTRO="lunar" ROS_REPO=ros-shadow-fixed ABICHECK_URL='github:ros-drivers/openni2_camera#indigo-devel'
24+
- ROS_DISTRO="lunar" ROS_REPO=ros
25+
- ROS_DISTRO="lunar" ROS_REPO=ros-shadow-fixed
2726
- ROS_DISTRO="lunar" PRERELEASE=true
27+
- ROS_DISTRO="melodic" ROS_REPO=ros ABICHECK_URL='github:ros-drivers/openni2_camera#indigo-devel'
28+
- ROS_DISTRO="melodic" ROS_REPO=ros-shadow-fixed ABICHECK_URL='github:ros-drivers/openni2_camera#indigo-devel'
29+
- ROS_DISTRO="melodic" PRERELEASE=true
2830
matrix:
2931
allow_failures:
30-
- env: ROS_DISTRO="indigo" PRERELEASE=true # Run docker-based ROS prerelease test http://wiki.ros.org/bloom/Tutorials/PrereleaseTest Because we might not want to run prerelease test for all PRs, it's omitted from pass-fail criteria.
3132
- env: ROS_DISTRO="indigo" PRERELEASE=true
32-
- env: ROS_DISTRO="jade" ROS_REPO=ros
3333
- env: ROS_DISTRO="kinetic" PRERELEASE=true
3434
- env: ROS_DISTRO="lunar" PRERELEASE=true
35+
- env: ROS_DISTRO="melodic" PRERELEASE=true
3536
install:
3637
- git clone https://github.com/ros-industrial/industrial_ci.git .ci_config
3738
script:

openni2_launch/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.3)
22
project(openni2_launch)
33

44
find_package(catkin)
5-
5+
catkin_python_setup()
66
catkin_package()
77

88
install(DIRECTORY launch

openni2_launch/doc/index.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,78 @@ E.g. When 2 openni2-based cameras are connected and `lsusb -t` returns the follo
4545

4646
TBD
4747

48+
Support tools
49+
==========
50+
51+
Check the number of devices plugged in by `roswtf plugin <http://wiki.ros.org/roswtf/Plugins>`_.
52+
Change the number of devices to expect by setting the number in ROS parameter "``openni2_num_sensors_expected``".
53+
54+
Example: ::
55+
56+
$ lsusb
57+
:
58+
Bus 005 Device 002: ID 1d27:0601 ASUS
59+
Bus 003 Device 002: ID 1d27:0601 ASUS
60+
61+
term-1$ roscore
62+
63+
term-2$ roswtf
64+
65+
Loaded plugin tf.tfwtf
66+
Loaded plugin openni2_launch.wtf_plugin
67+
No package or stack in context
68+
================================================================================
69+
Static checks summary:
70+
71+
Found 1 error(s).
72+
73+
ERROR Different number of openni2 sensors found.
74+
* 2 openni2 sensors found (expected: 1).
75+
76+
================================================================================
77+
Beginning tests of your ROS graph. These may take awhile...
78+
analyzing graph...
79+
... done analyzing graph
80+
running graph rules...
81+
... done running graph rules
82+
83+
Online checks summary:
84+
85+
Found 1 warning(s).
86+
Warnings are things that may be just fine, but are sometimes at fault
87+
88+
WARNING The following node subscriptions are unconnected:
89+
* /rosout:
90+
* /rosout
91+
92+
After setting `openni2_num_sensors_expected` param with 2, no error occurs. ::
93+
94+
term-2$ rosparam set openni2_num_sensors_expected 2
95+
96+
$ roswtf
97+
Loaded plugin tf.tfwtf
98+
Loaded plugin openni2_launch.wtf_plugin
99+
No package or stack in context
100+
================================================================================
101+
Static checks summary:
102+
103+
No errors or warnings
104+
================================================================================
105+
Beginning tests of your ROS graph. These may take awhile...
106+
analyzing graph...
107+
... done analyzing graph
108+
running graph rules...
109+
... done running graph rules
110+
111+
Online checks summary:
112+
113+
Found 1 warning(s).
114+
Warnings are things that may be just fine, but are sometimes at fault
115+
116+
WARNING The following node subscriptions are unconnected:
117+
* /rosout:
118+
* /rosout
119+
48120
Indices and tables
49121
==================
50122

openni2_launch/launch/includes/device.launch.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
<!-- Driver parameters -->
88
<arg name="device_id" />
9+
<arg name="id_manufacturer" />
10+
<arg name="id_product" />
911
<arg name="rgb_frame_id" />
1012
<arg name="depth_frame_id" />
1113
<arg name="rgb_camera_info_url" />
@@ -34,6 +36,8 @@
3436
args="load openni2_camera/OpenNI2DriverNodelet $(arg manager) $(arg bond)"
3537
respawn="$(arg respawn)">
3638
<param name="device_id" type="str" value="$(arg device_id)" />
39+
<param name="id_manufacturer" type="str" value="$(arg id_manufacturer)" />
40+
<param name="id_product" type="str" value="$(arg id_product)" />
3741
<param name="rgb_camera_info_url" value="$(arg rgb_camera_info_url)" />
3842
<param name="depth_camera_info_url" value="$(arg depth_camera_info_url)" />
3943
<param name="rgb_frame_id" value="$(arg rgb_frame_id)" />

openni2_launch/launch/openni2.launch

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
'#1' : the first device found
1313
'2@X' : the Xth device on USB bus 2"/>
1414

15+
<arg name="id_manufacturer" default="1d27"
16+
doc="Vendor ID of the sensor (maintained at http://www.linux-usb.org/usb-ids.html). Default: ASUS."/>
17+
<arg name="id_product" default="0601"
18+
doc="Product ID of the sensor. Default: Xtion."/>
19+
1520
<arg name="rgb_camera_info_url" default=""
1621
doc="By default, calibrations are stored to file://${ROS_HOME}/camera_info/${NAME}.yaml,
1722
where ${NAME} is of the form '[rgb|depth]_[serial#]', e.g. 'depth_B00367707227042B'.
@@ -72,6 +77,8 @@
7277
file="$(find openni2_launch)/launch/includes/device.launch.xml">
7378
<arg name="manager" value="$(arg manager)" />
7479
<arg name="device_id" value="$(arg device_id)" />
80+
<arg name="id_manufacturer" value="$(arg id_manufacturer)" />
81+
<arg name="id_product" value="$(arg id_product)" />
7582
<arg name="rgb_frame_id" value="$(arg rgb_frame_id)" />
7683
<arg name="depth_frame_id" value="$(arg depth_frame_id)" />
7784
<arg name="rgb_camera_info_url" value="$(arg rgb_camera_info_url)" />

openni2_launch/package.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
<run_depend>image_proc</run_depend>
1818
<run_depend>nodelet</run_depend>
1919
<run_depend>openni2_camera</run_depend>
20+
<run_depend>rospy</run_depend>
21+
<run_depend>roswtf</run_depend>
2022
<run_depend>tf</run_depend>
2123
<export>
2224
<rosdoc config="rosdoc.yaml"/>
25+
<roswtf plugin="openni2_launch.wtf_plugin" />
2326
</export>
2427
</package>

openni2_launch/setup.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD
2+
3+
from distutils.core import setup
4+
from catkin_pkg.python_setup import generate_distutils_setup
5+
6+
# fetch values from package.xml
7+
setup_args = generate_distutils_setup(
8+
packages=["openni2_launch"],
9+
package_dir={'': 'src'})
10+
11+
setup(**setup_args)

openni2_launch/src/openni2_launch/__init__.py

Whitespace-only changes.
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Software License Agreement (BSD License)
2+
#
3+
# Copyright (c) 2018, PlusOne Robotics, Inc. All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without
6+
# modification, are permitted provided that the following conditions
7+
# are met:
8+
#
9+
# * Redistributions of source code must retain the above copyright
10+
# notice, this list of conditions and the following disclaimer.
11+
# * Redistributions in binary form must reproduce the above
12+
# copyright notice, this list of conditions and the following
13+
# disclaimer in the documentation and/or other materials provided
14+
# with the distribution.
15+
# * Neither the name of Plus One Robotics, Inc. nor the names of its
16+
# contributors may be used to endorse or promote products derived
17+
# from this software without specific prior written permission.
18+
#
19+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22+
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23+
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28+
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29+
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30+
# POSSIBILITY OF SUCH DAMAGE.
31+
32+
from __future__ import print_function
33+
import logging
34+
import re
35+
import subprocess
36+
37+
import rospy
38+
from roswtf.rules import warning_rule, error_rule
39+
40+
41+
def _device_notfound_subproc(id_manufacturer, id_product):
42+
"""
43+
@rtype: [dict]
44+
@return: Example:
45+
46+
[{'device': '/dev/bus/usb/002/004', 'tag': 'Lenovo ', 'id': '17ef:305a'},
47+
{'device': '/dev/bus/usb/002/001', 'tag': 'Linux Foundation 3.0 root hub', 'id': '1d6b:0003'},
48+
{'device': '/dev/bus/usb/001/006', 'tag': 'Validity Sensors, Inc. ', 'id': '138a:0090'},,,]
49+
50+
@note: This method depends on Linux command (via subprocess), which makes
51+
this command platform-dependent. Ubuntu Xenial onward, a Python module
52+
that encapsulate platform operation becomes available so this method
53+
can be wiped out. See https://github.com/ros-drivers/openni2_camera/pull/80#discussion_r193295442
54+
"""
55+
device_re = re.compile("Bus\s+(?P<bus>\d+)\s+Device\s+(?P<device>\d+).+ID\s(?P<id>\w+:\w+)\s(?P<tag>.+)$", re.I)
56+
df = subprocess.check_output("lsusb")
57+
devices = []
58+
for i in df.split('\n'):
59+
if i:
60+
info = device_re.match(i)
61+
if info:
62+
dinfo = info.groupdict()
63+
logging.debug("dinfo: {}, dinfo.id: {}".format(dinfo, dinfo["id"]))
64+
if dinfo["id"] == "{}:{}".format(id_manufacturer, id_product):
65+
dinfo['device'] = "/dev/bus/usb/{}/{}".format(dinfo.pop('bus'), dinfo.pop('device'))
66+
devices.append(dinfo)
67+
logging.info("#devices: {}\ndevices: {}".format(len(devices), devices))
68+
return devices
69+
70+
71+
def sensor_notfound(ctx):
72+
"""
73+
@summary: Check if expected number of sensors are found.
74+
Expected number of sensors can be set by
75+
ROS Parameter 'openni2_num_sensors_expected'.
76+
@note: Technically this can be static check, but because of the
77+
need for connecting to ROS Param server, this needs
78+
to be online check.
79+
"""
80+
errors = []
81+
num_sensors_expected = rospy.get_param("openni2_num_sensors_expected", 1)
82+
# The set of manufacture id and prod id. Default: Asus Xtion.
83+
id_manufacturer = rospy.get_param("id_manufacturer", "1d27")
84+
id_product = rospy.get_param("id_product", "0601")
85+
devices = _device_notfound_subproc(
86+
id_manufacturer=id_manufacturer, id_product=id_product)
87+
num_sensors = len(devices)
88+
if num_sensors != num_sensors_expected:
89+
errors.append("{} openni2 sensors found (expected: {}).".format(
90+
num_sensors, num_sensors_expected))
91+
return errors
92+
93+
94+
# app_warnings and app_errors declare the rules that we actually check
95+
app_warnings_online = [
96+
]
97+
98+
app_warnings_static = [
99+
]
100+
101+
app_errors_online = [
102+
(sensor_notfound, "Different number of openni2 sensors found."),
103+
]
104+
105+
app_errors_static = [
106+
]
107+
108+
109+
# roswtf entry point for online checks
110+
def roswtf_plugin_online(ctx):
111+
for r in app_warnings_online:
112+
warning_rule(r, r[0](ctx), ctx)
113+
for r in app_errors_online:
114+
error_rule(r, r[0](ctx), ctx)
115+
116+
117+
def roswtf_plugin_static(ctx):
118+
for r in app_warnings_static:
119+
warning_rule(r, r[0](ctx), ctx)
120+
for r in app_errors_static:
121+
error_rule(r, r[0](ctx), ctx)

0 commit comments

Comments
 (0)