This file is indexed.

/usr/lib/topic_tools/relay_field is in topic-tools 1.11.16-3.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Allows to take a topic or one of its fields and output it on another topic
or fields.

The operations are done on the message, which is taken in the variable 'm'.

Example:
    $ rosrun topic_tools relay_field /chatter /header std_msgs/Header
      "seq: 0
       stamp:
         secs: 0
         nsecs: 0
         frame_id: m.data"
"""

from __future__ import print_function
import argparse
import sys
import copy

import yaml

import roslib
import rospy
import rostopic
import genpy
import std_msgs

__author__ = 'www.kentaro.wada@gmail.com (Kentaro Wada)'


def _eval_in_dict_impl(dict_, globals_, locals_):
    res = copy.deepcopy(dict_)
    for k, v in res.items():
        type_ = type(v)
        if type_ is dict:
            res[k] = _eval_in_dict_impl(v, globals_, locals_)
        elif (type_ is str) or (type_ is unicode):
            try:
                res[k] = eval(v, globals_, locals_)
            except NameError:
                pass
            except SyntaxError:
                pass
    return res


class RelayField(object):
    def __init__(self):
        parser = argparse.ArgumentParser(
            formatter_class=argparse.RawTextHelpFormatter,
            description=(
                'Allows to relay field data from one topic to another.\n\n'
                'Usage:\n\trosrun topic_tools relay_field '
                '<input> <output topic> <output type> '
                '<expression on m>\n\n'
                'Example:\n\trosrun topic_tools relay_field '
                '/chatter /header std_msgs/Header\n\t'
                '"seq: 0\n\t stamp:\n\t   secs: 0\n\t   nsecs: 0\n\t   '
                'frame_id: m.data"\n\n'
                )
            )
        parser.add_argument('input', help='Input topic or topic field.')
        parser.add_argument('output_topic', help='Output topic.')
        parser.add_argument('output_type', help='Output topic type.')
        parser.add_argument(
            'expression',
            help='Python expression to apply on the input message \'m\'.'
            )

        args = parser.parse_args()

        self.expression = args.expression

        input_class, input_topic, self.input_fn = rostopic.get_topic_class(
            args.input)
        if input_topic is None:
            print('ERROR: Wrong input topic (or topic field): %s' % args.input,
                  file=sys.stderr)
            sys.exit(1)

        self.output_class = roslib.message.get_message_class(args.output_type)

        self.sub = rospy.Subscriber(input_topic, input_class, self.callback)
        self.pub = rospy.Publisher(args.output_topic, self.output_class,
                                   queue_size=1)

    def callback(self, m):
        if self.input_fn is not None:
            m = self.input_fn(m)

        msg_generation = yaml.load(self.expression)
        pub_args = _eval_in_dict_impl(msg_generation, None, {'m': m})

        now = rospy.get_rostime()
        keys = {'now': now, 'auto': std_msgs.msg.Header(stamp=now)}
        msg = self.output_class()
        genpy.message.fill_message_args(msg, [pub_args], keys=keys)
        self.pub.publish(msg)


if __name__ == '__main__':
    rospy.init_node('relay_field', anonymous=True)
    app = RelayField()
    rospy.spin()