Ask Your Question
1

sensor_msgs/Image generates float instead of int with python3

asked 2019-02-21 12:17:17 -0600

fbelmonteklein gravatar image

updated 2019-02-21 12:39:02 -0600

I am trying to compile ros from source to run some python code that requires python3 and opencv.

I got it mostly working, I think, but I have this strange error message when I try to publish an image using cv_bridge:

 File "/root/ros_catkin_ws/install_isolated/lib/python3/dist-packages/sensor_msgs/msg/_Image.py", line 134, in serialize
     buff.write(_get_struct_BI().pack(_x.is_bigendian, _x.step))
 struct.error: required argument is not an integer
(...)
rospy.exceptions.ROSSerializationException: field step must be unsigned integer type

I've edited this file and it turns out _x.step is a float, even though on the header of _Image.py it says it should be a UINT32. Manually changing this file and typecasting it into int, works, but I would like to fix what I did wrong.

The code that breaks this is very simple, just try to publish any image:

#!/usr/bin/env python3

import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import numpy as np

rospy.init_node('blank_image')
image_pub = rospy.Publisher("image_raw",Image, queue_size=1)

bridge = CvBridge()
blank_image = np.zeros((200,600,3), np.uint8)

r = rospy.Rate(10)
try:
    while not rospy.is_shutdown():
        try:
            image_pub.publish(bridge.cv2_to_imgmsg(blank_image, "bgr8"))
        except CvBridgeError as e:
            print(e)
        r.sleep()
    rospy.spin()
except KeyboardInterrupt:
    print("Shutting down")

Manually changing _Image.py is not a very good option since it is autogenerated (although I am not going to compile ros all the time...) I feel like I messed something up and that genpy is not generating the package appropriately.

My ros compilation script is:

#!/usr/bin/env bash
#from http://wiki.ros.org/kinetic/Installation/Source with minor adaptations to make it compile
OLDDIR=$PWD
set -e
rosdep init
rosdep update

echo "deb http://ppa.launchpad.net/ondrej/apache2/ubuntu xenial main " >>  /etc/apt/sources.list
echo "deb-src http://ppa.launchpad.net/ondrej/apache2/ubuntu xenial main " >>  /etc/apt/sources.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 14AA40EC0831756756D7F66C4F4EA0AAE5267A6C

apt-get update

mkdir ~/ros_catkin_ws
cd ~/ros_catkin_ws
# fix.py is a workaround for the issue https://github.com/vcstools/vcstools/issues/147
cp /root/face_recognition/fix.py ./

rosinstall_generator ros_comm sensor_msgs image_transport common_msgs --rosdistro kinetic --deps --wet-only --tar > kinetic-ros_comm-wet.rosinstall

### this needs to be python2.7
python fix.py

wstool init -j`nproc` src kinetic-ros_comm-wet-fixed.rosinstall

rosdep install --from-paths src --ignore-src --rosdistro kinetic -y

./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release --cmake-args -DPYTHON_VERSION=3.5

cd  /usr/lib/x86_64-linux-gnu/
ln -s /usr/lib/x86_64-linux-gnu/libboost_python-py35.so libboost_python3.so

cd $OLDDIR

I compile my catkin_ws with my own python3 code, vision_opencv-1.11.16 (I am trying to avoid installing opencv3) and using the line to catkin_make it as:

catkin_make --cmake-args -DPYTHON_VERSION=3.5 -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.5m -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.5m.so

List of installed packages (apt list --installed ) is https://pastebin.com/E3W6EH7K

List of pip installed packages (pip freeze) is https://pastebin.com/hYv6skJa

List of pip installed packages (pip3 freeze) is https://pastebin.com/3cZVVgSZ

fix ... (more)

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2019-10-15 15:14:27 -0600

jdlangs gravatar image

Not sure if this still needs an answer but I'll go ahead anyway.

The question seems to presume that the field types are fixed in the generated code but Python lets you the change a variable any time. So the problem is not that the step field is incorrect but that at some point someone assigned a float value to it instead of an int. Since it happened when you ran with Python 3, it likely was the change to the division operator, where someone had written code that assumed a divison would return an int directly. Very likely this happens in the cv2_to_imgmsg function and should be considered a bug blocking Python 3 migration.

edit flag offensive delete link more

Your Answer

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

Add Answer

Question Tools

2 followers

Stats

Asked: 2019-02-21 12:17:17 -0600

Seen: 75 times

Last updated: Oct 15