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

Revision history [back]

I'm working on this same issue and tried the solution you posted William. It seems like what I did should work, but when I republish the image data from the camera to a different topic (/displayed_image), the RVIZ camera view does not show the image, just a black screen. RVIZ doesn't even give out a warning, it shows that it is receiving the images. When I echo the topic data from /displayed_image, it seems like I get the same data as the actual camera topic. Any idea's as to why RVIZ is not correctly displaying my image?

#!/usr/bin/env python

import rospy
from std_msgs.msg import Header, String, Int16
from sensor_msgs.msg import Image

def image_publish_callback(data):
    #This publishes out the information from the Gazebo camera to a topic which the RVIZ camera displays.
    #Only triggers when toggle_key=0
    global toggle_key, pub
    img = Image()
    img.data = data.data
    img.height = data.height
    img.width = data.width
    img.step = data.step
    img.is_bigendian = data.is_bigendian
    img.encoding = data.encoding
    img.header = data.header
    img.header.stamp = data.header.stamp
    img.header.frame_id = data.header.frame_id
    pub.publish(img)

def blank_pub():
    global toggle_key,pub,rate
    #This publishes out a black screen to the RVIZ camera topic if the toggle_key=1 (black screen selected)
    while not rospy.is_shutdown() and toggle_key == 1:
        img = Image()
        img.data = [0 for _ in range(1200*800)] # data
        img.height = 800
        img.width = 1200
        img.step = 3600
        img.is_bigendian = 0
        img.encoding = "rgb8"
        img.header = Header() 
        img.header.stamp = rospy.Time.now()
        img.header.frame_id = "camera_link"
        pub.publish(img)
        rate.sleep()

def toggle_callback(data):
    global toggle_key, sub_gi, sub_bs
    toggle_key = (toggle_key+1)%2 #Switch from 0 to 1 w/ each button press        
    if toggle_key == 0:
        sub_gi = rospy.Subscriber('/rrbot/camera1/image_raw',Image,image_publish_callback)
        print(0)
    elif toggle_key == 1:
        sub_gi.unregister()
        print(1)

def publisher_subscriber():
    global pub, toggle_key,rate, sub_gi

    #setup subscribers and publisher
    rospy.init_node('camera_view_publisher')
    sub_gi = rospy.Subscriber('/rrbot/camera1/image_raw',Image,image_publish_callback)
    rospy.Subscriber('screen_swap_button1',Int16,toggle_callback)
    #rospy.Subscriber('screen_swap_button2',Int16,toggle_callback)
    #rospy.Subscriber('screen_swap_button3',Int16,toggle_callback)
    #rospy.Subscriber('screen_swap_button4',Int16,toggle_callback)
    pub = rospy.Publisher('displayed_image',Image,queue_size=10)
    rate = rospy.Rate(1)
    toggle_key = 0   #start on the gazebo published screen

    while not rospy.is_shutdown():
        blank_pub()  #publishes a blank screen if toggle key=0 and does nothing if toggle key=1

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

Original Question:

I'm working on this same issue and tried the solution you posted William. It seems like what I did should work, but when I republish the image data from the camera to a different topic (/displayed_image), the RVIZ camera view does not show the image, just a black screen. RVIZ doesn't even give out a warning, it shows that it is receiving the images. When I echo the topic data from /displayed_image, it seems like I get the same data as the actual camera topic. Any idea's as to why RVIZ is not correctly displaying my image?

Answer: Thanks to the suggestion of William and Dornhege, I figured out a workaround. The issue was actually something with rviz (not sure what), but when I use rosrun image_view image_view <image_topic> it correctly shows either the camera view image or the blank screen image depending on my mux settings. For future reference for anyone trying to do something similar:

  1. Run your gazebo model with the camera
  2. Run your blank screen publisher (code for mine is below)
  3. Setup the mux: rosrun topic_tools mux topic_to_publish_to camera_topic blank_screen_topic mux:=image_mux
  4. To switch between the selected images use: rosrun topic_tools mux_select image_mux image_topic_to_display
  5. You can also do this through service calls, I haven't yet, but see http://wiki.ros.org/topic_tools/mux for details.

"Preformatted text" won't allow me to select the whole code... it just takes bits and pieces if I try to do the whole thing. However, here is the important bit (this node is not terribly difficult anyway).

#!/usr/bin/env python

import rospy
from std_msgs.msg import Header, String, Int16
from sensor_msgs.msg import Image

def image_publish_callback(data):
    #This publishes out the information from the Gazebo camera to a topic which the RVIZ camera displays.
    #Only triggers when toggle_key=0
    global toggle_key, pub
    img = Image()
    img.data = data.data
    img.height = data.height
    img.width = data.width
    img.step = data.step
    img.is_bigendian = data.is_bigendian
    img.encoding = data.encoding
    img.header = data.header
    img.header.stamp = data.header.stamp
    img.header.frame_id = data.header.frame_id
    pub.publish(img)

def blank_pub():
    global toggle_key,pub,rate
    #This publishes out a black screen to the RVIZ camera topic if the toggle_key=1 (black screen selected)
    blanker():

rospy.init_node('blank_screen')
pub=rospy.Publisher('blank_screen', Image, queue_size=10)
rate = rospy.Rate(1)

while not rospy.is_shutdown() and toggle_key == 1:
    rospy.is_shutdown():
    img = Image()
     img.data = [0 for _ in range(1200*800)] range(800*3600)] # data
     img.height = 800
     img.width = 1200
    =1200
    img.step = 3600
     img.is_bigendian = 0
     img.encoding = "rgb8"
     img.header = Header() 
    Header()
    img.header.frame_id = "camera_link"
    img.header.stamp = rospy.Time.now()
        img.header.frame_id = "camera_link"
        pub.publish(img)
     rate.sleep()

def toggle_callback(data):
    global toggle_key, sub_gi, sub_bs
    toggle_key = (toggle_key+1)%2 #Switch from 0 to 1 w/ each button press        
    if toggle_key == 0:
        sub_gi = rospy.Subscriber('/rrbot/camera1/image_raw',Image,image_publish_callback)
        print(0)
    elif toggle_key == 1:
        sub_gi.unregister()
        print(1)

def publisher_subscriber():
    global pub, toggle_key,rate, sub_gi

    #setup subscribers and publisher
    rospy.init_node('camera_view_publisher')
    sub_gi = rospy.Subscriber('/rrbot/camera1/image_raw',Image,image_publish_callback)
    rospy.Subscriber('screen_swap_button1',Int16,toggle_callback)
    #rospy.Subscriber('screen_swap_button2',Int16,toggle_callback)
    #rospy.Subscriber('screen_swap_button3',Int16,toggle_callback)
    #rospy.Subscriber('screen_swap_button4',Int16,toggle_callback)
    pub = rospy.Publisher('displayed_image',Image,queue_size=10)
    rate = rospy.Rate(1)
    toggle_key = 0   #start on the gazebo published screen

    while not rospy.is_shutdown():
        blank_pub()  #publishes a blank screen if toggle key=0 and does nothing if toggle key=1

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