<<MenuNavi(rosh/Overview)>>

= Topics =

<<TOC(3)>>

== topics ==

The `topics` object provides you access to all active ROS [[Topics|topics]] in your system. This object follows the general ROSH convention for converting ROS [[Names|names]], i.e. to access the topic `/foo/bar/laser`, you would use:
 {{{
topics.foo.bar.laser
}}}

You can also use mapping-style lookups on `topics`, which is useful if you are dealing with string names:
 {{{
topics['/foo/bar'].laser
}}}


== TopicNS Instances ==

`info(topics.foo)`
  Returns `TopicInfo` object. Equivalent to `rostopic info foo`.

`str(topics.foo)`
  Get the ROS message definition for the topic. 

`rostype(topics.foo)`
  Return the message class for the topic.

`rostype(obj, type)`
  Set the type of an object, e.g. the message class for a topic. You may need to use this if publishing to a topic where the type cannot be inferred:{{{
In [1]: rostype(topics.echo, msg.std_msgs.String)
In [2]: topics.echo('hello world')
}}}


`topics.foo(msg)`
  Publish `msg` to topic. NOTE: by default, all calls to publish are ''latching''.

`topics.foo(key2=value2, key2=value2)`
  Construct a new message using keyword arguments and publish to topic. Example: {{{
topics.rosout(msg="hello world")
}}}

`topics.foo(arg1, arg2...argN)`
  Construct a new message using positional arguments and publish to topic. Example: {{{
topics.rosout(autoheader(), 2, 'my_node', 'hello world', 'file.txt', 'function', 42, ['/foo'])
}}}

`topics.foo[0]`
  ''Non-blocking'': return the last received message on this topic, or `None` if no message has been received. This registers a new subscription to the topic if one does not already exist.

`topics.foo[1]`
  ''Blocking'': return the next message on this topic. This registers a new subscription to the topic if one does not already exists.

`topics.foo[N]`
  ''Blocking'': return the next message on this topic. This registers a new subscription to the topic if one does not already exists.

`topics.foo[:]`
  Returns an infinite iterator over all future messages on this topic.

`topics.foo[M:N]`
  Returns an iterator that will return the `M`th to `N`th message on this topic.

`topics.foo[M:N:step]`
  Returns an iterator that will return the `M`th to `N`th message on this topic, incremented by `step`.

`topics.foo = topics.bar`
  Create a new mux that pipes output from `bar` to `foo`.

== TopicInfo instances ==

`topic.name`
  Name of the topic.

`topic_info.pub_nodes`
  Nodes that publish this topic. These can be used like normal [[../Nodes|node instances]].

`topic_info.sub_nodes`
  Nodes that subscribe this topic. These can be used like normal [[../Nodes|node instances]].

`list(topic_info.pub_nodes)`
  Convert `pub_nodes` to a `list`. 

`list(topic_info.sub_nodes)`
  Convert `sub_nodes` to a `list`. 

== Examples ==


=== rostopic echo ===

Print every message (using standard Python slice syntax): 
{{{
for m in topics.chatter[:]:
     print m

data: hello world 1275964384.53
data: hello world 1275964384.63
data: hello world 1275964384.73
}}}

Print every 10th message (using standard Python slice syntax):
{{{
for m in topics.yo[::10]:
     print m

data: hello world 1275964128.88
data: hello world 1275964350.23
data: hello world 1275964351.23
}}}

=== rostopic type/rosmsg show ===

Typing the name of the topic and hitting enter will show you the msg definition of the topic:

{{{
In [1]: topics.rosout
Out[1]: 
byte DEBUG=1
byte INFO=2
byte WARN=4
byte ERROR=8
byte FATAL=16
Header header
  uint32 seq
  time stamp
  string frame_id
byte level
string name
string msg
string file
string function
uint32 line
string[] topics
}}}

If you want to access the underlying message class, you can access the `._type` or `._type_name` fields, e.g.

{{{
In [5]: topics.rosout._type_name
Out[5]: 'roslib/Log'

In [6]: topics.rosout._type
Out[6]: <class 'roslib.msg._Log.Log'>

In [7]: topics.rosout._type()
Out[7]: 
header: 
  seq: 0
  stamp: 
    secs: 0
    nsecs: 0
  frame_id: ''
level: 0
name: ''
msg: ''
file: ''
function: ''
line: 0
topics: []
}}}

=== rostopic pub ===

Calling a method on a topic is equivalent to publishing to that topic. A common pattern is to print the msg definition of the topic first to familiarize yourself with the fields, then publishing your desired fields.

{{{
In [1]: topics.rosout
Out[1]: 
byte DEBUG=1
byte INFO=2
byte WARN=4
byte ERROR=8
byte FATAL=16
Header header
  uint32 seq
  time stamp
  string frame_id
byte level
string name
string msg
string file
string function
uint32 line
string[] topics
}}}

Followed by
{{{
In [2]: topics.rosout(msg='Hello There')
}}}

=== Republishing ===

{{{
for m in topics.chatter[:]:
     topics.chatter_echo(m)
}}}

=== Piping/Muxing ===

You can easily pipe from one topic to another. This creates a [[topic_tools/mux|mux]] that can then be used for future reassignment.

{{{
topics.foo = topics.bar
topics.foo = topics.car
}}}