View on GitHub

Rosworkshop

HOME

Publisher Subscriber node

These are the basics nodes in ROS which used to share informations between nodes a publisher node publish the data using ROS Topics and Subscriber nodes will Subscribe to this topic to do this nodes specific task

In ROS we can write these nodes in c++ python lisp and a node can have many publishers and subscribers

Publisher nodes

These nodes in ROS which the user make only has funtionality of publishing required data to topics to which any number of subscriber can attach

Subscriber nodes

These nodes can subscribe to published topics from an another node and do its actions based on the input data

Publisher Subscriber nodes

These nodes can subscribe to a topic published topic from a node and also publish data based on conditions or refine the data and input to various nodes attached to it

All the examples from this this chapter can be done in c++ also but we use python for this course Since this is an introducry course plus learning curve for ROS is higher if many new to C++. ___ I hope Every one has Atom ide installed then

Open ATOM ide
File->Open Folder->select ROSworksop folder from UI appeard->click ok
after that you left side you have tree view
|--ROS_Worksop
   |--devel
   |--build
   |--src
      |--rosbasics
         |--include
         |--src
             -- node1.py
             -- node2.cpp
         --CMakeLists.txt
         --package.xml

Let’s create publisher/subscriber node

Create a file name ‘helloworldpub.py’ in src folder in rosbasics

Publisher node

helloworldpub.py

#!/usr/bin/python

import rospy #ROS module
from std_msgs.msg import String #ROSmsg module

def main():
 rospy.init_node(name="Helloworld",anonymous=False)  #init_node will start the node
 pub=rospy.Publisher("mytopic",String,queue_size=0) #create publisher in name
 r=rospy.Rate(hz=10) # Rate at which data publishes
 msg=String()
 msg.data="Helloworld"
 while not rospy.is_shutdown():
  pub.publish(msg)
  r.sleep()
if __name__ == '__main__':
 try:
     main()
 except rospy.ROSInterruptException:
  pass

To make code excuatable

cd ROS_Worksop/src/rosbasics/src
#then
chmod +x helloworldpub.py
#then
cd ROSworksop
catkin_make

To run the node

Subscriber node

helloworldsub.py

#!/usr/bin/python
import rospy
from std_msgs.msg import String

def callback(msg):
  print(msg.data)

def main():
  rospy.init_node(name="mysub",anonymous=False)
  sub=rospy.Subscriber("/mytopic",String,callback)
  rospy.loginfo("subscriber init")

if __name__ == '__main__':
  try:
      main():
      rospy.spin()
      '''
        rospy.spin() is same as
        while not rospy.is_shutdown():
            pass

        '''
  except rospy.ROSInterruptException:
    pass

To make code excuatable

cd ROS_Worksop/src/rosbasics/src
#then
chmod +x helloworldsub.py
#then
cd ROSworksop
catkin_make

To run the node

Subscribler Publishers in one node

Till now we have made is individual subscriber and publisher in a ROS node you can have many publishers and subscribers

As we metioned a ROS node may contain any number of combinations of

As the funtionality of the node increases its better to impliment oops(object oriented programming) to remove errors pubsub.py here we are going to create a node which control location turtle which has one subscriber and one publisher which

pubsub.py

#!/usr/bin/python

import rospy
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose
import math
class pubsub():
  def __init__(self):
    rospy.init_node("turtlecontroller",anonymous=False)
    self.commad=Twist()
    self.null=Twist()
    self.pub=rospy.Publisher("turtle1/cmd_vel",Twist,queue_size=0)
    self.sub=rospy.Subscriber("turtle1/pose",Pose,self.callback)
    self.x =0
    self.y = 0
    self.pos=Pose()
    r=rospy.Rate(hz=10)
    self.flag=0
    self.maxv=0.5
    self.maxw=5.0

    self.commad.linear.y=0
    self.commad.linear.z=0
    self.commad.angular.x=0
    self.commad.angular.y=0

    self.headx=0
    self.heady=0
    self.null.linear.x=0
    self.null.linear.y=0
    self.null.linear.z=0
    self.null.angular.x=0
    self.null.angular.y=0
    self.null.angular.z=0

    rospy.loginfo("commad node status")

  def callback(self,msg):
    self.pos=msg

  def run(self):
    while not rospy.is_shutdown():
      if (self.flag==0 or  self.flag==1):
        self.pub.publish(self.null)
        self.x,self.y=map(float,raw_input("input x,y :\t").split())
        self.flag=2
      else:
        trgx=self.x-self.pos.x
        trgy=self.y-self.pos.y
        ttheta=self.pos.theta
        self.headx=math.cos(ttheta)
        self.heady=math.sin(ttheta)
        sqrt=pow(trgx,2)+pow(trgy,2)
        sqrt=pow(sqrt,0.5)

        if sqrt<=0.03:
          self.flag=1
          self.pub.publish(self.null)
        else:


          u=(trgx*self.headx+trgy*self.heady)/sqrt
          if u>1:
              u=1
          s=1-pow(u,2)
          print(self.pos.x,self.pos.y,u,sqrt)
          angle=math.atan2(pow(s,0.5),u)

          v=min(self.maxv,sqrt)
          if angle==0:
              self.commad.linear.x=v
              self.commad.angular.z=0

          elif angle!=0:
            self.commad.linear.x=v
            self.commad.angular.z=(angle/math.pi)*-1.0* self.maxw

          self.pub.publish(self.commad)

if __name__ == '__main__':
  try:
    mynode=pubsub()
    mynode.run()
  except rospy.ROSInterruptException:
    pass

Important points in pub/sub nodes

Back to:Chapter 2
Next to:Chapter 4