jsk_common¶
jsk_common is common stacks used in JSK lab.
The code is open source, and available on github.
Contents:
Tips & FAQ¶
Speed-up compilation by ccache¶
You can use ccache to speed-up compilation.
sudo apt-get install ccache
sudo ln -sf /usr/bin/ccache /usr/local/bin/gcc
sudo ln -sf /usr/bin/ccache /usr/local/bin/cc
sudo ln -sf /usr/bin/ccache /usr/local/bin/g++
sudo ln -sf /usr/bin/ccache /usr/local/bin/c++
ccache -M 10G
And all of your compilation should be done by ccache.
ROS Packages:
jsk_data¶
A stack for data management tools which are used in JSK lab.
data_collection_server.py¶
What is this?¶
Save topics with synchronization by std_srvs/Trigger
message
as {SAVE_DIR}/{TIMESTAMP}/{FILENAME}
.
Parameters¶
~save_dir
(String, Default:~/.ros
)Save directory.
topics
(Required)This param should look like below:
topics:
- name: /camera/rgb/image_raw
msg_class: sensor_msgs/Image
fname: image.png
savetype: ColorImage
- name: /camera/depth/image_raw
msg_class: sensor_msgs/Image
fname: depth.pkl
savetype: DepthImage
Currently, the supported save type is:
ColorImage
DepthImage
LabelImage
YAML
params
(Optional)This param should look like below:
params:
- key: /in_hand_data_collection_main/object
fname: label.txt
savetype: Text
Currently, the supported save type is:
Text
YAML
method
(String, Default:request
)request
: Save data when service is called.timer
: Save data whenstart
service is called. Finish collecting whenend
service is called.all
: Always save data.
message_filters
: (Bool, Default:False
)Subscribe topics with message_filters.
approximate_sync
: (Bool, Default:False
)Subscribe topic with ApproximateTimeSynchronizer in message_filters.
queue_size
: (Int, Default:10
)Queue size of message_filters.
slop
: (Float, Default0.1
)Slop of ApproximateTimeSynchronizer in message_filters.
timestamp_save_dir
: (Bool, Default:True
)Save data in timestamped dir.
If you set this as
False
, data will be saved as{SAVE_DIR}/{FILENAME}
.
Services¶
~save_request
(std_srvs/Trigger
)Save data when
method
isrequest
.~start_request
(std_srvs/Trigger
)Start saving data when
method
istimer
.~end_request
(std_srvs/Trigger
)Finish saving data when
method
istimer
.
jsk_data command¶
jsk_data
is command line interface to rename, upload and download data, and
this is fully designed for JSK lab members.
(this command communicates with internal server in lab)
There are following sub commands. See jsk_data [sub command] --help
for more detail.
ls
: List data on the server.Usage is
jsk_data ls [OPTIONS] [QUERY]
.get
: Download data from the server.Usage is
jsk_data put [OPTIONS] FILENAME
.put
: Upload data to the server.Usage is
jsk_data put [OPTIONS] FILENAME
. With--public
option, it also uploads to public Google Drive folder, so please care about it when you handle secure data.delete
: Delete file on the server.Usage is
jsk_data delete FILENAME
. It only supports with--public
option. If you want to delete private data, delete it manually by logging in aries via ssh.pubinfo
: Show public data info.Usage is
jsk_data pubinfo [OPTIONS] FILENAME
. Downloading large file withwget
orcurl
from Google Drive can be failed. (see here) Please runsudo pip install gdown
and use it at that time. (Usage: gdown [URL] -O [FILENAME]
)pubopen
: Open Google Drive Folder where public data is uploadedUsage is
jsk_data pubopen
.
Screencast
rosbag_always.py¶
rosbag_always.py can record bag files even if roscore is restarted. It also removes old bag files if recorded bag files exceed specified size.
$ rosrun jsk_data rosbag_always.py -h
usage: rosbag_always.py [-h] --topics TOPICS --size SIZE --save-dir SAVE_DIR
--max-size MAX_SIZE
rosbag record regardless of rosmaster status
optional arguments:
-h, --help show this help message and exit
--topics TOPICS topics to record
--size SIZE size of each rosbag
--save-dir SAVE_DIR directory to store rosbag
--max-size MAX_SIZE maximum size of rosbags in save_dir
jsk_tools¶
This package includes several useful tools and library for ROS software.
test_stdout.py¶
What is this?¶
This node is to test the expected stdout of shell command while running rostest
.
Parameters¶
~command
(str
)The command to run.
~shell
(bool
)Run the command with shell mode or not. See here for more detail.
~stdout
(str
)Expected stdout.
~stdout_line%d
(str
)Expected stdout of the specific line.
Example¶
<test test-name="test_stdout"
pkg="jsk_tools" type="test_stdout.py">
<param name="command" value="timeout 10 rostopic echo /label_image_decomposer/output/header/frame_id -n1 || true" />
<param name="stdout_line0" value="camera" />
<param name="shell" value="true" />
</test>
test_topic_published.py¶
What is this?¶
This node is to test the expected published topics while running rostest
.
Parameters¶
~topic_%d
(str
)The name of topics to test if published.
~timeout_%d
(int
)Timeout for the topic.
~negative_%d
(bool
, Default:false
, Optional)If it’s
True
, it tests if not published.~import
(List[str]
, Default:[]
, Optional)List of Python modules to import and use in
~condition_%d
expression. For commodity rospy and numpy modules are imported by default.~condition_%d
(str
, Default:None
, Optional)Check bool value condition using the given Python expression. The Python expression can access any of the Python builtins plus:
topic
(the topic of the message),m
(the message) andt
(time of message).For example, topic is
std_msgs/String
and if you want to check whether a sentence is ahello
, you can do the following.condition_0: m.data == 'hello'
If you want to check the frame id of the header, you can do the following.
condition_0: m.header.frame_id in ['base', 'base_link']
Note that, use escape sequence when using the following symbols
<(<)
,>(>)
,&(&)
,'(')
and"(")
.condition_0: m.data < 'spbm'
The modules given to
~import
can also be used.condition_0: 'numpy.linalg.norm([m.wrench.force.x, m.wrench.force.y, m.wrench.force.z]) < 10.0'
Example¶
<test test-name="image_view2_topics"
name="image_view2_topics"
pkg="jsk_tools" type="test_topic_published.py">
<rosparam>
topic_0: /camera_0/image/screenrectangle_image
timeout_0: 10
topic_1: /camera_1/image/screenrectangle_image
timeout_1: 10
</rosparam>
</test>
bag_plotter.py¶
bag_plotter is a script to plot from a bag file directly.
usage: bag_plotter.py [-h] [--duration DURATION] [--start-time START_TIME]
config bag
Plot from bag file
positional arguments:
config yaml file to configure plot
bag bag file to plot
optional arguments:
-h, --help show this help message and exit
--duration DURATION, -d DURATION
Duration to plot
--start-time START_TIME, -s START_TIME
Start timestamp to plot
Format of yaml file is like:
global:
layout: <vertical, horizontal or manual, optional and defaults to vertical>
plots:
- title: <title of plot, required>
topic: <list of topics, required>
field: <list of accessor to get value to plot, required>
layout: <2-d layout. if global/layout is manual, this field is required>
legend: <show legend or not, optional and defaults to true>
the length of topic and field should be same. You can use “array format” in field.
a/b/c[0]
means the 1st element of arraya/b/c
.a/b/c[0:3]
means 1st, 2nd and 4rd elements of arraya/b/c
.
Example is like:
global:
layout: vertical
plots:
- title: "rleg temp"
topic: [/motor_states]
field: ["driver_temp[0:6]"]
- title: "lleg temp"
topic: [/motor_states]
field: ["driver_temp[6:12]"]
- title: "leg force (z)"
topic: [/off_lfsensor, /off_rfsensor]
field: [wrench/force/z, wrench/force/z,]
When you want to use manual layout, example should be like follows:
global:
layout: manual
plots:
- title: "rleg temp"
topic: [/motor_states]
field: ["driver_temp[0:6]"]
layout: [0, 0]
- title: "lleg temp"
topic: [/motor_states]
field: ["driver_temp[6:12]"]
layout: [0, 1]
- title: "chest temp"
topic: [/motor_states]
field: ["driver_temp[12:15]"]
layout: [1, 0]
- title: "head temp"
topic: [/motor_states]
field: ["driver_temp[15:17]"]
layout: [1, 1]
config_switch¶
Seamlessly switch user configuration with dotfiles and shell.
Currently supports below dotfiles:
- .bashrc
- .zshrc
- .vimrc
- .vim
- .gitconfig
Usage¶
$ gh_user=wkentaro
$ vim ~/.zshrc.$gh_user
$ vim ~/.vimrc.$gh_user
# set user and shell
$ config_switch wkentaro /usr/local/bin/zsh
Switching user: -> wkentaro
Linked .bashrc -> .bashrc.wkentaro
WARNING: .zshrc is not symlink, so skipping
Logging in as 'wkentaro' with '/usr/local/bin/zsh'
$ ls -la ~/.vimrc
~/.vimrc -> ~/.vimrc.wkentaro
$ cat ~/.ros/jsk_tools/current_config
wkentaro
/usr/local/bin/zsh
$ config_switch
Current user: wkentaro
Current shell: /usr/local/bin/zsh
restart_travis¶
Restart a travis job for specified github repository.
Firstly, add below in your .bashrc
:
# you can get SLACK_TOKEN at https://api.slack.com/web.
export SLACK_TOKEN=xoxp-XXXXXXXX-XXXXXXXX-XXXXXXXX
To restart travis, need the repository slug (ex: jsk-ros-pkg/jsk_common
) and job id (ex: 2019.6
):
$ restart_travis jsk-ros-pkg/jsk_common 2019.6 # usage: restart_travis <repo_slug> <job_id>
sending... 'restart travis jsk-ros-pkg/jsk_common 2019.6' -> #travis
rosbag_record_interactive¶
You can choose topics to record in GUI and record them into a bag file
roscore_regardless.py¶
This script always checks roscore liveness and automatically run and kill a program.
rosrun jsk_tools roscore_regardless.py rostopic echo /foo
Usage¶
$ rosrun jsk_tools roscore_regardless.py -h
usage: roscore_regardless.py [-h] [--respawn] [--timeout TIMEOUT]
[--ping-trials PING_TRIALS]
[--sigint-timeout SIGINT_TIMEOUT]
[--sigterm-timeout SIGTERM_TIMEOUT]
...
positional arguments:
commands
optional arguments:
-h, --help show this help message and exit
--respawn, -r respawn if child process stops
--timeout TIMEOUT Timeout to verify if rosmaster is alive by ping
command in seconds
--ping-trials PING_TRIALS
If ping fails PING-TRIALS times, master is regarded as
dead
--sigint-timeout SIGINT_TIMEOUT
Timeout to escalete from sigint to sigterm to kill
child processes
--sigterm-timeout SIGTERM_TIMEOUT
Timeout to escalete from sigterm to sigkill to kill
child processes
rostopic_host_sanity¶

