ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

writing a publisher and subscriber and unsure how to finish it

asked 2017-09-20 10:19:23 -0600

I am taking this edx course on robotics using ROS and our first project is "writing a node that subscribes to a topic and publishes to another. Your code will subscribe to a topic called 'two_ints', on which a custom message containing two integers can be broadcast. Make sure to familiarize yourself with the message format of this topic:

int16 a
int16 b

. Those two integers are to be added and the result published to topic 'sum' as an Int16 from std_msgs. "

ok this is what I have so far from stringing other examples I have seen together and guessing... very lost now though about how to connect these and also what the 'callback' thing does or if I need to define that..

#!/usr/bin/env python  
import rospy

from std_msgs.msg import Int16
from project1_solution.msg import TwoInts

def listener():
 rospy.init_node('project1_solution', anonymous=True)
 rospy.Subscriber("two_ints", TwoInts, callback)
 rospy.spin()

while not rospy.is_shutdown():
  msg = TwoInts()
  solution = msg.a + msg.b


def talker():
 pub = rospy.Publisher('Sum', Int16, queue_size=10)
 rospy.init_node('project1_solution', anonymous=True)
 rate = rospy.Rate(0.5) #.5hz



 while not rospy.is_shutdown():
  msg = Int16()

  pub.publish(msg)
  rate.sleep()

thank you, any tips or help would be great!

edit retag flag offensive close merge delete

Comments

How far have you gotten with the official tutorials found on the wiki?

jayess gravatar image jayess  ( 2017-09-20 10:39:53 -0600 )edit

@jayess, I have completed 1-20 plus beginning tf tutorials and some urdf tutorials now. also reading 'gentle introduction to ROS'

moonspacedancer gravatar image moonspacedancer  ( 2017-09-20 10:54:03 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2017-11-06 07:07:15 -0600

updated 2017-11-06 08:23:48 -0600

I have created a package (my_pkg) with two nodes, trying to reproduce your situation.. It is like that:

catkin_create_pkg my_pkg rospy std_msgs message_generation message_runtime

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(my_pkg)

find_package(catkin REQUIRED COMPONENTS
  message_generation
  message_runtime
  rospy
  std_msgs
)

add_message_files(
  FILES
  two_ints.msg
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES my_pkg
#  CATKIN_DEPENDS message_generation message_runtime rospy std_msgs
#  DEPENDS system_lib
)

include_directories(
  ${catkin_INCLUDE_DIRS}
)

package.xml

<?xml version="1.0"?>
<package>
  <name>my_pkg</name>
  <version>0.0.0</version>
  <description>The my_pkg package</description>

  <maintainer email="user@todo.todo">user</maintainer>

  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>message_generation</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <run_depend>message_runtime</run_depend>
  <run_depend>rospy</run_depend>
  <run_depend>std_msgs</run_depend>

  <export>

  </export>
</package>

The message file msg/two_ints.msg

int16 a
int16 b

The publisher node (that publishes the two_ints message) scripts/publisher_two_ints.py:

#!/usr/bin/env python
import rospy

from my_pkg.msg import two_ints

def main():
    rospy.init_node("two_ints_publisher")
    pub = rospy.Publisher("two_ints", two_ints, queue_size=1)
    r = rospy.Rate(1)

    msg = two_ints()
    while not rospy.is_shutdown():
        msg.a = 2
        msg.b = 15
        pub.publish(msg)
        r.sleep()

if __name__ == "__main__":
    try:
        main()
    except rospy.ROSInterruptException:
        pass

And finally, the one you are interested, the subscriber, which calculates the sum and publishes the result into the /sum topic: (subscriber_two_ints.py)

#!/usr/bin/env python
import rospy

from my_pkg.msg import two_ints
from std_msgs.msg import Int16

result = Int16()

def callback(msg):
    result.data = msg.a + msg.b
    rospy.loginfo(result)

def main():
    rospy.init_node("two_ints_subscriber")
    pub = rospy.Publisher("sum", Int16, queue_size=1)
    sub = rospy.Subscriber("two_ints", two_ints, callback)
    r = rospy.Rate(1)

    while not rospy.is_shutdown():
        pub.publish(result)
        r.sleep()

if __name__ == "__main__":
    try:
        main()
    except rospy.ROSInterruptException:
        pass

Basically, you have a publisher and a publisher+subscriber. It's common to have a node with both, you have to handle the loop rate and the callback methods and be careful to not freeze inside your loop.

You can check the development, step-by-step in this video: https://youtu.be/H6bw5aw9mOQ

I hope it can help you!

edit flag offensive delete link more

Comments

1

Please do not suggest writing the subscriber in this way. There is absolutely no need to run your own while loop here, or to continuously publish result.

gvdhoorn gravatar image gvdhoorn  ( 2017-11-06 07:46:28 -0600 )edit
0

answered 2017-09-20 11:36:12 -0600

jayess gravatar image

Some of the issues with your solution is that you're calling init_node() twice, your subscriber's scope is limited to the scope of the listener() function, your publisher's scope is limited to the scope of the talker() function, and your subscriber says that a function called callback() is the callback but you don't have a function called callback.

This is how it can be done in a very simple manner and I'll try to stick with the naming that you used and some inspiration from the subscriber/publisher tutorial. I'm going to give a high-level overview, but I can always update with more information.

# 1. Declare any libraries/messages that you need
import rospy

from std_msgs.msg import Int16
from project1_solution.msg import TwoInts

# 2. Define a callback in order to handle any incoming messages. This is where you process 
# the messages and is definitely needed. 
def callback(msg):
    sum = Int16()
    sum = msg.a + msg.b
    # Now, publish the message from the callback. I'll leave it for you to figure out how

# 3. This is where you will start your node, declare your publisher, 
# declare your subscriber, and spin()
def listener():
    # I'll leave this part up to you. Read the tutorial and see if you can finish
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-09-20 10:19:23 -0600

Seen: 3,810 times

Last updated: Nov 06 '17