Ask Your Question
1

how do I make a ros publisher run under python 3?

asked 2013-04-14 13:03:28 -0500

packrat gravatar image

updated 2013-04-15 17:09:03 -0500

joq gravatar image

I made a python3 script that will read left, right encoder ticks from an arduino. I am trying to now get that same code to publish those ticks. This is what I have so far. sorry I not at all good with python.

    #!/usr/bin/env python3
import serial
import time
import rospy
from std_msgs.msg import Int16
# assign your port and speed
ser = serial.Serial('/dev/ttyUSB0', 1152000)
print("Reset Arduino")
time.sleep(3)
while (1)  # WORKING PART
    #left encoder read
    ser.write(bytes('l', 'UTF-8'))
    left = ser.readline().decode('ascii').strip()
    print("left")
    #print(left)
        #right encoder read
    ser.write(bytes('r', 'UTF-8'))
    right = ser.readline().decode('ascii').strip()
    right = right.rstrip('\r\n')
    print('right')
    #print(right)
    time.sleep(.0125)
    #node to publish left to lwheel (std_msgs/Int16)
#not working part
    def leftticks():
        pub = rospy.Publisher('lwheel', Int16)
        rospy.init_node('leftticks')
        while not rospy.is_shutdown():
            lstr = left
            rospy.loginfo(lstr)
            pub.publish(String(lstr))
            rospy.sleep(.5)


    if __name__ == '__main__':
        try:
            leftticks()
        except rospy.ROSInterruptException:
            pass

    #node to pulish right to rwheel (std_msgs/Int16)
    def rightticks():
        pub = rospy.Publisher('rwheel', Int16)
        rospy.init_node('rightticks')
        while not rospy.is_shutdown():
            rstr = right
            rospy.loginfo(rstr)
            pub.publish(String(rstr))
            rospy.sleep(.5)


    if __name__ == '__main__':
        try:
            rightticks()
        except rospy.ROSInterruptException:
            pass

How do I get it all to work together. As you can tell I have no clue what I am doing. Thanks for any help you can give.

edit retag flag offensive close merge delete

Comments

Right now that is really hard to do. You don't mention what OS or ROS version you are using.

joq gravatar image joq  ( 2013-04-15 17:12:16 -0500 )edit

BTW, the shebang (#!) needs to be left justified.

joq gravatar image joq  ( 2013-04-15 17:12:57 -0500 )edit

I am using Ubuntu 12.04lts and groovy. If I can't get to work on python3 how do I make it work under python 2.7 or what ros uses?

packrat gravatar image packrat  ( 2013-04-15 22:53:58 -0500 )edit

1 Answer

Sort by » oldest newest most voted
1

answered 2013-04-16 05:06:45 -0500

joq gravatar image

updated 2013-04-16 15:06:29 -0500

The ROS Groovy release on Ubuntu Precise 12.04 uses Python 2.7, which is the default interpreter for that system.

Precise also provides Python 3.2, which you can install, but the ROS distribution was not built to use that. It is probably possible to get it working by building everything from source, but I do not recommend that approach.

If you are willing to use Python 2, things will be much easier for now. Note that handling of bytes and strings differs between Python 2 and Python 3. It is possible to write code that works with either, but that gets tricky. Keep it simple until you have something that works.

First, you need to get comfortable with basic ROS programming in Python. This tutorial will explain how to publish ROS messages.

It's a little hard to untangle the code you posted. If you are new to Python: beware that indentation is significant because it defines the block structure of your program. So, be careful.

You should not try to create two ROS nodes in that single script. You don't need to, anyway, one node will suffice. Your main function will probably look more like this:

rospy.init_node('ticks')
lpub = rospy.Publisher('lwheel', Int16)
rpub = rospy.Publisher('rwheel', Int16)
hz_rate = rospy.Rate(80)
while not rospy.is_shutdown():
    # read left encoder
    lpub.publish(Int16(data=int(left)))
    # read right encoder
    rpub.publish(Int16(data=int(right)))
    hz_rate.sleep()

That is just a simplified overview. Your actual logic will be more complex.

edit flag offensive delete link more

Comments

Awesome. I made the changes, and it runs until I try to subscribe to the topic. I get this error

packrat gravatar image packrat  ( 2013-04-16 12:03:14 -0500 )edit

Traceback (most recent call last): File "Desktop/try3.py", line 20, in <module> lpub.publish(Int16(left)) File "/opt/ros/groovy/lib/python2.7/dist-packages/rospy/topics.py", line 801, in publish raise ROSSerializationException(str(e))

packrat gravatar image packrat  ( 2013-04-16 12:03:59 -0500 )edit

rospy.exceptions.ROSSerializationException: field data must be an integer type

packrat gravatar image packrat  ( 2013-04-16 12:04:15 -0500 )edit

See edited version above.

joq gravatar image joq  ( 2013-04-16 15:07:09 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2013-04-14 13:03:28 -0500

Seen: 2,962 times

Last updated: Apr 16 '13