What is this?¶
Check the network connection between the local PC and each hosts which are inside the ROS topic graph.
In above example image, 111.111.111.111
is non-existent IP,
and it detects the disconnected status.
Usage¶
rosrun jsk_tools rostopic_host_sanity
rosview¶
Usage¶
$ rosview jsk_tools CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(jsk_tools)
...
This is short version of:
export PAGER=less
roscat jsk_tools CMakeLists | $PAGER
Setup environmental variables for ROS¶
You can use commands below after source /opt/ros/$DISTRO/setup.bash
.
rossetip¶
Setup your ROS_IP
and ROS_HOSTNAME
.
$ rossetip
set ROS_IP and ROS_HOSTNAME to 192.168.11.1
$ echo $ROS_IP, $ROS_HOSTNAME
192.168.11.1, 192.168.11.1
rossetlocal¶
Setup your ROS_MASTER_URI
to localhost.
$ rossetlocal
set ROS_MASTER_URI to http://localhost:11311
$ echo $ROS_MASTER_URI
http://localhost:11311
rossetmaster¶
Setup your ROS_MASTER_URI
to robot’s hostname.
# rossetmaster ${hostname} ${ros_port}
# default: hostname=pr1040, ros_port=11311
user@host $ rossetmaster
set ROS_MASTER_URI to http://pr1040:11311
[http://pr1040:11311] user@host $ echo $ROS_MASTER_URI
http://pr1040:11311
rosdefault¶
Setup ROS_MASTER_URI
with default hostname written in ~/.rosdefault
.
$ cat ~/.rosdefault
pr1040
$ rosdefault
set ROS_MASTER_URI to http://pr1040:11311
It is recommended to run rosdefault
in your .bashrc or .zshrc.
rossetdefault¶
Setup your default hostname.
After running this command, you can setup ROS_MASTER_URI
with default hostname by rosdefault
.
(default hostname will be stored at ~/.rosdefault
)
# rossetdefault ${hostname}
# default: hostname=local
$ rossetdefault baxter
set ROS_MASTER_URI to http://baxter:11311
$ bash
$ rosdefault
set ROS_MASTER_URI to http://baxter:11311
topic_delay_monitor.py¶
This script is mostly same as topic_hz_monitor.py but it computes the time lag from sensor input using timestamp in the header.
Example¶
rosrun jsk_tools topic_delay_monitor.py /euclidean_segmentation/output --search-parent
rosrun jsk_tools topic_delay_monitor.py /euclidean_segmentation/output /camera/rgb/points
topic_hz_monitor.py¶
This script is used to find bottleneck of topic nodes flow.
You can specify one topic and use --search-parent
option to collect topics automatically.
(Note Subscribing too many topics makes it difficult to get correct result.)
Example
rosrun jsk_tools topic_hz_monitor.py /euclidean_segmentation/output --search-parent
rosrun jsk_tools topic_hz_monitor.py /euclidean_segmentation/output /camera/rgb/points
sanity_lib.py¶
check Topic is published¶
- If you set
echo
param as True, the topic message will be shown in terminal
Example
from jsk_tools.sanity_lib import *
from std_msgs.msg import String
rospy.init_node("check_sanity", anonymous = True)
checkTopicIsPublished("/chatter", String)
check Node State¶
There is 4 cases
- Node exists, and you want to exist.
- Node exists, and you don’t want to exist
- Node doesn’t exist and you want to exist
- Node doesn’t exist and you don’t want to exist
The second parameter is Needed Parameter.
Example
from jsk_tools.sanity_lib import *
rospy.init_node("check_sanity", anonymous = True)
checkNodeState("/listener", True)
check Params¶
Example
from jsk_tools.sanity_lib import *
rospy.init_node("check_sanity", anonymous = True)
checkROSParam("/param_test", 5)
sanity_diagnostics.py¶
What is this¶
This node publishes essential robot topic and node status to /diagnostics
.
Publishing Topics¶
/diagnostics
(diagnostic_msgs/DiagnosticStatus
)Diagnostics topic
Subscribing Topics¶
- topics specified in the
~sanity_targets
yaml file
Parameter¶
~sanity_targets
(String
, default:/var/lib/robot/sanity_targets.yaml
)Yaml file which contains topics and nodes to be monitored.
Sample yaml format for fetch:
topics: - /audio - /base_scan - /battery_state - /edgetpu_human_pose_estimator/output/image - /edgetpu_object_detector/output/image - /gripper/imu - /head_camera/depth/image_raw - /head_camera/rgb/image_raw - /imu - /insta360/image_raw - /joint_states - /tf nodes: - /amcl - /auto_dock - /gripper_driver - /head_camera/head_camera_nodelet_manager - /move_base - /move_group - /respeaker_node - /robot_driver - /roswww
~duration
(Float
, default:60
)Duration in which sanity is checked.
~pub_duration
(Float
, default:0.3
)Duration in which
/diagnostics
is published.
emacs¶
We strongly recommend to use dot.emacs
for common user.
(load "~/ros/hydro/src/jsk-ros-pkg/jsk_common/jsk_tools/dot-files/dot.emacs")
inferior-lisp-mode¶
inferior-lisp-mode is a classic lisp environment on emacs.
You can invoke roseus by C-c e
.
When you use inferior-lisp-mode, you can immediately evaluate sexpression
without copy-and-paste it by C-x C-e
.
tmux¶
Write following line in your ~/.tmux.conf
source-file ~/ros/hydro/src/jsk-ros-pkg/jsk_common/jsk_tools/dot-files/tmux.conf
jsk_topic_tools¶
This package includes several useful library for ROS software.
constant_rate_throttle_nodelet¶
Description¶
This nodelet provides function like lightweight_throttle_nodelet
, but support accurate publish rate.
The rate of throttled message is configurable by passing ~update rate
parameter on launching this nodelet.
Subscribing Topic¶
~input
(AnyMsg
):Input topic. This topic is throttled to low publish rate.
Publishing Topic¶
~output
(AnyMsg
):Throttled topic. Publish rate of throttled topic is configurable by setting
~update_rate
parameter. If~update_rate
is higher than input topic rate, published message is used from buffer.
Parameter¶
~update_rate
(Double, default:1.0
):Publish rate of throttled message [Hz]. This parameter is updated only on launching this nodelet.
lightweight_throttle_nodelet¶
Description¶
This nodelet provides function like rosrun topic_tools throttle messages
, but subscribes high rate topic only when throttled topic is subscribed by more than equal one subscriber.
The rate of throttled message is configurable by passing ~update rate
parameter on launching this nodelet.
Subscribing Topic¶
~input
(AnyMsg
):Input topic. This topic is throttled to low publish rate.
Publishing Topic¶
~output
(AnyMsg
):Throttled topic. Publish rate of throttled topic is configurable by setting
~update_rate
parameter.
Parameter¶
~update_rate
(Double, default:1.0
):Publish rate of throttled message [Hz]. This parameter is updated only on launching this nodelet.
Passthrough¶
jsk_topic_tools/Passthrough
is a node/nodelet to relay topics only for specified duration. You can use the service call to turn relay on and off. By default, the topic relay is turned off.
Subscribing Topics¶
~input
(AnyMsg
)Incoming topic to be relayed
Publishing Topics¶
~output
(AnyMsg
, same type as~input
)Outgoing topic to publish on
Services¶
~request
(std_srvs/Empty
)Start topic relay
~stop
(std_srvs/Empty
)Stop topic relay
~request_duration
(jsk_topic_tools/PassthroughDuration
)Perform topic relay for a specified duration. Duration 0 means infinite relay.
Parameters¶
~default_duration
(double
, default:10.0
)Duration [s] to relay the topic. Duration 0 means infinite relay.
Usage¶
# Terminal 1
$ roslaunch jsk_topic_tools passthrough_sample.launch
# Terminal 2
$ rostopic pub /passthrough_sample/input std_msgs/String "data: 'hello'" -r10
# Terminal 3
$ rostopic echo /passthrough_sample/input
# Terminal 4
$ rostopic echo /passthrough_sample/output
# Terminal 5
$ rosservice call /passthrough_sample/request
$ rosservice call /passthrough_sample/stop
Relay¶
jsk_topic_tools/Relay
is a node/nodelet that subscribes to ~input
topic and
republishes all incoming data to ~output
topic like topic_tools/Relay
but
has several additional features such as latch and lazy mode.
Subscribing Topics¶
~input
(AnyMsg
)Incoming topic to be relayed
Publishing Topics¶
~output
(AnyMsg
, same type as~input
)Outgoing topic to publish on
Parameters¶
~always_subscribe
(bool
, default:false
)If
true
, it turns off its lazy mode, where the input topic is subscribed only when the output topic is subscribed.~latch
(bool
, default:false
)If
true
, it publishes the output topic in latch mode.
standalone_complexed_nodelet¶
Why needed?¶
nodelet is a good framework to decrease overhead of network communication between ROS nodes.
roscpp has a feature to communicate topics by passing reference pointers if publisher and subscriber are in the same process. By taking advantage of this feature, nodelet can communicate without network overhead each other.
However, nodelet has a problem in system architecture of server-client model. server is a manager and all the actual computation run in this process. client just sends a request to manager to load some classes in the manager process by dynamic loading.
The issue occurs in bond between server and client. If server is killded, client should be killed as well. If a client is killed, the class which is requested by the client loaded in server process should be unloded. nodelet implements this functionality by bond package. server publishes heatbeat topic in fixed rate and client subscribes the topic. If client detects stoll of the topic, client regards manager is dead and kill itself and request unloading to the manager.
This mechanism works well if nodelet system is relatively small but if we run a lot of nodelet, it does not work because communication via ROS topics is not reliable and somtimes it has a lot of latency.
This “unreliable bond mechanism” issue occurs a lot and
standalone_complexed_nodelet
can solve it.
standalone_complexed_nodelet
is a nodelet manager but it does not
require client to send request. standalone_complexed_nodelet
knows
nodelet classes via ros parameter instead of server-client model.
Limitation of standalone_complexed_nodelet
is that it does not support
dynamic loading/unloading of nodelet classes but we know we do not need
the feature from our experiences.
We recommend to use standalone_complexed_nodelet
instead of normal
nodelet
.
APIs¶
standalone_complexed_nodelet
read definition of nodelet classes from
ros parameter. The parameter are ~nodelets
, ~nodelets_0
, ...,
~nodelets_99
. You can extend the suffix numbers by
~candidate_num
parameter. default is 100. These multiple parameters
(~nodelets_0
, nodelets_1
, ...) are useful to include multiple
launch files and run one standalone_complexed_nodelet
.
nodelet definition should follow next format:
nodelets:
- name: <name of nodelet, required>
type: <type of nodelet, required>
if: <the defnition is enabled only if this field is true, optional>
unless: <the defnition is enabled only if this field is false, optional>
remappings: <field to lead remapping definition, optional>
- from: <ros name to be remapped>
to: <ros name to remap to>
- from:
to:
...
- name:
type:
remappings:
...
Examples¶
StealthRelay¶
jsk_topic_tools/StealthRelay
is a node/nodelet that subscribes to ~input
topic and republishes all incoming data to ~output
topic like topic_tools/Relay
but only if ~monitor_topic
topic is subscribed by any other nodes.
When ~input
and ~monitor_topic
topic name point to the same topic, it looks that this node subscribes ~input
topic only when other nodes also subscribes it, which is equivalent to subscribing without incrementing subscription counter.
~monitor_topic
can be set by rosparam and is set to ~input
by default.
Subscribing Topics¶
~input
(AnyMsg
)Incoming topic to be relayed
Publishing Topics¶
~output
(AnyMsg
, same type as~input
)Outgoing topic to publish on
Parameters¶
~use_multithread_callback
(bool
, default:True
)If
true
, initializeNodeHandle
with multi threading.~queue_size
(int
, default:1
)Queue size for subscription of the incoming topic.
~enable_monitor
(bool
, default:True
)If enabled, monitoring feature is enabled, otherwise this nodelet behaves as same as
Relay
nodelet.~monitor_topic
(string
, default:~input
)Topic name to monitor.
~monitor_rate
(double
, default:1.0
)Desired monitoring rate of subscribing messages of
~monitor_topic
.
SynchronizedThrottle Nodelet¶
Description¶
This is a nodelet for throttling like topic_tools/throttle
, but throttled topics are synchronized.
Unlike topic_tools/throttle
, this nodelet accepts parameters to specify input topics and rate for throttling.
Parameters¶
~topics
(String[]
, required)Input topics to be synchronized and throttled.
Warning
This nodelet uses message_filters
for message synchronization.
message_filters
limits a number of input topics to 8 at maximum.
~suffix
(string
, default:throttled
)Suffix for advertised throttled topics.
~update_rate
(Double
, default:1.0
)A rate for throttling messages. If this parameter is
0.0
, no message is published.~use_wall_time
(Bool
, default:false
)Use wall time for throttling timer if enabled.
~use_multithread_callback
(Bool
, default:true
)Use multithreaded node handle if enabled.
~approximate_sync
(Bool
, default:false
)Use approximate synchronization policy if enabled, otherwise messages are published only when they are strictly synchronized.
queue_size
(Int
, default:100
)Size of subscription queue.
boolean_node.py¶
What is this?¶
A node that takes bool values and returns the results of the boolean operation such as or
, and
, not
and xor
.
For example, this node can be used to merge the results of a node that outputs whether the robot is speaking in English or Japanese.
Subscribing Topics¶
Input is prepared for the ~number_of_input
. A number suffix is added to the ~input
.
The suffixes start with 1
. If ~number_of_input
equals 2, subscribing topic names are ~input1
and ~input2
.
In the case of not
operation, only ~input1
is subscribed.
~input{%d}
(AnyMsg
)input value.
Publishing Topics¶
~output/or
(std_msgs/Bool
)The result of the
or
operation.~output/and
(std_msgs/Bool
)The result of the
and
operation.~output/not
(std_msgs/Bool
)The result of the
not
operation.~output/xor
(std_msgs/Bool
)The result of the
xor
operation.
Parameters¶
~import
(List[str]
, Default:[]
, Optional)List of Python modules to import and use in
~input{%d}_condition
expression. For commodity rospy and numpy modules are imported by default.
~input{%d}_condition
(String, Default:m.data
)Returning bool value condition using the given Python expression. The Python expression can access any of the Python builtins plus:
topic
(the topic of the message),m
(the message) andt
(time of message).For example,
~input1
topic isstd_msgs/String
and if you want to check whether a sentence is ahello
, you can do the following.input1_condition: m.data == 'hello'
If you want to check the frame id of the header, you can do the following.
input1_condition: m.header.frame_id in ['base', 'base_link']
The modules given to
~import
can also be used.condition_0: 'numpy.linalg.norm([m.wrench.force.x, m.wrench.force.y, m.wrench.force.z]) < 10.0'
Note that this condition is evaluated each time a topic is published. For example, a condition that checks whether a certain topic has arrived within one second look like this.
input1_condition: "(rospy.Time.now() - t).to_sec() < 1.0"
Use escape sequence when using the following symbols <(
<
), >(>
), &(&
), ‘('
) and “("
) in launch file.~rate
(Int, Default:100
)Publishing rate [Hz].
~number_of_input
(Int, Default:2
)Number of input.
~number_of_input
should be greater than 0.
Example¶
$ roslaunch jsk_topic_tools sample_boolean_node.launch
The outputs of a simple Boolean operation are as follows.
$ rostopic echo /robotsound/is_speaking -n1
data: True
---
$ rostopic echo /robotsound_jp/is_speaking -n1
data: False
---
$ rostopic echo /is_speaking -n1 # or
data: True
---
$ rostopic echo /both_are_speaking -n1 # and
data: False
---
$ rostopic echo /either_one_is_speaking -n1 # xor
data: True
---
In sample_boolean_node.launch
, there is a description that gives input_condition
as follows.
<node name="boolean_node_checking_conditions"
pkg="jsk_topic_tools" type="boolean_node.py"
clear_params="true" >
<remap from="~input1" to="/image1" />
<remap from="~input2" to="/image2" />
<remap from="~input3" to="/chatter" />
<rosparam>
number_of_input: 3
input1_condition: "'base' in m.header.frame_id"
input2_condition: "'base' in m.header.frame_id"
input3_condition: m.data == 'hello'
</rosparam>
</node>
The output results when using the condition are as follows.
$ rostopic echo /image1 -n1
header:
seq: 15029
stamp:
secs: 0
nsecs: 0
frame_id: "base"
height: 0
width: 0
encoding: ''
is_bigendian: 0
step: 0
data: []
---
$ rostopic echo /image2 -n1
header:
seq: 32445
stamp:
secs: 0
nsecs: 0
frame_id: "base_link"
height: 0
width: 0
encoding: ''
is_bigendian: 0
step: 0
data: []
---
$ rostopic echo /chatter -n1
data: "hello"
---
$ rostopic echo /boolean_node_checking_conditions/output/and -n1
data: True
---
$ rostopic echo /boolean_node_checking_conditions/output/not -n1
data: False
---
$ rostopic echo /boolean_node_checking_conditions/output/or -n1
data: True
---
$ rostopic echo /boolean_node_checking_conditions/output/xor -n1
data: True
---
is_synchronized¶

What is this?¶
Tool to check if specified topics are ‘synchronized’ or not.
‘synchronized’ means timestamps completely match with ‘Exact’ synchronization policy (default).
With ‘Approximate’ policy (with --approximate-sync
option), it means the timestamps’
difference falls within ‘slop’ (default 0.1
seconds).
Usage¶
usage: is_synchronized [-h] [-t TIMEOUT] [-q QUEUE_SIZE] [-a] [--slop SLOP]
topics [topics ...]
positional arguments:
topics topics which should be synchronized
optional arguments:
-h, --help show this help message and exit
-t TIMEOUT, --timeout TIMEOUT
Timeout for the test of synchronization
-q QUEUE_SIZE, --queue-size QUEUE_SIZE
Size of queue for the synchronization
-a, --approximate-sync
Flag to use approximate synchronization
--slop SLOP Allowed time delta in approximate synchronization
Example¶
$ rosrun jsk_topic_tools is_synchronized /mask_image/mask /mask_image/output/camera_info
****************** Test Condition ******************
timeout: 5 seconds
queue_size: 100
topics:
- /mask_image/mask [sensor_msgs/Image]
- /mask_image/output/camera_info [sensor_msgs/CameraInfo]
****************************************************
listening these topics for at most 5 seconds in rostime
synchronized in 1.0 seconds
these topics are: 'synchronized'
$ rosrun jsk_topic_tools is_synchronized /mask_image/mask /raw_image_rgb/image_color
****************** Test Condition ******************
timeout: 5 seconds
queue_size: 100
topics:
- /mask_image/mask [sensor_msgs/Image]
- /raw_image_rgb/image_color [sensor_msgs/Image]
****************************************************
listening these topics for at most 5 seconds in rostime
timeout for 5 seconds
these topics are: 'not synchronized'
pose_stamped_publisher.py¶
Publish static geometry_msgs/PoseStamped
.
Usage: pose_stamped_publisher.py x y z roll pitch yaw from_frame rate
rostopic_connection_list¶
Description¶
Tool to check rostopic connection with different hosts.
Usage¶
$ rosrun jsk_topic_tools rostopic_connection_list --help
usage: rostopic_connection_list [-h] [--subscriber-host SUBSCRIBER_HOST]
[--publisher-host PUBLISHER_HOST]
[--publisher-host-sort] [--include-rosout]
[--show-nodes]
optional arguments:
-h, --help show this help message and exit
--subscriber-host SUBSCRIBER_HOST, -s SUBSCRIBER_HOST
Subscriber hostname: (default: all)
--publisher-host PUBLISHER_HOST, -p PUBLISHER_HOST
Publisher hostname: (default: all)
--publisher-host-sort
Sort by publisher host name or not (default: False)
--include-rosout Include /rosout topic or not: (default: False)
--show-nodes Show node names or not: (default: False)
Example¶
Show all connection¶
$ rosrun jsk_topic_tools rostopic_connection_list
Subscriber host: 133.11.216.168
133.11.216.211 -> /pr1040/wan0/transmit -> 133.11.216.168
133.11.216.211 -> /pr1040/wan0/receive -> 133.11.216.168
133.11.216.211 -> /tf -> 133.11.216.168
133.11.216.211 -> /joint_states -> 133.11.216.168
133.11.216.211 -> /tf_static -> 133.11.216.168
pr1040 -> /tf -> 133.11.216.168
pr1040s -> /audio -> 133.11.216.168
pr1040s -> /battery/server2 -> 133.11.216.168
pr1040s -> /kinect_head/rgb/image_rect_color/compressed -> 133.11.216.168
pr1040s -> /tf -> 133.11.216.168
Subscriber host: 133.11.216.211
pr1040 -> /l_arm_controller/follow_joint_trajectory/goal -> 133.11.216.211
pr1040 -> /l_gripper_sensor_controller/event_detector -> 133.11.216.211
pr1040 -> /robotsound_jp/cancel -> 133.11.216.211
...
...
(long lines)
Specify subscriber and publisher host name¶
You can specify subscriber host and publisher host by -s
and -p
.
$ rosrun jsk_topic_tools rostopic_connection_list -s 133.11.216.168 -p 133.11.216.211
Subscriber host: 133.11.216.168
133.11.216.211 -> /pr1040/wan0/transmit -> 133.11.216.168
133.11.216.211 -> /pr1040/wan0/receive -> 133.11.216.168
133.11.216.211 -> /tf -> 133.11.216.168
133.11.216.211 -> /joint_states -> 133.11.216.168
133.11.216.211 -> /tf_static -> 133.11.216.168
Sort by publisher host name¶
You can sort by publisher host name with --publisher-host-sort
.
$ rosrun jsk_topic_tools rostopic_connection_list --publisher-host-sort
Publisher host: 133.11.216.211
133.11.216.211 -> /pr1040/wan0/transmit -> 133.11.216.168
133.11.216.211 -> /pr1040/wan0/receive -> 133.11.216.168
133.11.216.211 -> /tf -> 133.11.216.168
133.11.216.211 -> /joint_states -> 133.11.216.168
133.11.216.211 -> /tf_static -> 133.11.216.168
...
...
(long lines)
Show nodes¶
--show-nodes
shows all node names, too.
$ rosrun jsk_topic_tools rostopic_connection_list --show-nodes
Subscriber host: 133.11.216.168
133.11.216.211 -> /pr1040/wan0/transmit -> 133.11.216.168
Publisher nodes:
/network_status
Subscriber nodes:
/network_states_logger
133.11.216.211 -> /pr1040/wan0/receive -> 133.11.216.168
Publisher nodes:
/network_status
Subscriber nodes:
/network_states_logger
133.11.216.211 -> /tf -> 133.11.216.168
Publisher nodes:
/robot_state_publisher
/robot_pose_ekf
/realtime_loop
Subscriber nodes:
/base_transform_logger
/map_transform_logger
...
...
(long lines)
static_tf_republisher.py¶
What is this?¶
Node to republish /tf_static from a rosbag file
Usage¶
`
rosrun jsk_topic_tools static_tf_republisher.py _file:=<absolute file path to a rosbag file>
`
or
`
rosrun jsk_topic_tools static_tf_republisher.py <file path to a rosbag file>
`
Sample¶
`
roslaunch jsk_topic_tools sample_static_tf_republisher.launch
`
Parameters¶
~file
(String)Absolute file path to a rosbag file. Positional argument is prioritized over this parameters.
~mode_static
(Bool, default: True)If set to True, static transforms in a rosbag file are published to
/tf_static
. Otherwise, they are published to/tf
.~publish_rate
(Float, default: 10)Publishing rate of
/tf
if~mode_static
is set to False.
synchronize_republish.py¶
What is this?¶
Node to republish multiple topics with exact/approximate synchronization.
Subscribing Topics¶
This is assigned by ~topics
rosparam.
Publishing Topics¶
~pub_{0>2}
{0>2}
represents the index of the topic assigned by~topics
rosparam, for example~pub_00
,~pub_11
.
Parameters¶
~topics
(List of string, Required)Topics to synchronize.
~approximate_sync
(Bool, Default:false
)If
true
, approximate synchronization is used for synchoronizing assigned topics.~queue_size
(Integer, Default:100
)Queue length for subscribing topics.
~slop
(Double, Default:0.1
)Allowable misalignment time between the subscribing topics.
tf_to_pose.py¶
What is this?¶
Tool to convert /tf to geometry_msgs::PoseStamped.
Subscribing Topics¶
/tf (tf2_msgs/TFMessage)
Transformation.
Parameters¶
src_frame, dst_frame (String, required)
Frames to compute transform to get the relative pose.
rate (Float, default: 1.)
Publishing rate [Hz].
Example¶
rosrun tf static_tf_transform 0 0 1 0 0 0 base_link head_link 100
rosrun jsk_topic_tools tf_to_pose.py _src_frame:=base_link _dst_frame:=head_link
rostopic echo /tf_to_pose/output
tf_to_transform.py¶
What is this?¶
Specific TransformStamped publisher. You specify parent_frame_id and child_frame_id, and this node publish geometry_msgs::TransformStamped. You can define –duration (default=0.1).
Difference from tf_to_pose.py¶
TransformStamped msg carries parent_frame_id and child_frame_id. Otherwise, PoseStamped msg only carries parent_frame_id.
Usage¶
Command Line¶
$ rosrun jsk_topic_tools tf_to_transform.py -h
usage: tf_to_transform.py [-h] [--duration DURATION]
[parent_frame_id] [child_frame_id]
positional arguments:
parent_frame_id parent frame id
child_frame_id child frame id
optional arguments:
-h, --help show this help message and exit
--duration DURATION, -d DURATION
Duration [s]: default=1.0
Param¶
~parent_frame_id (String)
Parent frame id
~child_frame_id (String)
Child frame id
~duration (Float, default=1.0)
Duration
Example¶
$ rosrun jsk_topic_tools transform_publisher.py /base /right_gripper_vacuum_pad_base -d 2.0
$ rostopic echo /transform_publisher/output
header:
seq: 1
stamp:
secs: 1479108976
nsecs: 799304962
frame_id: /base
child_frame_id: /right_gripper_vacuum_pad_base
transform:
translation:
x: 0.614187621295
y: -0.70974742075
z: 0.332638443526
rotation:
x: 0.0231768305754
y: 0.764117456951
z: -0.0773262537191
w: 0.640006247621
---
header:
seq: 2
stamp:
secs: 1479108978
nsecs: 799195051
frame_id: /base
child_frame_id: /right_gripper_vacuum_pad_base
transform:
translation:
x: 0.61417389684
y: -0.709704671921
z: 0.332801975644
rotation:
x: 0.0237198976862
y: 0.764003459868
z: -0.0768511001916
w: 0.640179653038
---
transform_wrench.py¶

What is this?¶
Convert WrenchStamped
topic with respect to ~target_frame_id
.
Subscribing Topics¶
~input
(geometry_msgs/WrenchStamped
)Input wrench stamped message.
Publishing Topics¶
~output
Transformed
WrenchStamped
topic with respect to~target_frame_id
.
Parameters¶
~target_frame_id
(String
, required)Reference frame of wrench.
~duration_timeout
(Float
, default:0.05
)Duration of timeout for lookup transform.
Example¶
roslaunch jsk_topic_tools sample_transform_wrench.launch launch_robot_model:=true gui:=true
ConnectionBasedNodelet (C++)¶
WARNING
This base-class is being deprecated and replaced by nodelet_topic_tools::NodeletLazy
in
nodelet_topic_tools.
Description¶
This class is a base-class which can start subscribing topics if published topics are subscribed by the other node. This is abstruct class.
Note¶
Each subclass of this class must call onInitPostProcess
in the last line onInit
.
Parameter¶
~use_multithread_callback
(Bool, default:true
):
If true, node use getMTNodeHandle and getMTPrivateNodeHandle for getting NodeHandle. MTNodeHandle generates threads for processing its callback function.
If false, node use getNodeHandle and getPrivateNodeHandle. This is default behavior of normal node (not nodelet).
Please see nodelet
~always_subscribe
(Bool, default:false
):Subscribes topics even if there is no subscribers of advertised topics if
true
.~verbose_connection
(Bool, default:false
):Show verbose log message on topic connection
~no_warn_on_init_post_process
(Bool, default:false
):Never warn if
onInitPostProcess
method is not yet called.
DiagnosticNodelet (C++)¶
Description¶
This class is a subclass of ConnectionBasedNodelet
.
Instances of this class can publish diagnostics messages.
This is an abstruct class.
Note¶
Each subclass of this class is required to call vital_checker_->poke()
on all callback functions so that this class can check the health of the functionality of the nodelet.
Publishing Topic¶
~diagnostics
(diagnostic_msgs::DiagnosticArray
):Diagnostic messages
Parameter¶
~vital_rate
(Double, default:1.0
):Rate to determine if the nodelet is in health. If the rate that the callback functions is below this parameter, error messages are displayed on diagnostics.
/diagnostic_nodelet/use_warn
or~use_warn
(Bool, default:False
):If this parameter is enabled, diagnostic messages on failure is displayed on
WARN
level instead ofERROR
level./diagnostic_nodelet/use_warn
affects every nodelets that inherits this class, but it still can be overriden for each nodelet by setting~use_warn
parameter.
HzMeasureNodelet (C++)¶
Description¶
This node publishes hz
of target topic and diagnostics
.
User can specify ~warning_hz
param.
If target hz
is smaller than ~warning_hz
, this node outputs diagnostics
at WARN
level (if ~use_warn
is True
) or ERROR
level.
Subscribing Topic¶
~input
(AnyMsg
):Target topic.
Publishing Topic¶
~output
(std_msgs::Float32
):Target topic’s
hz
.~diagnostics
(diagnostic_msgs::DiagnosticArray
):Diagnostic messages.
Parameter¶
~measure_time
(Double
, default:1.0
):Calculate
hz
from the number of topics received in time in~measure_time
.~message_num
(Int
, default:-1
):Calculate
hz
from the arrival times of~message_num
topics. Note that if this value is less than 0 or not set,~measure_time
will be used.~warning_hz
(Double
, default:-1
):If target
hz
is smaller than~warning_hz
, this node outputsdiagnostics
atWARN
level (if~use_warn
isTrue
) orERROR
level.~use_warn
(Bool, default:False
):If this parameter is enabled, diagnostic messages on failure is displayed on
WARN
level instead ofERROR
level.
ConnectionBasedTransport (Python)¶
Description¶
This class is a base-class which can start subscribing topics if published topics are subscribed by the other node. This is abstruct class.
Users inherit this class and define publisher by calling the self.advertise
function.
The return value of self.advertise
is the Publisher
class. User should execute publish in callback
function.
For Expert¶
When publish
is executed, it is judged that this node is running normally, and published diagnostics
becomes OK
level.
However, if the publisher is subscribed but the publish
function is not called, the node is not working properly and diagnostics
will be at the ERROR
level.
Some users may executepublish
at any time (eg rospy.Timer
).
In that case, by executing the self.poke
function in the callback function, the state of diagnostics
will be OK
level without executing publish.
Parameter¶
~always_subscribe
(Bool, default:false
):Subscribes topics even if there is no subscribers of advertised topics if
true
.~enable_vital_check
(Bool, default:true
):If this value is
true
,/diagnostics
will be published and the status of whether the topic has been published will be output from this node.~vital_rate
(Double, default:1.0
):Rate to determine if the nodelet is in health. If the rate that the callback functions is below this parameter, error messages are displayed on diagnostics. This value is valid only if
~enable_vital_check
istrue
./diagnostic_nodelet/use_warn
or~use_warn
(Bool, default:False
):If this parameter is enabled, diagnostic messages on failure is displayed on
WARN
level instead ofERROR
level./diagnostic_nodelet/use_warn
affects every nodelets that inherits this class, but it still can be overriden for each nodelet by setting~use_warn
parameter.
Publishing Topic¶
/diagnostics
(diagnostic_msgs.DiagnosticArray
):Diagnostic messages. Required if
~enable_vital_check:=true
How does it behaves?¶
# terminal 1:
$ roslaunch jsk_topic_tools test_connection_based_transport.test
# terminal 2:
$ rostopic echo /simple_image_transport/output
# terminal 3:
$ rostopic info /simple_image_transport/output
Type: sensor_msgs/Image
Publishers:
* /simple_image_transport (http://133.11.216.160:42481/)
Subscribers:
* /rostopic_137980_1496651422064 (http://133.11.216.160:38414/)
# terminal 2:
$ ^C # cancel
# terminal 3:
$ rostopic info /simple_image_transport/output
Type: sensor_msgs/Image
Publishers:
* /simple_image_transport (http://133.11.216.160:42481/)
Subscribers: None
How to use it?¶
See jsk_topic_tool/sample/simple_image_transport.py
to how to use it.
import rospy
from sensor_msgs.msg import Image
from jsk_topic_tools import ConnectionBasedTransport
class SimpleImageTransport(ConnectionBasedTransport):
def __init__(self):
super(SimpleImageTransport, self).__init__()
self._pub = self.advertise('~output', Image, queue_size=1)
def subscribe(self):
self.sub_img = rospy.Subscriber('~input', Image, self._process)
def unsubscribe(self):
self.sub_img.unregister()
def _process(self, img_msg):
self._pub.publish(img_msg)
if __name__ == '__main__':
rospy.init_node('sample_image_transport')
img_trans = SimpleImageTransport()
rospy.spin()
Checking the node status by diagnostics¶
You can check diagnostics by setting ~enable_vital_check
to true
.
# terminal 1:
$ roslaunch jsk_topic_tools sample_connection_based_transport.launch
# terminal 2:
$ rostopic list
/diagnostics
/diagnostics_agg
/diagnostics_toplevel_state
/input
/input_dummy
/input_image
/mux/selected
/rosout
/rosout_agg
/simple_image_transport/output
# terminal 3:
$ rosrun rqt_robot_monitor rqt_robot_monitor
There is no one to subscribe to /simple_image_transport/output
, so diagnostics is OK.
# terminal 4:
rostopic echo /simple_image_transport/output
If you subscribe to /simple_image_transport/output
,
it will change to the diagnostics message /simple_image_transport is running
.
# terminal 5:
rosservice call /mux/select input_dummy
When changing input for simple_image_transport
by mux,
the error message will change to /simple_image_transport is not running
.
You can check if the node is running correctly like these.
jsk_network_tools¶
This ROS package includes JSK network tools.
network_status.py¶
Publish network status
$ rostopic list
/ecublens/docker0/receive
/ecublens/docker0/receive_kbps
/ecublens/docker0/receive_mbps
/ecublens/docker0/transmit
/ecublens/docker0/transmit_kbps
/ecublens/docker0/transmit_mbps
/ecublens/eno1/receive
/ecublens/eno1/receive_kbps
/ecublens/eno1/receive_mbps
/ecublens/eno1/transmit
/ecublens/eno1/transmit_kbps
/ecublens/eno1/transmit_mbps
/ecublens/eno2/receive
/ecublens/eno2/receive_kbps
/ecublens/eno2/receive_mbps
/ecublens/eno2/transmit
/ecublens/eno2/transmit_kbps
/ecublens/eno2/transmit_mbps
/ecublens/lo/receive
/ecublens/lo/receive_kbps
/ecublens/lo/receive_mbps
/ecublens/lo/transmit
/ecublens/lo/transmit_kbps
/ecublens/lo/transmit_mbps
/ecublens/nonlocal/receive
/ecublens/nonlocal/receive_kbps
/ecublens/nonlocal/receive_mbps
/ecublens/nonlocal/transmit
/ecublens/nonlocal/transmit_kbps
/ecublens/nonlocal/transmit_mbps
Publishing Topics¶
/<host name>/<interface name>/receive
Amount of receiving data by the interface in bps
/<host name>/<interface name>/receive_kbps
Amount of receiving data by the interface in Kbps
/<host name>/<interface name>/receive_mbps
Amount of receiving data by the interface in Mbps
/<host name>/<interface name>/transmit
Amount of transmitting data by the interface in bps
/<host name>/<interface name>/transmit_kbps
Amount of transmitting data by the interface in Kbps
/<host name>/<interface name>/transmit_mbps
Amount of transmitting data by the interface in Mbps
/<host name>/nonlocal/receive
Amount of receiving data by the non-local interfaces in bps
/<host name>/nonlocal/receive_kbps
Amount of receiving data by the non-local interfaces in Kbps
/<host name>/nonlocal/receive_mbps
Amount of receiving data by the non-local interfaces in Mbps
/<host name>/nonlocal/transmit
Amount of transmitting data by the non-local interfaces in bps
/<host name>/nonlocal/transmit_kbps
Amount of transmitting data by the non-local interfaces in Kbps
/<host name>/nonlocal/transmit_mbps
Amount of transmitting data by the non-local interfaces in Mbps
Parameters¶
~hz
(float
, default:10
)Publish frequency
~skip_interfaces
(List of string
, default:None
)List of skipping interface names
Usage¶
rosrun jsk_network_tools network_status.py